Commit:    8915c3fb4fa40743bdddf23013a63e014d03d02c
Author:    Tjerk Meesters <tj...@muvee.com>         Sat, 21 Sep 2013 16:45:20 
+0800
Parents:   9e3bedcd73265acb3d190c894860bd9aa1015121
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=8915c3fb4fa40743bdddf23013a63e014d03d02c

Log:
added better wildcard matching for CN

Changed paths:
  M  ext/openssl/openssl.c
  A  ext/openssl/tests/bug65729.pem
  A  ext/openssl/tests/bug65729.phpt


Diff:
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 4aac4e3..5460f3a 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -4829,6 +4829,30 @@ static int verify_callback(int preverify_ok, 
X509_STORE_CTX *ctx) /* {{{ */
 }
 /* }}} */
 
+static int php_openssl_match_cn(const char *subjectname, const char *certname)
+{
+       int match = strcmp(subjectname, certname) == 0;
+
+       if (!match) {
+               char *wildcard = strchr(certname, '*');
+               int prefix_len = wildcard - certname;
+
+               /* 1) prefix, if not empty, must match */
+               if (wildcard && (prefix_len == 0 || strncmp(subjectname, 
certname, prefix_len) == 0)) {
+                       const char *suffix = subjectname + strlen(subjectname) 
- strlen(wildcard + 1);
+
+                       /*
+                        * 2) suffix must match
+                        * 3) no period between prefix and suffix
+                       **/
+                       match = strcmp(wildcard + 1, suffix) == 0 &&
+                               memchr(subjectname + prefix_len, '.', suffix - 
subjectname - prefix_len) == NULL;
+               }
+       }
+
+       return match;
+}
+
 int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream 
*stream TSRMLS_DC) /* {{{ */
 {
        zval **val = NULL;
@@ -4881,16 +4905,7 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 
*peer, php_stream *stre
                        return FAILURE;
                }
 
-               match = strcmp(cnmatch, buf) == 0;
-               if (!match && strlen(buf) > 3 && buf[0] == '*' && buf[1] == 
'.') {
-                       /* Try wildcard */
-
-                       if (strchr(buf+2, '.')) {
-                               char *tmp = strstr(cnmatch, buf+1);
-
-                               match = tmp && strcmp(tmp, buf+2) && tmp == 
strchr(cnmatch, '.');
-                       }
-               }
+               match = php_openssl_match_cn(cnmatch, buf);
 
                if (!match) {
                        /* didn't match */
diff --git a/ext/openssl/tests/bug65729.pem b/ext/openssl/tests/bug65729.pem
new file mode 100644
index 0000000..dbeed6e
--- /dev/null
+++ b/ext/openssl/tests/bug65729.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIICCTCCAXICCQDNMI29sowT7TANBgkqhkiG9w0BAQUFADBJMQswCQYDVQQGEwJT
+RzESMBAGA1UECBMJVGVzdHZpbGxlMREwDwYDVQQKEwhkYXRpYmJhdzETMBEGA1UE
+AxQKKi50ZXN0LmNvbTAeFw0xMzA5MjEwNzUyMjRaFw0xNDA5MjEwNzUyMjRaMEkx
+CzAJBgNVBAYTAlNHMRIwEAYDVQQIEwlUZXN0dmlsbGUxETAPBgNVBAoTCGRhdGli
+YmF3MRMwEQYDVQQDFAoqLnRlc3QuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
+iQKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK03oAd1jTe
+Vd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOXZPG3UViD
+rtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQABMA0GCSqG
+SIb3DQEBBQUAA4GBAAS07u/Ke+EhEHidz6CG3Qcr+zg483JKRgZFyGz+YUKyyKKy
+fmLs7JieGJxYQjOmIpj/6X9Gnb2HjIPDnI6A+MV1emXDTnnmsgf2/lZGcthhpZn2
+rMbj9bI0iH6HwOVGtp4ZJA5fB7nj3J+gWNTCQzDDOxwX36d2LL9ua+UMnk/g
+-----END CERTIFICATE-----
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCdzVnic8K5W4SVbwVuqezcTjeqVLoQ91vVNZB0Jnsuz6q3DoK0
+3oAd1jTeVd0k+MQDbXpHoc37lA4+8z/g5Bs0UXxNx+nkbFTE7Ba2/G24caI9/cOX
+ZPG3UViDrtqXKL6h5/umqRG9Dt5liF2MVP9XFAesVC7B8+Ca+PbPlQoYzwIDAQAB
+AoGAeyzTwKPDl5QMRejHQL57GOwlH1vLcXrjv+VzwHZZKQ0IoKM++5fCQYf29KXp
+XPahaluGW2u9sWa8R/7wGcd0Q4RtquGzsgT3+AQsIc5KfIamyOyDaRVM/ymX3fWg
+gHIU7OOzB+ihOU8sHyRIwfbk01/kmrBXLRj8E31sy3i3PIECQQDQQYE+aN7Acrdt
+yN5CaqvbkiCGjRvASlemiTzPosgOtndyp21w1gakJwKYhYDk1N6A6Qb8REMZqM/U
+wFypldV/AkEAwfq6NFuhpGL6hDA7MvlyY1KiZ0cHetPUX+PgdNqy2DA+1Sv4i7gm
+Wd/uA651K7aPXuUaf9dKtPCmZwI4M6SEsQJBALW89HTqP7niYoDEEnITdPaghxHk
+gptERUln6lGo1L1CLus3gSI/JHyMLo+7scgAnEwTD62GRKhX0Ubwt+ymfTECQAY5
+fHYnppU20+EgBxZIqOIFCc8UmWnYmE0Ha/Fz/x8u1SVUBuK84wYpSGL32yyu7ATY
+hzQo/W229zABAzqtAdECQQCUdB7IBFpPnsfv/EUBFX7X/7zAc9JpACmu9It5ju8C
+KIsMuz/02D+TQoJNjdAngBM+4AJDIaGFgTMIfaDMh5L7
+-----END RSA PRIVATE KEY-----
diff --git a/ext/openssl/tests/bug65729.phpt b/ext/openssl/tests/bug65729.phpt
new file mode 100644
index 0000000..d4645d9
--- /dev/null
+++ b/ext/openssl/tests/bug65729.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Bug #65729: CN_match gives false positive when wildcard is used
+--SKIPIF--
+<?php 
+if (!extension_loaded("openssl")) die("skip");
+if (!function_exists('pcntl_fork')) die("skip no fork");
+--FILE--
+<?php
+$context = stream_context_create();
+
+stream_context_set_option($context, 'ssl', 'local_cert', __DIR__ . 
"/bug65729.pem");
+stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
+$server = stream_socket_server('ssl://127.0.0.1:64321', $errno, $errstr,
+       STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);
+
+$pid = pcntl_fork();
+if ($pid == -1) {
+       die('could not fork');
+} else if ($pid) {
+       $contextC = stream_context_create(
+               array(
+                       'ssl' => array(
+                               'verify_peer'           => true,
+                               'allow_self_signed'     => true,
+                               'CN_match'              => 'foo.test.com.sg',
+                       )
+               )
+       );
+       var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 
1,
+               STREAM_CLIENT_CONNECT, $contextC));
+} else {       
+       @pcntl_wait($status);
+       @stream_socket_accept($server, 1);
+}
+--EXPECTF--
+Warning: stream_socket_client(): Peer certificate CN=`*.test.com' did not 
match expected CN=`foo.test.com.sg' in %s on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
+
+Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 
(Unknown error) in %s on line %d
+bool(false)
+


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to