From 8d69fcd6bb5ba67b498372d717ffb5a8d5f5e4c0 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Tue, 15 Jul 2025 11:53:58 +0200 Subject: [PATCH] [PM-22271] Switch to SDK argon2 implementation, and drop other impls (#15401) * Switch to SDK argon2 implementation * Cleanup and update to the latest sdk * Update package lock * Remove copy patch * Fix builds * Fix test build * Remove error * Fix tests * Fix build * Run prettier * Remove argon2 references * Regenerate index.d.ts for desktop_native napi * Replace mocked crypto function service type (cherry picked from commit 8250e40c6c19d1b1007b8e9ed152eabdda8c1ab8) --- .github/renovate.json5 | 12 +- .github/workflows/build-browser.yml | 4 - apps/browser/webpack.config.js | 12 - apps/cli/package.json | 4 +- apps/desktop/desktop_native/Cargo.lock | 34 --- apps/desktop/desktop_native/Cargo.toml | 1 - apps/desktop/desktop_native/core/Cargo.toml | 1 - .../desktop_native/core/src/crypto/crypto.rs | 52 +--- apps/desktop/desktop_native/core/src/error.rs | 2 - apps/desktop/desktop_native/napi/index.d.ts | 3 - apps/desktop/desktop_native/napi/src/lib.rs | 19 -- .../renderer-crypto-function.service.ts | 31 -- .../src/app/services/services.module.ts | 4 +- .../main-biometrics.service.spec.ts | 4 +- apps/desktop/src/main.ts | 9 +- .../main/main-crypto-function.service.ts | 34 --- apps/desktop/src/platform/preload.ts | 11 - apps/desktop/webpack.renderer.js | 11 - apps/web/webpack.config.js | 6 - .../abstractions/crypto-function.service.ts | 7 - .../services/web-crypto-function.service.ts | 47 --- .../services/key-generation.service.spec.ts | 22 +- .../services/key-generation.service.ts | 45 +-- .../services/node-crypto-function.service.ts | 23 -- package-lock.json | 269 +----------------- package.json | 7 +- patches/argon2-browser+1.18.0.patch | 67 ----- 27 files changed, 44 insertions(+), 697 deletions(-) delete mode 100644 apps/desktop/src/app/services/renderer-crypto-function.service.ts delete mode 100644 apps/desktop/src/platform/main/main-crypto-function.service.ts delete mode 100644 patches/argon2-browser+1.18.0.patch diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 09afb97174f..906bbbd7125 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -398,17 +398,7 @@ reviewers: ["team:team-vault-dev"], }, { - matchPackageNames: [ - "@types/argon2-browser", - "aes", - "argon2", - "argon2-browser", - "big-integer", - "cbc", - "rsa", - "russh-cryptovec", - "sha2", - ], + matchPackageNames: ["aes", "big-integer", "cbc", "rsa", "russh-cryptovec", "sha2"], description: "Key Management owned dependencies", commitMessagePrefix: "[deps] KM:", reviewers: ["team:team-key-management-dev"], diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index c75298a3e92..40b03d9e753 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -163,10 +163,6 @@ jobs: FILES=$(find . -maxdepth 1 -type f) for FILE in $FILES; do cp "$FILE" browser-source/; done - # Copy patches to the Browser source directory - mkdir -p browser-source/patches - cp -r patches/* browser-source/patches - # Copy apps/browser to the Browser source directory mkdir -p browser-source/apps/browser cp -r apps/browser/* browser-source/apps/browser diff --git a/apps/browser/webpack.config.js b/apps/browser/webpack.config.js index 4aab0beefbb..90638f4e334 100644 --- a/apps/browser/webpack.config.js +++ b/apps/browser/webpack.config.js @@ -92,11 +92,6 @@ const moduleRules = [ test: /\.[jt]sx?$/, loader: "@ngtools/webpack", }, - { - test: /argon2(-simd)?\.wasm$/, - loader: "base64-loader", - type: "javascript/auto", - }, ]; const requiredPlugins = [ @@ -290,7 +285,6 @@ const mainConfig = { clean: true, }, module: { - noParse: /argon2(-simd)?\.wasm$/, rules: moduleRules, }, experiments: { @@ -365,13 +359,7 @@ if (manifestVersion == 2) { test: /\.tsx?$/, loader: "ts-loader", }, - { - test: /argon2(-simd)?\.wasm$/, - loader: "base64-loader", - type: "javascript/auto", - }, ], - noParse: /argon2(-simd)?\.wasm$/, }, cache: ENV !== "development" diff --git a/apps/cli/package.json b/apps/cli/package.json index 27f3585bff7..ca7af3ec596 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -59,14 +59,12 @@ }, "pkg": { "assets": [ - "./build/**/*", - "../../node_modules/argon2/**/*" + "./build/**/*" ] }, "dependencies": { "@koa/multer": "4.0.0", "@koa/router": "13.1.0", - "argon2": "0.41.1", "big-integer": "1.6.52", "browser-hrtime": "1.1.8", "chalk": "4.1.2", diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 9d0fe633013..4c514016675 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -135,19 +135,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "argon2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", - "zeroize", -] - [[package]] name = "ashpd" version = "0.11.0" @@ -452,15 +439,6 @@ dependencies = [ "tokio-util", ] -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -887,7 +865,6 @@ dependencies = [ "aes", "anyhow", "arboard", - "argon2", "ashpd", "base64", "bitwarden-russh", @@ -2264,17 +2241,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "paste" version = "1.0.15" diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml index a778c9ed359..8e12dded52c 100644 --- a/apps/desktop/desktop_native/Cargo.toml +++ b/apps/desktop/desktop_native/Cargo.toml @@ -12,7 +12,6 @@ publish = false aes = "=0.8.4" anyhow = "=1.0.94" arboard = { version = "=3.6.0", default-features = false } -argon2 = "=0.5.3" ashpd = "=0.11.0" base64 = "=0.22.1" bindgen = "=0.72.0" diff --git a/apps/desktop/desktop_native/core/Cargo.toml b/apps/desktop/desktop_native/core/Cargo.toml index 7cd67dbad6a..50c07b56600 100644 --- a/apps/desktop/desktop_native/core/Cargo.toml +++ b/apps/desktop/desktop_native/core/Cargo.toml @@ -23,7 +23,6 @@ anyhow = { workspace = true } arboard = { workspace = true, features = [ "wayland-data-control", ] } -argon2 = { workspace = true, features = ["zeroize"] } base64 = { workspace = true } byteorder = { workspace = true } cbc = { workspace = true, features = ["alloc"] } diff --git a/apps/desktop/desktop_native/core/src/crypto/crypto.rs b/apps/desktop/desktop_native/core/src/crypto/crypto.rs index a254d34c434..d9e2aec3046 100644 --- a/apps/desktop/desktop_native/core/src/crypto/crypto.rs +++ b/apps/desktop/desktop_native/core/src/crypto/crypto.rs @@ -5,7 +5,7 @@ use aes::cipher::{ BlockEncryptMut, KeyIvInit, }; -use crate::error::{CryptoError, KdfParamError, Result}; +use crate::error::{CryptoError, Result}; use super::CipherString; @@ -33,53 +33,3 @@ pub fn encrypt_aes256( Ok(CipherString::AesCbc256_B64 { iv, data }) } - -pub fn argon2( - secret: &[u8], - salt: &[u8], - iterations: u32, - memory: u32, - parallelism: u32, -) -> Result<[u8; 32]> { - use argon2::*; - - let params = Params::new(memory, iterations, parallelism, Some(32)).map_err(|e| { - KdfParamError::InvalidParams(format!("Argon2 parameters are invalid: {e}",)) - })?; - let argon = Argon2::new(Algorithm::Argon2id, Version::V0x13, params); - - let mut hash = [0u8; 32]; - argon - .hash_password_into(secret, salt, &mut hash) - .map_err(|e| KdfParamError::InvalidParams(format!("Argon2 hashing failed: {e}",)))?; - - // Argon2 is using some stack memory that is not zeroed. Eventually some function will - // overwrite the stack, but we use this trick to force the used stack to be zeroed. - #[inline(never)] - fn clear_stack() { - std::hint::black_box([0u8; 4096]); - } - clear_stack(); - Ok(hash) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_argon2() { - let test_hash: [u8; 32] = [ - 112, 200, 85, 209, 100, 4, 246, 146, 117, 180, 152, 44, 103, 198, 75, 14, 166, 77, 201, - 22, 62, 178, 87, 224, 95, 209, 253, 68, 166, 209, 47, 218, - ]; - let secret = b"supersecurepassword"; - let salt = b"mail@example.com"; - let iterations = 3; - let memory = 1024 * 64; - let parallelism = 4; - - let hash = argon2(secret, salt, iterations, memory, parallelism).unwrap(); - assert_eq!(hash, test_hash,); - } -} diff --git a/apps/desktop/desktop_native/core/src/error.rs b/apps/desktop/desktop_native/core/src/error.rs index 34624ed630e..d70d8624018 100644 --- a/apps/desktop/desktop_native/core/src/error.rs +++ b/apps/desktop/desktop_native/core/src/error.rs @@ -9,8 +9,6 @@ pub enum Error { #[error("Cryptography Error, {0}")] Crypto(#[from] CryptoError), - #[error("KDF Parameter Error, {0}")] - KdfParam(#[from] KdfParamError), } #[derive(Debug, Error)] diff --git a/apps/desktop/desktop_native/napi/index.d.ts b/apps/desktop/desktop_native/napi/index.d.ts index cb9430290e3..6ee460a8065 100644 --- a/apps/desktop/desktop_native/napi/index.d.ts +++ b/apps/desktop/desktop_native/napi/index.d.ts @@ -195,9 +195,6 @@ export declare namespace autofill { completeError(clientId: number, sequenceNumber: number, error: string): number } } -export declare namespace crypto { - export function argon2(secret: Buffer, salt: Buffer, iterations: number, memory: number, parallelism: number): Promise -} export declare namespace passkey_authenticator { export function register(): void } diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index 49f653d4809..784bfb72086 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -798,25 +798,6 @@ pub mod autofill { } } -#[napi] -pub mod crypto { - use napi::bindgen_prelude::Buffer; - - #[napi] - pub async fn argon2( - secret: Buffer, - salt: Buffer, - iterations: u32, - memory: u32, - parallelism: u32, - ) -> napi::Result { - desktop_core::crypto::argon2(&secret, &salt, iterations, memory, parallelism) - .map_err(|e| napi::Error::from_reason(e.to_string())) - .map(|v| v.to_vec()) - .map(Buffer::from) - } -} - #[napi] pub mod passkey_authenticator { #[napi] diff --git a/apps/desktop/src/app/services/renderer-crypto-function.service.ts b/apps/desktop/src/app/services/renderer-crypto-function.service.ts deleted file mode 100644 index 8f109e0613f..00000000000 --- a/apps/desktop/src/app/services/renderer-crypto-function.service.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; -import { WebCryptoFunctionService } from "@bitwarden/common/key-management/crypto/services/web-crypto-function.service"; - -export class RendererCryptoFunctionService - extends WebCryptoFunctionService - implements CryptoFunctionService -{ - constructor(win: Window | typeof global) { - super(win); - } - - // We can't use the `argon2-browser` implementation because it loads WASM and the Content Security Policy doesn't allow it. - // Rather than trying to weaken the policy, we'll just use the Node.js implementation though the IPC channel. - // Note that the rest of the functions on this service will be inherited from the WebCryptoFunctionService, as those work just fine. - async argon2( - password: string | Uint8Array, - salt: string | Uint8Array, - iterations: number, - memory: number, - parallelism: number, - ): Promise { - if (typeof password === "string") { - password = new TextEncoder().encode(password); - } - if (typeof salt === "string") { - salt = new TextEncoder().encode(salt); - } - - return await ipc.platform.crypto.argon2(password, salt, iterations, memory, parallelism); - } -} diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 4111a62d3b2..a69a9d7f41b 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -55,6 +55,7 @@ import { ClientType } from "@bitwarden/common/enums"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { WebCryptoFunctionService } from "@bitwarden/common/key-management/crypto/services/web-crypto-function.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { DefaultProcessReloadService } from "@bitwarden/common/key-management/services/default-process-reload.service"; import { @@ -140,7 +141,6 @@ import { DesktopFileDownloadService } from "./desktop-file-download.service"; import { DesktopSetPasswordJitService } from "./desktop-set-password-jit.service"; import { InitService } from "./init.service"; import { NativeMessagingManifestService } from "./native-messaging-manifest.service"; -import { RendererCryptoFunctionService } from "./renderer-crypto-function.service"; import { DesktopSetInitialPasswordService } from "./set-initial-password/desktop-set-initial-password.service"; const RELOAD_CALLBACK = new SafeInjectionToken<() => any>("RELOAD_CALLBACK"); @@ -296,7 +296,7 @@ const safeProviders: SafeProvider[] = [ }), safeProvider({ provide: CryptoFunctionServiceAbstraction, - useClass: RendererCryptoFunctionService, + useClass: WebCryptoFunctionService, deps: [WINDOW], }), safeProvider({ diff --git a/apps/desktop/src/key-management/biometrics/main-biometrics.service.spec.ts b/apps/desktop/src/key-management/biometrics/main-biometrics.service.spec.ts index 213f3d48a98..bc57a7e55fb 100644 --- a/apps/desktop/src/key-management/biometrics/main-biometrics.service.spec.ts +++ b/apps/desktop/src/key-management/biometrics/main-biometrics.service.spec.ts @@ -1,5 +1,6 @@ import { mock, MockProxy } from "jest-mock-extended"; +import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -13,7 +14,6 @@ import { } from "@bitwarden/key-management"; import { WindowMain } from "../../main/window.main"; -import { MainCryptoFunctionService } from "../../platform/main/main-crypto-function.service"; import { MainBiometricsService } from "./main-biometrics.service"; import OsBiometricsServiceLinux from "./os-biometrics-linux.service"; @@ -35,7 +35,7 @@ describe("MainBiometricsService", function () { const windowMain = mock(); const logService = mock(); const biometricStateService = mock(); - const cryptoFunctionService = mock(); + const cryptoFunctionService = mock(); const encryptService = mock(); it("Should call the platformspecific methods", async () => { diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index 4821b018148..d91d37c9689 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -28,8 +28,9 @@ import { DefaultSingleUserStateProvider } from "@bitwarden/common/platform/state import { DefaultStateProvider } from "@bitwarden/common/platform/state/implementations/default-state.provider"; import { StateEventRegistrarService } from "@bitwarden/common/platform/state/state-event-registrar.service"; import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service"; -import { DefaultBiometricStateService } from "@bitwarden/key-management"; /* eslint-enable import/no-restricted-paths */ +import { DefaultBiometricStateService } from "@bitwarden/key-management"; +import { NodeCryptoFunctionService } from "@bitwarden/node/services/node-crypto-function.service"; import { MainSshAgentService } from "./autofill/main/main-ssh-agent.service"; import { DesktopAutofillSettingsService } from "./autofill/services/desktop-autofill-settings.service"; @@ -46,7 +47,6 @@ import { WindowMain } from "./main/window.main"; import { NativeAutofillMain } from "./platform/main/autofill/native-autofill.main"; import { ClipboardMain } from "./platform/main/clipboard.main"; import { DesktopCredentialStorageListener } from "./platform/main/desktop-credential-storage-listener"; -import { MainCryptoFunctionService } from "./platform/main/main-crypto-function.service"; import { VersionMain } from "./platform/main/version.main"; import { DesktopSettingsService } from "./platform/services/desktop-settings.service"; import { ElectronLogMainService } from "./platform/services/electron-log.main.service"; @@ -68,7 +68,7 @@ export class Main { desktopCredentialStorageListener: DesktopCredentialStorageListener; mainBiometricsIpcListener: MainBiometricsIPCListener; desktopSettingsService: DesktopSettingsService; - mainCryptoFunctionService: MainCryptoFunctionService; + mainCryptoFunctionService: NodeCryptoFunctionService; migrationRunner: MigrationRunner; ssoUrlService: SsoUrlService; @@ -140,8 +140,7 @@ export class Main { this.i18nService = new I18nMainService("en", "./locales/", globalStateProvider); - this.mainCryptoFunctionService = new MainCryptoFunctionService(); - this.mainCryptoFunctionService.init(); + this.mainCryptoFunctionService = new NodeCryptoFunctionService(); const stateEventRegistrarService = new StateEventRegistrarService( globalStateProvider, diff --git a/apps/desktop/src/platform/main/main-crypto-function.service.ts b/apps/desktop/src/platform/main/main-crypto-function.service.ts deleted file mode 100644 index 0751f6b3a85..00000000000 --- a/apps/desktop/src/platform/main/main-crypto-function.service.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ipcMain } from "electron"; - -import { CryptoFunctionService } from "@bitwarden/common/key-management/crypto/abstractions/crypto-function.service"; -import { crypto } from "@bitwarden/desktop-napi"; -import { NodeCryptoFunctionService } from "@bitwarden/node/services/node-crypto-function.service"; - -export class MainCryptoFunctionService - extends NodeCryptoFunctionService - implements CryptoFunctionService -{ - init() { - ipcMain.handle( - "crypto.argon2", - async ( - event, - opts: { - password: Uint8Array; - salt: Uint8Array; - iterations: number; - memory: number; - parallelism: number; - }, - ) => { - return await crypto.argon2( - Buffer.from(opts.password), - Buffer.from(opts.salt), - opts.iterations, - opts.memory, - opts.parallelism, - ); - }, - ); - } -} diff --git a/apps/desktop/src/platform/preload.ts b/apps/desktop/src/platform/preload.ts index bf81021922f..0487675c792 100644 --- a/apps/desktop/src/platform/preload.ts +++ b/apps/desktop/src/platform/preload.ts @@ -98,17 +98,6 @@ const nativeMessaging = { }, }; -const crypto = { - argon2: ( - password: Uint8Array, - salt: Uint8Array, - iterations: number, - memory: number, - parallelism: number, - ): Promise => - ipcRenderer.invoke("crypto.argon2", { password, salt, iterations, memory, parallelism }), -}; - const ephemeralStore = { setEphemeralValue: (key: string, value: string): Promise => ipcRenderer.invoke("setEphemeralValue", { key, value }), diff --git a/apps/desktop/webpack.renderer.js b/apps/desktop/webpack.renderer.js index 7c80c719aca..555e1ed38bd 100644 --- a/apps/desktop/webpack.renderer.js +++ b/apps/desktop/webpack.renderer.js @@ -41,11 +41,6 @@ const common = { }, type: "asset/resource", }, - { - test: /argon2(-simd)?\.wasm$/, - loader: "base64-loader", - type: "javascript/auto", - }, ], }, plugins: [], @@ -154,13 +149,7 @@ const renderer = { test: /[\/\\]@angular[\/\\].+\.js$/, parser: { system: true }, }, - { - test: /argon2(-simd)?\.wasm$/, - loader: "base64-loader", - type: "javascript/auto", - }, ], - noParse: /argon2(-simd)?\.wasm$/, }, experiments: { asyncWebAssembly: true, diff --git a/apps/web/webpack.config.js b/apps/web/webpack.config.js index a28052b98e3..77403914e9a 100644 --- a/apps/web/webpack.config.js +++ b/apps/web/webpack.config.js @@ -90,11 +90,6 @@ const moduleRules = [ test: /\.[jt]sx?$/, loader: "@ngtools/webpack", }, - { - test: /argon2(-simd)?\.wasm$/, - loader: "base64-loader", - type: "javascript/auto", - }, ]; const plugins = [ @@ -404,7 +399,6 @@ const webpackConfig = { clean: true, }, module: { - noParse: /argon2(-simd)?\.wasm$/, rules: moduleRules, }, experiments: { diff --git a/libs/common/src/key-management/crypto/abstractions/crypto-function.service.ts b/libs/common/src/key-management/crypto/abstractions/crypto-function.service.ts index 4b89dde7021..d9541481083 100644 --- a/libs/common/src/key-management/crypto/abstractions/crypto-function.service.ts +++ b/libs/common/src/key-management/crypto/abstractions/crypto-function.service.ts @@ -12,13 +12,6 @@ export abstract class CryptoFunctionService { algorithm: "sha256" | "sha512", iterations: number, ): Promise; - abstract argon2( - password: string | Uint8Array, - salt: string | Uint8Array, - iterations: number, - memory: number, - parallelism: number, - ): Promise; abstract hkdf( ikm: Uint8Array, salt: string | Uint8Array, diff --git a/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts b/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts index 430774ca2ed..32cbd58dde2 100644 --- a/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts +++ b/libs/common/src/key-management/crypto/services/web-crypto-function.service.ts @@ -1,4 +1,3 @@ -import * as argon2 from "argon2-browser"; import * as forge from "node-forge"; import { EncryptionType } from "../../../platform/enums"; @@ -14,7 +13,6 @@ import { CryptoFunctionService } from "../abstractions/crypto-function.service"; export class WebCryptoFunctionService implements CryptoFunctionService { private crypto: Crypto; private subtle: SubtleCrypto; - private wasmSupported: boolean; constructor(globalContext: { crypto: Crypto }) { if (globalContext?.crypto?.subtle == null) { @@ -24,7 +22,6 @@ export class WebCryptoFunctionService implements CryptoFunctionService { } this.crypto = globalContext.crypto; this.subtle = this.crypto.subtle; - this.wasmSupported = this.checkIfWasmSupported(); } async pbkdf2( @@ -55,33 +52,6 @@ export class WebCryptoFunctionService implements CryptoFunctionService { return new Uint8Array(buffer); } - async argon2( - password: string | Uint8Array, - salt: string | Uint8Array, - iterations: number, - memory: number, - parallelism: number, - ): Promise { - if (!this.wasmSupported) { - throw "Webassembly support is required for the Argon2 KDF feature."; - } - - const passwordArr = new Uint8Array(this.toBuf(password)); - const saltArr = new Uint8Array(this.toBuf(salt)); - - const result = await argon2.hash({ - pass: passwordArr, - salt: saltArr, - time: iterations, - mem: memory, - parallelism: parallelism, - hashLen: 32, - type: argon2.ArgonType.Argon2id, - }); - argon2.unloadRuntime(); - return result.hash; - } - async hkdf( ikm: Uint8Array, salt: string | Uint8Array, @@ -442,21 +412,4 @@ export class WebCryptoFunctionService implements CryptoFunctionService { private toWebCryptoAesMode(mode: "cbc" | "ecb"): string { return mode === "cbc" ? "AES-CBC" : "AES-ECB"; } - - // ref: https://stackoverflow.com/a/47880734/1090359 - private checkIfWasmSupported(): boolean { - try { - if (typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function") { - const module = new WebAssembly.Module( - Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00), - ); - if (module instanceof WebAssembly.Module) { - return new WebAssembly.Instance(module) instanceof WebAssembly.Instance; - } - } - } catch { - return false; - } - return false; - } } diff --git a/libs/common/src/platform/services/key-generation.service.spec.ts b/libs/common/src/platform/services/key-generation.service.spec.ts index 4fdad48e0fa..fb6c0a459b3 100644 --- a/libs/common/src/platform/services/key-generation.service.spec.ts +++ b/libs/common/src/platform/services/key-generation.service.spec.ts @@ -6,6 +6,7 @@ import { PBKDF2KdfConfig, Argon2KdfConfig } from "@bitwarden/key-management"; import { CryptoFunctionService } from "../../key-management/crypto/abstractions/crypto-function.service"; import { CsprngArray } from "../../types/csprng"; +import { SdkLoadService } from "../abstractions/sdk/sdk-load.service"; import { EncryptionType } from "../enums"; import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; @@ -77,27 +78,30 @@ describe("KeyGenerationService", () => { describe("deriveKeyFromPassword", () => { it("should derive a 32 byte key from a password using pbkdf2", async () => { - const password = "password"; - const salt = "salt"; + const password = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); + const salt = new Uint8Array([9, 10, 11, 12]); const kdfConfig = new PBKDF2KdfConfig(600_000); - cryptoFunctionService.pbkdf2.mockResolvedValue(new Uint8Array(32)); + Object.defineProperty(SdkLoadService, "Ready", { + value: Promise.resolve(), + configurable: true, + }); const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig); - expect(key.inner().type).toEqual(EncryptionType.AesCbc256_B64); }); it("should derive a 32 byte key from a password using argon2id", async () => { - const password = "password"; - const salt = "salt"; + const password = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]); + const salt = new Uint8Array([9, 10, 11, 12]); const kdfConfig = new Argon2KdfConfig(3, 16, 4); - cryptoFunctionService.hash.mockResolvedValue(new Uint8Array(32)); - cryptoFunctionService.argon2.mockResolvedValue(new Uint8Array(32)); + Object.defineProperty(SdkLoadService, "Ready", { + value: Promise.resolve(), + configurable: true, + }); const key = await sut.deriveKeyFromPassword(password, salt, kdfConfig); - expect(key.inner().type).toEqual(EncryptionType.AesCbc256_B64); }); }); diff --git a/libs/common/src/platform/services/key-generation.service.ts b/libs/common/src/platform/services/key-generation.service.ts index 49f99eb79a9..d25be087b06 100644 --- a/libs/common/src/platform/services/key-generation.service.ts +++ b/libs/common/src/platform/services/key-generation.service.ts @@ -2,11 +2,13 @@ // @ts-strict-ignore // This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. // eslint-disable-next-line no-restricted-imports -import { KdfConfig, PBKDF2KdfConfig, Argon2KdfConfig, KdfType } from "@bitwarden/key-management"; +import { KdfConfig } from "@bitwarden/key-management"; +import { PureCrypto } from "@bitwarden/sdk-internal"; import { CryptoFunctionService } from "../../key-management/crypto/abstractions/crypto-function.service"; import { CsprngArray } from "../../types/csprng"; import { KeyGenerationService as KeyGenerationServiceAbstraction } from "../abstractions/key-generation.service"; +import { SdkLoadService } from "../abstractions/sdk/sdk-load.service"; import { EncryptionType } from "../enums"; import { Utils } from "../misc/utils"; import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; @@ -47,38 +49,17 @@ export class KeyGenerationService implements KeyGenerationServiceAbstraction { salt: string | Uint8Array, kdfConfig: KdfConfig, ): Promise { - let key: Uint8Array = null; - if (kdfConfig.kdfType == null || kdfConfig.kdfType === KdfType.PBKDF2_SHA256) { - if (kdfConfig.iterations == null) { - kdfConfig.iterations = PBKDF2KdfConfig.ITERATIONS.defaultValue; - } - - key = await this.cryptoFunctionService.pbkdf2(password, salt, "sha256", kdfConfig.iterations); - } else if (kdfConfig.kdfType == KdfType.Argon2id) { - if (kdfConfig.iterations == null) { - kdfConfig.iterations = Argon2KdfConfig.ITERATIONS.defaultValue; - } - - if (kdfConfig.memory == null) { - kdfConfig.memory = Argon2KdfConfig.MEMORY.defaultValue; - } - - if (kdfConfig.parallelism == null) { - kdfConfig.parallelism = Argon2KdfConfig.PARALLELISM.defaultValue; - } - - const saltHash = await this.cryptoFunctionService.hash(salt, "sha256"); - key = await this.cryptoFunctionService.argon2( - password, - saltHash, - kdfConfig.iterations, - kdfConfig.memory * 1024, // convert to KiB from MiB - kdfConfig.parallelism, - ); - } else { - throw new Error("Unknown Kdf."); + if (typeof password === "string") { + password = new TextEncoder().encode(password); } - return new SymmetricCryptoKey(key); + if (typeof salt === "string") { + salt = new TextEncoder().encode(salt); + } + + await SdkLoadService.Ready; + return new SymmetricCryptoKey( + PureCrypto.derive_kdf_material(password, salt, kdfConfig.toSdkConfig()), + ); } async stretchKey(key: SymmetricCryptoKey): Promise { diff --git a/libs/node/src/services/node-crypto-function.service.ts b/libs/node/src/services/node-crypto-function.service.ts index 33ea3adf357..f3ac71b13e7 100644 --- a/libs/node/src/services/node-crypto-function.service.ts +++ b/libs/node/src/services/node-crypto-function.service.ts @@ -33,29 +33,6 @@ export class NodeCryptoFunctionService implements CryptoFunctionService { }); } - async argon2( - password: string | Uint8Array, - salt: string | Uint8Array, - iterations: number, - memory: number, - parallelism: number, - ): Promise { - const nodePassword = this.toNodeValue(password); - const nodeSalt = this.toNodeBuffer(this.toUint8Buffer(salt)); - - const argon2 = await import("argon2"); - const hash = await argon2.hash(nodePassword, { - salt: nodeSalt, - raw: true, - hashLength: 32, - timeCost: iterations, - memoryCost: memory, - parallelism: parallelism, - type: argon2.argon2id, - }); - return this.toUint8Buffer(hash); - } - // ref: https://tools.ietf.org/html/rfc5869 async hkdf( ikm: Uint8Array, diff --git a/package-lock.json b/package-lock.json index ea003e2b3f8..541c596c78a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "@bitwarden/clients", "version": "0.0.0", - "hasInstallScript": true, "license": "GPL-3.0", "workspaces": [ "apps/*", @@ -36,8 +35,6 @@ "@nx/eslint": "21.1.2", "@nx/jest": "21.1.2", "@nx/js": "21.1.2", - "argon2": "0.41.1", - "argon2-browser": "1.18.0", "big-integer": "1.6.52", "bootstrap": "4.6.0", "braintree-web-drop-in": "1.44.0", @@ -64,7 +61,6 @@ "oidc-client-ts": "2.4.1", "open": "10.1.2", "papaparse": "5.5.3", - "patch-package": "8.0.0", "proper-lockfile": "4.1.2", "qrcode-parser": "2.1.3", "qrious": "4.0.2", @@ -102,7 +98,6 @@ "@storybook/test-runner": "0.22.0", "@storybook/theming": "8.6.12", "@storybook/web-components-webpack5": "8.6.12", - "@types/argon2-browser": "1.18.4", "@types/chrome": "0.0.306", "@types/firefox-webext-browser": "120.0.4", "@types/inquirer": "8.2.10", @@ -206,7 +201,6 @@ "dependencies": { "@koa/multer": "4.0.0", "@koa/router": "13.1.0", - "argon2": "0.41.1", "big-integer": "1.6.52", "browser-hrtime": "1.1.8", "chalk": "4.1.2", @@ -9873,15 +9867,6 @@ "node": ">=4.2.0" } }, - "node_modules/@phc/format": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz", - "integrity": "sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/@phenomnomnominal/tsquery": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-5.0.1.tgz", @@ -12071,13 +12056,6 @@ "@types/node": "*" } }, - "node_modules/@types/argon2-browser": { - "version": "1.18.4", - "resolved": "https://registry.npmjs.org/@types/argon2-browser/-/argon2-browser-1.18.4.tgz", - "integrity": "sha512-K/PHAEKzdCY4mCRhgUTBcuTxeaJyLoPcd5pJ1UFSTb/FAPjj3TCK4EM/DvNmVtDzkQBMD5peJjtch3kVQDf4YQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", @@ -14799,27 +14777,6 @@ "dev": true, "license": "MIT" }, - "node_modules/argon2": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.41.1.tgz", - "integrity": "sha512-dqCW8kJXke8Ik+McUcMDltrbuAWETPyU6iq+4AhxqKphWi7pChB/Zgd/Tp/o8xRLbg8ksMj46F/vph9wnxpTzQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@phc/format": "^1.0.0", - "node-addon-api": "^8.1.0", - "node-gyp-build": "^4.8.1" - }, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/argon2-browser": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/argon2-browser/-/argon2-browser-1.18.0.tgz", - "integrity": "sha512-ImVAGIItnFnvET1exhsQB7apRztcoC5TnlSqernMJDUjbc/DLq3UEYeXFrLPrlaIl8cVfwnXb6wX2KpFf2zxHw==", - "license": "MIT" - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -16390,6 +16347,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -18210,6 +18168,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -20914,15 +20873,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", - "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", - "license": "Apache-2.0", - "dependencies": { - "micromatch": "^4.0.2" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -21939,6 +21889,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -23621,6 +23572,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, "license": "MIT" }, "node_modules/isbinaryfile": { @@ -25682,25 +25634,6 @@ "dev": true, "license": "BSD-2-Clause" }, - "node_modules/json-stable-stringify": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", - "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "isarray": "^2.0.5", - "jsonify": "^0.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -25744,15 +25677,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "license": "Public Domain", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", @@ -25875,15 +25799,6 @@ "node": ">=0.10.0" } }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", - "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11" - } - }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -29102,15 +29017,6 @@ "dev": true, "license": "MIT" }, - "node_modules/node-addon-api": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz", - "integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==", - "license": "MIT", - "engines": { - "node": "^18 || ^20 || >= 21" - } - }, "node_modules/node-api-version": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.1.tgz", @@ -30703,6 +30609,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -31585,171 +31492,6 @@ "tslib": "^2.0.3" } }, - "node_modules/patch-package": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", - "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", - "license": "MIT", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "chalk": "^4.1.2", - "ci-info": "^3.7.0", - "cross-spawn": "^7.0.3", - "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", - "json-stable-stringify": "^1.0.2", - "klaw-sync": "^6.0.0", - "minimist": "^1.2.6", - "open": "^7.4.2", - "rimraf": "^2.6.3", - "semver": "^7.5.3", - "slash": "^2.0.0", - "tmp": "^0.0.33", - "yaml": "^2.2.2" - }, - "bin": { - "patch-package": "index.js" - }, - "engines": { - "node": ">=14", - "npm": ">5" - } - }, - "node_modules/patch-package/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/patch-package/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/patch-package/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/patch-package/node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/patch-package/node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/patch-package/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/patch-package/node_modules/open": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", - "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/patch-package/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/patch-package/node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -34504,6 +34246,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", diff --git a/package.json b/package.json index d94295c5ea3..b7923a92f6f 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,7 @@ "build-storybook": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" ng run components:build-storybook", "build-storybook:ci": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" ng run components:build-storybook --webpack-stats-json", "test-stories": "test-storybook --url http://localhost:6006", - "test-stories:watch": "test-stories --watch", - "postinstall": "patch-package" + "test-stories:watch": "test-stories --watch" }, "workspaces": [ "apps/*", @@ -62,7 +61,6 @@ "@storybook/test-runner": "0.22.0", "@storybook/theming": "8.6.12", "@storybook/web-components-webpack5": "8.6.12", - "@types/argon2-browser": "1.18.4", "@types/chrome": "0.0.306", "@types/firefox-webext-browser": "120.0.4", "@types/inquirer": "8.2.10", @@ -172,8 +170,6 @@ "@nx/eslint": "21.1.2", "@nx/jest": "21.1.2", "@nx/js": "21.1.2", - "argon2": "0.41.1", - "argon2-browser": "1.18.0", "big-integer": "1.6.52", "bootstrap": "4.6.0", "braintree-web-drop-in": "1.44.0", @@ -200,7 +196,6 @@ "oidc-client-ts": "2.4.1", "open": "10.1.2", "papaparse": "5.5.3", - "patch-package": "8.0.0", "proper-lockfile": "4.1.2", "qrcode-parser": "2.1.3", "qrious": "4.0.2", diff --git a/patches/argon2-browser+1.18.0.patch b/patches/argon2-browser+1.18.0.patch deleted file mode 100644 index 160661cd915..00000000000 --- a/patches/argon2-browser+1.18.0.patch +++ /dev/null @@ -1,67 +0,0 @@ -diff --git a/node_modules/argon2-browser/lib/argon2.js b/node_modules/argon2-browser/lib/argon2.js -index ffa77a5..98b2f13 100644 ---- a/node_modules/argon2-browser/lib/argon2.js -+++ b/node_modules/argon2-browser/lib/argon2.js -@@ -78,16 +78,27 @@ - if (global.loadArgon2WasmBinary) { - return global.loadArgon2WasmBinary(); - } -+ -+ const simd = checkIfSIMDSupported(); -+ - if (typeof require === 'function') { -- return Promise.resolve(require('../dist/argon2.wasm')).then( -- (wasmModule) => { -- return decodeWasmBinary(wasmModule); -- } -- ); -+ if (simd) { -+ return Promise.resolve(require('../dist/argon2-simd.wasm')).then( -+ (wasmModule) => { -+ return decodeWasmBinary(wasmModule); -+ } -+ ); -+ } else { -+ return Promise.resolve(require('../dist/argon2.wasm')).then( -+ (wasmModule) => { -+ return decodeWasmBinary(wasmModule); -+ } -+ ); -+ } - } - const wasmPath = - global.argon2WasmPath || -- 'node_modules/argon2-browser/dist/argon2.wasm'; -+ 'node_modules/argon2-browser/dist/argon2' + (simd? "-simd" : "") + '.wasm'; - return fetch(wasmPath) - .then((response) => response.arrayBuffer()) - .then((ab) => new Uint8Array(ab)); -@@ -351,7 +362,28 @@ - loadModule._module.unloadRuntime(); - delete loadModule._promise; - delete loadModule._module; -+ if (typeof require !== 'undefined') { -+ delete require.cache[require.resolve('../dist/argon2.js')] -+ } -+ } -+ } -+ -+ // ref: https://stackoverflow.com/a/47880734/1090359 -+ // ref: https://github.com/GoogleChromeLabs/wasm-feature-detect/blob/main/src/detectors/simd/module.wat (translated with wat2wasm) -+ function checkIfSIMDSupported() { -+ try { -+ if (typeof WebAssembly === "object" && typeof WebAssembly.instantiate === "function") { -+ const module = new WebAssembly.Module( -+ Uint8Array.of(0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03, 0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00, 0x41, 0x00, 0xfd, 0x0f, 0xfd, 0x62, 0x0b) -+ ); -+ if (module instanceof WebAssembly.Module) { -+ return new WebAssembly.Instance(module) instanceof WebAssembly.Instance; -+ } -+ } -+ } catch { -+ return false; - } -+ return false; - } - - return {