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. Jan 9, 2020 at 3:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .