13

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?

  • For clarity sake, it appears that LDAPS, when served from Windows, does not present the CA certificate when a connection is made. Therefore, you should obtain the CA X.509 cert, export as base64 and assign as described in answers below. In my case, using python-ldap you assign it at GLOBAL scope (not your ldap.initialize() instance) as: `ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,'./ca_issuer_cert.pem')` After this, I was able to use STARTTLS (within LDAP port 389) as expected. – brandeded Jan 15 '13 at 15:23

3 Answers3

4

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?

mgorven
  • 30,615
  • 7
  • 79
  • 122
Brian
  • 41
  • 1
3

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

sysadmin1138
  • 133,124
  • 18
  • 176
  • 300
  • Ok, thanks for the response. So I tried that. Got the CA cert by doing the same thing with the -showcerts option on, grabbed the other certificate. That should be the CA cert, right? Tried that instead of the server certificate in the pem file and got the same error message. Any other thoughts? –  Jan 22 '11 at 01:27
  • In that case it is probable that it is failing validation for another reason, such as being expired. – sysadmin1138 Jan 22 '11 at 02:24
1

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:

If you're using OpenLDAP, you can set:

TLS_REQCERT=never

in your openldap.conf file, which instructs OpenLDAP to not attempt certificate verification. There's a similar option if you're doing LDAP authentication with Apache.

If you really want to perform certificate verification, the following may help:

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

I don't think so. While the following may sound definitive, it's really just my best guest:

What you tried would only work for a self-signed certificate. Because the certificate was actually issued by the Windows CA, attempting to use the server certificate as the argument to -CAfile won't get you anything.

Got the CA cert by doing the same thing with the -showcerts option on, grabbed the other certificate. That should be the CA cert, right?

Not necessarily, no. There's no guarantee that the remote server presents the CA certificate in its output. You need to first look at the issuer of the server certificate:

openssl x509 -in server.crt -noout -text | grep Issuer

...and then see if one of the other certificates you have matches that issuer.

larsks
  • 43,623
  • 14
  • 121
  • 180