opensslcertificatex509

How to generate x509 v3 cert with the PrivateKeyUsagePeriod extension


I want to generate a v3 certificate which contains the PrivateKeyUsagePeriod extension. I have created an opnessl.cnf configuration file which contains the privateKeyUsagePeriod under [v3_req] but the OPENSSL cli tool gives the following error:

Error Loading extension section v3_req
42949672976:error:22097067:X509 V3 routines:do_ext_nconf:extension setting not supported:crypto/x509v3/v3_conf.c:116:name=privateKeyUsagePeriod
42949672976:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto/x509v3/v3_conf.c:47:name=privateKeyUsagePeriod, value=@private_key_usage

I can sucessfully generate a v3 certificate if I remove privateKeyUsagePeriod section from the configuration, but I need the Validity under extensions and not on the root level to test a feature.

  1. I created a openssl.cnf configuration file:
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[req_distinguished_name]
C = US
ST = California
L = San Francisco
O = Example Company
OU = IT Department
CN = example.com

[v3_req]
basicConstraints = critical,CA:FALSE
keyUsage = digitalSignature, keyEncipherment
privateKeyUsagePeriod = @private_key_usage

[ private_key_usage ]
notBefore = ASN1:GENERALIZEDTIME:20240101000000Z
notAfter = ASN1:GENERALIZEDTIME:20241231235959Z
  1. Generated a new private key and CSR using: openssl req -newkey rsa:2048 -keyout key.pem -out req.csr -config openssl.cnf

  2. Signed the CSR: openssl x509 -req -in req.csr -out cert.pem -signkey key.pem -days 365 -extfile openssl.cnf -extensions v3_req

  3. Display the details using: openssl x509 -in cert.pem -text -noout

Error Loading extension section v3_req
42949672976:error:22097067:X509 V3 routines:do_ext_nconf:extension setting not supported:crypto/x509v3/v3_conf.c:116:name=privateKeyUsagePeriod
42949672976:error:22098080:X509 V3 routines:X509V3_EXT_nconf:error in extension:crypto/x509v3/v3_conf.c:47:name=privateKeyUsagePeriod, value=@private_key_usage
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            [...]
        Signature Algorithm: ecdsa-with-SHA256
        [...]
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                [...]
            X509v3 Issuer Alternative Name: 
                [...]
            X509v3 Basic Constraints: critical
                [...]
            X509v3 Key Usage: critical
                [...]
            X509v3 Private Key Usage Period: 
                [...]
            X509v3 Subject Key Identifier: 
                [...]
            X509v3 Authority Key Identifier: 
                [...]
            X509v3 CRL Distribution Points: 
                [...]
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        [...]

Instead I get this:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            [...]
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = IN, ST = CA, L = SF, O = abc, OU = abc, CN = acc.com
        Validity
            Not Before: Jul 10 13:32:57 2024 GMT
            Not After : Jul 10 13:32:57 2025 GMT
        Subject: C = IN, ST = CA, L = SF, O = abc, OU = abc, CN = acc.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    [...]
                Exponent: [...]
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Key Usage:
                Digital Signature, Key Encipherment
    Signature Algorithm: sha256WithRSAEncryption
         [...]

Solution

  • PrivateKeyUsagePeriod extension is defined as a sequence of two GeneralizedTime fields:

    PrivateKeyUsagePeriod ::= SEQUENCE {
         notBefore       [0]     GeneralizedTime OPTIONAL,
         notAfter        [1]     GeneralizedTime OPTIONAL }
    

    It can be added to OpenSSL configuration this way (tested with OpenSSL 3.0.7):

    [ v3_req ]
    ...
    privateKeyUsagePeriod   = ASN1:SEQUENCE:privateKeyUsagePeriod
    
    [ privateKeyUsagePeriod ]
    notBefore               = IMPLICIT:0,GENERALIZEDTIME:20240101000000Z
    notAfter                = IMPLICIT:1,GENERALIZEDTIME:20241231235959Z