I know that I can dump the entire information from a PEM certificate file with this command:
openssl x509 -in certfile -noout -textAnd I've already found another direct parameter to show me only the expiry date of a certificate:
openssl x509 -in certfile -noout -enddateBut is there also a shortcut to get only the alternative names? Like when a certificate can be used for example.com as well as In the full dump, it's here:
Certificate: Data: X509v3 extensions: X509v3 Subject Alternative Name: DNS: DNS:example.comI'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+))*?
5 Answers
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.comOf 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.comResults in...
*.google.com 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 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 2 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: DNS:domain3.com, DNS:sub.domain3.comto
domain1.com, domain3.com, sub.domain3.com I think the best way to do this is this:
openssl x509 -in cert_file_name.crt -noout -ext subjectAltName
You can check more about the -ext flag in the official documentation of openssl here:
This way you'll only get the relevant information you need with one command, no need to use other softwares like awk and sed.
1