[packages] curl: fix handling of '\0' character in domain names of x509 certificates
authorNicolas Thill <nico@openwrt.org>
Wed, 19 Aug 2009 13:14:31 +0000 (13:14 +0000)
committerNicolas Thill <nico@openwrt.org>
Wed, 19 Aug 2009 13:14:31 +0000 (13:14 +0000)
 - CVE-2009-2417

SVN-Revision: 17309

libs/curl/Makefile
libs/curl/patches/901-cve-2009-2417.patch [new file with mode: 0644]

index 7716edcf6f9abee27a40aaf932d1a3f6140f707f..14e6adaabe18423ddf3716ea2246f0d878dc885c 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=curl
 PKG_VERSION:=7.17.1
-PKG_RELEASE:=1
+PKG_RELEASE:=1.1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=http://curl.haxx.se/download/ \
diff --git a/libs/curl/patches/901-cve-2009-2417.patch b/libs/curl/patches/901-cve-2009-2417.patch
new file mode 100644 (file)
index 0000000..51266ee
--- /dev/null
@@ -0,0 +1,81 @@
+http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-2417
+
+--- a/lib/ssluse.c
++++ b/lib/ssluse.c
+@@ -1028,7 +1028,7 @@ static CURLcode verifyhost(struct connec
+       if(check->type == target) {
+         /* get data and length */
+         const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
+-        int altlen;
++        size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
+         switch(target) {
+         case GEN_DNS: /* name/pattern comparison */
+@@ -1042,14 +1042,16 @@ static CURLcode verifyhost(struct connec
+              "I checked the 0.9.6 and 0.9.8 sources before my patch and
+              it always 0-terminates an IA5String."
+           */
+-          if (cert_hostcheck(altptr, conn->host.name))
++          if((altlen == strlen(altptr)) &&
++             /* if this isn't true, there was an embedded zero in the name
++                string and we cannot match it. */
++             cert_hostcheck(altptr, conn->host.name))
+             matched = TRUE;
+           break;
+         case GEN_IPADD: /* IP address comparison */
+           /* compare alternative IP address if the data chunk is the same size
+              our server IP address is */
+-          altlen = ASN1_STRING_length(check->d.ia5);
+           if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
+             matched = TRUE;
+           break;
+@@ -1089,18 +1091,27 @@ static CURLcode verifyhost(struct connec
+          string manually to avoid the problem. This code can be made
+          conditional in the future when OpenSSL has been fixed. Work-around
+          brought by Alexis S. L. Carvalho. */
+-      if (tmp && ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
+-        j = ASN1_STRING_length(tmp);
+-        if (j >= 0) {
+-          peer_CN = OPENSSL_malloc(j+1);
+-          if (peer_CN) {
+-            memcpy(peer_CN, ASN1_STRING_data(tmp), j);
+-            peer_CN[j] = '\0';
++      if(tmp) {
++        if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
++          j = ASN1_STRING_length(tmp);
++          if(j >= 0) {
++            peer_CN = OPENSSL_malloc(j+1);
++            if(peer_CN) {
++              memcpy(peer_CN, ASN1_STRING_data(tmp), j);
++              peer_CN[j] = '\0';
++            }
+           }
+         }
++        else /* not a UTF8 name */
++          j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
++
++        if(peer_CN && ((int)strlen((char *)peer_CN) != j)) {
++          /* there was a terminating zero before the end of string, this
++             cannot match and we return failure! */
++          failf(data, "SSL: illegal cert name field");
++          res = CURLE_SSL_PEER_CERTIFICATE;
++        }
+       }
+-      else /* not a UTF8 name */
+-        j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
+     }
+     if (peer_CN == nulstr)
+@@ -1118,7 +1129,10 @@ static CURLcode verifyhost(struct connec
+     }
+ #endif /* CURL_DOES_CONVERSIONS */
+-    if (!peer_CN) {
++    if(res)
++      /* error already detected, pass through */
++      ;
++    else if(!peer_CN) {
+       failf(data,
+             "SSL: unable to obtain common name from peer certificate");
+       return CURLE_PEER_FAILED_VERIFICATION;