Here is a simple PHP script that opens an SSL socket ready to send HTTP requests:
$contextOptions = array(); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); exit; } var_dump($socket); exit('Socket created.');
This works - I've just tested it - but there is no validation against a trusted CA store.
We can modify that script to use PHP's SSL Context options:
$contextOptions = array( 'ssl' => array( 'cafile' => 'C:\xampp\cacerts.pem', 'CN_match' => '*.google.com', // CN_match will only be checked if 'verify_peer' is set to TRUE. See https://bugs.php.net/bug.php?id=47030. 'verify_peer' => TRUE, ) ); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); exit; } var_dump($socket); exit('Socket created.');
As long as the 'cafile' exists and has the correct CA then this example also works...
...but how can we do this without hard-coding a CA filename/filepath? We're trying to create something that verifies SSL certificates OS-independently without requiring separate configuration for each server that runs this script.
I know Linux has a directory for CAs that we could put as the 'capath'. What about Windows? Where does it store its trusted CAs? I searched and these unfortunately seemed to be in the registry, so is there no way we can access them from PHP? What about other OSs?