WP_Http_Streams::verify_ssl_certificate()public staticWP 3.7.0

Verifies the received SSL certificate against its 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.

Method of the class: WP_Http_Streams{}

No Hooks.

Return

true|false. If the certificate presented in $stream is valid for $host

Usage

$result = WP_Http_Streams::verify_ssl_certificate( $stream, $host );
$stream(resource) (required)
The PHP Stream which the SSL request is being made over
$host(string) (required)
The hostname being requested

Changelog

Since 3.7.0 Introduced.

WP_Http_Streams::verify_ssl_certificate() code WP 6.5.2

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 ( strtolower( trim( $match_type ) ) === $host_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, true ) ) {
		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, true );
}