Пример #1
0
 /**
  * Verifies the received SSL certificate against it's Common Names and subjectAltName fields
  *
  * PHP's SSL verifications only verify that it's a valid Certificate, it doesn't verify if
  * the certificate is valid for the hostname which was requested.
  * This function verifies the requested hostname against certificate's subjectAltName field,
  * if that is empty, or contains no DNS entries, a fallback to the Common Name field is used.
  *
  * IP Address support is included if the request is being made to an IP address.
  *
  * @since 3.7.0
  * @static
  *
  * @param stream $stream The PHP Stream which the SSL request is being made over
  * @param string $host The hostname being requested
  * @return bool If the cerficiate presented in $stream is valid for $host
  */
 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 = WP_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 ('ip' == $host_type) {
         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);
 }