Requests_SSL

SSL utilities for Requests.

Defined (1)

The class is defined in the following location(s).

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