summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-10-09 12:41:25 +0200
committerJustus Winter <justus@sequoia-pgp.org>2020-10-13 12:08:10 +0200
commit81573890225522e55f8b2983405723f0f16e7f28 (patch)
tree5f910e6a8816fe8cb4329fd1ad27eee015464cb4
parente20ff12313610091de4ac8b054b50412afccd7f5 (diff)
openpgp: Avoid possible reallocations in From::<Vec<u8>>.
-rw-r--r--openpgp/src/crypto/mem.rs22
1 files changed, 17 insertions, 5 deletions
diff --git a/openpgp/src/crypto/mem.rs b/openpgp/src/crypto/mem.rs
index f62244fe..2c9f7fca 100644
--- a/openpgp/src/crypto/mem.rs
+++ b/openpgp/src/crypto/mem.rs
@@ -98,11 +98,23 @@ impl DerefMut for Protected {
}
impl From<Vec<u8>> for Protected {
- fn from(v: Vec<u8>) -> Self {
- // FIXME(xanewok): This can potentially realloc and leave a lingering
- // copy of the secret somewhere. It'd be great to explicitly move the
- // source data by copying it and zeroing it explicitly afterwards.
- Protected(v.into_boxed_slice())
+ fn from(mut v: Vec<u8>) -> Self {
+ // Make a vector with the correct size to avoid potential
+ // reallocations when turning it into a `Protected`.
+ let mut p = Vec::with_capacity(v.len());
+ p.extend_from_slice(&v);
+
+ // Now clear the previous allocation. Just to be safe, we
+ // clear the whole allocation.
+ let capacity = v.capacity();
+ unsafe {
+ // Safety: New size is equal to the capacity, and we
+ // initialize all elements.
+ v.set_len(capacity);
+ memsec::memzero(v.as_mut_ptr(), capacity);
+ }
+
+ p.into_boxed_slice().into()
}
}