Skip to content

Commit cde9ae6

Browse files
committed
ACME: zeroize buffers with private keys after use.
We trust the SSL library to securely clear the EVP_PKEY objects, but all the places where we may store a PEM data should be cleared by us.
1 parent 2a435bb commit cde9ae6

File tree

5 files changed

+29
-3
lines changed

5 files changed

+29
-3
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ openssl-foreign-types = { package = "foreign-types", version = "0.3" }
1717
openssl-sys = { version = "0.9.109", features = ["bindgen"] }
1818
siphasher = { version = "1.0.1", default-features = false }
1919
thiserror = { version = "2.0.12", default-features = false }
20+
zeroize = "1.8.1"
2021

2122
[dependencies.nginx-sys]
2223
git = "https://github.com/nginx/ngx-rust"

src/conf/issuer.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use ngx::ngx_log_debug;
1616
use ngx::sync::RwLock;
1717
use openssl::pkey::{PKey, Private};
1818
use thiserror::Error;
19+
use zeroize::Zeroizing;
1920

2021
use super::ext::NgxConfExt;
2122
use super::order::CertificateOrder;
@@ -256,7 +257,7 @@ impl Issuer {
256257
}
257258
}
258259

259-
if let Ok(buf) = pkey.private_key_to_pem_pkcs8() {
260+
if let Ok(buf) = pkey.private_key_to_pem_pkcs8().map(Zeroizing::new) {
260261
// Ignore write errors.
261262
let _ = state_dir.write(&path, &buf);
262263
}
@@ -349,7 +350,8 @@ impl StateDir {
349350
}
350351

351352
let mut cert = CertificateContextInner::new_in(cf.pool());
352-
cert.set(&chain, &pkey.private_key_to_pem_pkcs8()?, valid)?;
353+
let pkey = Zeroizing::new(pkey.private_key_to_pem_pkcs8()?);
354+
cert.set(&chain, &pkey, valid)?;
353355

354356
Ok(cert)
355357
}

src/conf/ssl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub fn conf_read_private_key(
5959
_cf: &mut ngx_conf_t,
6060
name: &str,
6161
) -> Result<PKey<Private>, CertificateFetchError> {
62-
let Ok(buf) = std::fs::read_to_string(name) else {
62+
let Ok(buf) = std::fs::read_to_string(name).map(zeroize::Zeroizing::new) else {
6363
return Err(CertificateFetchError::Fetch(c"cannot load key"));
6464
};
6565

src/state/certificate.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use ngx::allocator::{AllocError, Allocator, TryCloneIn};
22
use ngx::collections::Vec;
33
use ngx::core::{Pool, SlabPool};
44
use ngx::sync::RwLock;
5+
use zeroize::Zeroize;
56

67
use crate::time::{jitter, Time, TimeRange};
78

@@ -110,6 +111,10 @@ where
110111
.try_reserve_exact(PREFIX.len() + pkey.len())
111112
.map_err(|_| AllocError)?;
112113

114+
// Zeroize is not implemented for allocator-api2 types.
115+
self.chain.as_mut_slice().zeroize();
116+
self.pkey.as_mut_slice().zeroize();
117+
113118
self.chain = new_chain;
114119
self.pkey = new_pkey;
115120
}
@@ -150,3 +155,14 @@ where
150155
None
151156
}
152157
}
158+
159+
impl<A> Drop for CertificateContextInner<A>
160+
where
161+
A: Allocator + Clone,
162+
{
163+
fn drop(&mut self) {
164+
// Zeroize is not implemented for allocator-api2 types.
165+
self.chain.as_mut_slice().zeroize();
166+
self.pkey.as_mut_slice().zeroize();
167+
}
168+
}

0 commit comments

Comments
 (0)