Skip to content

Commit

Permalink
Update rustls (#153)
Browse files Browse the repository at this point in the history
* Update rustls

* Clippy fix
  • Loading branch information
richardpringle authored Feb 15, 2024
1 parent 921b2f1 commit e556514
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 79 deletions.
4 changes: 2 additions & 2 deletions core/cert-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ rand = "0.8.5"
random-manager = "0.0.5" # https://crates.io/crates/random-manager/versions
rcgen = { version = "0.12.1", features = ["pem", "x509-parser"] }
rsa = { version = "0.9.2", features = ["pem"] } # https://crates.io/crates/rsa
rustls = "0.21.8"
rustls-pemfile = "1.0.3"
rustls = "0.22.2"
rustls-pemfile = "2.0.0"
x509-parser = "0.15.1"

[dev-dependencies]
Expand Down
73 changes: 44 additions & 29 deletions core/cert-manager/src/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ use rcgen::{
use rsa::{pkcs1::LineEnding, pkcs8::EncodePrivateKey, RsaPrivateKey};
use rustls_pemfile::{read_one, Item};

type PrivateKeyDer = rustls::pki_types::PrivateKeyDer<'static>;
type CertificateDer = rustls::pki_types::CertificateDer<'static>;

/// Represents a certificate authoriry.
/// CA acts as a trusted third party.
/// ref. <https://en.wikipedia.org/wiki/Certificate_authority>
Expand Down Expand Up @@ -651,7 +654,7 @@ fn test_pem() {
pub fn load_pem_key_cert_to_der(
key_path: &str,
cert_path: &str,
) -> io::Result<(rustls::PrivateKey, rustls::Certificate)> {
) -> io::Result<(PrivateKeyDer, CertificateDer)> {
log::info!("loading PEM from key path '{key_path}' and cert '{cert_path}' (to DER)");
if !Path::new(key_path).exists() {
return Err(Error::new(
Expand Down Expand Up @@ -690,51 +693,57 @@ pub fn load_pem_key_cert_to_der(
log::warn!("key path {} has unexpected certificate", key_path);
None
}
Item::RSAKey(key) => {
log::info!("loaded RSA key");
Some(key)
Item::Crl(_) => {
log::warn!("key path {} has unexpected CRL", key_path);
None
}
Item::Pkcs1Key(key) => {
log::info!("loaded PKCS1 key");
Some(PrivateKeyDer::from(key))
}
Item::PKCS8Key(key) => {
Item::Pkcs8Key(key) => {
log::info!("loaded PKCS8 key");
Some(key)
Some(PrivateKeyDer::from(key))
}
Item::ECKey(key) => {
Item::Sec1Key(key) => {
log::info!("loaded EC key");
Some(key)
Some(PrivateKeyDer::from(key))
}
_ => None,
}
};
if key.is_none() {
let Some(key_der) = key else {
return Err(Error::new(
ErrorKind::NotFound,
format!("key path '{key_path}' found no key"),
));
}
let key_der = key.unwrap();
};

let cert_file = File::open(cert_path)?;
let mut reader = BufReader::new(cert_file);
let pem_read = read_one(&mut reader)?;
let cert = {
match pem_read.unwrap() {
Item::X509Certificate(cert) => Some(cert),
Item::RSAKey(_) | Item::PKCS8Key(_) | Item::ECKey(_) => {
Item::Pkcs1Key(_) | Item::Pkcs8Key(_) | Item::Sec1Key(_) => {
log::warn!("cert path '{cert_path}' has unexpected private key");
None
}
Item::Crl(_) => {
log::warn!("cert path '{cert_path}' has unexpected CRL");
None
}
_ => None,
}
};
if cert.is_none() {
let Some(cert_der) = cert else {
return Err(Error::new(
ErrorKind::NotFound,
format!("cert path '{cert_path}' found no cert"),
));
}
let cert_der = cert.unwrap();
};

Ok((rustls::PrivateKey(key_der), rustls::Certificate(cert_der)))
Ok((key_der, cert_der))
}

/// Loads the serial number from the PEM-encoded certificate.
Expand Down Expand Up @@ -763,7 +772,7 @@ pub fn load_pem_cert_serial(cert_path: &str) -> io::Result<Vec<u8>> {
}

/// Loads the PEM-encoded certificate as DER.
pub fn load_pem_cert_to_der(cert_path: &str) -> io::Result<rustls::Certificate> {
pub fn load_pem_cert_to_der(cert_path: &str) -> io::Result<CertificateDer> {
log::info!("loading PEM cert '{cert_path}' (to DER)");
if !Path::new(cert_path).exists() {
return Err(Error::new(
Expand All @@ -778,29 +787,33 @@ pub fn load_pem_cert_to_der(cert_path: &str) -> io::Result<rustls::Certificate>
let cert = {
match pem_read.unwrap() {
Item::X509Certificate(cert) => Some(cert),
Item::RSAKey(_) | Item::PKCS8Key(_) | Item::ECKey(_) => {
Item::Pkcs1Key(_) | Item::Pkcs8Key(_) | Item::Sec1Key(_) => {
log::warn!("cert path '{cert_path}' has unexpected private key");
None
}
Item::Crl(_) => {
log::warn!("cert path '{cert_path}' has unexpected CRL");
None
}
_ => None,
}
};
if cert.is_none() {

let Some(cert_der) = cert else {
return Err(Error::new(
ErrorKind::NotFound,
format!("cert path '{cert_path}' found no cert"),
));
}
let cert_der = cert.unwrap();
};

Ok(rustls::Certificate(cert_der))
Ok(cert_der)
}

/// Generates a X509 certificate pair and returns them in DER format.
/// ref. <https://pkg.go.dev/github.com/ava-labs/avalanchego/staking#NewCertAndKeyBytes>
pub fn generate_der(
params: Option<CertificateParams>,
) -> io::Result<(rustls::PrivateKey, rustls::Certificate)> {
) -> io::Result<(PrivateKeyDer, CertificateDer)> {
log::info!("generating key and cert (DER format)");

let cert_params = if let Some(p) = params {
Expand All @@ -820,18 +833,20 @@ pub fn generate_der(
// ref. "crypto/tls.parsePrivateKey"
// ref. "crypto/x509.MarshalPKCS8PrivateKey"
let key_der = cert.serialize_private_key_der();
let key_der = rustls::pki_types::PrivatePkcs8KeyDer::from(key_der);
let key_der = key_der.into();
let cert_der = CertificateDer::from(cert_der);

Ok((rustls::PrivateKey(key_der), rustls::Certificate(cert_der)))
Ok((key_der, cert_der))
}

/// Loads the TLS key and certificate from the DER-encoded files.
pub fn load_der_key_cert(
key_path: &str,
cert_path: &str,
) -> io::Result<(rustls::PrivateKey, rustls::Certificate)> {
) -> io::Result<(PrivateKeyDer, CertificateDer)> {
log::info!("loading DER from key path '{key_path}' and cert '{cert_path}'");
let (key, cert) = fs::read(key_path).and_then(|x| Ok((x, fs::read(cert_path)?)))?;
Ok((rustls::PrivateKey(key), rustls::Certificate(cert)))
load_pem_key_cert_to_der(key_path, cert_path)
}

/// RUST_LOG=debug cargo test --all-features --lib -- x509::test_generate_der --exact --show-output
Expand All @@ -843,8 +858,8 @@ fn test_generate_der() {
.try_init();

let (key, cert) = generate_der(None).unwrap();
log::info!("key: {} bytes", key.0.len());
log::info!("cert: {} bytes", cert.0.len());
log::info!("key: {} bytes", key.secret_der().len());
log::info!("cert: {} bytes", cert.len());
}

/// ref. <https://doc.rust-lang.org/std/fs/fn.read.html>
Expand Down
6 changes: 3 additions & 3 deletions core/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ readme = "README.md"
[dependencies]
avalanche-types = { path = "../../crates/avalanche-types", features = ["message"] }
log = "0.4.20"
rustls = { version = "0.21.5", features = ["logging", "dangerous_configuration"]} # https://github.com/rustls/rustls/tags
rustls = { version = "0.22.2", features = ["logging"] }
hyper-rustls = "0.26.0"
rustls-native-certs = "0.7.0"
hyper = { version = "0.14.27", features = ["full"], optional = true }
tokio-rustls = { version = "0.24.1", optional = true }
tokio-rustls = { version = "0.25.0", optional = true }
rand = "0.8.5"
random-manager = "0.0.5" # https://crates.io/crates/random-manager/versions
rcgen = { version = "0.12.1", features = ["pem", "x509-parser"] }
rsa = { version = "0.9.2", features = ["pem"] } # https://crates.io/crates/rsa
rustls-pemfile = "1.0.3"
rustls-pemfile = "2.0.0"
x509-parser = "0.15.1"
# for feature "pem"
pem = { version = "3.0.0", optional = true } # https://github.com/jcreekmore/pem-rs
Expand Down
1 change: 0 additions & 1 deletion core/network/src/peer/inbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ impl Listener {
// ref. https://docs.rs/rustls/latest/rustls/struct.ConfigBuilder.html#method.with_single_cert
// ref. https://github.com/rustls/hyper-rustls/blob/main/examples/server.rs
let server_config = ServerConfig::builder()
.with_safe_defaults()
.with_client_cert_verifier(Arc::new(NoClientAuth))
.with_single_cert(vec![certificate], private_key)
.map_err(|e| {
Expand Down
1 change: 0 additions & 1 deletion core/network/src/peer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ mod test {

let join_handle = tokio::task::spawn(async move {
let server_config = ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(vec![certificate], private_key)
.unwrap();
Expand Down
Loading

0 comments on commit e556514

Please sign in to comment.