Here's a simple program that generates a CA certificate with a directoryName constraint:
use std::fs;
use rcgen::{
date_time_ymd, BasicConstraints, CertificateParams, DistinguishedName, DnType, GeneralSubtree,
IsCa, KeyPair, NameConstraints,
};
fn main() {
let ca_key = KeyPair::generate().unwrap();
let mut ca_params = CertificateParams::new(Vec::<String>::new()).unwrap();
ca_params
.distinguished_name
.push(DnType::CommonName, "Test Root CA");
ca_params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained);
ca_params.not_before = date_time_ymd(2024, 1, 1);
ca_params.not_after = date_time_ymd(2050, 1, 1);
let mut permitted = DistinguishedName::new();
permitted.push(DnType::CommonName, "leaf.example.com");
ca_params.name_constraints = Some(NameConstraints {
permitted_subtrees: vec![GeneralSubtree::DirectoryName(permitted)],
excluded_subtrees: vec![],
});
let ca_cert = ca_params.self_signed(&ca_key).unwrap();
fs::write("ca.pem", ca_cert.pem()).unwrap();
}
OpenSSL is unable to parse the constraint:
$ openssl x509 -text -in ca.pem
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
3b:4a:80:3f:dd:07:4b:96:de:c9:1d:ad:49:47:de:ff:ef:ca:7c:9d
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN=Test Root CA
Validity
Not Before: Jan 1 00:00:00 2024 GMT
Not After : Jan 1 00:00:00 2050 GMT
Subject: CN=Test Root CA
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:10:df:f4:bf:ea:83:90:22:c5:b4:45:20:83:25:
57:a5:f0:04:da:ca:ee:c4:55:7d:b9:52:ca:33:12:
f1:aa:76:6d:d5:21:69:40:85:18:08:bc:69:8e:48:
a6:8b:2d:42:f3:8f:b0:11:42:9b:e3:48:f4:bd:46:
1c:f3:a8:ab:48
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Name Constraints: critical
0!..0...1.0...U....leaf.example.com
X509v3 Subject Key Identifier:
B3:45:BD:60:C1:FB:A7:BE:73:D9:23:6C:EB:31:43:6C:EF:E4:3C:4A
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:44:02:20:24:43:f9:bd:35:b9:66:93:1a:b2:40:95:7a:22:
93:59:d4:78:8e:09:dd:4f:3c:af:17:84:79:7d:b3:a4:45:5b:
02:20:58:83:13:b7:5a:a2:96:ce:60:59:9b:5c:db:a0:a0:5c:
b9:bc:08:2f:71:b8:d5:27:3e:bd:1f:3c:0a:69:5f:7a
-----BEGIN CERTIFICATE-----
MIIBkjCCATmgAwIBAgIUO0qAP90HS5beyR2tSUfe/+/KfJ0wCgYIKoZIzj0EAwIw
FzEVMBMGA1UEAwwMVGVzdCBSb290IENBMCAXDTI0MDEwMTAwMDAwMFoYDzIwNTAw
MTAxMDAwMDAwWjAXMRUwEwYDVQQDDAxUZXN0IFJvb3QgQ0EwWTATBgcqhkjOPQIB
BggqhkjOPQMBBwNCAAQQ3/S/6oOQIsW0RSCDJVel8ATayu7EVX25UsozEvGqdm3V
IWlAhRgIvGmOSKaLLULzj7ARQpvjSPS9RhzzqKtIo2EwXzAtBgNVHR4BAf8EIzAh
oB8wHaQbMRkwFwYDVQQDDBBsZWFmLmV4YW1wbGUuY29tMB0GA1UdDgQWBBSzRb1g
wfunvnPZI2zrMUNs7+Q8SjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0cA
MEQCICRD+b01uWaTGrJAlXoik1nUeI4J3U88rxeEeX2zpEVbAiBYgxO3WqKWzmBZ
m1zboKBcubwIL3G41Sc+vR88Cmlfeg==
-----END CERTIFICATE-----
(notably)
X509v3 extensions:
X509v3 Name Constraints: critical
0!..0...1.0...U....leaf.example.com
As a result, it will also fail to verify certificate chains containing one of these misformatted constraints.
The issue appears to be that rcgen serializes it as implicit while it is supposed to be explicit.
Here's a simple program that generates a CA certificate with a directoryName constraint:
OpenSSL is unable to parse the constraint:
(notably)
As a result, it will also fail to verify certificate chains containing one of these misformatted constraints.
The issue appears to be that rcgen serializes it as implicit while it is supposed to be explicit.