Description:
------------
When trying to capture the server certificate of an TLS socket connection using the stream_socket_client API no certificate is captured. If connecting to the same host via SSL transport everything works fine. The remote server is known to support TLSv1 properly.
Reproduce code:
---------------
<?php $mode = "tls";
$site_cert = NULL;
$context = stream_context_create();
$result = stream_context_set_option($context, $mode, 'verify_host', true);
$result = stream_context_set_option($context, $mode, 'capture_peer_cert', true);
if ($fp = stream_socket_client("$mode://ssl.example.de:443/", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context)) {
if ($options = stream_context_get_options($context)) {
var_dump($options);
if (isset($options[$mode]) && isset($options[$mode]['peer_certificate'])) {
$site_cert = $options[$mode]['peer_certificate'];
}
}
fclose($fp);
}
if ($site_cert) {
openssl_x509_export($site_cert, $str_cert);
$pubkey = openssl_pkey_get_public($str_cert);
$keyinfo = openssl_pkey_get_details($pubkey);
var_dump($keyinfo);
}
Expected result:
----------------
The first var_dump should contain a resource for the peer_certificate, both when $mode='ssl' AND $mode='tls'. The second dump should include the PEM-encoded public key of the server as well as some info on the key.
Actual result:
--------------
When $mode is set to 'tls' the 'peer_certificate' index in the first dump is missing and no second dump is written. When $mode='ssl' everything works as expected.