Skip to content

Commit

Permalink
update rcgen
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianUekermann committed May 16, 2024
1 parent a586195 commit dfaf4de
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 41 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustls-acme"
version = "0.10.0"
version = "0.10.1"
authors = ["Florian Uekermann <florian@uekermann.me>"]
edition = "2018"
description = "TLS certificate management and serving using rustls"
Expand All @@ -13,7 +13,7 @@ categories = ["asynchronous", "cryptography", "network-programming"]
[dependencies]
futures-rustls = { version = "0.26", default-features = false }
futures = "0.3.21"
rcgen = { version = "0.12", default-features = false, features = ["pem"] }
rcgen = { version = "0.13", default-features = false, features = ["pem"] }
serde_json = "1.0.81"
serde = { version = "1.0.137", features=["derive"] }
ring = { version = "0.17.7", features = ["std"], optional = true }
Expand Down
17 changes: 9 additions & 8 deletions src/acme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use crate::crypto::signature::{EcdsaKeyPair, EcdsaSigningAlgorithm, ECDSA_P256_S
use crate::https_helper::{https, HttpsRequestError};
use crate::jose::{key_authorization_sha256, sign, JoseError};
use base64::prelude::*;
use futures_rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use futures_rustls::pki_types::{PrivateKeyDer, PrivatePkcs8KeyDer};
use futures_rustls::rustls::{sign::CertifiedKey, ClientConfig};
use http::header::ToStrError;
use http::{Method, Response};
use rcgen::{Certificate, CustomExtension, PKCS_ECDSA_P256_SHA256};
use rcgen::{CustomExtension, KeyPair, PKCS_ECDSA_P256_SHA256};
use serde::{Deserialize, Serialize};
use serde_json::json;
use thiserror::Error;
Expand Down Expand Up @@ -106,7 +106,7 @@ impl Account {
let response = self.request(client_config, &url, "").await?;
Ok(serde_json::from_str(&response.1)?)
}
pub async fn finalize(&self, client_config: &Arc<ClientConfig>, url: impl AsRef<str>, csr: Vec<u8>) -> Result<Order, AcmeError> {
pub async fn finalize(&self, client_config: &Arc<ClientConfig>, url: impl AsRef<str>, csr: &[u8]) -> Result<Order, AcmeError> {
let payload = format!("{{\"csr\":\"{}\"}}", BASE64_URL_SAFE_NO_PAD.encode(csr));
let response = self.request(client_config, &url, &payload).await?;
Ok(serde_json::from_str(&response.1)?)
Expand All @@ -120,13 +120,14 @@ impl Account {
Some(challenge) => challenge,
None => return Err(AcmeError::NoTlsAlpn01Challenge),
};
let mut params = rcgen::CertificateParams::new(vec![domain]);
let mut params = rcgen::CertificateParams::new(vec![domain])?;
let key_auth = key_authorization_sha256(&self.key_pair, &*challenge.token)?;
params.alg = &PKCS_ECDSA_P256_SHA256;
params.custom_extensions = vec![CustomExtension::new_acme_identifier(key_auth.as_ref())];
let cert = Certificate::from_params(params)?;
let pk = any_ecdsa_type(&PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(cert.serialize_private_key_der()))).unwrap();
let certified_key = CertifiedKey::new(vec![CertificateDer::from(cert.serialize_der()?)], pk);
let key_pair = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?;
let cert = params.self_signed(&key_pair)?;

let sk = any_ecdsa_type(&PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(key_pair.serialize_der()))).unwrap();
let certified_key = CertifiedKey::new(vec![cert.der().clone()], sk);
Ok((challenge, certified_key))
}
}
Expand Down
36 changes: 12 additions & 24 deletions src/caches/test.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{AccountCache, CertCache};
use async_trait::async_trait;
use rcgen::{date_time_ymd, BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyUsagePurpose, PKCS_ECDSA_P256_SHA256};
use rcgen::{date_time_ymd, BasicConstraints, CertificateParams, DistinguishedName, DnType, IsCa, KeyPair, KeyUsagePurpose, PKCS_ECDSA_P256_SHA256};
use std::fmt::Debug;
use std::marker::PhantomData;
use std::sync::atomic::AtomicPtr;
Expand All @@ -19,6 +19,7 @@ use std::sync::Arc;
/// ```
#[derive(Clone)]
pub struct TestCache<EC: Debug = std::io::Error, EA: Debug = std::io::Error> {
ca_key: Arc<KeyPair>,
ca_cert: Arc<rcgen::Certificate>,
ca_pem: Arc<String>,
_cert_error: PhantomData<AtomicPtr<Box<EC>>>,
Expand All @@ -33,15 +34,15 @@ impl<EC: Debug, EA: Debug> TestCache<EC, EA> {
distinguished_name.push(DnType::OrganizationName, "Test CA");
distinguished_name.push(DnType::CommonName, "Test CA");
params.distinguished_name = distinguished_name;
params.alg = &PKCS_ECDSA_P256_SHA256;
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
params.key_usages = vec![KeyUsagePurpose::KeyCertSign, KeyUsagePurpose::CrlSign];
params.not_before = date_time_ymd(2000, 1, 1);
params.not_after = date_time_ymd(3000, 1, 1);

let ca_cert = rcgen::Certificate::from_params(params).unwrap();
let ca_pem = ca_cert.serialize_pem().unwrap();
let key_pair = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256).unwrap();
let ca_cert = params.self_signed(&key_pair).unwrap();
let ca_pem = ca_cert.pem();
Self {
ca_key: key_pair.into(),
ca_cert: ca_cert.into(),
ca_pem: ca_pem.into(),
_cert_error: Default::default(),
Expand All @@ -57,30 +58,17 @@ impl<EC: Debug, EA: Debug> TestCache<EC, EA> {
impl<EC: Debug, EA: Debug> CertCache for TestCache<EC, EA> {
type EC = EC;
async fn load_cert(&self, domains: &[String], _directory_url: &str) -> Result<Option<Vec<u8>>, Self::EC> {
let mut params = CertificateParams::new(domains);
let mut params = CertificateParams::new(domains).unwrap();
let mut distinguished_name = DistinguishedName::new();
distinguished_name.push(DnType::CommonName, "Test Cert");
params.distinguished_name = distinguished_name;
params.alg = &PKCS_ECDSA_P256_SHA256;
params.not_before = date_time_ymd(2000, 1, 1);
params.not_after = date_time_ymd(3000, 1, 1);
let cert = match rcgen::Certificate::from_params(params) {
Ok(cert) => cert,
Err(err) => {
log::error!("test cache: generation error: {:?}", err);
return Ok(None);
}
};
let cert_pem = match cert.serialize_pem_with_signer(&self.ca_cert) {
Ok(pem) => pem,
Err(err) => {
log::error!("test cache: signing error: {:?}", err);
return Ok(None);
}
};

let pem = [&cert.serialize_private_key_pem(), "\n", &cert_pem, "\n", &self.ca_pem].concat();
Ok(Some(pem.into_bytes()))
let key_pair = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256).unwrap();
let cert = params.signed_by(&key_pair, &self.ca_cert, &self.ca_key).unwrap();
let private_key_pem = key_pair.serialize_pem();
let signed_cert_pem = cert.pem();
Ok(Some([&private_key_pem, "\n", &signed_cert_pem, "\n", &self.ca_pem].concat().into_bytes()))
}
async fn store_cert(&self, _domains: &[String], _directory_url: &str, _cert: &[u8]) -> Result<(), Self::EC> {
log::info!("test cache configured, could not store certificate");
Expand Down
13 changes: 6 additions & 7 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use futures_rustls::pki_types::{CertificateDer as RustlsCertificate, PrivateKeyD
use futures_rustls::rustls::crypto::CryptoProvider;
use futures_rustls::rustls::sign::CertifiedKey;
use futures_rustls::rustls::ServerConfig;
use rcgen::{CertificateParams, DistinguishedName, PKCS_ECDSA_P256_SHA256};
use rcgen::{CertificateParams, DistinguishedName, KeyPair, PKCS_ECDSA_P256_SHA256};
use std::convert::Infallible;
use std::fmt::Debug;
use std::future::Future;
Expand Down Expand Up @@ -242,10 +242,10 @@ impl<EC: 'static + Debug, EA: 'static + Debug> AcmeState<EC, EA> {
let directory = Directory::discover(&config.client_config, &config.directory_url).await?;
let account = Account::create_with_keypair(&config.client_config, directory, &config.contact, &key_pair).await?;

let mut params = CertificateParams::new(config.domains.clone());
let mut params = CertificateParams::new(config.domains.clone())?;
params.distinguished_name = DistinguishedName::new();
params.alg = &PKCS_ECDSA_P256_SHA256;
let cert = rcgen::Certificate::from_params(params)?;
let key_pair = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256)?;
let csr = params.serialize_request(&key_pair)?;

let (order_url, mut order) = account.new_order(&config.client_config, config.domains.clone()).await?;
loop {
Expand All @@ -271,13 +271,12 @@ impl<EC: 'static + Debug, EA: 'static + Debug> AcmeState<EC, EA> {
}
OrderStatus::Ready => {
log::info!("sending csr");
let csr = cert.serialize_request_der()?;
order = account.finalize(&config.client_config, order.finalize, csr).await?
order = account.finalize(&config.client_config, order.finalize, csr.der()).await?
}
OrderStatus::Valid { certificate } => {
log::info!("download certificate");
let pem = [
&cert.serialize_private_key_pem(),
&key_pair.serialize_pem(),
"\n",
&account.certificate(&config.client_config, certificate).await?,
]
Expand Down

0 comments on commit dfaf4de

Please sign in to comment.