/** * NV_http_streams::verify_ssl_certificate() * * @param mixed $stream * @param mixed $host * @return */ public static function verify_ssl_certificate($stream, $host) { $context_options = stream_context_get_options($stream); if (empty($context_options['ssl']['peer_certificate'])) { return false; } $cert = openssl_x509_parse($context_options['ssl']['peer_certificate']); if (!$cert) { return false; } // If the request is being made to an IP address, we'll validate against IP fields in the cert (if they exist) $host_type = NV_Http::is_ip_address($host) ? 'ip' : 'dns'; $certificate_hostnames = array(); if (!empty($cert['extensions']['subjectAltName'])) { $match_against = preg_split('/,\\s*/', $cert['extensions']['subjectAltName']); foreach ($match_against as $match) { list($match_type, $match_host) = explode(':', $match); if ($host_type == strtolower(trim($match_type))) { // IP: or DNS: $certificate_hostnames[] = strtolower(trim($match_host)); } } } elseif (!empty($cert['subject']['CN'])) { // Only use the CN when the certificate includes no subjectAltName extension $certificate_hostnames[] = strtolower($cert['subject']['CN']); } // Exact hostname/IP matches if (in_array(strtolower($host), $certificate_hostnames)) { return true; } // IP's can't be wildcards, Stop processing if ($host_type == 'ip') { return false; } // Test to see if the domain is at least 2 deep for wildcard support if (substr_count($host, '.') < 2) { return false; } // Wildcard subdomains certs (*.example.com) are valid for a.example.com but not a.b.example.com $wildcard_host = preg_replace('/^[^.]+\\./', '*.', $host); return in_array(strtolower($wildcard_host), $certificate_hostnames); }