Skip to content

fix: wipe private key bytes and passphrases when they're freed - #542

Draft
irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit into
ffi/dotnet-restore-disposablefrom
ffi/zeroize-secrets
Draft

irvingouj@Devolutions (irvingoujAtDevolution) wants to merge 1 commit into
ffi/dotnet-restore-disposablefrom
ffi/zeroize-secrets

Conversation

@irvingoujAtDevolution

@irvingoujAtDevolution irvingouj@Devolutions (irvingoujAtDevolution) commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

On top of #541. Disposing a key from .NET now zeroes what it held instead of just freeing it.

  • Pem: the decoded bytes, since a PEM can carry a private key
  • SshPrivateKey: the passphrase. picky already wipes the key itself
  • SshPrivateKey.ToRepr / PuttyPpk.ToRepr: the temporary string holding the encoded key
  • Ppk (picky core): the private key buffer is Zeroizing now, so the copies made while encrypting, decrypting and converting get wiped too. make_padding allocates its final size up front so a resize can't leave a plaintext copy behind. Field is private, no API change

What this doesn't cover (it's all outside picky):

  • the Diplomat write buffer behind every ToRepr string, and the byte[] C# builds for a string argument (Diplomat.Utf8.Clone). That's the generator, so it's a follow-up in Devolutions/diplomat
  • the .NET string you get back from ToRepr or pass in as a passphrase. It's immutable, nothing to wipe

New tests: passphrase-protected SSH key and encrypted PPK round trips. Neither had .NET coverage before.

Tested: 34/34 on net6 and 17/17 on net48, debug and release native. picky putty/ssh/pem 95/95.

Disposing a key object from .NET now zeroes what it held instead of just freeing it.

- Pem: the decoded bytes, since a PEM can carry a private key
- SshPrivateKey: the passphrase (picky already wipes the key itself)
- SshPrivateKey/PuttyPpk ToRepr: the temporary string holding the encoded key
- Ppk: the private key buffer and the copies made while encrypting, decrypting and
  converting. make_padding now allocates its final size up front so a resize can't
  leave a plaintext copy behind.

Adds .NET round-trip tests for passphrase-protected SSH keys and encrypted PPKs,
which had no coverage before.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant