2010-06-20 3 views
20

J'aimerais pouvoir lire les informations du certificat SSL avec CURL. A partir de la console Linux je reçois cet en-tête de réponse:Comment obtenir des informations de certificat SSL avec CURL en PHP?

GET https://www.google.com/ -ed 
Cache-Control: private, max-age=0 
Connection: close 
Date: Sun, 20 Jun 2010 21:34:12 GMT 
Server: gws 
Content-Type: text/html; charset=ISO-8859-1 
Expires: -1 
Client-Date: Sun, 20 Jun 2010 21:34:18 GMT 
Client-Peer: 66.102.13.106:443 
Client-Response-Num: 1 
Client-SSL-Cert-Issuer: /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA 
Client-SSL-Cert-Subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com 
Client-SSL-Cipher: RC4-SHA 
Client-SSL-Warning: Peer certificate not verified 
Set-Cookie: PREF=ID=4d56960f6e3ad831:TM=1277069652:LM=1277069652:S=GF-w8Yc-_61NBzzJ; expires=Tue, 19-Jun-2012 21:34:12 GMT; path=/; domain=.google.com 
Title: Google 
X-XSS-Protection: 1; mode=block 

Mais avec CURL l'en-tête est beaucoup plus courte:

HTTP/1.1 200 OK 
Date: Sun, 20 Jun 2010 21:39:07 GMT 
Expires: -1 
Cache-Control: private, max-age=0 
Content-Type: text/html; charset=UTF-8 
Set-Cookie: PREF=ID=2d4fb1c933eebd09:TM=1277069947:LM=1277069947:S=6_TgGKzD0rM4IWms; expires=Tue, 19-Jun-2012 21:39:07 GMT; path=/; domain=.google.com 
Server: gws 
X-XSS-Protection: 1; mode=block 
Transfer-Encoding: chunked 

Est-il possible d'obtenir ces informations, l'en-tête complète avec CURL ou une autre fonction PHP?

Répondre

17

n ° EDIT: Une option CURLINFO_CERTINFO a été ajoutée à PHP 5.3.2. Voir http://bugs.php.net/49253

Apparemment, cette information vous est donnée par votre mandataire dans les en-têtes de réponse. Si vous voulez vous en servir, vous pouvez utiliser CURLOPT_HEADER option à true pour inclure les en-têtes dans la sortie.

Cependant, pour récupérer le certificat sans compter sur une procuration, vous devez faire

<?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"]); 

Vous pouvez manipuler la valeur de $cont["options"]["ssl"]["peer_certificate"] avec l'extension OpenSSL.

EDIT: Cette option est préférable car il ne fait pas réellement la requête HTTP et ne nécessite pas 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"]); 
+0

Donc, j'aurai besoin de la directive "allow_url_fopen" pour obtenir les informations du certificat? –

+0

BTW: Pourquoi pensez-vous que cette connexion passe par un serveur proxy? Le curseur CURLOPT_HEADER a été défini. Mais l'en-tête ne semble pas être complet –

+0

@Radek Suski Parce que google n'envoie pas de tels en-têtes 'Client- *'. – Artefacto

13

Pour ce faire en php et boucle:

 
<?php 
if($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); 
} 
?> 
+0

Etes-vous sûr de lire ma question et toutes ces réponses? –

+2

Mon exemple nécessite PHP 5.3.2, et les informations de cert SSL sont disponibles dans $ str, les en-têtes HTTP sont disponibles dans $ result. – velcrow

+0

C'est la solution dont j'avais besoin pour vérifier non seulement si le certificat SSL existe mais aussi s'il a des erreurs ou non. Merci! – armandbertea

17

Vous obtiendrez le certificat en tant que ressource en utilisant stream_context_get_params. Branchez cette ressource sur $certinfo = openssl_x509_parse($cert['options']['ssl']['peer_certificate']); pour obtenir plus d'informations sur le certificat.

$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); 

Exemple de résultat

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.crt 
OCSP - 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 

     ) 

) 
+2

Ceci est une meilleure réponse que la réponse acceptée manquait la ligne de clé '$ certinfo = openssl_x509_parse ($ cert ['options'] ['ssl'] ['peer_certificate']);' dont j'avais besoin pour vérifier les différents détails de mon Cert –

+0

C'est la solution dont j'avais besoin, mais avec un petit changement. Je vais l'utiliser pour vérifier la période de validité de cert sur localhost (donc le CERT n'est pas valide pour ce "domaine"), donc je devais changer: '$ get = stream_context_create (array (" ssl "=> array (" capture_peer_cert "=> TRUE)));' à '$ get = stream_context_create (array (" ssl "=> array (" capture_peer_cert "=> VRAI," verify_peer_name "=> FALSE)));' – Whatts

0

Cet extrait de code n'utilise pas boucle spécifiquement, mais il récupère et imprime le texte du certificat à distance (peut être manipulé pour retourner tout détail que vous voulez utiliser les différentes fonctions openssl_)

$g = stream_context_create (array("ssl" => array("capture_peer_cert" => true))); 
$r = fopen("https://somesite/my/path/", "rb", false, $g); 
$cont = stream_context_get_params($r); 
openssl_x509_export($cont["options"]["ssl"]["peer_certificate"],$cert); 
print $cert; 

sorties:

-----BEGIN CERTIFICATE----- 
...certificate content... 
-----END CERTIFICATE-----