Skip to content

Commit 8f8df5c

Browse files
authored
fix: Remove unreliable webkit-linux useragent check (libp2p#319)
Closes libp2p#318
1 parent 3f6506c commit 8f8df5c

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

src/ciphers/aes-gcm.browser.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ import { fromString } from 'uint8arrays/from-string'
33
import webcrypto from '../webcrypto.js'
44
import type { CreateOptions, AESCipher } from './interface.js'
55

6-
export function isWebkitLinux (): boolean {
7-
return typeof navigator !== 'undefined' && navigator.userAgent.includes('Safari') && navigator.userAgent.includes('Linux') && !navigator.userAgent.includes('Chrome')
8-
}
9-
106
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
117
// So, as a workaround, we provide the generated key as a constant. We test that
128
// this generated key is accurate in test/workaround.spec.ts
@@ -46,8 +42,15 @@ export function create (opts?: CreateOptions): AESCipher {
4642
}
4743

4844
let cryptoKey: CryptoKey
49-
if (password.length === 0 && isWebkitLinux()) {
45+
if (password.length === 0) {
5046
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt'])
47+
try {
48+
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } }
49+
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey'])
50+
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt'])
51+
} catch {
52+
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt'])
53+
}
5154
} else {
5255
// Derive a key using PBKDF2.
5356
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } }
@@ -77,8 +80,14 @@ export function create (opts?: CreateOptions): AESCipher {
7780
}
7881

7982
let cryptoKey: CryptoKey
80-
if (password.length === 0 && isWebkitLinux()) {
81-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt'])
83+
if (password.length === 0) {
84+
try {
85+
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } }
86+
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey'])
87+
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt'])
88+
} catch {
89+
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt'])
90+
}
8291
} else {
8392
// Derive the key using PBKDF2.
8493
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } }

test/workaround.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11

22
/* eslint-env mocha */
3-
import { isWebkitLinux, derivedEmptyPasswordKey } from '../src/ciphers/aes-gcm.browser.js'
3+
import { derivedEmptyPasswordKey } from '../src/ciphers/aes-gcm.browser.js'
44
import { expect } from 'aegir/chai'
55

66
describe('Constant derived key is generated correctly', () => {
77
it('Generates correctly', async () => {
8-
if (isWebkitLinux() || typeof crypto === 'undefined') {
8+
if ((typeof navigator !== 'undefined' && navigator.userAgent.includes('Safari')) || typeof crypto === 'undefined') {
99
// WebKit Linux can't generate this. Hence the workaround.
1010
return
1111
}

0 commit comments

Comments
 (0)