n3mo
n3mo

Reputation: 761

Get chain or CA issuer from x509 certificate using OpenSSL CLI

I am trying to build a chain (or just get it from somewhere) from a certificate using OpenSSL, preferibly using the command line interface.

I have found some example in internet, but I am stuck at the question "Where do I get the CA issuer from the certificate?"

For example check this website openssl command cheatsheet, you will find the command

openssl s_client -showcerts -host example.com -port 443

to get the chain. You can try it using www.google.com instead of example.com. The output should give you the chain. Other websites use the same command, sooner or later...

So, I cannot get the chain directly from the certificate, but I should ask somewhere for the chain.

Now my problem is: where do I get the hostname, where I can send my request for the chain?

I had a look to two certificates.

  1. stackexchange.com
  2. google.com

Using OpenSSL, I can ask the Issuer using the command

openssl x509 -in certFile -noout -issuer

and I get respectively

  1. issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
  2. issuer=C = US, O = Google Trust Services, CN = GTS CA 1O1

Honestly, I do not know what to do with these results....

Then, investigating with the command

openssl x509 -text -in certFile

I have found the AIA extensions:

  1. CA Issuers - URI:http://cert.int-x3.letsencrypt.org/
  2. CA Issuers - URI:http://pki.goog/gsr2/GTS1O1.crt

Ok in the first example, I can finally use the command

openssl s_client -showcerts -host http://cert.int-x3.letsencrypt.org/ -port 443

but with google, I do not know how to download the chain using openssl....I could use wget maybe, but I don't have the same format that I get from stackexchange...

So, finally, my questions:

PS: What I try to achieve at the very end, is to validate a certificate, going through the complete chain, and checking all the OCSP or CRL for each certificate in the chain...If you have working example in C++, or just using OpenSSL CLI, I would be really grateful :)

EDIT:

What I am doing right now is creating the chain by myself.

Using the AIA extensions, I get the CA Issuer URI, download the CA Issuer certificate (convert to PEM if needed), and so on till I do not find a CA Issuer anymore. Then, probably it is a root CA.

After that, I manually collect all the pem and create the chain.

Upvotes: 4

Views: 14572

Answers (3)

adrock20
adrock20

Reputation: 327

Bonusing off of @bng44270's answer, this script will walk up the chain grabbing certs into the current directory

#!/bin/bash
# get-cert-chain.sh

machine=${1?No address passed}

machine_cert=${machine}.pem

# from https://stackoverflow.com/a/68637388/5401366
getcaissuer() {
    openssl x509 -noout -text -in $1 -ext authorityInfoAccess | awk '/^[ \t]+CA Issuers[ \t]+-[ \t]+URI:/ { print gensub(/^.*URI:(.*)$/,"\\1","g",$0); }'
}

if [ ! -e "${machine_cert}" ];
then
    openssl s_client -connect ${machine}:443 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM >${machine_cert}
fi;

cur_cert=$machine_cert

while :;
do
    # Get the first matching http line to grab the next cert loc
    nextca=$(getcaissuer ${cur_cert} | grep -m1 http)

    # ran out of stuff to retrieve
    [ -z "${nextca}" ] && break

    echo "Trying to get '${nextca}'"

    nextfile=$(basename ${nextca})

    if [ ! -e ${nextfile} ];
    then
        echo "Getting $nextca"
        curl -sO $nextca
    else
        echo "Found ${nextfile}"
    fi

    # Convert
    openssl x509 -in $nextfile -outform PEM > ${nextfile}.pem

    # down the rabbit hole...
    cur_cert=${nextfile}.pem

done

Upvotes: 3

bng44270
bng44270

Reputation: 349

Know this is a bit old and it's been resolved but I thought I'd add a little script I write to parse out the CA Issuer from the x509 output:

getcaissuer() {
openssl x509 -noout -text -in $1 | awk '/^[ \t]+CA Issuers[ \t]+-[ \t]+URI:/ { print gensub(/^.*URI:(.*)$/,"\\1","g",$0); }'
}

# usage:  getcaissuer <certificate>

Upvotes: 3

n3mo
n3mo

Reputation: 761

It seems a lot of example in internet have in mind the SSL certificate. In SSL certificate, you can just connect to the website and download the complete chain. I think it is in the SSL protocol itself that the server should give you the complete chain.

I was doing it for SMIME certificates, that is why I was confused, because I can not use the same method they use for SSL certificates.

After speaking with my collegues and also comparing what I was doing with some similar programs found in internet, it seems the AIA extension is the correct way to do it. Maybe it is not mandatory in the X509 standard, but it seems widely used (I have never seen a SMIME certificate without the AIA extension).

Then, I create the chain manually, go back using the AIA extension till I find a certificate without such extension.

At this point, that should be a root certificate and I will try to just validate it, using the installed certificates in the machine.

(Of course, do not forget to check the revocation status through CRL or OCSP)

So far, everything is working well :)

Upvotes: -1

Related Questions