commit: r1681 - in neon/trunk: src test

joe at manyfish.co.uk joe at manyfish.co.uk
Tue Aug 18 09:12:31 EDT 2009


Author: joe
Date: Tue Aug 18 06:12:29 2009
New Revision: 1681

Added:
   neon/trunk/test/nulca.pem
   neon/trunk/test/nulcn.pem
   neon/trunk/test/nulsan.pem
   neon/trunk/test/nulsrv.key
Modified:
   neon/trunk/src/ne_gnutls.c
   neon/trunk/src/ne_openssl.c
   neon/trunk/src/ne_private.h
   neon/trunk/src/ne_session.c
   neon/trunk/test/ssl.c

Log:
Security fix for CVE-2009-2474, handling of "NUL" bytes in certificate
names:

* src/ne_private.h (ne__ssl_match_hostname): Take cn len, make cn
  const.

* src/ne_session.c (ne__ssl_match_hostname): Drop handling of
  unqualified hostnames; check CN length matches.

* src/ne_gnutls.c (check_identity): Adjust accordingly.

* src/ne_openssl.c (append_dirstring): Use a quoted append for ASCII
  data.  Check for embedded NUL bytes in UTF-8 data.
  (dup_ia5string): Use quoted append.  

* test/ssl.c (struct ssl_server_args): Add key field.
  (ssl_server): Use key field from args.
  (fail_ssl_request_with_error2): Rename from
  fail_ssl_request_with_error, add host, fakehost 
  parameters.
  (fail_ssl_request_with_error): Reimplement using
  fail_ssl_request_with_error2.
  (fail_nul_cn, fail_nul_san, nulcn_identity): New tests.

* test/nulca.pem, test/nulcn.pem, test/nulsan.pem, test/nulsrv.key:
  Add test cases, thanks to Tomas Hoger <thoger redhat.com>.


Modified: neon/trunk/src/ne_gnutls.c
==============================================================================
--- neon/trunk/src/ne_gnutls.c	(original)
+++ neon/trunk/src/ne_gnutls.c	Tue Aug 18 06:12:29 2009
@@ -373,7 +373,7 @@
         case GNUTLS_SAN_DNSNAME:
             name[len] = '\0';
             if (identity && !found) *identity = ne_strdup(name);
-            match = ne__ssl_match_hostname(name, hostname);
+            match = ne__ssl_match_hostname(name, len, hostname);
             found = 1;
             break;
         case GNUTLS_SAN_IPADDRESS: {
@@ -442,7 +442,7 @@
                                                 seq, 0, name, &len);
             if (ret == 0) {
                 if (identity) *identity = ne_strdup(name);
-                match = ne__ssl_match_hostname(name, hostname);
+                match = ne__ssl_match_hostname(name, len, hostname);
             }
         } else {
             return -1;

Modified: neon/trunk/src/ne_openssl.c
==============================================================================
--- neon/trunk/src/ne_openssl.c	(original)
+++ neon/trunk/src/ne_openssl.c	Tue Aug 18 06:12:29 2009
@@ -92,10 +92,16 @@
     int len;
 
     switch (str->type) {
-    case V_ASN1_UTF8STRING:
     case V_ASN1_IA5STRING: /* definitely ASCII */
     case V_ASN1_VISIBLESTRING: /* probably ASCII */
     case V_ASN1_PRINTABLESTRING: /* subset of ASCII */
+        ne_buffer_qappend(buf, str->data, str->length);
+        break;
+    case V_ASN1_UTF8STRING:
+        /* Fail for embedded NUL bytes. */
+        if (strlen((char *)str->data) != (size_t)str->length) {
+            return -1;
+        }
         ne_buffer_append(buf, (char *)str->data, str->length);
         break;
     case V_ASN1_UNIVERSALSTRING:
@@ -103,8 +109,15 @@
     case V_ASN1_BMPSTRING: 
         len = ASN1_STRING_to_UTF8(&tmp, str);
         if (len > 0) {
-            ne_buffer_append(buf, (char *)tmp, len);
-            OPENSSL_free(tmp);
+            /* Fail if there were embedded NUL bytes. */
+            if (strlen((char *)tmp) != (size_t)len) {
+                OPENSSL_free(tmp);
+                return -1;
+            } 
+            else {
+                ne_buffer_append(buf, (char *)tmp, len);
+                OPENSSL_free(tmp);
+            }
             break;
         } else {
             ERR_clear_error();
@@ -119,13 +132,11 @@
     return 0;
 }
 
-/* Returns a malloc-allocate version of IA5 string AS.  Really only
- * here to prevent char * vs unsigned char * type mismatches without
- * losing all hope at type-safety. */
+/* Returns a malloc-allocated version of IA5 string AS, escaped for
+ * safety. */
 static char *dup_ia5string(const ASN1_IA5STRING *as)
 {
-    unsigned char *data = as->data;
-    return ne_strndup((char *)data, as->length);
+    return ne_strnqdup(as->data, as->length);
 }
 
 char *ne_ssl_readable_dname(const ne_ssl_dname *name)
@@ -236,7 +247,7 @@
 	    if (nm->type == GEN_DNS) {
 		char *name = dup_ia5string(nm->d.ia5);
                 if (identity && !found) *identity = ne_strdup(name);
-		match = ne__ssl_match_hostname(name, hostname);
+		match = ne__ssl_match_hostname(name, strlen(name), hostname);
 		ne_free(name);
 		found = 1;
             } 
@@ -320,7 +331,7 @@
             return -1;
         }
         if (identity) *identity = ne_strdup(cname->data);
-        match = ne__ssl_match_hostname(cname->data, hostname);
+        match = ne__ssl_match_hostname(cname->data, cname->used - 1, hostname);
         ne_buffer_destroy(cname);
     }
 

Modified: neon/trunk/src/ne_private.h
==============================================================================
--- neon/trunk/src/ne_private.h	(original)
+++ neon/trunk/src/ne_private.h	Tue Aug 18 06:12:29 2009
@@ -1,6 +1,6 @@
 /* 
    HTTP Request Handling
-   Copyright (C) 1999-2008, Joe Orton <joe at manyfish.co.uk>
+   Copyright (C) 1999-2009, Joe Orton <joe at manyfish.co.uk>
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
@@ -147,8 +147,7 @@
 void ne__ssl_set_verify_err(ne_session *sess, int failures);
 
 /* Return non-zero if hostname from certificate (cn) matches hostname
- * used for session (hostname); follows RFC2818 logic.  cn is modified
- * in-place. */
-int ne__ssl_match_hostname(char *cn, const char *hostname);
+ * used for session (hostname); follows RFC2818 logic. */
+int ne__ssl_match_hostname(const char *cn, size_t cnlen, const char *hostname);
 
 #endif /* HTTP_PRIVATE_H */

Modified: neon/trunk/src/ne_session.c
==============================================================================
--- neon/trunk/src/ne_session.c	(original)
+++ neon/trunk/src/ne_session.c	Tue Aug 18 06:12:29 2009
@@ -557,24 +557,21 @@
 
 /* This doesn't actually implement complete RFC 2818 logic; omits
  * "f*.example.com" support for simplicity. */
-int ne__ssl_match_hostname(char *cn, const char *hostname)
+int ne__ssl_match_hostname(const char *cn, size_t cnlen, const char *hostname)
 {
     const char *dot;
 
-    dot = strchr(hostname, '.');
-    if (dot == NULL) {
-	char *pnt = strchr(cn, '.');
-	/* hostname is not fully-qualified; unqualify the cn. */
-	if (pnt != NULL) {
-	    *pnt = '\0';
-	}
-    }
-    else if (strncmp(cn, "*.", 2) == 0) {
+    NE_DEBUG(NE_DBG_SSL, "ssl: Match common name '%s' against '%s'\n",
+             cn, hostname);
+
+    if (strncmp(cn, "*.", 2) == 0 && cnlen > 2
+        && (dot = strchr(hostname, '.')) != NULL) {
 	hostname = dot + 1;
 	cn += 2;
+        cnlen -= 2;
     }
 
-    return !ne_strcasecmp(cn, hostname);
+    return cnlen == strlen(hostname) && !ne_strcasecmp(cn, hostname);
 }
 
 #endif /* NE_HAVE_SSL */

Added: neon/trunk/test/nulca.pem
==============================================================================
--- (empty file)
+++ neon/trunk/test/nulca.pem	Tue Aug 18 06:12:29 2009
@@ -0,0 +1,85 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            ce:4e:0c:d6:f7:2b:d6:6c
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA
+        Validity
+            Not Before: Aug  4 06:49:34 2009 GMT
+            Not After : Aug  2 06:49:34 2019 GMT
+        Subject: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:ca:bc:b4:01:72:0a:f4:a3:ce:c0:04:8c:43:fd:
+                    5d:27:4f:12:38:d3:11:ef:cc:1f:10:02:ef:e2:b8:
+                    24:3c:dd:2f:bf:1f:d2:27:11:d9:51:59:d2:f7:a7:
+                    c0:3d:38:a4:ff:64:86:ef:dc:f5:95:ca:49:34:8f:
+                    46:21:00:54:04:46:a0:d7:11:a1:48:a8:bd:68:27:
+                    f9:b2:72:c0:79:28:49:bb:55:b0:19:a0:6a:6f:70:
+                    8e:8a:43:a8:a3:e7:d1:13:a0:af:38:4b:09:cb:29:
+                    ca:26:c6:0c:3c:4b:20:fd:2f:08:ca:90:c6:41:35:
+                    31:ae:db:16:09:69:99:0c:fd:d1:ce:71:44:24:4f:
+                    4a:d5:c2:e1:1b:7a:c0:e3:4f:ef:72:8c:1e:32:83:
+                    5c:bc:2e:29:f1:3e:a6:7b:be:4b:10:d5:c9:5a:5a:
+                    3b:c3:f7:c4:0a:44:f7:41:d9:e8:c7:8c:17:d8:a0:
+                    86:5e:9c:5b:19:85:96:ca:68:db:d8:dc:3b:b2:26:
+                    79:f8:b1:07:2d:c3:2c:fa:e5:51:8e:aa:da:15:5a:
+                    56:fb:dc:f3:05:90:ac:05:d1:54:3b:6d:f5:14:fa:
+                    9d:0e:85:da:e9:6f:5d:46:12:f3:02:0a:a2:fe:4b:
+                    45:b6:4e:7e:41:34:cc:ab:cc:ca:b2:4a:7f:4d:66:
+                    55:81
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier: 
+                0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A
+            X509v3 Authority Key Identifier: 
+                keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A
+                DirName:/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=CA/CN=NULL-friendly CA
+                serial:CE:4E:0C:D6:F7:2B:D6:6C
+
+            X509v3 Basic Constraints: 
+                CA:TRUE
+    Signature Algorithm: sha1WithRSAEncryption
+        02:c9:aa:28:0b:d4:c6:34:2c:a9:b6:99:29:f9:b9:42:97:c5:
+        c0:25:0d:1c:cc:35:65:a1:03:97:0d:88:7e:69:99:48:98:4b:
+        77:f6:09:1b:e6:fc:6e:52:ab:68:d1:8d:eb:2e:51:c5:7b:94:
+        7d:b5:b9:d2:1f:9a:85:67:04:51:21:97:ec:c1:1f:92:8b:74:
+        c0:3d:69:17:c1:60:4a:b2:67:6f:47:51:ef:ca:38:d4:d2:c1:
+        4c:f8:8e:3c:ab:63:cd:84:67:1e:bf:5e:38:d0:89:f6:ee:a8:
+        2d:e6:51:72:c0:b3:ed:ca:5e:58:f7:a8:23:9c:64:dc:92:81:
+        56:e5:5e:2d:70:58:cc:f3:f1:3e:00:ff:41:9a:5f:01:28:22:
+        da:55:39:4c:c2:50:e8:27:e5:89:55:c0:b6:b2:10:28:2d:9e:
+        d6:27:b1:ec:d6:74:f8:a6:31:e9:f5:79:06:46:ab:a8:54:95:
+        8f:7e:33:45:5c:fa:32:a6:0b:2f:61:b6:0d:f9:42:66:9b:b8:
+        60:be:3d:1d:83:9d:0d:b7:04:13:4c:52:9c:e8:e1:a5:82:fd:
+        29:b0:2d:f4:f7:0a:30:a1:8d:01:cb:db:5d:dd:a4:b8:36:09:
+        84:56:a9:ea:54:80:3e:fa:18:be:13:89:c7:d4:38:1f:7f:25:
+        ad:5b:22:23
+-----BEGIN CERTIFICATE-----
+MIIERTCCAy2gAwIBAgIJAM5ODNb3K9ZsMA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNV
+BAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkxFzAV
+BgNVBAoTDk15IENvbXBhbnkgTHRkMQswCQYDVQQLEwJDQTEZMBcGA1UEAxMQTlVM
+TC1mcmllbmRseSBDQTAeFw0wOTA4MDQwNjQ5MzRaFw0xOTA4MDIwNjQ5MzRaMHQx
+CzAJBgNVBAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1
+cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQswCQYDVQQLEwJDQTEZMBcGA1UE
+AxMQTlVMTC1mcmllbmRseSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAMq8tAFyCvSjzsAEjEP9XSdPEjjTEe/MHxAC7+K4JDzdL78f0icR2VFZ0ven
+wD04pP9khu/c9ZXKSTSPRiEAVARGoNcRoUiovWgn+bJywHkoSbtVsBmgam9wjopD
+qKPn0ROgrzhLCcspyibGDDxLIP0vCMqQxkE1Ma7bFglpmQz90c5xRCRPStXC4Rt6
+wONP73KMHjKDXLwuKfE+pnu+SxDVyVpaO8P3xApE90HZ6MeMF9ighl6cWxmFlspo
+29jcO7ImefixBy3DLPrlUY6q2hVaVvvc8wWQrAXRVDtt9RT6nQ6F2ulvXUYS8wIK
+ov5LRbZOfkE0zKvMyrJKf01mVYECAwEAAaOB2TCB1jAdBgNVHQ4EFgQUCmk5X50w
+BBgILgIO5uqdsib24mowgaYGA1UdIwSBnjCBm4AUCmk5X50wBBgILgIO5uqdsib2
+4mqheKR2MHQxCzAJBgNVBAYTAkdCMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNV
+BAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMQswCQYDVQQLEwJD
+QTEZMBcGA1UEAxMQTlVMTC1mcmllbmRseSBDQYIJAM5ODNb3K9ZsMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAALJqigL1MY0LKm2mSn5uUKXxcAlDRzM
+NWWhA5cNiH5pmUiYS3f2CRvm/G5Sq2jRjesuUcV7lH21udIfmoVnBFEhl+zBH5KL
+dMA9aRfBYEqyZ29HUe/KONTSwUz4jjyrY82EZx6/XjjQifbuqC3mUXLAs+3KXlj3
+qCOcZNySgVblXi1wWMzz8T4A/0GaXwEoItpVOUzCUOgn5YlVwLayECgtntYnsezW
+dPimMen1eQZGq6hUlY9+M0Vc+jKmCy9htg35QmabuGC+PR2DnQ23BBNMUpzo4aWC
+/SmwLfT3CjChjQHL213dpLg2CYRWqepUgD76GL4TicfUOB9/Ja1bIiM=
+-----END CERTIFICATE-----

Added: neon/trunk/test/nulcn.pem
==============================================================================
--- (empty file)
+++ neon/trunk/test/nulcn.pem	Tue Aug 18 06:12:29 2009
@@ -0,0 +1,81 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA
+        Validity
+            Not Before: Aug  4 07:33:43 2009 GMT
+            Not After : Aug  2 07:33:43 2019 GMT
+        Subject: CN=www.bank.com\x00.badguy.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:cd:26:70:96:a9:a6:5d:3e:9c:ed:0f:08:15:5a:
+                    7c:17:25:68:68:af:13:b9:ad:41:fa:12:54:e2:84:
+                    72:7d:58:d1:e2:40:42:c1:59:ed:05:3d:aa:10:53:
+                    70:00:88:3a:77:a0:c0:56:9e:ac:7d:21:2a:71:44:
+                    51:08:bc:17:07:da:a8:a3:76:dc:51:bc:1b:8a:f6:
+                    02:1a:55:bf:46:b4:44:6b:27:5e:be:e5:17:8b:56:
+                    b2:c6:82:36:11:83:a8:bf:f7:2f:0d:17:f6:cd:47:
+                    b5:6f:2b:a6:41:b6:8d:33:5f:ea:ea:8b:b1:1a:e2:
+                    99:38:ff:59:5b:0a:a1:71:13:ca:37:3f:b9:b0:1e:
+                    91:9a:c8:93:35:0c:4a:e0:9d:f4:d2:61:c7:4e:5b:
+                    41:0a:7c:31:54:99:db:f5:65:ce:80:d3:c2:02:37:
+                    64:fd:54:12:7b:ea:ac:85:59:5c:17:e1:2e:f6:d0:
+                    a8:f2:d0:2e:94:59:2f:c2:a6:5f:da:07:de:7b:2e:
+                    14:07:ed:e4:27:24:37:9d:09:2e:b1:f9:5a:48:b9:
+                    80:24:43:e6:cb:c7:6e:35:df:d5:69:34:ff:e6:d6:
+                    9e:e8:76:66:6e:5f:59:01:3c:96:3b:ec:72:0b:3c:
+                    1e:95:0f:ce:68:13:9c:22:dd:1b:b5:44:28:50:4a:
+                    05:7f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                33:15:24:BE:DA:66:3A:06:8B:D9:27:34:3A:AF:62:40:E4:95:66:5D
+            X509v3 Authority Key Identifier: 
+                keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A
+
+    Signature Algorithm: sha1WithRSAEncryption
+        32:65:23:1f:c8:d9:53:84:82:d0:0a:eb:14:51:24:03:bc:6c:
+        1b:2a:5a:fe:1b:f0:e8:69:0c:2b:19:86:cf:7f:32:76:d8:2b:
+        d2:cf:8b:c4:d1:b6:5b:9c:60:a3:99:2e:92:72:06:ce:de:8b:
+        d2:a2:d2:89:7c:13:a9:0b:4e:be:12:09:e5:d6:28:3a:ac:a7:
+        26:56:94:7f:13:ee:64:7d:de:94:60:75:c1:bc:55:97:d4:aa:
+        13:8e:02:d8:b0:b0:70:53:ae:18:53:ce:aa:b2:2c:85:3e:e3:
+        f3:e1:26:f3:fa:5c:ee:f8:7b:0b:c6:39:b5:04:33:5e:ae:b8:
+        5e:0e:66:cc:a8:c0:6a:0d:ec:60:c1:c5:d9:39:ea:bd:1b:8f:
+        1c:7d:16:38:b1:e8:c8:37:01:aa:4b:99:df:e4:0f:10:be:61:
+        ee:9a:cf:cd:27:05:46:00:60:d8:6a:74:08:32:3c:8b:90:01:
+        6a:07:33:0c:6c:90:db:ea:fb:6a:17:1a:76:bb:73:14:27:e1:
+        a4:7e:d5:dd:30:b1:5d:f2:0e:aa:d4:b2:d5:4c:f6:4f:91:2a:
+        07:f4:37:c1:cf:48:19:c5:fe:7e:92:96:a8:df:50:6a:31:92:
+        a3:b1:14:fe:41:cc:49:62:98:4d:ea:c5:ba:05:2d:49:c3:22:
+        72:ef:41:09
+-----BEGIN CERTIFICATE-----
+MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJHQjES
+MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
+eSBDb21wYW55IEx0ZDELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEE5VTEwtZnJpZW5k
+bHkgQ0EwHhcNMDkwODA0MDczMzQzWhcNMTkwODAyMDczMzQzWjAjMSEwHwYDVQQD
+Exh3d3cuYmFuay5jb20ALmJhZGd1eS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDNJnCWqaZdPpztDwgVWnwXJWhorxO5rUH6ElTihHJ9WNHiQELB
+We0FPaoQU3AAiDp3oMBWnqx9ISpxRFEIvBcH2qijdtxRvBuK9gIaVb9GtERrJ16+
+5ReLVrLGgjYRg6i/9y8NF/bNR7VvK6ZBto0zX+rqi7Ea4pk4/1lbCqFxE8o3P7mw
+HpGayJM1DErgnfTSYcdOW0EKfDFUmdv1Zc6A08ICN2T9VBJ76qyFWVwX4S720Kjy
+0C6UWS/Cpl/aB957LhQH7eQnJDedCS6x+VpIuYAkQ+bLx24139VpNP/m1p7odmZu
+X1kBPJY77HILPB6VD85oE5wi3Ru1RChQSgV/AgMBAAGjezB5MAkGA1UdEwQCMAAw
+LAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0G
+A1UdDgQWBBQzFSS+2mY6BovZJzQ6r2JA5JVmXTAfBgNVHSMEGDAWgBQKaTlfnTAE
+GAguAg7m6p2yJvbiajANBgkqhkiG9w0BAQUFAAOCAQEAMmUjH8jZU4SC0ArrFFEk
+A7xsGypa/hvw6GkMKxmGz38ydtgr0s+LxNG2W5xgo5kuknIGzt6L0qLSiXwTqQtO
+vhIJ5dYoOqynJlaUfxPuZH3elGB1wbxVl9SqE44C2LCwcFOuGFPOqrIshT7j8+Em
+8/pc7vh7C8Y5tQQzXq64Xg5mzKjAag3sYMHF2TnqvRuPHH0WOLHoyDcBqkuZ3+QP
+EL5h7prPzScFRgBg2Gp0CDI8i5ABagczDGyQ2+r7ahcadrtzFCfhpH7V3TCxXfIO
+qtSy1Uz2T5EqB/Q3wc9IGcX+fpKWqN9QajGSo7EU/kHMSWKYTerFugUtScMicu9B
+CQ==
+-----END CERTIFICATE-----

Added: neon/trunk/test/nulsan.pem
==============================================================================
--- (empty file)
+++ neon/trunk/test/nulsan.pem	Tue Aug 18 06:12:29 2009
@@ -0,0 +1,83 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 0 (0x0)
+        Signature Algorithm: sha1WithRSAEncryption
+        Issuer: C=GB, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=CA, CN=NULL-friendly CA
+        Validity
+            Not Before: Aug  4 06:53:05 2009 GMT
+            Not After : Aug  2 06:53:05 2019 GMT
+        Subject: CN=www.badguy.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:cd:26:70:96:a9:a6:5d:3e:9c:ed:0f:08:15:5a:
+                    7c:17:25:68:68:af:13:b9:ad:41:fa:12:54:e2:84:
+                    72:7d:58:d1:e2:40:42:c1:59:ed:05:3d:aa:10:53:
+                    70:00:88:3a:77:a0:c0:56:9e:ac:7d:21:2a:71:44:
+                    51:08:bc:17:07:da:a8:a3:76:dc:51:bc:1b:8a:f6:
+                    02:1a:55:bf:46:b4:44:6b:27:5e:be:e5:17:8b:56:
+                    b2:c6:82:36:11:83:a8:bf:f7:2f:0d:17:f6:cd:47:
+                    b5:6f:2b:a6:41:b6:8d:33:5f:ea:ea:8b:b1:1a:e2:
+                    99:38:ff:59:5b:0a:a1:71:13:ca:37:3f:b9:b0:1e:
+                    91:9a:c8:93:35:0c:4a:e0:9d:f4:d2:61:c7:4e:5b:
+                    41:0a:7c:31:54:99:db:f5:65:ce:80:d3:c2:02:37:
+                    64:fd:54:12:7b:ea:ac:85:59:5c:17:e1:2e:f6:d0:
+                    a8:f2:d0:2e:94:59:2f:c2:a6:5f:da:07:de:7b:2e:
+                    14:07:ed:e4:27:24:37:9d:09:2e:b1:f9:5a:48:b9:
+                    80:24:43:e6:cb:c7:6e:35:df:d5:69:34:ff:e6:d6:
+                    9e:e8:76:66:6e:5f:59:01:3c:96:3b:ec:72:0b:3c:
+                    1e:95:0f:ce:68:13:9c:22:dd:1b:b5:44:28:50:4a:
+                    05:7f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                33:15:24:BE:DA:66:3A:06:8B:D9:27:34:3A:AF:62:40:E4:95:66:5D
+            X509v3 Authority Key Identifier: 
+                keyid:0A:69:39:5F:9D:30:04:18:08:2E:02:0E:E6:EA:9D:B2:26:F6:E2:6A
+
+            X509v3 Subject Alternative Name: 
+                DNS:www.bank.com
+    Signature Algorithm: sha1WithRSAEncryption
+        27:6e:7d:b3:a9:86:52:57:6a:a0:c6:30:6c:1e:94:09:a7:6f:
+        ad:fe:11:9f:be:32:8d:01:7b:8b:94:66:d7:7c:b6:b1:90:fc:
+        e4:f5:b6:32:bc:6c:71:23:b1:18:88:d6:47:bc:da:07:c7:5e:
+        46:71:3a:e6:40:6e:c1:7f:1d:56:96:70:65:d8:51:a9:dc:9e:
+        a5:06:00:98:e7:1e:10:bc:82:ba:00:e5:4e:a2:0f:3e:ec:8a:
+        dd:6f:c6:c9:c1:ec:ed:6d:7c:31:3e:66:87:47:a1:8b:15:3c:
+        21:7e:ec:21:78:3d:21:70:72:ba:70:c3:64:f8:1d:4f:d9:d0:
+        27:3c:3e:7e:a2:59:ae:be:9a:d3:00:44:a7:72:3a:e3:3f:c8:
+        9b:c5:8f:b1:94:fe:00:0f:6e:b8:14:88:f1:03:50:91:51:af:
+        f0:1e:f7:b8:5a:a4:57:35:2d:f1:ad:c8:ae:dd:29:61:14:7d:
+        ea:d1:34:80:5c:1b:fd:eb:43:dc:21:6d:c6:44:f9:3b:54:76:
+        c4:91:5b:ac:a4:8e:72:e7:d8:24:ff:a7:5a:c0:ef:27:c3:d7:
+        e4:f9:7f:55:8d:0d:30:ec:a2:d9:6d:c8:76:f4:be:94:3d:12:
+        32:4a:91:4f:db:c3:e7:76:07:5a:12:97:18:b7:15:00:98:59:
+        21:89:3e:35
+-----BEGIN CERTIFICATE-----
+MIIDrTCCApWgAwIBAgIBADANBgkqhkiG9w0BAQUFADB0MQswCQYDVQQGEwJHQjES
+MBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5N
+eSBDb21wYW55IEx0ZDELMAkGA1UECxMCQ0ExGTAXBgNVBAMTEE5VTEwtZnJpZW5k
+bHkgQ0EwHhcNMDkwODA0MDY1MzA1WhcNMTkwODAyMDY1MzA1WjAZMRcwFQYDVQQD
+Ew53d3cuYmFkZ3V5LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AM0mcJappl0+nO0PCBVafBclaGivE7mtQfoSVOKEcn1Y0eJAQsFZ7QU9qhBTcACI
+OnegwFaerH0hKnFEUQi8FwfaqKN23FG8G4r2AhpVv0a0RGsnXr7lF4tWssaCNhGD
+qL/3Lw0X9s1HtW8rpkG2jTNf6uqLsRrimTj/WVsKoXETyjc/ubAekZrIkzUMSuCd
+9NJhx05bQQp8MVSZ2/VlzoDTwgI3ZP1UEnvqrIVZXBfhLvbQqPLQLpRZL8KmX9oH
+3nsuFAft5CckN50JLrH5Wki5gCRD5svHbjXf1Wk0/+bWnuh2Zm5fWQE8ljvscgs8
+HpUPzmgTnCLdG7VEKFBKBX8CAwEAAaOBpDCBoTAJBgNVHRMEAjAAMCwGCWCGSAGG
++EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU
+MxUkvtpmOgaL2Sc0Oq9iQOSVZl0wHwYDVR0jBBgwFoAUCmk5X50wBBgILgIO5uqd
+sib24mowJgYDVR0RBB8wHYIbd3d3LmJhbmsuY29tAHd3dy5iYWRndXkuY29tMA0G
+CSqGSIb3DQEBBQUAA4IBAQAnbn2zqYZSV2qgxjBsHpQJp2+t/hGfvjKNAXuLlGbX
+fLaxkPzk9bYyvGxxI7EYiNZHvNoHx15GcTrmQG7Bfx1WlnBl2FGp3J6lBgCY5x4Q
+vIK6AOVOog8+7Irdb8bJweztbXwxPmaHR6GLFTwhfuwheD0hcHK6cMNk+B1P2dAn
+PD5+olmuvprTAESncjrjP8ibxY+xlP4AD264FIjxA1CRUa/wHve4WqRXNS3xrciu
+3SlhFH3q0TSAXBv960PcIW3GRPk7VHbEkVuspI5y59gk/6dawO8nw9fk+X9VjQ0w
+7KLZbch29L6UPRIySpFP28PndgdaEpcYtxUAmFkhiT41
+-----END CERTIFICATE-----

Added: neon/trunk/test/nulsrv.key
==============================================================================
--- (empty file)
+++ neon/trunk/test/nulsrv.key	Tue Aug 18 06:12:29 2009
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAzSZwlqmmXT6c7Q8IFVp8FyVoaK8Tua1B+hJU4oRyfVjR4kBC
+wVntBT2qEFNwAIg6d6DAVp6sfSEqcURRCLwXB9qoo3bcUbwbivYCGlW/RrREayde
+vuUXi1ayxoI2EYOov/cvDRf2zUe1byumQbaNM1/q6ouxGuKZOP9ZWwqhcRPKNz+5
+sB6RmsiTNQxK4J300mHHTltBCnwxVJnb9WXOgNPCAjdk/VQSe+qshVlcF+Eu9tCo
+8tAulFkvwqZf2gfeey4UB+3kJyQ3nQkusflaSLmAJEPmy8duNd/VaTT/5tae6HZm
+bl9ZATyWO+xyCzwelQ/OaBOcIt0btUQoUEoFfwIDAQABAoIBAF55tl3b8O5+GDyf
+sIRM8FqkconLHtViccDdUlQi1KrfDYEZQOTUKfBA7qGoGytTkUFoOUtqtVrGvEn/
+QSY5oI2QaBsncNz/ONvs4RkJphXEjMGgFuTokcgsfBYo/wdfz4XgKr3n7FOrE2YH
+/v/CNxKSuJedD0mnUxLJnXfs1F5DAE+nE88T2LsWLqo8Jxr/6wFnazaAYmtkQd3/
+BNBn9a7K79G81e7FkRSIc+7De7iju6UMy010qY6UNyFw9hSWQgjxzxwiyFvRuu4C
+w4xRJo2z0vEL6TSnNZEpTVVAbBd8XYSjh/627uXBah8W50X4BWLOd1umgU1hJDXe
+cXIWVZkCgYEA9QXcOdOPzuQ6wQYEi7qvTKSRdUJ+D3BCbqSHyWEe4RotWqs9WV1F
+FFpaRO/aiIdqpVZE8YJlcAcKtIXBS/byKUfOFzHX2QvROmPlcavXrVtFnNsBQpIn
+hyYjs/z/vbFDgugLBKVsgEaZzlJeygbI61r2NjVnst7NzP9L8ZxFgDsCgYEA1ldI
+nZcXekaqpUAMCSdZPDcfocVUb8UjvRZf90EruWymbrJQxzym5HaX20MFFh1BKC+a
+JEexxhlbfth/zgX6Pux7fqxSJM11DBG1aik7t4GMRu1bfflpQjdQUXGn2YPI5Quz
+R6QPcXhLVLY8b8PJu2jSKjV0cDN02dFwEFv9340CgYBRpUhDBJow6KAjXav6G5T6
+RwQpPKTg5Ble4PhWREST4bMnOVRSCOBR7eGSgxIg2G7S9TI3/6lpcQ9CJCfK9liv
+JLwpwnQYYPWxLURxYj+WBonlwJxk4GrHgA/5k95sCTtjzYqOW8kR3XS26X+odiZR
+NphAa/9H/TI6kv9tXRNTrQKBgGoREVciwLR6qdFSq2IQPcFlidq02r7gsHnOy7iA
+YJHGqWmYBg9B/ViLM0SGmsrBuU+Yls+jRt7AB53ypvQd0yM2RTp/LbsWjPhm/v5E
+309E5VTn+mGRfbwNwUo8UxJ5e32U16f5EMdW/vgxoiCwo3CBQ5ctkqw/WnC7ipgd
+3bi1AoGAbJSdtaFdF0kSikqvcPEJMFBR24dT7W+JIXeuFHYbRkQGSVZLGxuAkbL5
+1mY+qclcvzfijH0wNFRP1Z3M5eFERALwI25YOrZGtI1ncIeKV+yFwkYC54XfZUvr
+hQO0wVIbTaE3N9fDIs0rHbSc1GJUhVr+2IsTW/ybHgdfDZMuXOI=
+-----END RSA PRIVATE KEY-----

Modified: neon/trunk/test/ssl.c
==============================================================================
--- neon/trunk/test/ssl.c	(original)
+++ neon/trunk/test/ssl.c	Tue Aug 18 06:12:29 2009
@@ -86,6 +86,8 @@
     int count; /* internal use. */
 
     int use_ssl2; /* force use of SSLv2 only */
+
+    const char *key;
 };
 
 /* default response string if args->response is NULL */
@@ -97,6 +99,7 @@
     struct ssl_server_args *args = userdata;
     int ret;
     char buf[BUFSIZ];
+    const char *key;
     static ne_ssl_context *ctx = NULL;
 
     if (ctx == NULL) {
@@ -106,11 +109,13 @@
 
     ONV(ctx == NULL, ("could not create SSL context"));
 
-    ONV(ne_ssl_context_keypair(ctx, args->cert, server_key),
+    key = args->key ? args->key : server_key;
+    NE_DEBUG(NE_DBG_HTTP, "SSL server init with keypair (%s, %s).\n",
+             args->cert, key);
+             
+    ONV(ne_ssl_context_keypair(ctx, args->cert, key),
         ("failed to load server keypair: ..."));
 
-    NE_DEBUG(NE_DBG_HTTP, "using server cert %s\n", args->cert);
-
     if (args->require_cc && !args->ca_list) {
         args->ca_list = CA_CERT;
     }
@@ -746,18 +751,37 @@
 /* Helper function: run a request using the given self-signed server
  * certificate, and expect the request to fail with the given
  * verification failure flags. */
-static int fail_ssl_request_with_error(char *cert, char *cacert, const char *host,
-                                       const char *msg, int failures,
-                                       const char *errstr)
+static int fail_ssl_request_with_error2(char *cert, char *key, char *cacert, 
+                                        const char *host, const char *fakehost,
+                                        const char *msg, int failures,
+                                        const char *errstr)
 {
     ne_session *sess = ne_session_create("https", host, 7777);
     int gotf = 0, ret;
+    struct ssl_server_args args = {0};
+    ne_sock_addr *addr;
+    const ne_inet_addr *list[1];
+
+    if (fakehost) {
+        addr = ne_addr_resolve(fakehost, 0);
 
-    ret = any_ssl_request(sess, fail_serve, cert, cacert,
+        ONV(ne_addr_result(addr),
+            ("fake hostname lookup failed for %s", fakehost));
+        
+        list[0] = ne_addr_first(addr);
+        
+        ne_set_addrlist(sess, list, 1);
+    }
+
+    args.cert = cert;
+    args.key = key;
+    args.fail_silently = 1;
+    
+    ret = any_ssl_request(sess, ssl_server, &args, cacert,
 			  get_failures, &gotf);
 
     ONV(gotf == 0,
-	("no error in verification callback; request failed: %s",
+	("no error in verification callback; error string: %s",
 	 ne_get_error(sess)));
 
     ONV(gotf & ~NE_SSL_FAILMASK,
@@ -782,6 +806,18 @@
 /* Helper function: run a request using the given self-signed server
  * certificate, and expect the request to fail with the given
  * verification failure flags. */
+static int fail_ssl_request_with_error(char *cert, char *cacert, const char *host,
+                                       const char *msg, int failures,
+                                       const char *errstr)
+{
+    return fail_ssl_request_with_error2(cert, NULL, cacert, host, NULL,
+                                        msg, failures, errstr);
+}
+
+
+/* Helper function: run a request using the given self-signed server
+ * certificate, and expect the request to fail with the given
+ * verification failure flags. */
 static int fail_ssl_request(char *cert, char *cacert, const char *host,
 			    const char *msg, int failures)
 {
@@ -803,6 +839,24 @@
                             
 }
 
+static int fail_nul_cn(void)
+{
+    return fail_ssl_request_with_error2("nulcn.pem", "nulsrv.key", "nulca.pem", 
+                                        "www.bank.com", "localhost",
+                                        "certificate with incorrect CN was accepted",
+                                        NE_SSL_IDMISMATCH,
+                                        "certificate issued for a different hostname");
+}
+
+static int fail_nul_san(void)
+{
+    return fail_ssl_request_with_error2("nulsan.pem", "nulsrv.key", "nulca.pem", 
+                                        "www.bank.com", "localhost",
+                                        "certificate with incorrect CN was accepted",
+                                        NE_SSL_IDMISMATCH,
+                                        "certificate issued for a different hostname");
+}
+
 /* Check that an expired certificate is flagged as such. */
 static int fail_expired(void)
 {
@@ -1359,6 +1413,24 @@
     return OK;
 }
 
+static int nulcn_identity(void)
+{
+    ne_ssl_certificate *cert = ne_ssl_cert_read("nulcn.pem");
+    const char *id, *expected = "www.bank.com\\x00.badguy.com";
+
+    ONN("could not read nulcn.pem", cert == NULL);
+
+    id = ne_ssl_cert_identity(cert);
+
+    ONV(id != NULL
+        && strcmp(id, expected) != 0,
+        ("certificate `nulcn.pem' had identity `%s' not `%s'", 
+         id, expected));
+    
+    ne_ssl_cert_free(cert);
+    return OK;
+}
+
 static int check_validity(const char *fname,
                           const char *from, const char *until)
 {
@@ -1801,6 +1873,10 @@
     T(fail_ca_notyetvalid),
     T(fail_ca_expired),
 
+    T(nulcn_identity),
+    T(fail_nul_cn),
+    T(fail_nul_san),
+    
     T(session_cache),
 	
     T(fail_tunnel),



More information about the neon-commits mailing list