How to save the LDAP SSL Certificate from OpenSSL
Copy everything between -----BEGIN CERTIFICATE-----
and -----END CERTIFICATE-----
(including these delimiters) and paste it in a new text file (usually with the extension .pem
or .crt
). You can use your favourite (plain) text editor for this, for example Notepad, Gedit, Vim, Emacs (depending on the system you're using).
Alternatively, you can pipe the output to sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
, as described here:
echo -n | openssl s_client -connect 192.168.1.225:636 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ldapserver.pem
For those looking to grab the certs over a LDAP connection using StartTLS:
I have re-submitted a patch to OpenSSL to support LDAP when using -starttls for s_client. So eventually this should work (if it ever makes it in I guess -- not yet as of 10/18/16):
openssl s_client -connect servername:389 -starttls ldap -showcerts
Edit: Support was eventually merged under this PR. C is not my forte so luckily someone else ran with it ;)
I also wrote a PHP function to extract the SSL certificates after issuing a STARTTLS command over a TCP connection. It could easily be ported to other languages with a little work:
/**
* @param string $server The server name to connect to
* @param int $port The standard LDAP port
* @return array In the form of ['peer_certificate' => '', 'peer_certificate_chain' => [] ]
*/
function getLdapSslCertificates($server, $port = 389)
{
$certificates = [
'peer_certificate' => null,
'peer_certificate_chain' => [],
];
// This is the hex encoded extendedRequest for the STARTTLS operation...
$startTls = hex2bin("301d02010177188016312e332e362e312e342e312e313436362e3230303337");
$opts = [
'ssl' => [
'capture_peer_cert' => true,
'capture_peer_cert_chain' => true,
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
];
$context = stream_context_create($opts);
$client = @stream_socket_client(
"tcp://$server:$port",
$errorNumber,
$errorMessage,
5,
STREAM_CLIENT_CONNECT,
$context
);
@stream_set_timeout($client, 2);
@fwrite($client, $startTls);
@fread($client, 10240);
@stream_socket_enable_crypto($client, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
$info = @stream_context_get_params($client);
if (!$info) {
return $certificates;
}
openssl_x509_export($info['options']['ssl']['peer_certificate'], $certificates['peer_certificate']);
foreach ($info['options']['ssl']['peer_certificate_chain'] as $index => $cert) {
$certChain = '';
openssl_x509_export($cert, $certChain);
$certificates['peer_certificate_chain'][$index] = $certChain;
}
@fclose($client);
return $certificates;
}
The above function will return an array containing the peer certificate and the peer certificate chain. So it could be used like so:
// Just pass it the server name
$certificates = getLdapSslCertificates('dc1.example.local');
// The certificates are in the array as strings in PEM format
echo $certificates['peer_certificate'].PHP_EOL;
foreach ($certificates['peer_certificate_chain'] as $cert) {
echo $cert.PHP_EOL;
}
The easiest way i found to save a certificate from any SSL enabled protocols like ldap, imap, pop, ftps, https etc. is just using chrome browser. Assume if your server running any protocol (like mentioned) create the url like this
http://: (example if your ldap server is running on SSL port 10636 it would be https://example.com:10636). Simply just hit this URL and obtain the certificate from the chrome browser itself. A simple demo below. In this demo my ldap server is using a self-signed certificate.
Click on copy to file and save the certificate by clicking next.
This method works for any server running on SSL irrespective of protocol.
Cheers.
There is a tool that lets you collect and save an SSL/TLS certificate from a server that speaks not only LDAPS, but LDAP/STARTTLS too. That's a revision of the well-known InstallCert program, written in Java.
Just run it like this:
java -jar installcert-usn-20131123.jar host_name:port
and it will save the certificate for you in the jssecacerts
keystore file in your JRE file tree, and also in the extracerts
keystore file in your current directory. You can then use Java keytool to export the certificate(s) to other formats.
You are welcome to visit my blog page Yet another InstallCert for Java, now with STARTTLS support for download and instructions.
There is a pretty simple way using only openssl
:
openssl s_client -connect 192.168.1.225:636 < /dev/null |
openssl x509 -out cert.pem
The first line fetches the cert from server and the second line parses the cert and allows transforming it into different formats, for example:
-
openssl x509 -noout -text
: prints certificate in text format, e.g., for debugging. -
openssl x509 -outform der -out cert.crt
: saves cert in DER format
You can checkout docs for all possible variations.