1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-28 06:03:40 +00:00

[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
This commit is contained in:
Bernd Schoolmann
2025-07-15 11:53:58 +02:00
committed by GitHub
parent 1315e7c37c
commit 8250e40c6c
27 changed files with 44 additions and 697 deletions

View File

@@ -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<Uint8Array> {
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);
}
}

View File

@@ -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({

View File

@@ -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<WindowMain>();
const logService = mock<LogService>();
const biometricStateService = mock<BiometricStateService>();
const cryptoFunctionService = mock<MainCryptoFunctionService>();
const cryptoFunctionService = mock<CryptoFunctionService>();
const encryptService = mock<EncryptService>();
it("Should call the platformspecific methods", async () => {

View File

@@ -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,

View File

@@ -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,
);
},
);
}
}

View File

@@ -98,17 +98,6 @@ const nativeMessaging = {
},
};
const crypto = {
argon2: (
password: Uint8Array,
salt: Uint8Array,
iterations: number,
memory: number,
parallelism: number,
): Promise<Uint8Array> =>
ipcRenderer.invoke("crypto.argon2", { password, salt, iterations, memory, parallelism }),
};
const ephemeralStore = {
setEphemeralValue: (key: string, value: string): Promise<void> =>
ipcRenderer.invoke("setEphemeralValue", { key, value }),