I wanted the SSL Certificate of my LDAP Server which is Novell eDirectory. I have used openssl to connect to ldap to view the certificate.
openssl s_client
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;
}