rustls / rcgen

Generate X.509 certificates
Other
324 stars 102 forks source link

CA certificate parsed as NoCa #95

Closed andrenth closed 1 year ago

andrenth commented 1 year ago

Hello

I'm using rcgen to create a CA certificate and then parse its parameters back. The issue is that I create the certificate with params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);, but when parsing it, I get IsCa::NoCa in the is_ca field:

use std::fs;

use rcgen::{
    BasicConstraints, Certificate, CertificateParams, DistinguishedName, DnType,
    ExtendedKeyUsagePurpose, IsCa, KeyPair, KeyUsagePurpose, PKCS_ECDSA_P384_SHA384,
};
use time::{Duration, OffsetDateTime};

fn create_ca_cert() -> Result<(), Box<dyn std::error::Error>> {
    let now = OffsetDateTime::now_utc();
    let mut params = CertificateParams::default();
    let organization = "MyOrg".to_owned();

    params.alg = &PKCS_ECDSA_P384_SHA384;
    params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);

    params.not_before = now;
    params.not_after = now + Duration::days(3650);

    params.key_usages.push(KeyUsagePurpose::KeyCertSign);
    params.key_usages.push(KeyUsagePurpose::DigitalSignature);

    params
        .extended_key_usages
        .push(ExtendedKeyUsagePurpose::ClientAuth);
    params
        .extended_key_usages
        .push(ExtendedKeyUsagePurpose::ServerAuth);

    let mut distinguished_name = DistinguishedName::new();
    distinguished_name.push(DnType::OrganizationName, &organization);
    distinguished_name.push(DnType::OrganizationalUnitName, "MyOrgUnit");
    params.distinguished_name = distinguished_name;

    let certificate = Certificate::from_params(params)?;
    fs::write("ca.pem", certificate.serialize_pem()?)?;
    fs::write("ca.key", certificate.serialize_private_key_pem())?;

    Ok(())
}

fn parse_ca_cert() -> Result<IsCa, Box<dyn std::error::Error>> {
    let crt = fs::read_to_string("ca.pem")?;
    let key = fs::read_to_string("ca.key")?;

    let key_pair = KeyPair::from_pem(&key)?;
    let params = CertificateParams::from_ca_cert_pem(&crt, key_pair)?;
    Ok(params.is_ca)
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    create_ca_cert()?;
    println!("{:?}", parse_ca_cert()?); // prints NoCa
    Ok(())
}

Am I doing something wrong or is this a bug?

Thanks

est31 commented 1 year ago

Yeah not all fields are supported for parsing. PRs welcome to add plumbing for that!

andrenth commented 1 year ago

PR submitted.

est31 commented 1 year ago

https://github.com/est31/rcgen/pull/96 is merged