Re-issuing self-signed root CA without invalidating certificates signed by it

12

I created a self-signed root Certificate Authority for a few internal services in our company, which I configured myself (mostly served over HTTPS). Then I created certificates for those services, signed with this CA.

Now I want to add an x509 extension (CRL distribution point) to the root CA without invalidating existing server certificates issued from this CA. Is this possible?

My gut feel is "yes" because as I understand, access to the corresponding private key is necessary and sufficient for "full authority" over certificate identity. That is, unless there is some sort of nonce incorporated along with the public key into the certificate when it is generated (likely).

I'm still fairly new to SSL certificate management, but I (think I) understand the basics of the standard trust chain. I'm also comfortable with basic use of other PKI crypto: I manage SSH keys and use GPG for signing and encryption. I studied Computer Science, though I'm only a self-taught dabbler in cryptography.

I never made a CSR for the original IIRC (I think it was the direct output of openssl req -new -x509). I still have the original CA's private key, of course, and using it I was able to "reverse" the original cert into a Certificate Signing Request: openssl x509 -x509toreq -in MyCA.pem -out MyCA.csr -signkey private/MyCA.key

I was hoping this would effectively "extract" the nonce mentioned above, and allow me to recreate the certificate but this time with a crlDistributionPoints field, and consequently all certificates that were signed with the original CA would still validate against this new CA, with the exception that clients would retrieve my (currently empty) CRL file from the HTTP URL designated in the field.

So I made an extension config file ext.conf:

[ cert_ext ] 
subjectKeyIdentifier=hash
crlDistributionPoints=URI:http://security.mycompany.co.za/root.crl

And I generated the new version of the root CA from the CSR:

openssl x509 -extfile ./ext.conf -extensions cert_ext -req -signkey private/MyCA.key -in MyCA.csr -out MyNewCA.pem

Now when I view the certificate with openssl x509 -text -in MyNewCA.pem | less

I can see the CRL extension part:

X509v3 extensions:
    X509v3 Subject Key Identifier: 
        82:D0:01:03:49:FF:30:16:FA:DC:0A:1E:C1:8C:3D:66:A1:78:FF:F8
    X509v3 CRL Distribution Points: 

        Full Name:
          URI:http://security.mycompany.co.za/root.crl`

But alas! My previously signed certificates no longer validate against this one:

openssl verify -verbose -CAfile MyCA.pem git.pem 
git.pem: OK

openssl verify -verbose -CAfile MyNewCA.pem git.pem 
git.pem: <redacted DN>
error 20 at 0 depth lookup:unable to get local issuer certificate

Mostly I'm looking for more insight into how certificates work and why. But I'd also welcome a solution to the problem that lead to this one, so here's some background info too.

How I got into this mess: HTTPS to internal services work great once my CA is installed via the Explorer RMB → Install Certificate GUI on Windows, or the /usr/local/share/ca-certificates followed by update-ca-certificates on Debian and Ubuntu. But I recently ran into an exception: Git on Windows, specifically if installed to use Windows Secure Channel as SSL back-end. Which apparently by default insists that there must be a CRL field in SSL certificates.

So I guess it's really a Windows Secure Channel issue because the error message I keep running into seems entirely Microsoft-specific: fatal: unable to access 'https://angery@git.mycompany.co.za/gitblit/r/secret_project.git/': schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) - The revocation function was unable to check revocation for the certificate.

If I install Git with OpenSSL and manually concatenate my CA onto the file pointed to by git.http.sslcainfo then it works, but I fear my users will be inclined to nope out on SSL identity verification if they feel this process is more effort than clicking through the "easy" Windows certificate installer GUI.

ssl-certificate
openssl
certificate-authority
asked on Server Fault Jul 13, 2017 by AngerySysadmin • edited Jul 13, 2017 by AngerySysadmin

1 Answer

6

Two certificates are considered the same as long as the Subject Name and the Public Key of the certificates match.

Therefore, all you need to do is to re-use the keys and ensure that the Subject Name in the new certificate is the same as the old. After that, you can change any of the other fields and/or extensions and the resulting certificate will be considered the same.

For example, create your OpenSSL configuration file:

[ req ]

prompt             = no
string_mask        = default
distinguished_name = x509_distinguished_name
x509_extensions     = x509_ext

[ x509_distinguished_name ]

# Note that the following are in 'reverse order' to what you'd expect to see.
# Adjust for your setup:

countryName = za
organizationName = My Company
organizationalUnitName = Security
commonName = My Root CA

[ x509_ext ]

basicConstraints = critical,CA:true
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
crlDistributionPoints = URI:http://security.mycompany.co.za/root.crl

and save it as e.g. rootca.cnf. Ensure that the elements of the [req_distinguished_name] are identical to the ones in your original Root CA certificate (this is the identical Subject Name part).

Next, run:

openssl req -new -x509 -key rootca.key -out MyNewCA.pem -config rootca.cnf

where rootca.key is the private key used in the original certificate (this is the identical Public/Private Key part).

This creates MyNewCA.pem, which you can check with:

$ openssl x509 -noout -text -in MyNewCA.pem

Certificate:
Data:
    Version: 3 (0x2)
    Serial Number: 17564687072266118846 (0xf3c24dd49d5166be)
Signature Algorithm: sha256WithRSAEncryption
    Issuer: C=za, O=My Company, OU=Security, CN=My Root CA
    Validity
        Not Before: Jul 15 05:05:54 2017 GMT
        Not After : Aug 14 05:05:54 2017 GMT
    Subject: C=za, O=My Company, OU=Security, CN=My Root CA
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
            Modulus:
                00:c8:3d:32:8a:56:31:f6:27:1a:ce:9e:b2:1d:fb:
                ce:9f:ce:5b:42:25:aa:fe:8b:f4:34:32:ac:b3:02:
                50:71:f8:c3:43:0c:c7:2c:9f:fe:48:1b:c6:c0:e7:
                d6:44:a9:e7:d7:a0:7e:58:f4:b6:38:61:7e:d0:af:
                0f:56:21:e7:49:7a:66:13:f5:7a:fe:3d:ab:65:f8:
                01:eb:52:a7:3b:ae:a0:cf:50:57:b9:e0:09:0b:1f:
                90:14:fb:18:56:1d:57:99:a9:76:a2:63:d1:c2:d3:
                a3:f4:3a:ff:91:0d:ee:8d:44:13:58:00:09:93:da:
                e8:6a:fd:64:5f:c3:42:8e:2a:49:6e:0d:73:b7:b9:
                d4:6c:c6:ce:30:c5:82:24:a5:00:37:17:a0:1d:f1:
                c9:e9:e3:18:48:22:4f:33:96:a7:3c:a9:31:f1:3f:
                14:40:6a:74:e8:78:82:45:04:d4:4b:56:0b:cd:be:
                48:8d:03:fb:39:70:0b:91:99:70:06:bd:5e:8b:f2:
                d1:f4:6f:fc:ce:e7:f8:3c:0a:20:ea:35:b8:5f:2f:
                ee:8d:ff:d3:93:85:6b:fb:71:db:1b:e6:e9:1d:a7:
                f8:e4:ae:f4:71:fe:35:a7:89:24:af:69:a4:34:3b:
                14:66:05:02:5e:2a:1d:ac:e0:d2:48:6c:13:4e:75:
                58:93
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Basic Constraints: critical
            CA:TRUE
        X509v3 Key Usage: critical
            Certificate Sign, CRL Sign
        X509v3 Subject Key Identifier: 
            3B:45:93:3A:2A:BC:39:29:36:13:6C:BD:B6:B4:31:C7:E7:BB:32:73
        X509v3 CRL Distribution Points: 

            Full Name:
              URI:http://security.mycompany.co.za/root.crl

Signature Algorithm: sha256WithRSAEncryption
     4d:96:d4:03:4f:e3:7c:26:be:59:f8:23:87:60:f7:4c:d3:a1:
     1c:77:a1:14:e3:e7:da:c8:2a:a3:1b:06:2a:4d:55:1c:83:26:
     73:46:0d:8a:e4:b7:d1:1e:38:cc:78:90:00:01:b3:8e:f9:3c:
     62:be:04:09:90:4e:22:87:b1:aa:bd:f9:73:bd:a7:76:ad:d5:
     ae:2d:7a:1c:1e:1a:67:c8:57:4c:f9:6d:8b:62:d6:e5:ea:e0:
     40:5c:12:28:7e:ea:f0:0c:d6:cd:f4:1d:d5:56:09:ad:43:b4:
     eb:8c:68:ce:56:a2:a8:ae:a4:d5:35:bb:58:b8:ed:82:82:b5:
     ef:cb:e2:6d:76:61:ed:ee:a5:1f:68:95:07:ed:5b:f0:65:92:
     d2:dc:1d:c6:fa:7f:e0:c9:38:c2:c6:6f:03:38:e7:3a:b0:24:
     06:e0:bc:07:dd:e7:a0:dc:74:09:e5:37:7b:66:e1:6f:47:4c:
     71:ff:02:48:7f:d4:4f:ce:cb:91:e9:ee:cd:b6:f1:0a:03:19:
     3e:19:05:7d:8f:48:e7:f1:cc:07:37:3d:91:3c:6f:54:71:3c:
     a2:6c:55:c3:03:c1:7f:eb:9e:70:f1:8f:a1:fb:62:33:8b:86:
     2c:79:bc:76:e2:01:9a:68:df:af:40:a1:b2:9c:f6:a1:e1:6e:
     2a:dd:1a:d6

Use this new certificate in place of the original.

You can change other fields and extensions, such as the validity period of the certificate, but bear in mind that you shouldn't really have any constraints (other than basicConstraints = critical,CA:true) on the Root CA certificate.


After further consideration, your issue may simply be down to the fact that your replacement Root CA certificate doesn't have the basicConstraint and possibly the keyUsage extensions. It might be worth trying adding those two extensions to your ext.conf first and testing the resulting new Root CA certificate using the -x509toreq method you posted.

answered on Server Fault Jul 14, 2017 by garethTheRed • edited Jul 15, 2017 by garethTheRed

User contributions licensed under CC BY-SA 3.0