Skip to content

Conversation

OrionCodeDev
Copy link

@OrionCodeDev OrionCodeDev commented Aug 22, 2025

Summary
This change fixes loss of encryption headers when importing SSH private keys by preserving the exact original PEM (including bcrypt/aes header) and introducing a just-in-time decrypt function for SSH agent operations. It also plumbs new metadata through SshKeyView for clients to enable improved UX.

Linked PRs needed to work for this changes:

Linked Issue

Root Cause
Imported SSH keys were always re-encoded into unencrypted OpenSSH format (via to_openssh), stripping encrypted headers. Copying/using the key later did not match the original encrypted PEM.

Approach

  • Lossless storage: Store the original imported PEM verbatim and expose it to clients.
  • Metadata: SshKeyView now carries original_private_key, is_encrypted, and ssh_key_passphrase (optional).
  • Just-in-time decryption: Provide decrypt_openssh_key that returns an unencrypted OpenSSH PEM in memory for agent use only.

Changes

  • crates/bitwarden-ssh/src/import.rs
    • import_key now:
      • Detects PEM label (OpenSSH or PKCS#8; encrypted/unencrypted).
      • Preserves original PEM in SshKeyView.original_private_key.
      • Sets is_encrypted and optionally ssh_key_passphrase in SshKeyView.
    • New decrypt_openssh_key(encoded_key, password): Supports encrypted OpenSSH and PKCS#8 input; returns unencrypted OpenSSH PEM for transient use.
    • Added tests to ensure original OpenSSH PEM is preserved for encrypted/unencrypted keys.
  • crates/bitwarden-ssh/src/lib.rs
    • ssh_private_key_to_view sets defaults for new SshKeyView fields (original_private_key: None, is_encrypted: false, ssh_key_passphrase: None).
  • crates/bitwarden-vault/src/cipher/ssh_key.rs
    • Extend SshKey/SshKeyView with:
      • original_private_key: Option<String/EncString>
      • is_encrypted: bool
      • ssh_key_passphrase: Option<String/EncString>
    • Updated CompositeEncryptable/Decryptable implementations.
  • crates/bitwarden-wasm-internal/src/ssh.rs
    • Export decrypt_ssh_key_for_agent(encrypted_pem, password) for web/TS clients.
  • crates/bitwarden-uniffi/src/tool/ssh.rs
    • Add SshClient.decrypt_ssh_key_for_agent for native clients.

Backwards Compatibility

  • New fields are optional; existing clients continue to function.
  • Unencrypted keys behave as before.
  • The decrypt function is additive and does not change previous interfaces.

Security Considerations

  • OriginalPrivateKey and sshKeyPassphrase are encrypted-at-rest via existing model encryption mechanisms.
  • Decryptions for agent operations occur in memory only; no plaintext persistence.

Testing

  • cargo test -p bitwarden-ssh
  • Added unit tests for preserving original OpenSSH PEM (encrypted/unencrypted).
  • Recommended: add tests for PKCS#8 encrypted behavior.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants