How to get SSL certificate info with CURL in PHP? How to get SSL certificate info with CURL in PHP? curl curl

How to get SSL certificate info with CURL in PHP?


You will get the certificate as a resource using stream_context_get_params. Plug that resource into $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); to get more certificate information.

$url = "http://www.google.com";$orignal_parse = parse_url($url, PHP_URL_HOST);$get = stream_context_create(array("ssl" => array("capture_peer_cert" => TRUE)));$read = stream_socket_client("ssl://".$orignal_parse.":443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $get);$cert = stream_context_get_params($read);$certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']);print_r($certinfo);

Example result

Array(    [name] => /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com    [subject] => Array        (            [C] => US            [ST] => California            [L] => Mountain View            [O] => Google Inc            [CN] => www.google.com        )    [hash] => dcdd9741    [issuer] => Array        (            [C] => US            [O] => Google Inc            [CN] => Google Internet Authority G2        )    [version] => 2    [serialNumber] => 3007864570594926146    [validFrom] => 150408141631Z    [validTo] => 150707000000Z    [validFrom_time_t] => 1428498991    [validTo_time_t] => 1436223600    [purposes] => Array        (            [1] => Array                (                    [0] => 1                    [1] =>                     [2] => sslclient                )            [2] => Array                (                    [0] => 1                    [1] =>                     [2] => sslserver                )            [3] => Array                (                    [0] => 1                    [1] =>                     [2] => nssslserver                )            [4] => Array                (                    [0] =>                     [1] =>                     [2] => smimesign                )            [5] => Array                (                    [0] =>                     [1] =>                     [2] => smimeencrypt                )            [6] => Array                (                    [0] => 1                    [1] =>                     [2] => crlsign                )            [7] => Array                (                    [0] => 1                    [1] => 1                    [2] => any                )            [8] => Array                (                    [0] => 1                    [1] =>                     [2] => ocsphelper                )        )    [extensions] => Array        (            [extendedKeyUsage] => TLS Web Server Authentication, TLS Web Client Authentication            [subjectAltName] => DNS:www.google.com            [authorityInfoAccess] => CA Issuers - URI:http://pki.google.com/GIAG2.crtOCSP - URI:http://clients1.google.com/ocsp            [subjectKeyIdentifier] => FD:1B:28:50:FD:58:F2:8C:12:26:D7:80:E4:94:E7:CD:BA:A2:6A:45            [basicConstraints] => CA:FALSE            [authorityKeyIdentifier] => keyid:4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F            [certificatePolicies] => Policy: 1.3.6.1.4.1.11129.2.5.1            [crlDistributionPoints] => URI:http://pki.google.com/GIAG2.crl        ))


No. EDIT: A CURLINFO_CERTINFO option has been added to PHP 5.3.2. See http://bugs.php.net/49253

Apparently, that information is being given to you by your proxy in the response headers. If you want to rely on that, you can use curl's CURLOPT_HEADER option to trueto include the headers in the output.

However, to retrieve the certificate without relying on some proxy, you must do

<?php$g = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));$r = fopen("https://www.google.com/", "rb", false, $g);$cont = stream_context_get_params($r);var_dump($cont["options"]["ssl"]["peer_certificate"]);

You can manipulate the value of $cont["options"]["ssl"]["peer_certificate"] with the OpenSSL extension.

EDIT: This option is better since it doesn't actually make the HTTP request and does not require allow_url_fopen:

<?php$g = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));$r = stream_socket_client("ssl://www.google.com:443", $errno, $errstr, 30,    STREAM_CLIENT_CONNECT, $g);$cont = stream_context_get_params($r);var_dump($cont["options"]["ssl"]["peer_certificate"]);


To do this in php and curl:

<?phpif($fp = tmpfile()){    $ch = curl_init();    curl_setopt($ch, CURLOPT_URL,"https://www.digicert.com/");    curl_setopt($ch, CURLOPT_STDERR, $fp);    curl_setopt($ch, CURLOPT_CERTINFO, 1);    curl_setopt($ch, CURLOPT_VERBOSE, 1);    curl_setopt($ch, CURLOPT_HEADER, 1);    curl_setopt($ch, CURLOPT_NOBODY, 1);    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);    $result = curl_exec($ch);    curl_errno($ch)==0 or die("Error:".curl_errno($ch)." ".curl_error($ch));    fseek($fp, 0);//rewind    $str='';    while(strlen($str.=fread($fp,8192))==8192);    echo $str;    fclose($fp);}?>