Page MenuHomePhorge

D8521.1765333317.diff
No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None

D8521.1765333317.diff

diff --git a/keyserver/src/utils/aes-crypto-utils.js b/keyserver/src/utils/aes-crypto-utils.js
new file mode 100644
--- /dev/null
+++ b/keyserver/src/utils/aes-crypto-utils.js
@@ -0,0 +1,33 @@
+// @flow
+
+import crypto from 'crypto';
+
+import {
+ generateKeyCommon,
+ encryptCommon,
+ decryptCommon,
+} from 'lib/media/aes-crypto-utils-common.js';
+
+// crypto.webcrypto was introduced in Node 15.10.0.
+// It is not defined in Flow so we need a cast
+const commonCrypto: Crypto = (crypto: any).webcrypto;
+
+function generateKey(): Promise<Uint8Array> {
+ return generateKeyCommon(commonCrypto);
+}
+
+function encrypt(
+ keyBytes: Uint8Array,
+ plaintext: Uint8Array,
+): Promise<Uint8Array> {
+ return encryptCommon(commonCrypto, keyBytes, plaintext);
+}
+
+function decrypt(
+ keyBytes: Uint8Array,
+ sealedData: Uint8Array,
+): Promise<Uint8Array> {
+ return decryptCommon(commonCrypto, keyBytes, sealedData);
+}
+
+export { generateKey, encrypt, decrypt };
diff --git a/web/flow-typed/web-crypto.js b/lib/flow-typed/web-crypto-common.js
copy from web/flow-typed/web-crypto.js
copy to lib/flow-typed/web-crypto-common.js
--- a/web/flow-typed/web-crypto.js
+++ b/lib/flow-typed/web-crypto-common.js
@@ -279,7 +279,3 @@
| 'AES-KW',
): Promise<ArrayBuffer>;
}
-
-declare var crypto: Crypto;
-declare var msCrypto: Crypto;
-declare var webkitCrypto: Crypto;
diff --git a/lib/media/aes-crypto-utils-common.js b/lib/media/aes-crypto-utils-common.js
new file mode 100644
--- /dev/null
+++ b/lib/media/aes-crypto-utils-common.js
@@ -0,0 +1,84 @@
+// @flow
+
+const KEY_SIZE = 32; // bytes
+const IV_LENGTH = 12; // bytes - unique Initialization Vector (nonce)
+const TAG_LENGTH = 16; // bytes - GCM auth tag
+
+async function generateKeyCommon(commonCrypto: Crypto): Promise<Uint8Array> {
+ const algorithm = { name: 'AES-GCM', length: 256 };
+ const key = await commonCrypto.subtle.generateKey(algorithm, true, [
+ 'encrypt',
+ 'decrypt',
+ ]);
+ const keyData = await commonCrypto.subtle.exportKey('raw', key);
+ return new Uint8Array(keyData);
+}
+
+async function encryptCommon(
+ commonCrypto: Crypto,
+ keyBytes: Uint8Array,
+ plaintext: Uint8Array,
+): Promise<Uint8Array> {
+ if (keyBytes.length !== KEY_SIZE) {
+ throw new Error('Invalid AES key size');
+ }
+
+ // we're creating the buffer now so we can avoid reallocating it later
+ const outputBuffer = new ArrayBuffer(
+ plaintext.length + IV_LENGTH + TAG_LENGTH,
+ );
+ const ivBytes = new Uint8Array(outputBuffer, 0, IV_LENGTH);
+ const iv = commonCrypto.getRandomValues(ivBytes);
+
+ const algorithm = { name: 'AES-GCM', iv: iv, tagLength: TAG_LENGTH * 8 };
+ const key = await commonCrypto.subtle.importKey(
+ 'raw',
+ keyBytes,
+ 'AES-GCM',
+ false,
+ ['encrypt'],
+ );
+ const ciphertextWithTag = await commonCrypto.subtle.encrypt(
+ algorithm,
+ key,
+ plaintext,
+ );
+
+ const result = new Uint8Array(outputBuffer);
+ result.set(new Uint8Array(ciphertextWithTag), iv.length);
+ return result;
+}
+
+async function decryptCommon(
+ commonCrypto: Crypto,
+ keyBytes: Uint8Array,
+ sealedData: Uint8Array,
+): Promise<Uint8Array> {
+ if (keyBytes.length !== KEY_SIZE) {
+ throw new Error('Invalid AES key size');
+ }
+ if (sealedData.length < IV_LENGTH + TAG_LENGTH) {
+ throw new Error('Invalid ciphertext size');
+ }
+
+ const iv = sealedData.subarray(0, IV_LENGTH);
+ const ciphertextWithTag = sealedData.subarray(IV_LENGTH);
+
+ const algorithm = { name: 'AES-GCM', iv, tagLength: TAG_LENGTH * 8 };
+ const key = await commonCrypto.subtle.importKey(
+ 'raw',
+ keyBytes,
+ 'AES-GCM',
+ false,
+ ['decrypt'],
+ );
+
+ const plaintextBuffer = await commonCrypto.subtle.decrypt(
+ algorithm,
+ key,
+ ciphertextWithTag,
+ );
+ return new Uint8Array(plaintextBuffer);
+}
+
+export { generateKeyCommon, encryptCommon, decryptCommon };
diff --git a/web/flow-typed/web-crypto.js b/web/flow-typed/web-crypto.js
--- a/web/flow-typed/web-crypto.js
+++ b/web/flow-typed/web-crypto.js
@@ -1,285 +1,5 @@
// @flow
-declare interface RandomSource {
- getRandomValues<T: $TypedArray>(typedArray: T): T;
- randomUUID(): string;
-}
-
-declare interface Crypto extends RandomSource {
- +subtle: SubtleCrypto;
-}
-
-type CryptoKey$Type = 'secret' | 'public' | 'private';
-type CryptoKey$Usages =
- | 'encrypt'
- | 'decrypt'
- | 'sign'
- | 'verify'
- | 'deriveKey'
- | 'deriveBits'
- | 'wrapKey'
- | 'unwrapKey';
-
-declare type CryptoKey = {
- +algorithm:
- | SubtleCrypto$AesKeyGenParams
- | SubtleCrypto$RsaHashedKeyGenParams
- | SubtleCrypto$EcKeyGenParams
- | SubtleCrypto$HmacKeyGenParams,
- +extractable: boolean,
- +type: CryptoKey$Type,
- +usages: $ReadOnlyArray<CryptoKey$Usages>,
-};
-
-type SubtleCrypto$KeyFormatWithoutJwk = 'pkcs8' | 'raw' | 'spki';
-type SubtleCrypto$KeyFormat = 'jwk' | SubtleCrypto$KeyFormatWithoutJwk;
-type SubtleCrypto$HashAlgo = 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512';
-type SubtleCrypto$AesAlgo = 'AES-CBC' | 'AES-CTR' | 'AES-GCM' | 'AES-KW';
-
-type SubtleCrypto$RsaOaepParams = {
- +name: 'RSA-OAEP',
- +label?: BufferSource,
-};
-
-type SubtleCrypto$AesCtrParams = {
- +name: 'AES-CTR',
- +counter: BufferSource,
- +length: number,
-};
-
-type SubtleCrypto$AesCbcParams = {
- +name: 'AES-CBC',
- +iv: BufferSource,
-};
-
-type SubtleCrypto$AesGcmParams = {
- +name: 'AES-GCM',
- +iv: BufferSource,
- +additionalData?: BufferSource,
- +tagLength?: number,
-};
-
-type SubtleCrypto$EcdhKeyDeriveParams = {
- +name: 'ECDH',
- +public: CryptoKey,
-};
-
-type SubtleCrypto$HkdfParams = {
- +name: 'HKDF',
- +hash: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512',
- +info: BufferSource,
- +salt: BufferSource,
-};
-
-type SubtleCrypto$Pbkdf2Params = {
- +name: 'PBKDF2',
- +hash: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512',
- +iterations: number,
- +salt: BufferSource,
-};
-
-type SubtleCrypto$HmacImportParams = {
- +name: 'HMAC',
- +hash: 'SHA-256' | 'SHA-384' | 'SHA-512',
- +length?: number,
-};
-
-type SubtleCrypto$RsaHashedKeyGenParams = {
- +name: 'RSASSA-PKCS1-v1_5' | 'RSA-PSS' | 'RSA-OAEP',
- +modulusLength: number,
- +publicExponent: Uint8Array,
- +hash: 'SHA-256' | 'SHA-384' | 'SHA-512',
-};
-
-type SubtleCrypto$HmacKeyGenParams = {
- +name: 'HMAC',
- +hash: SubtleCrypto$HashAlgo,
- +length?: number,
-};
-
-type SubtleCrypto$RsaHashedImportParams = {
- +name: 'RSASSA-PKCS1-v1_5' | 'RSA-PSS' | 'RSA-OAEP',
- +hash: 'SHA-256' | 'SHA-384' | 'SHA-512',
-};
-
-type SubtleCrypto$EcKeyImportParams = {
- +name: 'ECDSA' | 'ECDH',
- +namedCurve: 'P-256' | 'P-384' | 'P-521',
-};
-
-type SubtleCrypto$EcKeyGenParams = {
- +name: 'ECDSA' | 'ECDH',
- +namedCurve: 'P-256' | 'P-384' | 'P-521',
-};
-
-type SubtleCrypto$RsaPssParams = {
- +name: 'RSA-PSS',
- +saltLength: number,
-};
-
-type SubtleCrypto$EcdsaParams = {
- +name: 'ECDSA',
- +hash: 'SHA-256' | 'SHA-384' | 'SHA-512',
-};
-
-type SubtleCrypto$AesKeyGenParams = {
- +name: 'AES-CBC' | 'AES-CTR' | 'AES-GCM' | 'AES-KW',
- +length: 128 | 192 | 256,
-};
-
-type SubtleCrypto$ImportKeyAlgo =
- | SubtleCrypto$RsaHashedImportParams
- | SubtleCrypto$EcKeyImportParams
- | SubtleCrypto$HmacImportParams
- | SubtleCrypto$AesAlgo
- | 'PBKDF2'
- | 'HKDF';
-
-type SubtleCrypto$RsaOtherPrimesInfo = {
- +d?: string,
- +r?: string,
- +t?: string,
-};
-
-type SubtleCrypto$JsonWebKey = {
- +alg?: string,
- +crv?: string,
- +d?: string,
- +dp?: string,
- +dq?: string,
- +e?: string,
- +ext?: boolean,
- +k?: string,
- +key_ops?: $ReadOnlyArray<string>,
- +kty?: string,
- +n?: string,
- +oth?: $ReadOnlyArray<SubtleCrypto$RsaOtherPrimesInfo>,
- +p?: string,
- +q?: string,
- +qi?: string,
- +use?: string,
- +x?: string,
- +y?: string,
-};
-
-declare interface SubtleCrypto {
- decrypt(
- algorithm:
- | SubtleCrypto$RsaOaepParams
- | SubtleCrypto$AesCtrParams
- | SubtleCrypto$AesCbcParams
- | SubtleCrypto$AesGcmParams,
- key: CryptoKey,
- data: BufferSource,
- ): Promise<ArrayBuffer>;
- deriveBits(
- algorithm:
- | SubtleCrypto$EcdhKeyDeriveParams
- | SubtleCrypto$HkdfParams
- | SubtleCrypto$Pbkdf2Params,
- baseKey: CryptoKey,
- length: number,
- ): Promise<ArrayBuffer>;
- deriveKey(
- algorithm:
- | SubtleCrypto$EcdhKeyDeriveParams
- | SubtleCrypto$HkdfParams
- | SubtleCrypto$Pbkdf2Params,
- baseKey: CryptoKey,
- derivedKeyType:
- | SubtleCrypto$HmacKeyGenParams
- | SubtleCrypto$AesKeyGenParams,
- extractable: boolean,
- keyUsages: $ReadOnlyArray<CryptoKey$Usages>,
- ): Promise<CryptoKey>;
- digest(
- algorithm: SubtleCrypto$HashAlgo | { +name: SubtleCrypto$HashAlgo },
- data: BufferSource,
- ): Promise<ArrayBuffer>;
- encrypt(
- algorithm:
- | SubtleCrypto$RsaOaepParams
- | SubtleCrypto$AesCtrParams
- | SubtleCrypto$AesCbcParams
- | SubtleCrypto$AesGcmParams,
- key: CryptoKey,
- data: BufferSource,
- ): Promise<ArrayBuffer>;
- exportKey(format: 'jwk', key: CryptoKey): Promise<SubtleCrypto$JsonWebKey>;
- exportKey(
- format: SubtleCrypto$KeyFormatWithoutJwk,
- key: CryptoKey,
- ): Promise<ArrayBuffer>;
- generateKey(
- algorithm:
- | SubtleCrypto$RsaHashedKeyGenParams
- | SubtleCrypto$EcKeyGenParams
- | SubtleCrypto$HmacKeyGenParams
- | SubtleCrypto$AesKeyGenParams,
- extractable: boolean,
- keyUsages: $ReadOnlyArray<CryptoKey$Usages>,
- ): Promise<CryptoKey>;
- importKey(
- format: SubtleCrypto$KeyFormatWithoutJwk,
- keyData: BufferSource,
- algorithm: SubtleCrypto$ImportKeyAlgo,
- extractable: boolean,
- keyUsages: $ReadOnlyArray<CryptoKey$Usages>,
- ): Promise<CryptoKey>;
- importKey(
- format: 'jwk',
- keyData: SubtleCrypto$JsonWebKey,
- algorithm: SubtleCrypto$ImportKeyAlgo,
- extractable: boolean,
- keyUsages: $ReadOnlyArray<CryptoKey$Usages>,
- ): Promise<CryptoKey>;
-
- sign(
- algorithm:
- | 'RSASSA-PKCS1-v1_5'
- | 'HMAC'
- | SubtleCrypto$RsaPssParams
- | SubtleCrypto$EcdsaParams,
- key: CryptoKey,
- data: BufferSource,
- ): Promise<ArrayBuffer>;
- unwrapKey(
- format: SubtleCrypto$KeyFormat,
- wrappedKey: ArrayBuffer,
- unwrappingKey: CryptoKey,
- unwrapAlgorithm:
- | SubtleCrypto$RsaOaepParams
- | SubtleCrypto$AesCtrParams
- | SubtleCrypto$AesCbcParams
- | SubtleCrypto$AesGcmParams
- | 'AES-KW',
- unwrappedKeyAlgorithm: SubtleCrypto$ImportKeyAlgo,
- extractable: boolean,
- keyUsages: $ReadOnlyArray<CryptoKey$Usages>,
- ): Promise<CryptoKey>;
- verify(
- algorithm:
- | SubtleCrypto$RsaPssParams
- | SubtleCrypto$EcdsaParams
- | 'RSASSA-PKCS1-v1_5'
- | 'HMAC',
- key: CryptoKey,
- signature: ArrayBuffer,
- data: ArrayBuffer,
- ): Promise<boolean>;
- wrapKey(
- format: SubtleCrypto$KeyFormat,
- key: CryptoKey,
- wrappingKey: CryptoKey,
- wrapAlgorithm:
- | SubtleCrypto$RsaOaepParams
- | SubtleCrypto$AesCtrParams
- | SubtleCrypto$AesCbcParams
- | SubtleCrypto$AesGcmParams
- | 'AES-KW',
- ): Promise<ArrayBuffer>;
-}
-
declare var crypto: Crypto;
declare var msCrypto: Crypto;
declare var webkitCrypto: Crypto;

File Metadata

Mime Type
text/plain
Expires
Wed, Dec 10, 2:21 AM (14 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5859924
Default Alt Text
D8521.1765333317.diff (11 KB)

Event Timeline