From 347bfcd4633f81fba0e833df6955e33cc469caf3 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 28 Nov 2024 12:35:32 +0100 Subject: [PATCH 01/18] Move desktop to sdk ssh-key generation --- .../core/src/ssh_agent/generator.rs | 45 ------------------- .../desktop_native/core/src/ssh_agent/mod.rs | 1 - apps/desktop/desktop_native/napi/src/lib.rs | 8 ---- .../platform/main/main-ssh-agent.service.ts | 6 --- apps/desktop/src/platform/preload.ts | 3 -- .../src/vault/app/vault/add-edit.component.ts | 9 ++-- 6 files changed, 5 insertions(+), 67 deletions(-) delete mode 100644 apps/desktop/desktop_native/core/src/ssh_agent/generator.rs diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/generator.rs b/apps/desktop/desktop_native/core/src/ssh_agent/generator.rs deleted file mode 100644 index fe639f20e7f..00000000000 --- a/apps/desktop/desktop_native/core/src/ssh_agent/generator.rs +++ /dev/null @@ -1,45 +0,0 @@ -use rand::SeedableRng; -use rand_chacha::ChaCha8Rng; -use ssh_key::{Algorithm, HashAlg, LineEnding}; - -use super::importer::SshKey; - -pub async fn generate_keypair(key_algorithm: String) -> Result { - // sourced from cryptographically secure entropy source, with sources for all targets: https://docs.rs/getrandom - // if it cannot be securely sourced, this will panic instead of leading to a weak key - let mut rng: ChaCha8Rng = ChaCha8Rng::from_entropy(); - - let key = match key_algorithm.as_str() { - "ed25519" => ssh_key::PrivateKey::random(&mut rng, Algorithm::Ed25519), - "rsa2048" | "rsa3072" | "rsa4096" => { - let bits = match key_algorithm.as_str() { - "rsa2048" => 2048, - "rsa3072" => 3072, - "rsa4096" => 4096, - _ => return Err(anyhow::anyhow!("Unsupported RSA key size")), - }; - let rsa_keypair = ssh_key::private::RsaKeypair::random(&mut rng, bits) - .or_else(|e| Err(anyhow::anyhow!(e.to_string())))?; - - let private_key = ssh_key::PrivateKey::new( - ssh_key::private::KeypairData::from(rsa_keypair), - "".to_string(), - ) - .or_else(|e| Err(anyhow::anyhow!(e.to_string())))?; - Ok(private_key) - } - _ => { - return Err(anyhow::anyhow!("Unsupported key algorithm")); - } - } - .or_else(|e| Err(anyhow::anyhow!(e.to_string())))?; - - let private_key_openssh = key - .to_openssh(LineEnding::LF) - .or_else(|e| Err(anyhow::anyhow!(e.to_string())))?; - Ok(SshKey { - private_key: private_key_openssh.to_string(), - public_key: key.public_key().to_string(), - key_fingerprint: key.fingerprint(HashAlg::Sha256).to_string(), - }) -} diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs index 8cbcd97d91e..0e98f1cd4c4 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs @@ -10,7 +10,6 @@ use bitwarden_russh::ssh_agent::{self, Key}; #[cfg_attr(target_os = "linux", path = "unix.rs")] mod platform_ssh_agent; -pub mod generator; pub mod importer; #[derive(Clone)] diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index 8e156eb3efa..095e6573cfe 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -344,14 +344,6 @@ pub mod sshagent { .map_err(|e| napi::Error::from_reason(e.to_string()))?; Ok(result.into()) } - - #[napi] - pub async fn generate_keypair(key_algorithm: String) -> napi::Result { - desktop_core::ssh_agent::generator::generate_keypair(key_algorithm) - .await - .map_err(|e| napi::Error::from_reason(e.to_string())) - .map(|k| k.into()) - } } #[napi] diff --git a/apps/desktop/src/platform/main/main-ssh-agent.service.ts b/apps/desktop/src/platform/main/main-ssh-agent.service.ts index 60487aae4da..71e0e27d788 100644 --- a/apps/desktop/src/platform/main/main-ssh-agent.service.ts +++ b/apps/desktop/src/platform/main/main-ssh-agent.service.ts @@ -90,12 +90,6 @@ export class MainSshAgentService { this.requestResponses.push({ requestId, accepted, timestamp: new Date() }); }, ); - ipcMain.handle( - "sshagent.generatekey", - async (event: any, { keyAlgorithm }: { keyAlgorithm: string }): Promise => { - return await sshagent.generateKeypair(keyAlgorithm); - }, - ); ipcMain.handle( "sshagent.importkey", async ( diff --git a/apps/desktop/src/platform/preload.ts b/apps/desktop/src/platform/preload.ts index 171e83bbef0..c82b993c991 100644 --- a/apps/desktop/src/platform/preload.ts +++ b/apps/desktop/src/platform/preload.ts @@ -50,9 +50,6 @@ const sshAgent = { signRequestResponse: async (requestId: number, accepted: boolean) => { await ipcRenderer.invoke("sshagent.signrequestresponse", { requestId, accepted }); }, - generateKey: async (keyAlgorithm: string): Promise => { - return await ipcRenderer.invoke("sshagent.generatekey", { keyAlgorithm }); - }, lock: async () => { return await ipcRenderer.invoke("sshagent.lock"); }, diff --git a/apps/desktop/src/vault/app/vault/add-edit.component.ts b/apps/desktop/src/vault/app/vault/add-edit.component.ts index 6a3ad8d62e1..0be26c978ab 100644 --- a/apps/desktop/src/vault/app/vault/add-edit.component.ts +++ b/apps/desktop/src/vault/app/vault/add-edit.component.ts @@ -24,6 +24,7 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; import { DialogService, ToastService } from "@bitwarden/components"; import { SshKeyPasswordPromptComponent } from "@bitwarden/importer/ui"; +import { generate_ssh_key } from "@bitwarden/sdk-internal"; import { PasswordRepromptService } from "@bitwarden/vault"; const BroadcasterSubscriptionId = "AddEditComponent"; @@ -158,10 +159,10 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On } async generateSshKey(showNotification: boolean = true) { - const sshKey = await ipc.platform.sshAgent.generateKey("ed25519"); - this.cipher.sshKey.privateKey = sshKey.privateKey; - this.cipher.sshKey.publicKey = sshKey.publicKey; - this.cipher.sshKey.keyFingerprint = sshKey.keyFingerprint; + const sshKey = generate_ssh_key("Ed25519"); + this.cipher.sshKey.privateKey = sshKey.private_key; + this.cipher.sshKey.publicKey = sshKey.public_key; + this.cipher.sshKey.keyFingerprint = sshKey.key_fingerprint; if (showNotification) { this.toastService.showToast({ From 7c95f06523bbf84e6c1d5d024cdc87db764bbd4c Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 28 Nov 2024 14:33:23 +0100 Subject: [PATCH 02/18] Add ssh keygen support on web and browser --- .../src/popup/services/services.module.ts | 2 +- .../new-item-dropdown-v2.component.html | 4 ++ .../components/vault/add-edit.component.ts | 4 +- .../src/vault/app/vault/add-edit.component.ts | 37 +------------------ .../emergency-add-edit-cipher.component.ts | 4 +- .../vault-item-dialog.component.ts | 3 ++ .../individual-vault/add-edit.component.html | 1 + .../individual-vault/add-edit.component.ts | 4 +- .../vault-header/vault-header.component.html | 4 ++ .../app/vault/org-vault/add-edit.component.ts | 4 +- .../vault/components/add-edit.component.ts | 36 +++++++++++++++++- .../sshkey-section.component.html | 7 ++++ .../sshkey-section.component.ts | 36 +++++++++++++++--- package.json | 2 +- 14 files changed, 101 insertions(+), 47 deletions(-) diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 18d109776a4..121f46884e7 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -576,7 +576,7 @@ const safeProviders: SafeProvider[] = [ }), safeProvider({ provide: SdkClientFactory, - useFactory: (logService) => + useFactory: (logService: LogService) => flagEnabled("sdk") ? new BrowserSdkClientFactory(logService) : new NoopSdkClientFactory(), deps: [LogService], }), diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html index 78403784f46..cebe9397c30 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.html @@ -19,6 +19,10 @@ {{ "note" | i18n }} + + + {{ "typeSshKey" | i18n }} + +