Overview

Packages

  • Requests
    • Authentication
    • Cookies
    • Proxy
    • Session
    • Transport
    • Utilities

Classes

  • Requests
  • Requests_Auth_Basic
  • Requests_Cookie
  • Requests_Cookie_Jar
  • Requests_Hooks
  • Requests_IDNAEncoder
  • Requests_IPv6
  • Requests_IRI
  • Requests_Proxy_HTTP
  • Requests_Response
  • Requests_Response_Headers
  • Requests_Session
  • Requests_SSL
  • Requests_Transport_cURL
  • Requests_Transport_fsockopen
  • Requests_Utility_CaseInsensitiveDictionary
  • Requests_Utility_FilteredIterator

Interfaces

  • Requests_Auth
  • Requests_Hooker
  • Requests_Proxy
  • Requests_Transport

Exceptions

  • Requests_Exception
  • Requests_Exception_HTTP
  • Requests_Exception_HTTP_304
  • Requests_Exception_HTTP_305
  • Requests_Exception_HTTP_306
  • Requests_Exception_HTTP_400
  • Requests_Exception_HTTP_401
  • Requests_Exception_HTTP_402
  • Requests_Exception_HTTP_403
  • Requests_Exception_HTTP_404
  • Requests_Exception_HTTP_405
  • Requests_Exception_HTTP_406
  • Requests_Exception_HTTP_407
  • Requests_Exception_HTTP_408
  • Requests_Exception_HTTP_409
  • Requests_Exception_HTTP_410
  • Requests_Exception_HTTP_411
  • Requests_Exception_HTTP_412
  • Requests_Exception_HTTP_413
  • Requests_Exception_HTTP_414
  • Requests_Exception_HTTP_415
  • Requests_Exception_HTTP_416
  • Requests_Exception_HTTP_417
  • Requests_Exception_HTTP_418
  • Requests_Exception_HTTP_428
  • Requests_Exception_HTTP_429
  • Requests_Exception_HTTP_431
  • Requests_Exception_HTTP_500
  • Requests_Exception_HTTP_501
  • Requests_Exception_HTTP_502
  • Requests_Exception_HTTP_503
  • Requests_Exception_HTTP_504
  • Requests_Exception_HTTP_505
  • Requests_Exception_HTTP_511
  • Requests_Exception_HTTP_Unknown
  • Requests_Exception_Transport
  • Requests_Exception_Transport_cURL
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated

Warning! You are currently reading the documentation for Requests 1.x.

It is recommended to upgrade to Requests 2.x at your earliest convenience. Upgrading to Requests 2.x is fairly straight-forward.
A full list of the changes can be found in the Changelog.

Visit the Requests 2.x documentation.

  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 
<?php
/**
 * SSL utilities for Requests
 *
 * @package Requests
 * @subpackage Utilities
 */

/**
 * SSL utilities for Requests
 *
 * Collection of utilities for working with and verifying SSL certificates.
 *
 * @package Requests
 * @subpackage Utilities
 */
class Requests_SSL {
    /**
     * Verify the certificate against common name and subject alternative names
     *
     * Unfortunately, PHP doesn't check the certificate against the alternative
     * names, leading things like 'https://www.github.com/' to be invalid.
     *
     * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
     *
     * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
     * @param string $host Host name to verify against
     * @param array $cert Certificate data from openssl_x509_parse()
     * @return bool
     */
    public static function verify_certificate($host, $cert) {
        $has_dns_alt = false;

        // Check the subjectAltName
        if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
            $altnames = explode(',', $cert['extensions']['subjectAltName']);
            foreach ($altnames as $altname) {
                $altname = trim($altname);
                if (strpos($altname, 'DNS:') !== 0) {
                    continue;
                }

                $has_dns_alt = true;

                // Strip the 'DNS:' prefix and trim whitespace
                $altname = trim(substr($altname, 4));

                // Check for a match
                if (self::match_domain($host, $altname) === true) {
                    return true;
                }
            }
        }

        // Fall back to checking the common name if we didn't get any dNSName
        // alt names, as per RFC2818
        if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
            // Check for a match
            if (self::match_domain($host, $cert['subject']['CN']) === true) {
                return true;
            }
        }

        return false;
    }

    /**
     * Verify that a reference name is valid
     *
     * Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
     * - Wildcards can only occur in a name with more than 3 components
     * - Wildcards can only occur as the last character in the first
     *   component
     * - Wildcards may be preceded by additional characters
     *
     * We modify these rules to be a bit stricter and only allow the wildcard
     * character to be the full first component; that is, with the exclusion of
     * the third rule.
     *
     * @param string $reference Reference dNSName
     * @return boolean Is the name valid?
     */
    public static function verify_reference_name($reference) {
        $parts = explode('.', $reference);

        // Check the first part of the name
        $first = array_shift($parts);

        if (strpos($first, '*') !== false) {
            // Check that the wildcard is the full part
            if ($first !== '*') {
                return false;
            }

            // Check that we have at least 3 components (including first)
            if (count($parts) < 2) {
                return false;
            }
        }

        // Check the remaining parts
        foreach ($parts as $part) {
            if (strpos($part, '*') !== false) {
                return false;
            }
        }

        // Nothing found, verified!
        return true;
    }

    /**
     * Match a hostname against a dNSName reference
     *
     * @param string $host Requested host
     * @param string $reference dNSName to match against
     * @return boolean Does the domain match?
     */
    public static function match_domain($host, $reference) {
        // Check if the reference is blocklisted first
        if (self::verify_reference_name($reference) !== true) {
            return false;
        }

        // Check for a direct match
        if ($host === $reference) {
            return true;
        }

        // Calculate the valid wildcard match if the host is not an IP address
        // Also validates that the host has 3 parts or more, as per Firefox's
        // ruleset.
        if (ip2long($host) === false) {
            $parts    = explode('.', $host);
            $parts[0] = '*';
            $wildcard = implode('.', $parts);
            if ($wildcard === $reference) {
                return true;
            }
        }

        return false;
    }
}
Requests 1.8.1 API Documentation API documentation generated by ApiGen