SSL Certificate error: verify error:num=20:unable to get local issuer certificate

I've been trying to get an SSL connection to an LDAPS server (Active Directory) to work, but keep having problems. I tried using this:

openssl s_client -connect the.server.edu:3269 

With the following result:

verify error:num=20:unable to get local issuer certificate 

I thought, OK, well server's an old production server a few years old. Maybe the CA isn't present. I then pulled the certificate from the output into a pem file and tried:

openssl s_client -CAfile mycert.pem -connect the.server.edu:3269

And that didn't work either.

What am I missing? Shouldn't that ALWAYS work?


Solution 1:

So this is what I see as the CA cert name:

depth=1 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at //www.verisign.com/rpa (c)10/CN=VeriSign Class 3 International Server CA - G3
verify error:num=20:unable to get local issuer certificate
verify return:0

That was the name of the certificate that I had imported after I did the -showcerts in my second try above. I listed the certs in the keystore by doing this:

$JAVA_HOME/bin/keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts

I see the CA certificate in there.

Alias name: versign2006
Creation date: Jan 21, 2011
Entry type: trustedCertEntry

Owner: CN=VeriSign Class 3 International Server CA - G3, OU=Terms of use at www.verisign.com/rpa (c)10, OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
Serial number: 641be820ce020813f32d4d2d95d67e67
Valid from: Sun Feb 07 19:00:00 EST 2010 until: Fri Feb 07 18:59:59 EST 2020
Certificate fingerprints:
  MD5:  BA:B0:65:B4:3B:9C:E8:40:30:21:7D:C5:C6:CD:3F:EB
  SHA1: B1:8D:9D:19:56:69:BA:0F:78:29:51:75:66:C2:5F:42:2A:27:71:04

To make sure that openssl is using the keystore that I'm using with the server, I'm using the -CAfile argument:

openssl s_client -connect the.server.edu:3269 -CAfile $JAVA_HOME/jre/lib/security/cacerts

Knowing that the java keystore for CA's has a password, I tried using the -pass pass:password option like this:

openssl s_client -connect the.server.edu:3269 -CAfile $JAVA_HOME/jre/lib/security/cacerts -pass pass:changeit

but that didn't work either.

What's funny about that is that the cacerts file has a password on it and openssl isn't complaining that it can't read the cacerts file. That seems fishy to me. Does that or anything else ring a bell?

Solution 2:

That error is openssl's way of saying, "I can't follow the certificate chain to a trusted root". I just did the same command to my own AD servers and I get a full cert-chain, but the top certificate has that exact error. If you have the pub-key of the CA that signed the cert you can specify it with the -CAfile or -CApath options