[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
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 blocklisted 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Mar 8 01:00:04 2021 | Cross-referenced by PHPXref 0.7.1 |