4

When attempting to verify google server's certificate chain using openssl, I am getting error.

Extract google's server and intermediate certificates:

$ echo | openssl s_client -showcerts -connect www.google.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/server_certs.crt

Extract google's root CA from jdk:

$ pwd

/cygdrive/c/Program Files/Java/jdk1.8.0_231/jre/lib/security

$ keytool -export -keystore cacerts -storepass changeit -alias 'globalsignr2ca [jdk]' -file /cygwin64/tmp/google_root.der

$ openssl x509 -in /tmp/google_root.der -out /tmp/google_root.pem -inform der

Also extracted google's root certificate from chrome browser to /tmp/google-chrome-root.pem. Doing a diff between chrome's root certificate and jdk extracted root certificate, there is no difference

$ diff /tmp/google_root.pem /tmp/google-chrome-root.pem

$ Based on this, I know, I am using the right root certificate.

Invoke openssl verify

$ openssl verify -CAfile /tmp/google_root.pem /tmp/server_certs.crt

C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com

error 20 at 0 depth lookup: unable to get local issuer certificate error /tmp/server_certs.crt: verification failed

I know verification through

$ openssl s_client -showcerts -servername www.google.com -connect www.google.com:443

is successful

CONNECTED(00000005) depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign verify return:1 depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1 verify return:1 depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com verify return:1 

and was expecting a similar successful result through the openssl verify command as well.

I am doing this exercise in windows 10 and cygwin.

2

1 Answer 1

6

TL;DR: You need to give openssl verify the intermediate certificate, too.

Your manual verification:

$ openssl verify -CAfile /tmp/google_root.pem /tmp/server_certs.crt 

Does not specify the intermediate cert. When you perform the verification using s_client, it shows that there are three certs - root, intermediate, and server. I've indented your output to make this more obvious:

CONNECTED(00000005) depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign verify return:1 depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1 verify return:1 depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com verify return:1 

In order for openssl verify to work, you need to download that intermediate cert (CN = GTS CA 101) and pass it in the command line using the -untrusted argument:

-untrusted file

A file of untrusted certificates. The file should contain multiple certificates in PEM format concatenated together.

Something like this:

$ openssl verify -CAfile /tmp/google_root.pem -untrusted /tmp/google_intermediate.pem /tmp/server_certs.crt 
1
  • 1
    Changed my command to : $ openssl verify -untrusted /tmp/server_certs.crt -CAfile /tmp/google_root.pem /tmp/server_certs.crt and it works.CommentedJan 9, 2020 at 3:13

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.