Verifying SSL certificates with drupal_http_request
Recently I was posed with the question about verifying self-signed SSL certificates with drupal_http_request(). The usecase here would be to use private APIs to surface information, secured with SSL, yet using an internally created certificate.
By default, drupal_http_request() does not verify the SSL certificate of sites it connects to; unlike command line tools such as curl. To have an extra layer of oversight, this may be undesirable, however because we're working with Drupal, we have the flexibility to alter this.
The following comment in common.inc provides us with a clue about how certificates may be checked.
// Create a stream with context. Allows verification of a SSL certificate.
The use of stream_socket_client() is key here, as it allows the modification of the stream context to pass in the expected certificate. We concatenate the private key, public key and any CA keys (unlikely if self-signed) to form a single pem file to use for verification. Then, we pass the location of this file into the context for drupal_http_request() and only receive information back if the certificates match.
$cert = '/home/website/ssl/example_com.pem';
$context = stream_context_create(array('ssl' => array('local_cert' => $cert, 'verify_peer' => true, 'verify_depth' => 5, 'allow_self_signed' => true)));
$request = drupal_http_request('https://example.com/', array('context' => $context));
Further reading on setting correct SSL contexts may be found on php.net.