diff --git a/russh-keys/Cargo.toml b/russh-keys/Cargo.toml index 3b245322..293ed9a4 100644 --- a/russh-keys/Cargo.toml +++ b/russh-keys/Cargo.toml @@ -71,6 +71,7 @@ thiserror = "1.0" tokio = { version = "1.17.0", features = ["io-util", "rt-multi-thread", "time", "net"] } tokio-stream = { version = "0.1", features = ["net"] } typenum = "1.17" +zeroize = "1.7" [features] vendored-openssl = ["openssl", "openssl/vendored"] diff --git a/russh-keys/src/key.rs b/russh-keys/src/key.rs index 1bc0373c..eae00283 100644 --- a/russh-keys/src/key.rs +++ b/russh-keys/src/key.rs @@ -462,6 +462,13 @@ pub struct RsaCrtExtra<'a> { pub dq: Cow<'a, [u8]>, } +impl Drop for RsaCrtExtra<'_> { + fn drop(&mut self) { + zeroize_cow(&mut self.dp); + zeroize_cow(&mut self.dq); + } +} + fn ec_signature(key: &ec::PrivateKey, b: &[u8]) -> Result, Error> { let (r, s) = key.try_sign(b)?; let mut buf = Vec::new(); @@ -513,3 +520,16 @@ pub fn parse_public_key(p: &[u8], prefer_hash: Option) -> Result< pub fn safe_rng() -> impl rand::CryptoRng + rand::RngCore { rand::thread_rng() } + +/// Zeroize `Cow` if value is owned. +pub(crate) fn zeroize_cow(v: &mut Cow) +where + T: ToOwned + ?Sized, + ::Owned: zeroize::Zeroize, +{ + use zeroize::Zeroize; + match v { + Cow::Owned(v) => v.zeroize(), + Cow::Borrowed(_) => (), + } +} diff --git a/russh-keys/src/protocol.rs b/russh-keys/src/protocol.rs index 52ea5275..ff9a2933 100644 --- a/russh-keys/src/protocol.rs +++ b/russh-keys/src/protocol.rs @@ -1,6 +1,8 @@ -use crate::encoding::{Encoding, Position, SshRead, SshWrite}; use std::borrow::Cow; +use crate::encoding::{Encoding, Position, SshRead, SshWrite}; +use crate::key::zeroize_cow; + type Result = std::result::Result; /// SSH RSA public key. @@ -72,3 +74,14 @@ impl SshWrite for RsaPrivateKey<'_> { encoder.extend_ssh_string(&self.comment); } } + +impl Drop for RsaPrivateKey<'_> { + fn drop(&mut self) { + // Private parts only. + zeroize_cow(&mut self.private_exponent); + zeroize_cow(&mut self.coefficient); + zeroize_cow(&mut self.prime1); + zeroize_cow(&mut self.prime2); + zeroize_cow(&mut self.comment); + } +}