How to save the LDAP SSL Certificate from OpenSSL

后端 未结 7 686
刺人心
刺人心 2020-12-07 16:32

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          


        
相关标签:
7条回答
  • 2020-12-07 17:24

    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;
    }
    
    0 讨论(0)
提交回复
热议问题