WP_Http_Streams::verify_ssl_certificate( stream $stream, string $host )
Verifies the received SSL certificate against its Common Names and subjectAltName fields.
Description Description
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.
Parameters Parameters
- $stream
-
(stream) (Required) The PHP Stream which the SSL request is being made over
- $host
-
(string) (Required) The hostname being requested
Return Return
(bool) If the cerficiate presented in $stream is valid for $host
Source Source
File: wp-includes/class-wp-http-streams.php
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 ); }
Expand full source code Collapse full source code View on Trac
Changelog Changelog
Version | Description |
---|---|
3.7.0 | Introduced. |