Asked  7 Months ago    Answers:  5   Viewed   48 times

I would like to be able to read the SSL certificate information with CURL. From the Linux console I get this response header:

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

But with CURL the header is much shorter:

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

Is there any possibility to get these information, the full header with CURL or with some other PHP function?

 Answers

33

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"]);
Wednesday, March 31, 2021
 
eek
answered 7 Months ago
eek
66

That's an interesting problem.

If you query SSLLabs for this site you will see, that it only supports various ECDHE-ECDSA-* ciphers and no other ciphers. But, in the version history of curl you will find a bug with ECC ciphers and the NSS library (which you use) which is only fixed in curl version 7.36 "nss: allow to use ECC ciphers if NSS implements them".

Since you are using curl 7.19.7 your curl is too old to use the necessary ciphers together with the NSS library. This means you need to upgrade your curl library.

Wednesday, March 31, 2021
 
mozlima
answered 7 Months ago
67

The current CA Cert extracts provided by cURL contain the GeoTrust Global CA certificate authority which signed Google's CA cert which in turn signs YouTube's cert, so you should have no problem using the file you have.

Based on the last error, it looks like the problem is because you were missing the / after C:. The message error setting certificate verify locations means that it couldn't open or read the file specified by curl.cainfo so it's not finding any certs at all.

If you change C:php/ext/cacert.pem to C:/php/ext/cacert.pem it should be able to read the CA file correctly and then verify the site properly.

Wednesday, March 31, 2021
 
samayo
answered 7 Months ago
11

Identify or detect the character encoding and convert the data to UTF-8 if necessary.

For HTML (i.e. text/html) there are three ways to specify the character encoding:

  1. An HTTP "charset" parameter in a "Content-Type" field.
  2. A META declaration with "http-equiv" set to "Content-Type" and a value set for "charset".
  3. The charset attribute set on an element that designates an external resource.

If neither of these is present, you might do some content sniffing or switch to some default character encoding (e.g. ISO 8859-1).

If the identified/detected character encoding is not UTF-8, you then can convert the data to UTF-8 with iconv or mb_convert_encoding.

Saturday, May 29, 2021
 
superfell
answered 5 Months ago
74

How to parse the expiration date from the certificate

Cast it to an X509Certificate and call getNotAfter().

How to determine the certificate chain, eg, the github certificate with chains

You've got it. That's what the Certificate[] array is, as it says in the Javadoc.

How did i know which certificate to get the expiration date from?

Read the Javadoc. "The peer's own certificate first followed by any certificate authorities".

However I don't know why you're doing any of this. Java should already do it all for you.

And please throw away that insecure and incorrect TrustManager implementation. The correct way to handle self-signed certificates is to import them into the client truststore. Please also throw away your insecure HostnameVerifier, and use the default one, or a secure one. Why use HTTPS at all if you don't want it to be secure?

Sunday, August 1, 2021
 
dream_variable
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share