Skip to content

Commit

Permalink
Merge pull request #109 from omjadas/dependabot/cargo/rcgen-0.13.0
Browse files Browse the repository at this point in the history
chore(deps): update rcgen requirement from 0.12.0 to 0.13.0
  • Loading branch information
omjadas committed Mar 29, 2024
2 parents 4203d5f + 08b36e6 commit 800a2fe
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 214 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ hyper-util = { version="0.1.3", features = ["client-legacy", "server", "http1"]
moka = { version = "0.12.0", features = ["future"], optional = true }
openssl = { version = "0.10.46", optional = true }
rand = { version = "0.8.0", optional = true }
rcgen = { version = "0.12.0", features = ["x509-parser"], optional = true }
rcgen = { version = "0.13.0", features = ["x509-parser"], optional = true }
thiserror = "1.0.30"
time = { version = "0.3.20", optional = true }
tokio = { version = "1.24.2", features = ["macros", "rt"] }
Expand Down
30 changes: 13 additions & 17 deletions benches/certificate_authorities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use http::uri::Authority;
use hudsucker::{
certificate_authority::{CertificateAuthority, OpensslAuthority, RcgenAuthority},
openssl::{hash::MessageDigest, pkey::PKey, x509::X509},
rcgen::{CertificateParams, KeyPair},
};
use rustls_pemfile as pemfile;

fn runtime() -> tokio::runtime::Runtime {
tokio::runtime::Builder::new_current_thread()
Expand All @@ -13,26 +13,22 @@ fn runtime() -> tokio::runtime::Runtime {
}

fn build_rcgen_ca(cache_size: u64) -> RcgenAuthority {
let mut private_key_bytes: &[u8] = include_bytes!("../examples/ca/hudsucker.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("../examples/ca/hudsucker.cer");
let private_key = pemfile::private_key(&mut private_key_bytes)
.unwrap()
.expect("Failed to parse private key");
let ca_cert = pemfile::certs(&mut ca_cert_bytes)
.next()
.unwrap()
.expect("Failed to parse CA certificate");
let key_pair = include_str!("../examples/ca/hudsucker.key");
let ca_cert = include_str!("../examples/ca/hudsucker.cer");
let key_pair = KeyPair::from_pem(key_pair).expect("Failed to parse private key");
let ca_cert = CertificateParams::from_ca_cert_pem(ca_cert)
.expect("Failed to parse CA certificate")
.self_signed(&key_pair)
.expect("Failed to sign CA certificate");

RcgenAuthority::new(private_key, ca_cert, cache_size)
.expect("Failed to create Certificate Authority")
RcgenAuthority::new(key_pair, ca_cert, cache_size)
}

fn build_openssl_ca(cache_size: u64) -> OpensslAuthority {
let private_key_bytes: &[u8] = include_bytes!("../examples/ca/hudsucker.key");
let ca_cert_bytes: &[u8] = include_bytes!("../examples/ca/hudsucker.cer");
let private_key =
PKey::private_key_from_pem(private_key_bytes).expect("Failed to parse private key");
let ca_cert = X509::from_pem(ca_cert_bytes).expect("Failed to parse CA certificate");
let private_key: &[u8] = include_bytes!("../examples/ca/hudsucker.key");
let ca_cert: &[u8] = include_bytes!("../examples/ca/hudsucker.cer");
let private_key = PKey::private_key_from_pem(private_key).expect("Failed to parse private key");
let ca_cert = X509::from_pem(ca_cert).expect("Failed to parse CA certificate");

OpensslAuthority::new(private_key, ca_cert, MessageDigest::sha256(), cache_size)
}
Expand Down
23 changes: 10 additions & 13 deletions benches/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use hudsucker::{
rt::{TokioExecutor, TokioIo},
server::conn::auto,
},
rcgen::{CertificateParams, KeyPair},
Body, Proxy,
};
use reqwest::Certificate;
use rustls_pemfile as pemfile;
use std::{convert::Infallible, net::SocketAddr};
use tokio::{net::TcpListener, sync::oneshot::Sender};
use tokio_graceful::Shutdown;
Expand All @@ -26,18 +26,15 @@ fn runtime() -> tokio::runtime::Runtime {
}

fn build_ca() -> RcgenAuthority {
let mut private_key_bytes: &[u8] = include_bytes!("../examples/ca/hudsucker.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("../examples/ca/hudsucker.cer");
let private_key = pemfile::private_key(&mut private_key_bytes)
.unwrap()
.expect("Failed to parse private key");
let ca_cert = pemfile::certs(&mut ca_cert_bytes)
.next()
.unwrap()
.expect("Failed to parse CA certificate");

RcgenAuthority::new(private_key, ca_cert, 1_000)
.expect("Failed to create Certificate Authority")
let key_pair = include_str!("../examples/ca/hudsucker.key");
let ca_cert = include_str!("../examples/ca/hudsucker.cer");
let key_pair = KeyPair::from_pem(key_pair).expect("Failed to parse private key");
let ca_cert = CertificateParams::from_ca_cert_pem(ca_cert)
.expect("Failed to parse CA certificate")
.self_signed(&key_pair)
.expect("Failed to sign CA certificate");

RcgenAuthority::new(key_pair, ca_cert, 1000)
}

async fn test_server(req: Request<Incoming>) -> Result<Response<Body>, Infallible> {
Expand Down
21 changes: 9 additions & 12 deletions examples/log.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use hudsucker::{
certificate_authority::RcgenAuthority,
hyper::{Request, Response},
rcgen::{CertificateParams, KeyPair},
tokio_tungstenite::tungstenite::Message,
*,
};
use rustls_pemfile as pemfile;
use std::net::SocketAddr;
use tracing::*;

Expand Down Expand Up @@ -44,18 +44,15 @@ impl WebSocketHandler for LogHandler {
async fn main() {
tracing_subscriber::fmt::init();

let mut private_key_bytes: &[u8] = include_bytes!("ca/hudsucker.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("ca/hudsucker.cer");
let private_key = pemfile::private_key(&mut private_key_bytes)
.unwrap()
.expect("Failed to parse private key");
let ca_cert = pemfile::certs(&mut ca_cert_bytes)
.next()
.unwrap()
.expect("Failed to parse CA certificate");
let key_pair = include_str!("ca/hudsucker.key");
let ca_cert = include_str!("ca/hudsucker.cer");
let key_pair = KeyPair::from_pem(key_pair).expect("Failed to parse private key");
let ca_cert = CertificateParams::from_ca_cert_pem(ca_cert)
.expect("Failed to parse CA certificate")
.self_signed(&key_pair)
.expect("Failed to sign CA certificate");

let ca = RcgenAuthority::new(private_key, ca_cert, 1_000)
.expect("Failed to create Certificate Authority");
let ca = RcgenAuthority::new(key_pair, ca_cert, 1_000);

let proxy = Proxy::builder()
.with_addr(SocketAddr::from(([127, 0, 0, 1], 3000)))
Expand Down
26 changes: 13 additions & 13 deletions examples/noop.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use hudsucker::{certificate_authority::RcgenAuthority, *};
use rustls_pemfile as pemfile;
use hudsucker::{
certificate_authority::RcgenAuthority,
rcgen::{CertificateParams, KeyPair},
*,
};
use std::net::SocketAddr;
use tracing::*;

Expand All @@ -13,18 +16,15 @@ async fn shutdown_signal() {
async fn main() {
tracing_subscriber::fmt::init();

let mut private_key_bytes: &[u8] = include_bytes!("ca/hudsucker.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("ca/hudsucker.cer");
let private_key = pemfile::private_key(&mut private_key_bytes)
.unwrap()
.expect("Failed to parse private key");
let ca_cert = pemfile::certs(&mut ca_cert_bytes)
.next()
.unwrap()
.expect("Failed to parse CA certificate");
let key_pair = include_str!("ca/hudsucker.key");
let ca_cert = include_str!("ca/hudsucker.cer");
let key_pair = KeyPair::from_pem(key_pair).expect("Failed to parse private key");
let ca_cert = CertificateParams::from_ca_cert_pem(ca_cert)
.expect("Failed to parse CA certificate")
.self_signed(&key_pair)
.expect("Failed to sign CA certificate");

let ca = RcgenAuthority::new(private_key, ca_cert, 1_000)
.expect("Failed to create Certificate Authority");
let ca = RcgenAuthority::new(key_pair, ca_cert, 1_000);

let proxy = Proxy::builder()
.with_addr(SocketAddr::from(([127, 0, 0, 1], 3000)))
Expand Down
4 changes: 2 additions & 2 deletions src/certificate_authority/openssl_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl CertificateAuthority for OpensslAuthority {
mod tests {
use super::*;

fn init_ca(cache_size: u64) -> OpensslAuthority {
fn build_ca(cache_size: u64) -> OpensslAuthority {
let private_key_bytes: &[u8] = include_bytes!("../../examples/ca/hudsucker.key");
let ca_cert_bytes: &[u8] = include_bytes!("../../examples/ca/hudsucker.cer");
let private_key =
Expand All @@ -157,7 +157,7 @@ mod tests {

#[test]
fn unique_serial_numbers() {
let ca = init_ca(0);
let ca = build_ca(0);

let authority1 = Authority::from_static("example.com");
let authority2 = Authority::from_static("example2.com");
Expand Down
141 changes: 42 additions & 99 deletions src/certificate_authority/rcgen_authority.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use crate::{
certificate_authority::{CertificateAuthority, CACHE_TTL, NOT_BEFORE_OFFSET, TTL_SECS},
Error,
};
use crate::certificate_authority::{CertificateAuthority, CACHE_TTL, NOT_BEFORE_OFFSET, TTL_SECS};
use http::uri::Authority;
use moka::future::Cache;
use rand::{thread_rng, Rng};
use rcgen::{DistinguishedName, DnType, KeyPair, SanType};
use rcgen::{
Certificate, CertificateParams, DistinguishedName, DnType, Ia5String, KeyPair, SanType,
};
use std::sync::Arc;
use time::{Duration, OffsetDateTime};
use tokio_rustls::rustls::{
pki_types::{CertificateDer, PrivateKeyDer},
pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer},
ServerConfig,
};
use tracing::debug;
Expand All @@ -24,54 +23,44 @@ use tracing::debug;
///
/// ```rust
/// use hudsucker::{certificate_authority::RcgenAuthority, rustls};
/// use rustls_pemfile as pemfile;
/// use rcgen::{CertificateParams, KeyPair};
///
/// let mut private_key_bytes: &[u8] = include_bytes!("../../examples/ca/hudsucker.key");
/// let mut ca_cert_bytes: &[u8] = include_bytes!("../../examples/ca/hudsucker.cer");
/// let private_key = pemfile::private_key(&mut private_key_bytes)
/// .unwrap()
/// .expect("Failed to parse private key");
/// let ca_cert = pemfile::certs(&mut ca_cert_bytes)
/// .next()
/// .unwrap()
/// .expect("Failed to parse CA certificate");
/// let key_pair = include_str!("../../examples/ca/hudsucker.key");
/// let ca_cert = include_str!("../../examples/ca/hudsucker.cer");
/// let key_pair = KeyPair::from_pem(key_pair).expect("Failed to parse private key");
/// let ca_cert = CertificateParams::from_ca_cert_pem(ca_cert)
/// .expect("Failed to parse CA certificate")
/// .self_signed(&key_pair)
/// .expect("Failed to sign CA certificate");
///
/// let ca = RcgenAuthority::new(private_key, ca_cert, 1_000).unwrap();
/// let ca = RcgenAuthority::new(key_pair, ca_cert, 1_000);
/// ```
#[cfg_attr(docsrs, doc(cfg(feature = "rcgen-ca")))]
pub struct RcgenAuthority {
key_pair: KeyPair,
ca_cert: Certificate,
private_key: PrivateKeyDer<'static>,
ca_cert: CertificateDer<'static>,
cache: Cache<Authority, Arc<ServerConfig>>,
}

impl RcgenAuthority {
/// Attempts to create a new rcgen authority.
///
/// # Errors
///
/// This will return an error if the provided key or certificate is invalid, or if the key does
/// not match the certificate.
pub fn new(
private_key: PrivateKeyDer<'static>,
ca_cert: CertificateDer<'static>,
cache_size: u64,
) -> Result<RcgenAuthority, Error> {
let ca = Self {
private_key,
/// Creates a new rcgen authority.
pub fn new(key_pair: KeyPair, ca_cert: Certificate, cache_size: u64) -> RcgenAuthority {
let private_key = PrivateKeyDer::from(PrivatePkcs8KeyDer::from(key_pair.serialize_der()));

Self {
key_pair,
ca_cert,
private_key,
cache: Cache::builder()
.max_capacity(cache_size)
.time_to_live(std::time::Duration::from_secs(CACHE_TTL))
.build(),
};

ca.validate()?;
Ok(ca)
}
}

fn gen_cert(&self, authority: &Authority) -> CertificateDer<'static> {
let mut params = rcgen::CertificateParams::default();
let mut params = CertificateParams::default();
params.serial_number = Some(thread_rng().gen::<u64>().into());

let not_before = OffsetDateTime::now_utc() - Duration::seconds(NOT_BEFORE_OFFSET);
Expand All @@ -82,37 +71,14 @@ impl RcgenAuthority {
distinguished_name.push(DnType::CommonName, authority.host());
params.distinguished_name = distinguished_name;

params
.subject_alt_names
.push(SanType::DnsName(authority.host().to_owned()));

let key_pair =
KeyPair::from_der(self.private_key.secret_der()).expect("Failed to parse private key");
params.alg = key_pair
.compatible_algs()
.next()
.expect("Failed to find compatible algorithm");
params.key_pair = Some(key_pair);

let key_pair =
KeyPair::from_der(self.private_key.secret_der()).expect("Failed to parse private key");

let ca_cert_params = rcgen::CertificateParams::from_ca_cert_der(&self.ca_cert, key_pair)
.expect("Failed to parse CA certificate");
let ca_cert = rcgen::Certificate::from_params(ca_cert_params)
.expect("Failed to generate CA certificate");

let cert = rcgen::Certificate::from_params(params).expect("Failed to generate certificate");
CertificateDer::from(
cert.serialize_der_with_signer(&ca_cert)
.expect("Failed to serialize certificate"),
)
}
params.subject_alt_names.push(SanType::DnsName(
Ia5String::try_from(authority.host()).expect("Failed to create Ia5String"),
));

fn validate(&self) -> Result<(), rcgen::Error> {
let key_pair = rcgen::KeyPair::from_der(self.private_key.secret_der())?;
rcgen::CertificateParams::from_ca_cert_der(&self.ca_cert, key_pair)?;
Ok(())
params
.signed_by(&self.key_pair, &self.ca_cert, &self.key_pair)
.expect("Failed to sign certificate")
.into()
}
}

Expand Down Expand Up @@ -150,45 +116,22 @@ impl CertificateAuthority for RcgenAuthority {
#[cfg(test)]
mod tests {
use super::*;
use rustls_pemfile as pemfile;
use tokio_rustls::rustls::pki_types::PrivatePkcs1KeyDer;

fn init_ca(cache_size: u64) -> RcgenAuthority {
let mut private_key_bytes: &[u8] = include_bytes!("../../examples/ca/hudsucker.key");
let mut ca_cert_bytes: &[u8] = include_bytes!("../../examples/ca/hudsucker.cer");
let private_key = pemfile::private_key(&mut private_key_bytes)
.unwrap()
.expect("Failed to parse private key");
let ca_cert = pemfile::certs(&mut ca_cert_bytes)
.next()
.unwrap()
.expect("Failed to parse CA certificate");

RcgenAuthority::new(private_key, ca_cert, cache_size).unwrap()
}

#[test]
fn error_for_invalid_key() {
let ca = init_ca(0);
let private_key =
PrivateKeyDer::from(PrivatePkcs1KeyDer::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));

let result = RcgenAuthority::new(private_key, ca.ca_cert, 0);
assert!(result.is_err());
}

#[test]
fn error_for_invalid_ca_cert() {
let ca = init_ca(0);
let ca_cert = CertificateDer::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
fn build_ca(cache_size: u64) -> RcgenAuthority {
let key_pair = include_str!("../../examples/ca/hudsucker.key");
let ca_cert = include_str!("../../examples/ca/hudsucker.cer");
let key_pair = KeyPair::from_pem(key_pair).expect("Failed to parse private key");
let ca_cert = CertificateParams::from_ca_cert_pem(ca_cert)
.expect("Failed to parse CA certificate")
.self_signed(&key_pair)
.expect("Failed to sign CA certificate");

let result = RcgenAuthority::new(ca.private_key, ca_cert, 0);
assert!(result.is_err());
RcgenAuthority::new(key_pair, ca_cert, cache_size)
}

#[test]
fn unique_serial_numbers() {
let ca = init_ca(0);
let ca = build_ca(0);

let authority1 = Authority::from_static("example.com");
let authority2 = Authority::from_static("example2.com");
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub use hyper;
pub use hyper_util;
#[cfg(feature = "openssl-ca")]
pub use openssl;
#[cfg(feature = "rcgen-ca")]
pub use rcgen;
pub use tokio_rustls::rustls;
pub use tokio_tungstenite;

Expand Down

0 comments on commit 800a2fe

Please sign in to comment.