SSL.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. <?php
  2. class RequestsTest_SSL extends PHPUnit_Framework_TestCase {
  3. public static function domainMatchProvider() {
  4. return array(
  5. array('example.com', 'example.com'),
  6. array('test.example.com', 'test.example.com'),
  7. array('test.example.com', '*.example.com'),
  8. );
  9. }
  10. public static function domainNoMatchProvider() {
  11. return array(
  12. // Check that we need at least 3 components
  13. array('com', '*'),
  14. array('example.com', '*.com'),
  15. // Check that double wildcards don't work
  16. array('abc.def.example.com', '*.*.example.com'),
  17. // Check that we only match with the correct number of components
  18. array('abc.def.example.com', 'def.example.com'),
  19. array('abc.def.example.com', '*.example.com'),
  20. // Check that the wildcard only works as the full first component
  21. array('abc.def.example.com', 'a*.def.example.com'),
  22. // Check that wildcards are not allowed for IPs
  23. array('192.168.0.1', '*.168.0.1'),
  24. array('192.168.0.1', '192.168.0.*'),
  25. );
  26. }
  27. /**
  28. * @dataProvider domainMatchProvider
  29. */
  30. public function testMatch($base, $dnsname) {
  31. $this->assertTrue(Requests_SSL::match_domain($base, $dnsname));
  32. }
  33. /**
  34. * @dataProvider domainNoMatchProvider
  35. */
  36. public function testNoMatch($base, $dnsname) {
  37. $this->assertFalse(Requests_SSL::match_domain($base, $dnsname));
  38. }
  39. protected function fakeCertificate($dnsname, $with_san = true) {
  40. $certificate = array(
  41. 'subject' => array(
  42. 'CN' => $dnsname
  43. ),
  44. );
  45. if ($with_san !== false) {
  46. // If SAN is set to true, default it to the dNSName
  47. if ($with_san === true) {
  48. $with_san = $dnsname;
  49. }
  50. $certificate['extensions'] = array(
  51. 'subjectAltName' => 'DNS: ' . $with_san,
  52. );
  53. }
  54. return $certificate;
  55. }
  56. /**
  57. * @dataProvider domainMatchProvider
  58. */
  59. public function testMatchViaCertificate($base, $dnsname) {
  60. $certificate = $this->fakeCertificate($dnsname);
  61. $this->assertTrue(Requests_SSL::verify_certificate($base, $certificate));
  62. }
  63. /**
  64. * @dataProvider domainNoMatchProvider
  65. */
  66. public function testNoMatchViaCertificate($base, $dnsname) {
  67. $certificate = $this->fakeCertificate($dnsname);
  68. $this->assertFalse(Requests_SSL::verify_certificate($base, $certificate));
  69. }
  70. public function testCNFallback() {
  71. $certificate = $this->fakeCertificate('example.com', false);
  72. $this->assertTrue(Requests_SSL::verify_certificate('example.com', $certificate));
  73. }
  74. public function testInvalidCNFallback() {
  75. $certificate = $this->fakeCertificate('example.com', false);
  76. $this->assertFalse(Requests_SSL::verify_certificate('example.net', $certificate));
  77. }
  78. /**
  79. * Test a certificate with both CN and SAN fields
  80. *
  81. * As per RFC2818, if the SAN field exists, we should parse that and ignore
  82. * the value of the CN field.
  83. *
  84. * @link http://tools.ietf.org/html/rfc2818#section-3.1
  85. */
  86. public function testIgnoreCNWithSAN() {
  87. $certificate = $this->fakeCertificate('example.net', 'example.com');
  88. $this->assertTrue(Requests_SSL::verify_certificate('example.com', $certificate), 'Checking SAN validation');
  89. $this->assertFalse(Requests_SSL::verify_certificate('example.net', $certificate), 'Checking CN non-validation');
  90. }
  91. }