对于那些希望使用StartTLS通过LDAP连接获取证书的用户:
当将-starttls用于s_client时,我已重新提交了OpenSSL修补程序以支持LDAP。 所以最终这应该工作(如果我认为可以实现的话-截至16年10月18日尚未完成):
openssl s_client -connect servername:389 -starttls ldap -showcerts
编辑:支持最终合并在此PR下。 C不是我的强项,所以幸运的是有人陪着它;)
通过TCP连接发出STARTTLS命令后,我还编写了PHP函数来提取SSL证书。 只需做一些工作,就可以轻松将其移植到其他语言:
/**
* @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;
}
上面的函数将返回一个包含对等证书和对等证书链的数组。 因此可以这样使用:
// 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;
}