How to dump the Subject Alternative Name (SAN) from an SSL certificate file

4

I know that I can dump the entire information from a PEM certificate file with this command:

openssl x509 -in certfile -noout -text

And I've already found another direct parameter to show me only the expiry date of a certificate:

openssl x509 -in certfile -noout -enddate

But is there also a shortcut to get only the alternative names? Like when a certificate can be used for example.com as well as www.example.com. In the full dump, it's here:

Certificate:
    Data:
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:www.example.com, DNS:example.com

I'd just like to save me the hassle to parse this output and get the domain names only. Is that possible? Otherwise, what would be best practices to parse this output? What can be assumed, what may change? Could I use a regexp like X509v3 Subject Alternative Name:\s*DNS:(\S+)(?:, DNS:(\S+))*?

ygoe

Posted 2013-11-10T15:44:56.437

Reputation: 1 597

Answers

2

Here's what I would do to make it a little more readable:

for i in $(openssl x509 -in certfile -noout -text | grep -A1 'Subject Alternative Name' | tail -n1 | tr -d ','); { echo $i | cut -f2 -d:; }

This gets you a long list format, assuming the same input as the sample above, something like this:

*.google.com
*.android.com
*.appengine.google.com
*.cloud.google.com
...

Where the raw output of the line would have been:

DNS:*.google.com, DNS:*.android.com, DNS:*.appengine.google.com, DNS:*.cloud.google.com

Of course you have to choose the right format for your list. For instance, that actual Google list is quite long and difficult to consume. If you're looking for something specific breaking the entries on to each line allows you to grep for the entry you're looking for and remove all the other information.

So this (notice the grep at the end) ...

for i in $(openssl x509 -in certfile -noout -text | grep -A1 'Subject Alternative Name' | tail -n1 | tr -d ','); { echo $i | cut -f2 -d:; } | grep google.com

Results in...

*.google.com

Brett Stauner

Posted 2013-11-10T15:44:56.437

Reputation: 21

2

I find this method works reasonably well and is easy to remember since it's just a grep DNS:.

$ openssl x509 -noout -text -in cert.pem | grep DNS:
                DNS:localhost, DNS:someserver1.somedom.local, DNS:someserver2.somedom.com, DNS:someserver3

slm

Posted 2013-11-10T15:44:56.437

Reputation: 7 449

2

Since there can be many entries, I simply select the next line and clean it up using awk and tr

openssl x509 -noout -text -in certfile | awk '/X509v3 Subject Alternative Name/ {getline;gsub(/ /, "", $0); print}' | tr -d "DNS:"

Here is what you get with google.com

*.google.com,*.android.com,*.appengine.google.com,*.cloud.google.com,*.google-analytics.com,*.google.ca,*.google.cl,*.google.co.in,*.google.co.jp,*.google.co.uk,*.google.com.ar,*.google.com.au,*.google.com.br,*.google.com.co,*.google.com.mx,*.google.com.tr,*.google.com.vn,*.google.de,*.google.es,*.google.fr,*.google.hu,*.google.it,*.google.nl,*.google.pl,*.google.pt,*.googleadapis.com,*.googleapis.cn,*.googlecommerce.com,*.googlevideo.com,*.gstatic.cn,*.gstatic.com,*.gvt1.com,*.gvt2.com,*.urchin.com,*.url.google.com,*.youtube-nocookie.com,*.youtube.com,*.youtubeeducation.com,*.ytimg.com,android.com,g.co,goo.gl,google-analytics.com,google.com,googlecommerce.com,urchin.com,youtu.be,youtube.com,youtubeeducation.com

Olivier - interfaSys

Posted 2013-11-10T15:44:56.437

Reputation: 271

2I think it's worth pointing out that "tr -d "DNS:" can be dangerous, it means delete all instances of the characters D,N,S and :, anywhere, in any order, in the input. It does NOT delete "DNS:" as a complete string. For example, echo "MY DOMAIN NAME SERVER: bla" | tr -d "DNS:" would output "MY OMAI AME ERVER bla" – Hamid – 2016-02-25T13:22:33.940

I should also point out that a better solution is to add multiple additional gsubs to do it properly. "gsub(/DNS:/,"",$0);gsub(/IPAddress:/,"",$0)" will remove both "DNS:" and "IPAddress:" (for IP type SANs). – Hamid – 2016-02-25T13:24:50.090

1

In addition to using awk, you can use sed:

openssl x509 -in cert_file_name.crt -noout -text | awk '/DNS:/' | sed 's/DNS://g'

This will turn a SAN list from:

DNS:domain1.com, DNS:www.domain2.com, DNS:domain3.com, DNS:sub.domain3.com

to

domain1.com, www.domain2.com, domain3.com, sub.domain3.com

ec0g

Posted 2013-11-10T15:44:56.437

Reputation: 111