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 true
to 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);}?>