]> git.codecow.com Git - libnemo.git/commitdiff
Convert password-to-cryptokey static class to module function.
authorChris Duncan <chris@codecow.com>
Mon, 3 Aug 2026 14:36:50 +0000 (07:36 -0700)
committerChris Duncan <chris@codecow.com>
Mon, 3 Aug 2026 14:36:50 +0000 (07:36 -0700)
src/lib/vault/passkey.ts
src/lib/vault/vault-worker.ts

index 58ecba764fddb046b4cf8b24eac7c908e48c4b37..a3c58061a6d0c3f4b060f8eef8bcab9f54976da3 100644 (file)
@@ -1,49 +1,47 @@
 //! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@codecow.com>
 //! SPDX-License-Identifier: GPL-3.0-or-later
 
-export class Passkey {
-       static create (action: string, salt: ArrayBuffer, data: Record<string, unknown>): Promise<CryptoKey | undefined> {
-               // Allowlisted wallet actions
-               if (['create', 'load', 'unlock', 'update'].includes(action)) {
+export async function passkey (action: string, salt: ArrayBuffer, data: Record<string, unknown>): Promise<CryptoKey | undefined> {
+       // Allowlisted wallet actions
+       if (['create', 'load', 'unlock', 'update'].includes(action)) {
 
-                       // Create local copy of password ASAP, then clear bytes from original buffer
-                       if (!(data.password instanceof ArrayBuffer)) {
-                               throw new TypeError('Password must be ArrayBuffer')
-                       }
+               // Create local copy of password ASAP, then clear bytes from original buffer
+               if (!(data.password instanceof ArrayBuffer)) {
+                       throw new TypeError('Password must be ArrayBuffer')
+               }
 
-                       const password = data.password.slice()
-                       new Uint8Array(data.password).fill(0)
-                       delete data.password
+               const password = data.password.slice()
+               new Uint8Array(data.password).fill(0)
+               delete data.password
 
-                       // Only unlocking should decrypt the vault; other sensitive actions should
-                       // throw if the vault is still locked and encrypted
-                       const keyUsages: KeyUsage[] = action === 'unlock' ? ['decrypt'] : ['encrypt']
+               // Only unlocking should decrypt the vault; other sensitive actions should
+               // throw if the vault is still locked and encrypted
+               const keyUsages: KeyUsage[] = action === 'unlock' ? ['decrypt'] : ['encrypt']
 
-                       return crypto.subtle
-                               .importKey('raw', password, 'PBKDF2', false, ['deriveKey'])
-                               .then(derivationKey => {
-                                       new Uint8Array(password).fill(0)
-                                       const derivationAlgorithm: Pbkdf2Params = {
-                                               name: 'PBKDF2',
-                                               hash: 'SHA-512',
-                                               iterations: 210000,
-                                               salt
-                                       }
-                                       const derivedKeyType: AesKeyGenParams = {
-                                               name: 'AES-GCM',
-                                               length: 256
-                                       }
-                                       return crypto.subtle
-                                               .deriveKey(derivationAlgorithm, derivationKey, derivedKeyType, false, keyUsages)
-                               })
-                               .catch(err => {
-                                       console.error(err)
-                                       throw new Error('Failed to derive CryptoKey from password', { cause: err })
-                               })
-               } else if (data.password !== undefined) {
-                       throw new Error('Password is not allowed for this action', { cause: action })
-               } else {
-                       return Promise.resolve(undefined)
-               }
+               return crypto.subtle
+                       .importKey('raw', password, 'PBKDF2', false, ['deriveKey'])
+                       .then(derivationKey => {
+                               new Uint8Array(password).fill(0)
+                               const derivationAlgorithm: Pbkdf2Params = {
+                                       name: 'PBKDF2',
+                                       hash: 'SHA-512',
+                                       iterations: 210000,
+                                       salt
+                               }
+                               const derivedKeyType: AesKeyGenParams = {
+                                       name: 'AES-GCM',
+                                       length: 256
+                               }
+                               return crypto.subtle
+                                       .deriveKey(derivationAlgorithm, derivationKey, derivedKeyType, false, keyUsages)
+                       })
+                       .catch(err => {
+                               console.error(err)
+                               throw new Error('Failed to derive CryptoKey from password', { cause: err })
+                       })
+       } else if (data.password !== undefined) {
+               throw new Error('Password is not allowed for this action', { cause: action })
+       } else {
+               return Promise.resolve(undefined)
        }
 }
index 57c73b89fa40f6618fd695be2bf3d4f183fa5d9d..c23c67fd1ef76699da1fe258b0c322cd9fbaf5c1 100644 (file)
@@ -10,7 +10,7 @@ import { dec, utf8 } from '../convert'
 import { Bip39, Bip44, Blake2b, WalletAesGcm } from '../crypto'
 import { WalletType } from '../wallet'
 import { parseAction, parseData, parseId, parseIv, parseKeySalt, parseType } from './parsers'
-import { Passkey } from './passkey'
+import { passkey } from './passkey'
 import { VaultTimer } from './vault-timer'
 
 let _locked: boolean = true
@@ -37,7 +37,7 @@ const listener = (event: MessageEvent<any>): void => {
        NODE: if (parentPort == null) setTimeout(() => listener(event), 0)
        const action = parseAction(data)
        const keySalt = parseKeySalt(action, data)
-       Passkey.create(action, keySalt, data)
+       passkey(action, keySalt, data)
                .then((key: CryptoKey | undefined): Promise<Record<string, boolean | number | ArrayBuffer> | void> => {
                        const type = parseType(action, data)
                        const id = parseId(action, data)