summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-04-21 16:27:08 +0200
committerJustus Winter <justus@sequoia-pgp.org>2022-04-21 16:27:08 +0200
commit7db41fd8385d0253906f240066f98cdce07c467d (patch)
tree1bda53e8ea3f7e5b83b686281827f0d84054585b /ipc
parent995d782619041c4cd09549c7f5305a53bec0415b (diff)
ipc: Securely erase decrypted session keys from Sexps.
Diffstat (limited to 'ipc')
-rw-r--r--ipc/src/sexp.rs31
1 files changed, 24 insertions, 7 deletions
diff --git a/ipc/src/sexp.rs b/ipc/src/sexp.rs
index 0a88391d..20947563 100644
--- a/ipc/src/sexp.rs
+++ b/ipc/src/sexp.rs
@@ -67,7 +67,7 @@ impl Sexp {
.into_iter().next().ok_or_else(not_a_session_key)?;
match value {
- Sexp::String(ref s) => match recipient.mpis() {
+ Sexp::String(s) => match recipient.mpis() {
PublicKey::RSA { .. } | PublicKey::ElGamal { .. } => if padding
{
// The session key is padded. The format is
@@ -81,7 +81,8 @@ impl Sexp {
// * (mpi_get_buffer already removed the leading zero).
// *
// * RND are non-zero random bytes.
- let mut s = &s[..];
+ let s_ = s.into_protected();
+ let mut s = &s_[..];
// The leading 0 may or may not be swallowed along
// the way due to MPI encoding.
@@ -115,25 +116,26 @@ impl Sexp {
// The session key is not padded. Currently, this
// happens if the session key is decrypted using
// scdaemon.
- Ok(s.to_vec().into())
+ Ok(s.into_protected().into())
},
PublicKey::ECDH { curve, .. } => {
// The shared point has been computed by the
// remote agent. The shared point is not padded.
- let s_: mpi::ProtectedMPI = s.to_vec().into();
+ let s_: mpi::ProtectedMPI = s.into_protected().into();
#[allow(non_snake_case)]
let S: Protected = s_.decode_point(curve)?.0.into();
- // XXX: Erase shared point from s.
// Now finish the decryption.
openpgp::crypto::ecdh::decrypt_unwrap(recipient, &S, ciphertext)
},
- _ =>
+ _ => {
+ let _ = s.into_protected();
Err(Error::InvalidArgument(
format!("Don't know how to handle key {:?}", recipient))
- .into()),
+ .into())
+ },
}
Sexp::List(..) => Err(not_a_session_key()),
}
@@ -390,6 +392,21 @@ impl String_ {
o.write_all(self)?;
Ok(())
}
+
+ /// Creates a Protected memory region from this String.
+ ///
+ /// Securely erases the contents of the original String.
+ pub fn into_protected(mut self) -> Protected {
+ let r = Protected::from(&self.0[..]);
+ unsafe {
+ memsec::memzero(self.0.as_mut_ptr(), self.0.len());
+ if let Some(p) = self.1.as_mut() {
+ memsec::memzero(p.as_mut_ptr(), p.len());
+ }
+ }
+ r
+ }
+
}
impl From<&str> for String_ {