1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
use rcgen::{
BasicConstraints, Certificate, CertificateParams, DnType, DnValue::PrintableString,
ExtendedKeyUsagePurpose, IsCa, Issuer, KeyPair, KeyUsagePurpose,
};
use time::{Duration, OffsetDateTime};
/// Example demonstrating signing end-entity certificate with ca
fn main() {
let (ca, issuer) = new_ca();
let end_entity = new_end_entity(&issuer);
let end_entity_pem = end_entity.pem();
println!("directly signed end-entity certificate: {end_entity_pem}");
let ca_cert_pem = ca.pem();
println!("ca certificate: {ca_cert_pem}");
}
fn new_ca() -> (Certificate, Issuer<'static, KeyPair>) {
let mut params =
CertificateParams::new(Vec::default()).expect("empty subject alt name can't produce error");
let (yesterday, tomorrow) = validity_period();
params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
params.distinguished_name.push(
DnType::CountryName,
PrintableString("BR".try_into().unwrap()),
);
params
.distinguished_name
.push(DnType::OrganizationName, "Crab widgits SE");
params.key_usages.push(KeyUsagePurpose::DigitalSignature);
params.key_usages.push(KeyUsagePurpose::KeyCertSign);
params.key_usages.push(KeyUsagePurpose::CrlSign);
params.not_before = yesterday;
params.not_after = tomorrow;
let key_pair = KeyPair::generate().unwrap();
let cert = params.self_signed(&key_pair).unwrap();
(cert, Issuer::new(params, key_pair))
}
fn new_end_entity(issuer: &Issuer<'static, KeyPair>) -> Certificate {
let name = "entity.other.host";
let mut params = CertificateParams::new(vec![name.into()]).expect("we know the name is valid");
let (yesterday, tomorrow) = validity_period();
params.distinguished_name.push(DnType::CommonName, name);
params.use_authority_key_identifier_extension = true;
params.key_usages.push(KeyUsagePurpose::DigitalSignature);
params
.extended_key_usages
.push(ExtendedKeyUsagePurpose::ServerAuth);
params.not_before = yesterday;
params.not_after = tomorrow;
let key_pair = KeyPair::generate().unwrap();
params.signed_by(&key_pair, issuer).unwrap()
}
fn validity_period() -> (OffsetDateTime, OffsetDateTime) {
let day = Duration::new(86400, 0);
let yesterday = OffsetDateTime::now_utc().checked_sub(day).unwrap();
let tomorrow = OffsetDateTime::now_utc().checked_add(day).unwrap();
(yesterday, tomorrow)
}
|