Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I wrote this bit of code to get the Common Name of the subject field in the SSL certificate for a given domain:

$ echo -e "GET / HTTP/1.1\nEOT" | openssl s_client -connect google.com:443 2>&1 | grep subject subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com

However, this only gives me the “subject” value. Alternative CNs may be listed in the “Subject Alternative Name” field. For example:

So, how can I get the value of the Subject Alternative Name field in Bash?

share|improve this question

3 Answers 3

up vote 3 down vote accepted

This might not work under every circumstance, but try

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text | grep DNS
share|improve this answer
1  
Thanks so much! openssl x509 -text is what I was looking for. I guess I was Googling for the wrong keywords. –  Mathias Bynens Mar 7 '13 at 14:28

Here's a version that will work in every circumstance (and strips leading space):

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text |
  sed -nr '/^ {12}X509v3 Subject Alternative Name/{n;s/^ *//p}'
share|improve this answer
    
Can you be more specific about what kind of issues this works around (that the other answer doesn’t)? Thanks! –  Mathias Bynens Aug 8 at 13:44
1  
Unlike the other answer, this doesn't inadvertently include other fields that contain "DNS" (such as what you could encounter running the other answer for the certificate of a service that provides DNS). –  Stuart P. Bentley Aug 8 at 21:20

What @stuart-p-bentley wrote got me thinking and I came up with this way of getting a comma delimited list of "Subject Alternative Names" using openssl, awk and tr. The sed line in his answer does not work on FreeBSD per example.

openssl s_client -connect google.com:443 2>&1 | openssl x509 -text | 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
share|improve this answer
    
tr -d "DNS:" is not a good solution to get all the domains in the SAN, as the SAN field may contain other kinds of values than DNS, such as IP addresses. I don't know how you'd do it with awk, but sed -nr '/^ {12}X509v3 Subject Alternative Name/{n; s/(^|,) *DNS:/,/g; s/(^|,) [^,]*//gp}' is how I did it with sed here. –  Stuart P. Bentley Oct 15 at 6:25
    
The equivalent awk translation would probably be awk '/^ {12}X509v3 Subject Alternative Name/ {getline; gsub(/(^|,) *DNS:/, ",", $0); gsub(/(^|,) [^,]*/, "", $0); print}', though I don't know why that would be any better than using sed (I can't see why the sed wouldn't work on FreeBSD, unless you need to use -nE instead of -nr due to being on an old version). –  Stuart P. Bentley Oct 15 at 6:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.