Verify certificate chain against CRL with openssl - ssl

I'm trying to learn about certificate and CRL handling, so I created the following example certificate chain:
Root CA (self-signed) → Intermediate CA (signed by Root CA) → Server Cert (signed bei Intermediate CA)
Now I would like to test certificate revocation to be effective. To do so, I revoke the Server Cert and create a CRL file (of the Intermediate CA) accordingly. The X509v3 CRL Distribution Points are present in all of the certificate files, and they are accessible via http, like:
X509v3 CRL Distribution Points:
Full Name:
URI:http://127.0.0.1:80/intermediate_ca.crl
(Which is the CRL I just created. (The same for the Root CA CRL at http://127.0.0.1:80/ca.crl.) I double-checked they are really present and accessible at that URI.)
Next, I cat the Root CA pem file and the Intermediata CA pem file into CAChain.pem.
I'd like to have a command that receives the Server Cert and the CAChain.pem and "crawls up" the certificate chain in order verify it in total.
I tried going with
openssl verify -extended_crl -crl_check_all -crl_download -CAfile CAChain.pem -verbose serverCert.pem
but I just get:
Error loading CRL from http://127.0.0.1:80/ca.crl
140041593399104:error:27076072:OCSP routines:parse_http_line1:server response error:crypto/ocsp/ocsp_ht.c:260:Code=404,Reason=Not Found
...
error 3 at 0 depth lookup: unable to get certificate CRL
Again, the CRL is really present at the URI denoted. That's why I can't explain the error 404. (Additionally it seems a little strange to me, that the error arises from an OSCP module as I'm just using CRL at the moment.)
I would highly appreciate if someone could tell me what my mistake is and how I can achieve what I originally intended (verifying the whole cert chain using the CRLs). Thanks in advance!

Indeed there were mainly two mistakes I had made:
The CRL file mandatorily has to be in DER format, which I did not know. (Conversion from the PEM format is simple: openssl crl -in ${crlFile}.pem -outform DER -out ${crlFile}).
Of course, a certicate's CRL distribution point has to be the one of its parent CA. (So, e. g. for my intermediate CA, it must be the one of the root CA.)
Keeping this in mind and also chaining the intermediate CA certs to the server certs, as dave_thompson_085s very helpful comments suggested, the original command
openssl verify -extended_crl -crl_check_all -crl_download -CAfile CAChain.pem -verbose serverCert.pem
works now.
I've created a gist of what I have done so far. It's still pretty ugly - I will tidy it up and also experiment with OCSP in the future.

Related

Why does openssl verify fail with a certificate chain file while it succeeds with the untrusted parameter?

I am working with a certificate chain with 3 certificates :
ca.crt : Root CA certificate
intermediate.crt : intermediate CA certificate (signed by ca.crt)
cert.crt : the final certificate
I first try to verify with:
openssl verify -CAfile ca.crt -untrusted intermediate.crt cert.crt
I get as result cert.crt: OK
So it's all fine.
But if I create a certificate chain with cat cert.crt intermediate.crt > cert.chain
And then I verify with openssl verify -CAfile ca.crt cert.chain
The result is error 20 at 0 depth lookup:unable to get local issuer certificate
And the cert.chain file is also rejected by a server for the exact same reason.
I don't understand where is the problem.
I first try to verify with: openssl verify -CAfile ca.crt -untrusted intermediate.crt cert.crt
This will take the first certificate out of cert.crt and try to build the trust chain using the given untrusted CA certificates in intermediate.crt up to some root CA certificate in ca.crt.
And then I verify with openssl verify -CAfile ca.crt cert.chain
This will also take the first certificate out of cert.chain. It will ignore remaining certificates in this file. It will then try to build the trust chain to some root CA certificate in ca.crt without using any intermediate CA certificates since none are given. It will thus fail.
And the cert.chain file is also rejected by a server for the exact same reason.
It is unknown what exactly happens here. If it is "rejected by a server" then you likely talk about validating a client certificate by the server. It might simply be that the client application does not send the whole chain to the server but only the first certificate from the file. None is known about this client application though, so this is only speculation.
Thanks to all. Yes, the correct way to verify a chain is with using the "untrusted" parameter of openssl verify to specify the intermediate certificate.
The connection to server was tried with openssl s_client and specifying the certificate chain in the "cert" parameter but it fails. Using a recent openssl version (1.1.0 or newer), it is now possible to add the "cert_chain" parameter to specify the intermediate certificate to use.
Hello you error just related in the fact that you chain is not build correctly.
Normally your verify with untrusted shall not work, that why you're confusing.The correct sequence is below. I invite you to regenerate and recreate your chain.
openssl verify -CAfile ca.crt -untrusted cert.crt intermediate
This will start at the end, (Root > intermediate > cert)
So that, your chain shall be build as following :
cat intermediate.crt cert.crt > chain.crt
Then it shall work.

Configuring TLS certificate for Github Enterprise server

On my Github enterprise when I install the SSL certificate with the key its displaying an error message:
"Github ssl cert The certificate is not signed by a trusted
certificate authority (CA) or the certificate chain is missing
intermediate CA signing certificates."
I was given from our certification authority team 4 certificates.
SSL certificate : github.pem
A set of 3 CA certificates : root, subca and subca2
On my Github enterprise management console, it needs 2 entries
A x509 SSL certificate
Unencrypted key
I have tried github.pem key alone and with different combination by concatenating CA certificates, but its failing always with the same error.
Is there a pattern to concatenate the certificate?
Any clue how i can resolve this?
Thanks in advance.
Please abide the following steps to add 3 certificates to your .pem file:
Open your domain certificate pem file in Notepad ++.
Add intermediate (DigiCertCA2.pem) certificate under Domain certificate.
Add root certificate (TrustedRoot.pem) to your domain certificate.
Save the .pem file that have the following 3 certificates (domain , intermediate, root).
Upload the modified certificate.pem file and the private key.
click on Save Settings.
I had the same issue.
When trying to load the PEM and Key files to GitHub Enterprise I got the same message. The cert was created using the exact same methods as I have done before, but was failing.
Github ssl cert The certificate is not signed by a trusted certificate authority (CA) or the certificate chain is missing intermediate CA signing certificates.
Steps I took:
Created a cert for the server (webserver with Private Key)
Exported from my users personal store (PFX including all certs in the path and export all extended properties)
C:\OpenSSL-Win64\bin> openssl.exe pkcs12 -in git_key_included.pfx -nocerts -out priv-key.pem -nodes
C:\OpenSSL-Win64\bin> openssl.exe pkcs12 -in git_key_included.pfx -nokeys -out cert.pem
C:\OpenSSL-Win64\bin> openssl rsa -in priv-key.pem -out server.key
I eventually figured it out by opening the PEM using Notepad++. The openssl commands work fine on the old exported cert, but swap around the ordering of the certs on the new exported cert. The broken cert had:
Primary SSL certificate
Root certificate
Intermediate certificate
Instead of the correct ordering of:
Primary SSL certificate
Intermediate certificate
Root certificate
So I swapped them around and it worked.

OpenSSL X509 Verify Signature with CA

I have a root certificate which I created based on a previously provided keypair (private & public). The certificate is called Root CA in file rootca.crt.
I've now been tasked with verifying a given signature with the Root CA.
I'm fairly sure this needs to be done through X509 but I'm not familiar with the command? The signature which I need to verify was supplied in Base64 and I've decoded it and converted to binary, so I believe the final step I'm missing is an OpenSSL X509 verify command, but that doesn't seem to exist?
Any advice would be appreciated, cheers.
Use the openssl verify command.
openssl verify -CAfile rootca.crt certificate
See also the verify(1) man page.

Transfered SSL Certificate to Rackspace Cloud Server - Occasional Error

Okay, I recently tranfered my Comodo SSL certificate from my previous Bluehost account to my new rackspace cloud server. (LAMP stack)
Basically I just copy pasted the server cert and key and checked to make sure it was properly installed which it was. Now I am running into some issues, occasionally I will hear from people that they are getting an 'Untrusted Connection Error' while others are not getting this error at all.
Recently someone sent me a screen shot of their error and it said: This Certificate is not trusted because no issuer chain was provided.
The browser they noticed this on was safari so I cleared all my history data in safari and opened the site but I am not seeing that error.
Does anyone have any idea how to fix something like this? Thanks!
When I enter openssl s_client... i get:
Certificate chain
0 s:/OU=Domain Control Validated/OU=Hosted by BlueHost.Com, INC/OU=PositiveSSL/CN=www.sitename.com
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=PositiveSSL CA 2
1 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=PositiveSSL CA 2
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
You most likely lack the 'chain' or inter mediate certificates (which some people may have in their browser, and some not).
The easiest way to resolve this is by looking at the issuer details on your certificate; and finding that certificate. Then look at the issuer details of that cert - until you hit the 'root' - which is a self signed certificate (subject identical to issuer).
Once you've got them all concatenate them in a file and point SSLCertificateChainFile at that.
Your httpd.conf then looks like
SSLEngine on
SSLCertificateKeyFile .../your-key.key
SSLCertificateFile .../your-cert.pem
SSLCertificateChainFile .../ca-bundle.pem
Some CA's make this file available as a 'ca-bundle' (https://support.comodo.com/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=1203) when they issue a cert. Most don't.
So in that case you'll need to create it. Doing
openssl x509 -in <your cert.pem> -noout -issuer
will get you the exact issuer string. Googling for it generally gives you the intermediate cert you need (usually at the support site of your CA). Once you have that - repeat above and keep going at it until you are at the final one -- where issuer is identical to subject.
Once done - restart the webserver and that should be it.
If you want to verify you got the whole chain - then use the command
openssl s_client -connect <your domain name>:443
and check that the output starts with:
0 s:/C=GB/OU=Domain Control Validated/CN=<your domain>
i:/C=BE/O=Comodo/CN=Comodo foobar
....
3 s:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
and at least has one entry (3 in above example) where you have a final root; the S is identical top the i. If you just see a single entry
0 s:/C=GB/OU=Domain Control Validated/CN=<your domain>
i:/C=BE/O=Comodo/CN=Comodo foobar
and nothing more - then check your chain again - and make sure that it contains a cert with a subject identical to your issuer (in above example '/C=BE/O=Comodo/CN=Comodo foobar').
You can check this by parsing each blob in your bundle with
openssl x509 -noout -in file.pem -subject -issuer
where file.pem is one chunk of your SSLCertificateChainFile file.
Caveat: Above is a slight simplification - some Chains may have multiple roots/cross-signing. In that case it gets a bit more complex - but follows above example.

How to generate intermediate and root cert from an existing leaf certificate?

Now i have a X509 leaf certificate. From the certification path to see, there's a intermediate cert and a root cert in it.
I want to generate the intermediate cert(..CA- G3) and the root cert(VerSign). Currently, my way is to double click the intermediate one and then click "Copy to file.." to export it. Do same for the root one too. Is this way to correct to generate intermediate/root certs?
From my test result, it seems the generated root cert with wrong fingerprint. The fingerpring doesn't match the one on server side.
Anyone can help on how to generate intermediate/root certs correctly?
You have fundamental misunderstanding of certificates and certificate chains.
CA and Root certificates are searched for and found, not generated.
Some certificates include location of their CA certificate in the body of the certificate (in special certificate extension). For others you need to look in your CA certificates storage (this is what Windows does). Sometimes chains are sent together with end-entity certificate (depending on data format). Finally, sometimes CA and Root are just not available.
[supply the answer... , maybe this is an alternative approach to get all certs that the SSL server using]
To retrieve the ntermediate and root certs by OpenSSL command:
openssl s_client -showcerts -connect [host]:[port]