[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/Requests/ -> SSL.php (source)

   1  <?php
   2  /**
   3   * SSL utilities for Requests
   4   *
   5   * @package Requests
   6   * @subpackage Utilities
   7   */
   8  
   9  /**
  10   * SSL utilities for Requests
  11   *
  12   * Collection of utilities for working with and verifying SSL certificates.
  13   *
  14   * @package Requests
  15   * @subpackage Utilities
  16   */
  17  class Requests_SSL {
  18      /**
  19       * Verify the certificate against common name and subject alternative names
  20       *
  21       * Unfortunately, PHP doesn't check the certificate against the alternative
  22       * names, leading things like 'https://www.github.com/' to be invalid.
  23       * Instead
  24       *
  25       * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
  26       *
  27       * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
  28       * @param string $host Host name to verify against
  29       * @param array $cert Certificate data from openssl_x509_parse()
  30       * @return bool
  31       */
  32  	public static function verify_certificate($host, $cert) {
  33          // Calculate the valid wildcard match if the host is not an IP address
  34          $parts = explode('.', $host);
  35          if (ip2long($host) === false) {
  36              $parts[0] = '*';
  37          }
  38          $wildcard = implode('.', $parts);
  39  
  40          $has_dns_alt = false;
  41  
  42          // Check the subjectAltName
  43          if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
  44              $altnames = explode(',', $cert['extensions']['subjectAltName']);
  45              foreach ($altnames as $altname) {
  46                  $altname = trim($altname);
  47                  if (strpos($altname, 'DNS:') !== 0) {
  48                      continue;
  49                  }
  50  
  51                  $has_dns_alt = true;
  52  
  53                  // Strip the 'DNS:' prefix and trim whitespace
  54                  $altname = trim(substr($altname, 4));
  55  
  56                  // Check for a match
  57                  if (self::match_domain($host, $altname) === true) {
  58                      return true;
  59                  }
  60              }
  61          }
  62  
  63          // Fall back to checking the common name if we didn't get any dNSName
  64          // alt names, as per RFC2818
  65          if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
  66              // Check for a match
  67              if (self::match_domain($host, $cert['subject']['CN']) === true) {
  68                  return true;
  69              }
  70          }
  71  
  72          return false;
  73      }
  74  
  75      /**
  76       * Verify that a reference name is valid
  77       *
  78       * Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
  79       * - Wildcards can only occur in a name with more than 3 components
  80       * - Wildcards can only occur as the last character in the first
  81       *   component
  82       * - Wildcards may be preceded by additional characters
  83       *
  84       * We modify these rules to be a bit stricter and only allow the wildcard
  85       * character to be the full first component; that is, with the exclusion of
  86       * the third rule.
  87       *
  88       * @param string $reference Reference dNSName
  89       * @return boolean Is the name valid?
  90       */
  91  	public static function verify_reference_name($reference) {
  92          $parts = explode('.', $reference);
  93  
  94          // Check the first part of the name
  95          $first = array_shift($parts);
  96  
  97          if (strpos($first, '*') !== false) {
  98              // Check that the wildcard is the full part
  99              if ($first !== '*') {
 100                  return false;
 101              }
 102  
 103              // Check that we have at least 3 components (including first)
 104              if (count($parts) < 2) {
 105                  return false;
 106              }
 107          }
 108  
 109          // Check the remaining parts
 110          foreach ($parts as $part) {
 111              if (strpos($part, '*') !== false) {
 112                  return false;
 113              }
 114          }
 115  
 116          // Nothing found, verified!
 117          return true;
 118      }
 119  
 120      /**
 121       * Match a hostname against a dNSName reference
 122       *
 123       * @param string $host Requested host
 124       * @param string $reference dNSName to match against
 125       * @return boolean Does the domain match?
 126       */
 127  	public static function match_domain($host, $reference) {
 128          // Check if the reference is blacklisted first
 129          if (self::verify_reference_name($reference) !== true) {
 130              return false;
 131          }
 132  
 133          // Check for a direct match
 134          if ($host === $reference) {
 135              return true;
 136          }
 137  
 138          // Calculate the valid wildcard match if the host is not an IP address
 139          // Also validates that the host has 3 parts or more, as per Firefox's
 140          // ruleset.
 141          if (ip2long($host) === false) {
 142              $parts = explode('.', $host);
 143              $parts[0] = '*';
 144              $wildcard = implode('.', $parts);
 145              if ($wildcard === $reference) {
 146                  return true;
 147              }
 148          }
 149  
 150          return false;
 151      }
 152  }


Generated: Tue Sep 17 01:00:03 2019 Cross-referenced by PHPXref 0.7.1