3

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.

4

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
| improve this answer | |
  • 1
    Changed my command to : $ openssl verify -untrusted /tmp/server_certs.crt -CAfile /tmp/google_root.pem /tmp/server_certs.crt and it works. – user3477071 Jan 9 at 3:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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