Title: WP_Http_Streams::verify_ssl_certificate
Published: April 25, 2014
Last modified: April 28, 2025

---

# WP_Http_Streams::verify_ssl_certificate( resource $stream, string $host ): bool

## In this article

 * [Description](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#wp--skip-link--target)

Verifies the received SSL certificate against its Common Names and subjectAltName
fields.

## 󠀁[Description](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#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](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#parameters)󠁿

 `$stream`resourcerequired

The PHP Stream which the SSL request is being made over

`$host`stringrequired

The hostname being requested

## 󠀁[Return](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#return)󠁿

 bool If the certificate presented in $stream is valid for $host

## 󠀁[Source](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#source)󠁿

    ```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 ( 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 );
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/class-wp-http-streams.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/class-wp-http-streams.php#L433)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/class-wp-http-streams.php#L433-L484)

## 󠀁[Related](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#related)󠁿

| Uses | Description | 
| [WP_Http::is_ip_address()](https://developer.wordpress.org/reference/classes/wp_http/is_ip_address/)`wp-includes/class-wp-http.php` |

Determines if a specified string represents an IP address or not.

  |

| Used by | Description | 
| [WP_Http_Streams::request()](https://developer.wordpress.org/reference/classes/wp_http_streams/request/)`wp-includes/class-wp-http-streams.php` |

Send a HTTP request to a URI using PHP Streams.

  |

## 󠀁[Changelog](https://developer.wordpress.org/reference/classes/wp_http_streams/verify_ssl_certificate/?output_format=md#changelog)󠁿

| Version | Description | 
| [3.7.0](https://developer.wordpress.org/reference/since/3.7.0/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Fclasses%2Fwp_http_streams%2Fverify_ssl_certificate%2F)
before being able to contribute a note or feedback.