[PM-6419] Change desktop argon implementation for Node (#8048)

* Fix desktop argon2

* Don't remove wasm loading in renderer

* Fix electron-builder not including dependency
This commit is contained in:
Daniel García 2024-02-26 23:31:09 +01:00 committed by GitHub
parent f53af7c466
commit 996823169a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 91 additions and 4 deletions

View File

@ -17,7 +17,12 @@
"**/*",
"!**/node_modules/@bitwarden/desktop-native/**/*",
"**/node_modules/@bitwarden/desktop-native/index.js",
"**/node_modules/@bitwarden/desktop-native/desktop_native.${platform}-${arch}*.node"
"**/node_modules/@bitwarden/desktop-native/desktop_native.${platform}-${arch}*.node",
"!**/node_modules/argon2/**/*",
"**/node_modules/argon2/argon2.js",
"**/node_modules/argon2/package.json",
"**/node_modules/argon2/lib/binding/napi-v3/argon2.node"
],
"electronVersion": "28.2.4",
"generateUpdatesFilesForAllChannels": true,

View File

@ -0,0 +1,24 @@
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
import { WebCryptoFunctionService } from "@bitwarden/common/platform/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> {
return await ipc.platform.crypto.argon2(password, salt, iterations, memory, parallelism);
}
}

View File

@ -10,6 +10,7 @@ import {
MEMORY_STORAGE,
OBSERVABLE_MEMORY_STORAGE,
OBSERVABLE_DISK_STORAGE,
WINDOW,
} from "@bitwarden/angular/services/injection-tokens";
import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module";
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
@ -66,6 +67,7 @@ import { SearchBarService } from "../layout/search/search-bar.service";
import { DesktopFileDownloadService } from "./desktop-file-download.service";
import { DesktopThemingService } from "./desktop-theming.service";
import { InitService } from "./init.service";
import { RendererCryptoFunctionService } from "./renderer-crypto-function.service";
const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
@ -175,6 +177,11 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
useClass: LoginService,
deps: [StateServiceAbstraction],
},
{
provide: CryptoFunctionServiceAbstraction,
useClass: RendererCryptoFunctionService,
deps: [WINDOW],
},
{
provide: CryptoServiceAbstraction,
useClass: ElectronCryptoService,

View File

@ -32,6 +32,7 @@ import { Account } from "./models/account";
import { BiometricsService, BiometricsServiceAbstraction } from "./platform/main/biometric/index";
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 { ElectronLogMainService } from "./platform/services/electron-log.main.service";
import { ElectronStateService } from "./platform/services/electron-state.service";
import { ElectronStorageService } from "./platform/services/electron-storage.service";
@ -47,6 +48,7 @@ export class Main {
messagingService: ElectronMainMessagingService;
stateService: StateService;
environmentService: EnvironmentService;
mainCryptoFunctionService: MainCryptoFunctionService;
desktopCredentialStorageListener: DesktopCredentialStorageListener;
migrationRunner: MigrationRunner;
@ -198,6 +200,9 @@ export class Main {
this.clipboardMain = new ClipboardMain();
this.clipboardMain.init();
this.mainCryptoFunctionService = new MainCryptoFunctionService();
this.mainCryptoFunctionService.init();
}
bootstrap() {

View File

@ -12,6 +12,7 @@
"url": "git+https://github.com/bitwarden/clients.git"
},
"dependencies": {
"@bitwarden/desktop-native": "file:../desktop_native"
"@bitwarden/desktop-native": "file:../desktop_native",
"argon2": "0.31.0"
}
}

View File

@ -0,0 +1,33 @@
import { ipcMain } from "electron";
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
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: string | Uint8Array;
salt: string | Uint8Array;
iterations: number;
memory: number;
parallelism: number;
},
) => {
return await this.argon2(
opts.password,
opts.salt,
opts.iterations,
opts.memory,
opts.parallelism,
);
},
);
}
}

View File

@ -76,6 +76,17 @@ const nativeMessaging = {
},
};
const crypto = {
argon2: (
password: string | Uint8Array,
salt: string | Uint8Array,
iterations: number,
memory: number,
parallelism: number,
): Promise<Uint8Array> =>
ipcRenderer.invoke("crypto.argon2", { password, salt, iterations, memory, parallelism }),
};
export default {
versions: {
app: (): Promise<string> => ipcRenderer.invoke("appVersion"),
@ -121,6 +132,7 @@ export default {
biometric,
clipboard,
nativeMessaging,
crypto,
};
function deviceType(): DeviceType {

View File

@ -72,8 +72,6 @@ const main = {
"./src/package.json",
{ from: "./src/images", to: "images" },
{ from: "./src/locales", to: "locales" },
"../../node_modules/argon2-browser/dist/argon2.wasm",
"../../node_modules/argon2-browser/dist/argon2-simd.wasm",
],
}),
new EnvironmentPlugin({
@ -84,6 +82,8 @@ const main = {
externals: {
"electron-reload": "commonjs2 electron-reload",
"@bitwarden/desktop-native": "commonjs2 @bitwarden/desktop-native",
argon2: "commonjs2 argon2",
},
};