forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
implemented frontend including separate message system; started to implement backend
This commit is contained in:
17
yjs-poll/node_modules/lib0/crypto/aes-gcm.d.ts
generated
vendored
Normal file
17
yjs-poll/node_modules/lib0/crypto/aes-gcm.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
export function encrypt(key: CryptoKey, data: Uint8Array<ArrayBuffer>): Promise<Uint8Array<ArrayBuffer>>;
|
||||
export function decrypt(key: CryptoKey, data: Uint8Array<ArrayBuffer>): PromiseLike<Uint8Array>;
|
||||
export function importKeyJwk(jwk: any, { usages, extractable }?: {
|
||||
usages?: Usages | undefined;
|
||||
extractable?: boolean | undefined;
|
||||
}): Promise<CryptoKey>;
|
||||
export function importKeyRaw(raw: Uint8Array<ArrayBuffer>, { usages, extractable }?: {
|
||||
usages?: Usages | undefined;
|
||||
extractable?: boolean | undefined;
|
||||
}): Promise<CryptoKey>;
|
||||
export function deriveKey(secret: Uint8Array<ArrayBuffer> | string, salt: Uint8Array<ArrayBuffer> | string, { extractable, usages }?: {
|
||||
extractable?: boolean | undefined;
|
||||
usages?: Usages | undefined;
|
||||
}): Promise<CryptoKey>;
|
||||
export type Usages = Array<"encrypt" | "decrypt">;
|
||||
export { exportKeyJwk, exportKeyRaw } from "./common.js";
|
||||
//# sourceMappingURL=aes-gcm.d.ts.map
|
||||
1
yjs-poll/node_modules/lib0/crypto/aes-gcm.d.ts.map
generated
vendored
Normal file
1
yjs-poll/node_modules/lib0/crypto/aes-gcm.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"aes-gcm.d.ts","sourceRoot":"","sources":["aes-gcm.js"],"names":[],"mappings":"AAuBO,6BAHI,SAAS,QACT,UAAU,CAAC,WAAW,CAAC,oCAkBjC;AAWM,6BAJI,SAAS,QACT,UAAU,CAAC,WAAW,CAAC,GACtB,WAAW,CAAC,UAAU,CAAC,CAclC;AAaM,kCALI,GAAG,4BAEX;IAAsB,MAAM;IACL,WAAW;CAAC,sBAQrC;AAUM,kCALI,UAAU,CAAC,WAAW,CAAC,4BAE/B;IAAsB,MAAM;IACL,WAAW;CAAC,sBAG0D;AAmBzF,kCANI,UAAU,CAAC,WAAW,CAAC,GAAC,MAAM,QAC9B,UAAU,CAAC,WAAW,CAAC,GAAC,MAAM,4BAEtC;IAAuB,WAAW;IACZ,MAAM;CAAC,sBAsB7B;qBAxHU,KAAK,CAAC,SAAS,GAAC,SAAS,CAAC"}
|
||||
132
yjs-poll/node_modules/lib0/crypto/aes-gcm.js
generated
vendored
Normal file
132
yjs-poll/node_modules/lib0/crypto/aes-gcm.js
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* AES-GCM is a symmetric key for encryption
|
||||
*/
|
||||
|
||||
import * as encoding from '../encoding.js'
|
||||
import * as decoding from '../decoding.js'
|
||||
import * as webcrypto from 'lib0/webcrypto'
|
||||
import * as string from '../string.js'
|
||||
export { exportKeyJwk, exportKeyRaw } from './common.js'
|
||||
|
||||
/**
|
||||
* @typedef {Array<'encrypt'|'decrypt'>} Usages
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Usages}
|
||||
*/
|
||||
const defaultUsages = ['encrypt', 'decrypt']
|
||||
|
||||
/**
|
||||
* @param {CryptoKey} key
|
||||
* @param {Uint8Array<ArrayBuffer>} data
|
||||
*/
|
||||
export const encrypt = (key, data) => {
|
||||
const iv = webcrypto.getRandomValues(new Uint8Array(16)) // 92bit is enough. 128bit is recommended if space is not an issue.
|
||||
return webcrypto.subtle.encrypt(
|
||||
{
|
||||
name: 'AES-GCM',
|
||||
iv
|
||||
},
|
||||
key,
|
||||
data
|
||||
).then(cipher => {
|
||||
const encryptedDataEncoder = encoding.createEncoder()
|
||||
// iv may be sent in the clear to the other peers
|
||||
encoding.writeUint8Array(encryptedDataEncoder, iv)
|
||||
encoding.writeVarUint8Array(encryptedDataEncoder, new Uint8Array(cipher))
|
||||
return encoding.toUint8Array(encryptedDataEncoder)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental The API is not final!
|
||||
*
|
||||
* Decrypt some data using AES-GCM method.
|
||||
*
|
||||
* @param {CryptoKey} key
|
||||
* @param {Uint8Array<ArrayBuffer>} data
|
||||
* @return {PromiseLike<Uint8Array>} decrypted buffer
|
||||
*/
|
||||
export const decrypt = (key, data) => {
|
||||
const dataDecoder = decoding.createDecoder(data)
|
||||
const iv = decoding.readUint8Array(dataDecoder, 16)
|
||||
const cipher = decoding.readVarUint8Array(dataDecoder)
|
||||
return webcrypto.subtle.decrypt(
|
||||
{
|
||||
name: 'AES-GCM',
|
||||
iv
|
||||
},
|
||||
key,
|
||||
cipher
|
||||
).then(data => new Uint8Array(data))
|
||||
}
|
||||
|
||||
const aesAlgDef = {
|
||||
name: 'AES-GCM',
|
||||
length: 256
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} jwk
|
||||
* @param {Object} opts
|
||||
* @param {Usages} [opts.usages]
|
||||
* @param {boolean} [opts.extractable]
|
||||
*/
|
||||
export const importKeyJwk = (jwk, { usages, extractable = false } = {}) => {
|
||||
if (usages == null) {
|
||||
/* c8 ignore next */
|
||||
usages = jwk.key_ops || defaultUsages
|
||||
}
|
||||
return webcrypto.subtle.importKey('jwk', jwk, 'AES-GCM', extractable, /** @type {Usages} */ (usages))
|
||||
}
|
||||
|
||||
/**
|
||||
* Only suited for importing public keys.
|
||||
*
|
||||
* @param {Uint8Array<ArrayBuffer>} raw
|
||||
* @param {Object} opts
|
||||
* @param {Usages} [opts.usages]
|
||||
* @param {boolean} [opts.extractable]
|
||||
*/
|
||||
export const importKeyRaw = (raw, { usages = defaultUsages, extractable = false } = {}) =>
|
||||
webcrypto.subtle.importKey('raw', raw, aesAlgDef, extractable, /** @type {Usages} */ (usages))
|
||||
|
||||
/**
|
||||
* @param {Uint8Array<ArrayBuffer> | string} data
|
||||
*/
|
||||
/* c8 ignore next */
|
||||
const toBinary = data => typeof data === 'string' ? string.encodeUtf8(data) : data
|
||||
|
||||
/**
|
||||
* @experimental The API is not final!
|
||||
*
|
||||
* Derive an symmetric key using the Password-Based-Key-Derivation-Function-2.
|
||||
*
|
||||
* @param {Uint8Array<ArrayBuffer>|string} secret
|
||||
* @param {Uint8Array<ArrayBuffer>|string} salt
|
||||
* @param {Object} opts
|
||||
* @param {boolean} [opts.extractable]
|
||||
* @param {Usages} [opts.usages]
|
||||
*/
|
||||
export const deriveKey = (secret, salt, { extractable = false, usages = defaultUsages } = {}) =>
|
||||
webcrypto.subtle.importKey(
|
||||
'raw',
|
||||
toBinary(secret),
|
||||
'PBKDF2',
|
||||
false,
|
||||
['deriveKey']
|
||||
).then(keyMaterial =>
|
||||
webcrypto.subtle.deriveKey(
|
||||
{
|
||||
name: 'PBKDF2',
|
||||
salt: toBinary(salt), // NIST recommends at least 64 bits
|
||||
iterations: 600000, // OWASP recommends 600k iterations
|
||||
hash: 'SHA-256'
|
||||
},
|
||||
keyMaterial,
|
||||
aesAlgDef,
|
||||
extractable,
|
||||
usages
|
||||
)
|
||||
)
|
||||
3
yjs-poll/node_modules/lib0/crypto/common.d.ts
generated
vendored
Normal file
3
yjs-poll/node_modules/lib0/crypto/common.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export function exportKeyJwk(key: CryptoKey): Promise<JsonWebKey>;
|
||||
export function exportKeyRaw(key: CryptoKey): Promise<Uint8Array<ArrayBuffer>>;
|
||||
//# sourceMappingURL=common.d.ts.map
|
||||
1
yjs-poll/node_modules/lib0/crypto/common.d.ts.map
generated
vendored
Normal file
1
yjs-poll/node_modules/lib0/crypto/common.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["common.js"],"names":[],"mappings":"AAKO,kCAFI,SAAS,uBAMnB;AAQM,kCAHI,SAAS,GACR,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAG6B"}
|
||||
19
yjs-poll/node_modules/lib0/crypto/common.js
generated
vendored
Normal file
19
yjs-poll/node_modules/lib0/crypto/common.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import * as webcrypto from 'lib0/webcrypto'
|
||||
|
||||
/**
|
||||
* @param {CryptoKey} key
|
||||
*/
|
||||
export const exportKeyJwk = async key => {
|
||||
const jwk = await webcrypto.subtle.exportKey('jwk', key)
|
||||
jwk.key_ops = key.usages
|
||||
return jwk
|
||||
}
|
||||
|
||||
/**
|
||||
* Only suited for exporting public keys.
|
||||
*
|
||||
* @param {CryptoKey} key
|
||||
* @return {Promise<Uint8Array<ArrayBuffer>>}
|
||||
*/
|
||||
export const exportKeyRaw = key =>
|
||||
webcrypto.subtle.exportKey('raw', key).then(key => new Uint8Array(key))
|
||||
17
yjs-poll/node_modules/lib0/crypto/ecdsa.d.ts
generated
vendored
Normal file
17
yjs-poll/node_modules/lib0/crypto/ecdsa.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
export function sign(key: CryptoKey, data: Uint8Array<ArrayBuffer>): PromiseLike<Uint8Array<ArrayBuffer>>;
|
||||
export function verify(key: CryptoKey, signature: Uint8Array<ArrayBuffer>, data: Uint8Array<ArrayBuffer>): PromiseLike<boolean>;
|
||||
export function generateKeyPair({ extractable, usages }?: {
|
||||
extractable?: boolean | undefined;
|
||||
usages?: Usages | undefined;
|
||||
}): Promise<CryptoKeyPair>;
|
||||
export function importKeyJwk(jwk: any, { extractable, usages }?: {
|
||||
extractable?: boolean | undefined;
|
||||
usages?: Usages | undefined;
|
||||
}): Promise<CryptoKey>;
|
||||
export function importKeyRaw(raw: any, { extractable, usages }?: {
|
||||
extractable?: boolean | undefined;
|
||||
usages?: Usages | undefined;
|
||||
}): Promise<CryptoKey>;
|
||||
export type Usages = Array<"sign" | "verify">;
|
||||
export { exportKeyJwk, exportKeyRaw } from "./common.js";
|
||||
//# sourceMappingURL=ecdsa.d.ts.map
|
||||
1
yjs-poll/node_modules/lib0/crypto/ecdsa.d.ts.map
generated
vendored
Normal file
1
yjs-poll/node_modules/lib0/crypto/ecdsa.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"ecdsa.d.ts","sourceRoot":"","sources":["ecdsa.js"],"names":[],"mappings":"AA8BO,0BAJI,SAAS,QACT,UAAU,CAAC,WAAW,CAAC,GACtB,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAOA;AAYzC,4BALI,SAAS,aACT,UAAU,CAAC,WAAW,CAAC,QACvB,UAAU,CAAC,WAAW,CAAC,GACtB,WAAW,CAAC,OAAO,CAAC,CAQ7B;AAaI,0DAHJ;IAAuB,WAAW;IACZ,MAAM;CAAC,0BAO7B;AAQI,kCALI,GAAG,4BAEX;IAAuB,WAAW;IACZ,MAAM;CAAC,sBAQ/B;AAUM,kCALI,GAAG,4BAEX;IAAuB,WAAW;IACZ,MAAM;CAAC,sBAGkD;qBAxFrE,KAAK,CAAC,MAAM,GAAC,QAAQ,CAAC"}
|
||||
97
yjs-poll/node_modules/lib0/crypto/ecdsa.js
generated
vendored
Normal file
97
yjs-poll/node_modules/lib0/crypto/ecdsa.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* ECDSA is an asymmetric key for signing
|
||||
*/
|
||||
|
||||
import * as webcrypto from 'lib0/webcrypto'
|
||||
export { exportKeyJwk, exportKeyRaw } from './common.js'
|
||||
|
||||
/**
|
||||
* @typedef {Array<'sign'|'verify'>} Usages
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Usages}
|
||||
*/
|
||||
const defaultUsages = ['sign', 'verify']
|
||||
|
||||
const defaultSignAlgorithm = {
|
||||
name: 'ECDSA',
|
||||
hash: 'SHA-384'
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental The API is not final!
|
||||
*
|
||||
* Sign a message
|
||||
*
|
||||
* @param {CryptoKey} key
|
||||
* @param {Uint8Array<ArrayBuffer>} data
|
||||
* @return {PromiseLike<Uint8Array<ArrayBuffer>>} signature
|
||||
*/
|
||||
export const sign = (key, data) =>
|
||||
webcrypto.subtle.sign(
|
||||
defaultSignAlgorithm,
|
||||
key,
|
||||
data
|
||||
).then(signature => new Uint8Array(signature))
|
||||
|
||||
/**
|
||||
* @experimental The API is not final!
|
||||
*
|
||||
* Sign a message
|
||||
*
|
||||
* @param {CryptoKey} key
|
||||
* @param {Uint8Array<ArrayBuffer>} signature
|
||||
* @param {Uint8Array<ArrayBuffer>} data
|
||||
* @return {PromiseLike<boolean>} signature
|
||||
*/
|
||||
export const verify = (key, signature, data) =>
|
||||
webcrypto.subtle.verify(
|
||||
defaultSignAlgorithm,
|
||||
key,
|
||||
signature,
|
||||
data
|
||||
)
|
||||
|
||||
const defaultKeyAlgorithm = {
|
||||
name: 'ECDSA',
|
||||
namedCurve: 'P-384'
|
||||
}
|
||||
|
||||
/* c8 ignore next */
|
||||
/**
|
||||
* @param {Object} opts
|
||||
* @param {boolean} [opts.extractable]
|
||||
* @param {Usages} [opts.usages]
|
||||
*/
|
||||
export const generateKeyPair = ({ extractable = false, usages = defaultUsages } = {}) =>
|
||||
webcrypto.subtle.generateKey(
|
||||
defaultKeyAlgorithm,
|
||||
extractable,
|
||||
usages
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {any} jwk
|
||||
* @param {Object} opts
|
||||
* @param {boolean} [opts.extractable]
|
||||
* @param {Usages} [opts.usages]
|
||||
*/
|
||||
export const importKeyJwk = (jwk, { extractable = false, usages } = {}) => {
|
||||
if (usages == null) {
|
||||
/* c8 ignore next 2 */
|
||||
usages = jwk.key_ops || defaultUsages
|
||||
}
|
||||
return webcrypto.subtle.importKey('jwk', jwk, defaultKeyAlgorithm, extractable, /** @type {Usages} */ (usages))
|
||||
}
|
||||
|
||||
/**
|
||||
* Only suited for importing public keys.
|
||||
*
|
||||
* @param {any} raw
|
||||
* @param {Object} opts
|
||||
* @param {boolean} [opts.extractable]
|
||||
* @param {Usages} [opts.usages]
|
||||
*/
|
||||
export const importKeyRaw = (raw, { extractable = false, usages = defaultUsages } = {}) =>
|
||||
webcrypto.subtle.importKey('raw', raw, defaultKeyAlgorithm, extractable, usages)
|
||||
10
yjs-poll/node_modules/lib0/crypto/jwt.d.ts
generated
vendored
Normal file
10
yjs-poll/node_modules/lib0/crypto/jwt.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export function encodeJwt(privateKey: CryptoKey, payload: Object): PromiseLike<string>;
|
||||
export function verifyJwt(publicKey: CryptoKey, jwt: string): Promise<{
|
||||
header: any;
|
||||
payload: any;
|
||||
}>;
|
||||
export function unsafeDecode(jwt: string): {
|
||||
header: any;
|
||||
payload: any;
|
||||
};
|
||||
//# sourceMappingURL=jwt.d.ts.map
|
||||
1
yjs-poll/node_modules/lib0/crypto/jwt.d.ts.map
generated
vendored
Normal file
1
yjs-poll/node_modules/lib0/crypto/jwt.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["jwt.js"],"names":[],"mappings":"AAqBO,sCAHI,SAAS,WACT,MAAM,uBAgBhB;AAMM,qCAHI,SAAS,OACT,MAAM;;;GAiBhB;AAOM,kCAFI,MAAM;;;EAQhB"}
|
||||
70
yjs-poll/node_modules/lib0/crypto/jwt.js
generated
vendored
Normal file
70
yjs-poll/node_modules/lib0/crypto/jwt.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import * as error from '../error.js'
|
||||
import * as buffer from '../buffer.js'
|
||||
import * as string from '../string.js'
|
||||
import * as json from '../json.js'
|
||||
import * as ecdsa from '../crypto/ecdsa.js'
|
||||
import * as time from '../time.js'
|
||||
|
||||
/**
|
||||
* @param {Object} data
|
||||
*/
|
||||
const _stringify = data => buffer.toBase64UrlEncoded(string.encodeUtf8(json.stringify(data)))
|
||||
|
||||
/**
|
||||
* @param {string} base64url
|
||||
*/
|
||||
const _parse = base64url => json.parse(string.decodeUtf8(buffer.fromBase64UrlEncoded(base64url)))
|
||||
|
||||
/**
|
||||
* @param {CryptoKey} privateKey
|
||||
* @param {Object} payload
|
||||
*/
|
||||
export const encodeJwt = (privateKey, payload) => {
|
||||
const { name: algName, namedCurve: algCurve } = /** @type {any} */ (privateKey.algorithm)
|
||||
/* c8 ignore next 3 */
|
||||
if (algName !== 'ECDSA' || algCurve !== 'P-384') {
|
||||
error.unexpectedCase()
|
||||
}
|
||||
const header = {
|
||||
alg: 'ES384',
|
||||
typ: 'JWT'
|
||||
}
|
||||
const jwt = _stringify(header) + '.' + _stringify(payload)
|
||||
return ecdsa.sign(privateKey, string.encodeUtf8(jwt)).then(signature =>
|
||||
jwt + '.' + buffer.toBase64UrlEncoded(signature)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CryptoKey} publicKey
|
||||
* @param {string} jwt
|
||||
*/
|
||||
export const verifyJwt = async (publicKey, jwt) => {
|
||||
const [headerBase64, payloadBase64, signatureBase64] = jwt.split('.')
|
||||
const verified = await ecdsa.verify(publicKey, buffer.fromBase64UrlEncoded(signatureBase64), string.encodeUtf8(headerBase64 + '.' + payloadBase64))
|
||||
/* c8 ignore next 3 */
|
||||
if (!verified) {
|
||||
throw new Error('Invalid JWT')
|
||||
}
|
||||
const payload = _parse(payloadBase64)
|
||||
if (payload.exp != null && time.getUnixTime() > payload.exp) {
|
||||
throw new Error('Expired JWT')
|
||||
}
|
||||
return {
|
||||
header: _parse(headerBase64),
|
||||
payload
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a jwt without verifying it. Probably a bad idea to use this. Only use if you know the jwt was already verified!
|
||||
*
|
||||
* @param {string} jwt
|
||||
*/
|
||||
export const unsafeDecode = jwt => {
|
||||
const [headerBase64, payloadBase64] = jwt.split('.')
|
||||
return {
|
||||
header: _parse(headerBase64),
|
||||
payload: _parse(payloadBase64)
|
||||
}
|
||||
}
|
||||
13
yjs-poll/node_modules/lib0/crypto/rsa-oaep.d.ts
generated
vendored
Normal file
13
yjs-poll/node_modules/lib0/crypto/rsa-oaep.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export { exportKeyJwk } from "./common.js";
|
||||
export function encrypt(key: CryptoKey, data: Uint8Array<ArrayBuffer>): PromiseLike<Uint8Array<ArrayBuffer>>;
|
||||
export function decrypt(key: CryptoKey, data: Uint8Array<ArrayBuffer>): PromiseLike<Uint8Array>;
|
||||
export function generateKeyPair({ extractable, usages }?: {
|
||||
extractable?: boolean | undefined;
|
||||
usages?: Usages | undefined;
|
||||
}): Promise<CryptoKeyPair>;
|
||||
export function importKeyJwk(jwk: any, { extractable, usages }?: {
|
||||
extractable?: boolean | undefined;
|
||||
usages?: Usages | undefined;
|
||||
}): Promise<CryptoKey>;
|
||||
export type Usages = Array<"encrypt" | "decrypt">;
|
||||
//# sourceMappingURL=rsa-oaep.d.ts.map
|
||||
1
yjs-poll/node_modules/lib0/crypto/rsa-oaep.d.ts.map
generated
vendored
Normal file
1
yjs-poll/node_modules/lib0/crypto/rsa-oaep.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"rsa-oaep.d.ts","sourceRoot":"","sources":["rsa-oaep.js"],"names":[],"mappings":";AAuBO,6BAJI,SAAS,QACT,UAAU,CAAC,WAAW,CAAC,GACtB,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CASZ;AAW7B,6BAJI,SAAS,QACT,UAAU,CAAC,WAAW,CAAC,GACtB,WAAW,CAAC,UAAU,CAAC,CASG;AAQ/B,0DAJJ;IAAuB,WAAW;IACZ,MAAM;CAC5B,GAAS,OAAO,CAAC,aAAa,CAAC,CAY/B;AAQI,kCALI,GAAG,4BAEX;IAAuB,WAAW;IACZ,MAAM;CAAC,sBAQ/B;qBAxEY,KAAK,CAAC,SAAS,GAAC,SAAS,CAAC"}
|
||||
81
yjs-poll/node_modules/lib0/crypto/rsa-oaep.js
generated
vendored
Normal file
81
yjs-poll/node_modules/lib0/crypto/rsa-oaep.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* RSA-OAEP is an asymmetric keypair used for encryption
|
||||
*/
|
||||
|
||||
import * as webcrypto from 'lib0/webcrypto'
|
||||
export { exportKeyJwk } from './common.js'
|
||||
|
||||
/**
|
||||
* @typedef {Array<'encrypt'|'decrypt'>} Usages
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Usages}
|
||||
*/
|
||||
const defaultUsages = ['encrypt', 'decrypt']
|
||||
|
||||
/**
|
||||
* Note that the max data size is limited by the size of the RSA key.
|
||||
*
|
||||
* @param {CryptoKey} key
|
||||
* @param {Uint8Array<ArrayBuffer>} data
|
||||
* @return {PromiseLike<Uint8Array<ArrayBuffer>>}
|
||||
*/
|
||||
export const encrypt = (key, data) =>
|
||||
webcrypto.subtle.encrypt(
|
||||
{
|
||||
name: 'RSA-OAEP'
|
||||
},
|
||||
key,
|
||||
data
|
||||
).then(buf => new Uint8Array(buf))
|
||||
|
||||
/**
|
||||
* @experimental The API is not final!
|
||||
*
|
||||
* Decrypt some data using AES-GCM method.
|
||||
*
|
||||
* @param {CryptoKey} key
|
||||
* @param {Uint8Array<ArrayBuffer>} data
|
||||
* @return {PromiseLike<Uint8Array>} decrypted buffer
|
||||
*/
|
||||
export const decrypt = (key, data) =>
|
||||
webcrypto.subtle.decrypt(
|
||||
{
|
||||
name: 'RSA-OAEP'
|
||||
},
|
||||
key,
|
||||
data
|
||||
).then(data => new Uint8Array(data))
|
||||
|
||||
/**
|
||||
* @param {Object} opts
|
||||
* @param {boolean} [opts.extractable]
|
||||
* @param {Usages} [opts.usages]
|
||||
* @return {Promise<CryptoKeyPair>}
|
||||
*/
|
||||
export const generateKeyPair = ({ extractable = false, usages = defaultUsages } = {}) =>
|
||||
webcrypto.subtle.generateKey(
|
||||
{
|
||||
name: 'RSA-OAEP',
|
||||
modulusLength: 4096,
|
||||
publicExponent: new Uint8Array([1, 0, 1]),
|
||||
hash: 'SHA-256'
|
||||
},
|
||||
extractable,
|
||||
usages
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {any} jwk
|
||||
* @param {Object} opts
|
||||
* @param {boolean} [opts.extractable]
|
||||
* @param {Usages} [opts.usages]
|
||||
*/
|
||||
export const importKeyJwk = (jwk, { extractable = false, usages } = {}) => {
|
||||
if (usages == null) {
|
||||
/* c8 ignore next */
|
||||
usages = jwk.key_ops || defaultUsages
|
||||
}
|
||||
return webcrypto.subtle.importKey('jwk', jwk, { name: 'RSA-OAEP', hash: 'SHA-256' }, extractable, /** @type {Usages} */ (usages))
|
||||
}
|
||||
Reference in New Issue
Block a user