From ca25b134c030f204d286f92071272a8989a42d89 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 14:06:42 -0700 Subject: [PATCH 01/12] Add webkit test to CI --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index e5daaa3..38b6ff2 100644 --- a/package.json +++ b/package.json @@ -172,6 +172,7 @@ "test:chrome-webworker": "aegir test -t webworker", "test:firefox": "aegir test -t browser -- --browser firefox", "test:firefox-webworker": "aegir test -t webworker -- --browser firefox", + "test:webkit": "aegir test -t browser -- --browser webkit", "test:node": "aegir test -t node --cov", "test:electron-main": "aegir test -t electron-main", "release": "aegir release", From 9021ea9ad8fc036ff3d9e4b2c0ac99afa54ee688 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 14:12:07 -0700 Subject: [PATCH 02/12] Add workaround --- src/ciphers/aes-gcm.browser.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ciphers/aes-gcm.browser.ts b/src/ciphers/aes-gcm.browser.ts index c90be82..14ec552 100644 --- a/src/ciphers/aes-gcm.browser.ts +++ b/src/ciphers/aes-gcm.browser.ts @@ -3,6 +3,10 @@ import { fromString } from 'uint8arrays/from-string' import webcrypto from '../webcrypto.js' import type { CreateOptions, AESCipher } from './interface.js' +function isSafariLinux (): boolean { + return typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Linux') !== -1 && navigator.userAgent.indexOf('Chrome') === -1 +} + // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples export function create (opts?: CreateOptions): AESCipher { @@ -29,6 +33,11 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } + if (password.length === 0 && isSafariLinux()) { + // Workaround for Safari on Linux not supporting empty keys to derive from + password = new Uint8Array(1) + } + // Derive a key using PBKDF2. const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } } const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey', 'deriveBits']) From b28d0b7c76d84be2642454a1d360d2f699492030 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 22:06:58 +0000 Subject: [PATCH 03/12] Do the same for the import side, and add tests --- src/ciphers/aes-gcm.browser.ts | 20 +++++++++++++++----- test/keys/ed25519.spec.ts | 18 ++++++++++++++++++ test/keys/importer.spec.ts | 21 +++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 test/keys/importer.spec.ts diff --git a/src/ciphers/aes-gcm.browser.ts b/src/ciphers/aes-gcm.browser.ts index 14ec552..d5b0328 100644 --- a/src/ciphers/aes-gcm.browser.ts +++ b/src/ciphers/aes-gcm.browser.ts @@ -3,8 +3,14 @@ import { fromString } from 'uint8arrays/from-string' import webcrypto from '../webcrypto.js' import type { CreateOptions, AESCipher } from './interface.js' -function isSafariLinux (): boolean { - return typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Safari') !== -1 && navigator.userAgent.indexOf('Linux') !== -1 && navigator.userAgent.indexOf('Chrome') === -1 +function isWebkitLinux (): boolean { + return typeof navigator !== 'undefined' && navigator.userAgent.includes('Safari') && navigator.userAgent.includes('Linux') && !navigator.userAgent.includes('Chrome') +} + +// WebKit on Linux does not support empty passwords to derive a key from. This +// is a workaround to use an empty 1 byte instead. +function webkitLinuxEmptyPasswordWorkaround (): Uint8Array { + return new Uint8Array(1) } // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples @@ -33,9 +39,8 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } - if (password.length === 0 && isSafariLinux()) { - // Workaround for Safari on Linux not supporting empty keys to derive from - password = new Uint8Array(1) + if (password.length === 0 && isWebkitLinux()) { + password = webkitLinuxEmptyPasswordWorkaround() } // Derive a key using PBKDF2. @@ -64,6 +69,11 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } + if (password.length === 0 && isWebkitLinux()) { + // Workaround for Safari on Linux not supporting empty keys to derive from + password = webkitLinuxEmptyPasswordWorkaround() + } + // Derive the key using PBKDF2. const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } } const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey', 'deriveBits']) diff --git a/test/keys/ed25519.spec.ts b/test/keys/ed25519.spec.ts index b040849..41b7614 100644 --- a/test/keys/ed25519.spec.ts +++ b/test/keys/ed25519.spec.ts @@ -100,6 +100,24 @@ describe('ed25519', function () { expect(key.equals(importedKey)).to.equal(true) }) + it('should export a libp2p-key with no password to encrypt', async () => { + const key = await crypto.keys.generateKeyPair('Ed25519') + + if (!(key instanceof Ed25519PrivateKey)) { + throw new Error('Key was incorrect type') + } + + const encryptedKey = await key.export('') + // Import the key + const importedKey = await crypto.keys.importKey(encryptedKey, '') + + if (!(importedKey instanceof Ed25519PrivateKey)) { + throw new Error('Key was incorrect type') + } + + expect(key.equals(importedKey)).to.equal(true) + }) + it('should fail to import libp2p-key with wrong password', async () => { const key = await crypto.keys.generateKeyPair('Ed25519') const encryptedKey = await key.export('my secret', 'libp2p-key') diff --git a/test/keys/importer.spec.ts b/test/keys/importer.spec.ts new file mode 100644 index 0000000..7a92fdc --- /dev/null +++ b/test/keys/importer.spec.ts @@ -0,0 +1,21 @@ +/* eslint max-nested-callbacks: ["error", 8] */ +/* eslint-env mocha */ +import { expect } from 'aegir/chai' + +import {importer} from '../../src/keys/importer.js' +import {exporter} from '../../src/keys/exporter.js' + +describe('libp2p-crypto importer/exporter', function () { + it('roundtrips', async () => { + for (const password of ['', 'password']) { + const secret = new Uint8Array(32) + for (let i = 0; i < secret.length; i++) { + secret[i] = i + } + + const exported = await exporter(secret, password) + const imported = await importer(exported, password) + expect(imported).to.deep.equal(secret) + } + }) +}) \ No newline at end of file From 5743169b7dc9bdfa8bd5fd8c515b7276bdc079cf Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 22:07:11 +0000 Subject: [PATCH 04/12] Install playwright deps --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38b6ff2..f3dcd2c 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,7 @@ "test:chrome-webworker": "aegir test -t webworker", "test:firefox": "aegir test -t browser -- --browser firefox", "test:firefox-webworker": "aegir test -t webworker -- --browser firefox", - "test:webkit": "aegir test -t browser -- --browser webkit", + "test:webkit": "playwright install-deps && aegir test -t browser -- --browser webkit", "test:node": "aegir test -t node --cov", "test:electron-main": "aegir test -t electron-main", "release": "aegir release", From 43d0338b45e41302075a566a12f49832b0d637d0 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 15:20:00 -0700 Subject: [PATCH 05/12] Lint --- test/keys/importer.spec.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/keys/importer.spec.ts b/test/keys/importer.spec.ts index 7a92fdc..2d7c423 100644 --- a/test/keys/importer.spec.ts +++ b/test/keys/importer.spec.ts @@ -2,20 +2,20 @@ /* eslint-env mocha */ import { expect } from 'aegir/chai' -import {importer} from '../../src/keys/importer.js' -import {exporter} from '../../src/keys/exporter.js' +import { importer } from '../../src/keys/importer.js' +import { exporter } from '../../src/keys/exporter.js' describe('libp2p-crypto importer/exporter', function () { it('roundtrips', async () => { for (const password of ['', 'password']) { - const secret = new Uint8Array(32) - for (let i = 0; i < secret.length; i++) { - secret[i] = i - } + const secret = new Uint8Array(32) + for (let i = 0; i < secret.length; i++) { + secret[i] = i + } - const exported = await exporter(secret, password) - const imported = await importer(exported, password) - expect(imported).to.deep.equal(secret) + const exported = await exporter(secret, password) + const imported = await importer(exported, password) + expect(imported).to.deep.equal(secret) } }) -}) \ No newline at end of file +}) From 63c9fc3f586d94ed3aeef52581642958ae45ed06 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 15:50:50 -0700 Subject: [PATCH 06/12] Only install deps in CI --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f3dcd2c..712fcff 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,7 @@ "test:chrome-webworker": "aegir test -t webworker", "test:firefox": "aegir test -t browser -- --browser firefox", "test:firefox-webworker": "aegir test -t webworker -- --browser firefox", - "test:webkit": "playwright install-deps && aegir test -t browser -- --browser webkit", + "test:webkit": "[ -n \"${CI}\" ] && [ \"${CI}\" == \"true\" ] && playwright install-deps; aegir test -t browser -- --browser webkit", "test:node": "aegir test -t node --cov", "test:electron-main": "aegir test -t electron-main", "release": "aegir release", From 55b6e065eccb4f604c5967e7b3caabc311844e42 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 16:17:32 -0700 Subject: [PATCH 07/12] Skip RSA private key unmarshalling test in Safari --- test/crypto.spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/crypto.spec.ts b/test/crypto.spec.ts index 24aa3fd..f02fb9e 100644 --- a/test/crypto.spec.ts +++ b/test/crypto.spec.ts @@ -60,11 +60,22 @@ describe('libp2p-crypto', function () { return expect(crypto.keys.generateKeyPairFromSeed('invalid-key-type', seed, 512)).to.eventually.be.rejected.with.property('code', 'ERR_UNSUPPORTED_KEY_DERIVATION_TYPE') }) + // https://github.com/libp2p/js-libp2p-crypto/issues/314 + function isSafari (): boolean { + return typeof navigator !== 'undefined' && navigator.userAgent.includes('AppleWebKit') && !navigator.userAgent.includes('Chrome') && navigator.userAgent.includes('Mac') + } + // marshalled keys seem to be slightly different // unsure as to if this is just a difference in encoding // or a bug describe('go interop', () => { it('unmarshals private key', async () => { + if (isSafari()) { + // eslint-disable-next-line no-console + console.warn('Skipping test in Safari. Known bug: https://github.com/libp2p/js-libp2p-crypto/issues/314') + return + } + const key = await crypto.keys.unmarshalPrivateKey(fixtures.private.key) const hash = fixtures.private.hash expect(fixtures.private.key).to.eql(key.bytes) @@ -83,6 +94,13 @@ describe('libp2p-crypto', function () { it('unmarshal -> marshal, private key', async () => { const key = await crypto.keys.unmarshalPrivateKey(fixtures.private.key) const marshalled = crypto.keys.marshalPrivateKey(key) + if (isSafari()) { + // eslint-disable-next-line no-console + console.warn('Running differnt test in Safari. Known bug: https://github.com/libp2p/js-libp2p-crypto/issues/314') + const key2 = await crypto.keys.unmarshalPrivateKey(marshalled) + expect(key2.bytes).to.eql(key.bytes) + return + } expect(marshalled).to.eql(fixtures.private.key) }) From cd1a767a7ed83a2aef091ae07c330bf800a15cd0 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 24 Mar 2023 17:31:11 -0700 Subject: [PATCH 08/12] Fix test:webkit script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 712fcff..dba86f4 100644 --- a/package.json +++ b/package.json @@ -172,7 +172,7 @@ "test:chrome-webworker": "aegir test -t webworker", "test:firefox": "aegir test -t browser -- --browser firefox", "test:firefox-webworker": "aegir test -t webworker -- --browser firefox", - "test:webkit": "[ -n \"${CI}\" ] && [ \"${CI}\" == \"true\" ] && playwright install-deps; aegir test -t browser -- --browser webkit", + "test:webkit": "bash -c '[ \"${CI}\" == \"true\" ] && playwright install-deps'; aegir test -t browser -- --browser webkit", "test:node": "aegir test -t node --cov", "test:electron-main": "aegir test -t electron-main", "release": "aegir release", From 00549d756d369b5c66d412feab2ece8d1953418d Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 31 Mar 2023 17:37:01 +0000 Subject: [PATCH 09/12] Use pregenerated key on webkit linux when user password is empty --- src/ciphers/aes-gcm.browser.ts | 45 ++++++++++++++++++++-------------- test/crypto.spec.ts | 19 ++++++++++++++ 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/ciphers/aes-gcm.browser.ts b/src/ciphers/aes-gcm.browser.ts index d5b0328..0540ae5 100644 --- a/src/ciphers/aes-gcm.browser.ts +++ b/src/ciphers/aes-gcm.browser.ts @@ -3,15 +3,21 @@ import { fromString } from 'uint8arrays/from-string' import webcrypto from '../webcrypto.js' import type { CreateOptions, AESCipher } from './interface.js' -function isWebkitLinux (): boolean { +export function isWebkitLinux (): boolean { return typeof navigator !== 'undefined' && navigator.userAgent.includes('Safari') && navigator.userAgent.includes('Linux') && !navigator.userAgent.includes('Chrome') } -// WebKit on Linux does not support empty passwords to derive a key from. This -// is a workaround to use an empty 1 byte instead. -function webkitLinuxEmptyPasswordWorkaround (): Uint8Array { - return new Uint8Array(1) -} +// WebKit on Linux does not support deriving a key from an empty PBKDF2 key. +// So, as a workaround, we provide the generated key as a constant. All other +// platforms will generate this given an empty PBKDF2 key +// Generated via: +// await crypto.subtle.exportKey('jwk', +// await crypto.subtle.deriveKey( +// { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } }, +// await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']), +// { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt']) +// ) +export const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' } // Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples @@ -39,14 +45,15 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } + let cryptoKey if (password.length === 0 && isWebkitLinux()) { - password = webkitLinuxEmptyPasswordWorkaround() - } - + cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']) + } else { // Derive a key using PBKDF2. - const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } } - const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey', 'deriveBits']) - const cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']) + const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } } + const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']) + cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']) + } // Encrypt the string. const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data) @@ -69,16 +76,16 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } + let cryptoKey if (password.length === 0 && isWebkitLinux()) { - // Workaround for Safari on Linux not supporting empty keys to derive from - password = webkitLinuxEmptyPasswordWorkaround() + cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']) + } else { + // Derive the key using PBKDF2. + const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } } + const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']) + cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['decrypt']) } - // Derive the key using PBKDF2. - const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } } - const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey', 'deriveBits']) - const cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['decrypt']) - // Decrypt the string. const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext) return new Uint8Array(plaintext) diff --git a/test/crypto.spec.ts b/test/crypto.spec.ts index f02fb9e..55b8446 100644 --- a/test/crypto.spec.ts +++ b/test/crypto.spec.ts @@ -5,6 +5,7 @@ import * as crypto from '../src/index.js' import fixtures from './fixtures/go-key-rsa.js' import { equals as uint8ArrayEquals } from 'uint8arrays/equals' import { RsaPrivateKey, RsaPublicKey } from '../src/keys/rsa-class.js' +import { isWebkitLinux, derivedEmptyPasswordKey } from '../src/ciphers/aes-gcm.browser.js' describe('libp2p-crypto', function () { this.timeout(20 * 1000) @@ -152,4 +153,22 @@ describe('libp2p-crypto', function () { expect(buf1).to.not.eql(buf2) }) }) + + describe('Constant derived key is generated correctly', () => { + it('Generates correctly', async () => { + if (isWebkitLinux()) { + // WebKit Linux can't generate this. Hence the workaround. + return + } + + const generatedKey = await global.crypto.subtle.exportKey('jwk', + await global.crypto.subtle.deriveKey( + { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } }, + await global.crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']), + { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt']) + ) + + expect(generatedKey).to.eql(derivedEmptyPasswordKey) + }) + }) }) From 9a7453c4ad2797d6074f0d9397a0f4b889e0f1f1 Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 31 Mar 2023 17:59:02 +0000 Subject: [PATCH 10/12] Expand comment, skip if missing webcrypto --- src/ciphers/aes-gcm.browser.ts | 4 ++-- test/crypto.spec.ts | 19 ------------------- test/workaround.spec.ts | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 test/workaround.spec.ts diff --git a/src/ciphers/aes-gcm.browser.ts b/src/ciphers/aes-gcm.browser.ts index 0540ae5..e80dfdb 100644 --- a/src/ciphers/aes-gcm.browser.ts +++ b/src/ciphers/aes-gcm.browser.ts @@ -8,8 +8,8 @@ export function isWebkitLinux (): boolean { } // WebKit on Linux does not support deriving a key from an empty PBKDF2 key. -// So, as a workaround, we provide the generated key as a constant. All other -// platforms will generate this given an empty PBKDF2 key +// So, as a workaround, we provide the generated key as a constant. We test that +// this generated key is accurate in test/workaround.spec.ts // Generated via: // await crypto.subtle.exportKey('jwk', // await crypto.subtle.deriveKey( diff --git a/test/crypto.spec.ts b/test/crypto.spec.ts index 55b8446..f02fb9e 100644 --- a/test/crypto.spec.ts +++ b/test/crypto.spec.ts @@ -5,7 +5,6 @@ import * as crypto from '../src/index.js' import fixtures from './fixtures/go-key-rsa.js' import { equals as uint8ArrayEquals } from 'uint8arrays/equals' import { RsaPrivateKey, RsaPublicKey } from '../src/keys/rsa-class.js' -import { isWebkitLinux, derivedEmptyPasswordKey } from '../src/ciphers/aes-gcm.browser.js' describe('libp2p-crypto', function () { this.timeout(20 * 1000) @@ -153,22 +152,4 @@ describe('libp2p-crypto', function () { expect(buf1).to.not.eql(buf2) }) }) - - describe('Constant derived key is generated correctly', () => { - it('Generates correctly', async () => { - if (isWebkitLinux()) { - // WebKit Linux can't generate this. Hence the workaround. - return - } - - const generatedKey = await global.crypto.subtle.exportKey('jwk', - await global.crypto.subtle.deriveKey( - { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } }, - await global.crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']), - { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt']) - ) - - expect(generatedKey).to.eql(derivedEmptyPasswordKey) - }) - }) }) diff --git a/test/workaround.spec.ts b/test/workaround.spec.ts new file mode 100644 index 0000000..896c33e --- /dev/null +++ b/test/workaround.spec.ts @@ -0,0 +1,22 @@ + +/* eslint-env mocha */ +import { isWebkitLinux, derivedEmptyPasswordKey } from '../src/ciphers/aes-gcm.browser.js' +import { expect } from 'aegir/chai' + +describe('Constant derived key is generated correctly', () => { + it('Generates correctly', async () => { + if (isWebkitLinux() || typeof crypto === 'undefined') { + // WebKit Linux can't generate this. Hence the workaround. + return + } + + const generatedKey = await crypto.subtle.exportKey('jwk', + await crypto.subtle.deriveKey( + { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } }, + await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']), + { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt']) + ) + + expect(generatedKey).to.eql(derivedEmptyPasswordKey) + }) +}) From d27c999710c56a80c13ace274b0dbef81a0e519e Mon Sep 17 00:00:00 2001 From: Marco Munizaga Date: Fri, 31 Mar 2023 21:56:18 +0000 Subject: [PATCH 11/12] Sort key ops so webkit macos passes --- test/workaround.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/workaround.spec.ts b/test/workaround.spec.ts index 896c33e..86dcbd5 100644 --- a/test/workaround.spec.ts +++ b/test/workaround.spec.ts @@ -17,6 +17,10 @@ describe('Constant derived key is generated correctly', () => { { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt']) ) + // Webkit macos flips these. Sort them so they match. + derivedEmptyPasswordKey.key_ops.sort() + generatedKey?.key_ops?.sort() + expect(generatedKey).to.eql(derivedEmptyPasswordKey) }) }) From 45ee79ee70a5a23013e2a60589d686232526ac87 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Tue, 4 Apr 2023 10:50:27 +0100 Subject: [PATCH 12/12] chore: apply suggestions from code review --- src/ciphers/aes-gcm.browser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ciphers/aes-gcm.browser.ts b/src/ciphers/aes-gcm.browser.ts index e80dfdb..6466ca3 100644 --- a/src/ciphers/aes-gcm.browser.ts +++ b/src/ciphers/aes-gcm.browser.ts @@ -45,7 +45,7 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } - let cryptoKey + let cryptoKey: CryptoKey if (password.length === 0 && isWebkitLinux()) { cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']) } else { @@ -76,7 +76,7 @@ export function create (opts?: CreateOptions): AESCipher { password = fromString(password) } - let cryptoKey + let cryptoKey: CryptoKey if (password.length === 0 && isWebkitLinux()) { cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']) } else {