title: PHP and SSL CA Verification - OS Independent
body: <p>Here is a simple PHP script that opens an SSL socket ready to send HTTP requests:</p>
  
  <pre>
  $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.');
  </pre>
  
  <p>This works - I've just tested it - but there is no validation against a trusted CA store.</p>
  
  <p>We can modify that script to use PHP's <a href="http://php.net/manual/en/context.ssl.php">SSL Context options</a>:</p>
  
  <pre>
  $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.');
  </pre>
  
  <p>As long as the 'cafile' exists and has the correct CA then this example also works...</p>
  
  <p>...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.</p>
  
  <p>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?</p>