curl: fix handling of '\0' character in domain names of x509 certificates - CVE-2009...
[openwrt/svn-archive/packages.git] / libs / curl / patches / 901-cve-2009-2417.patch
1 http://cve.mitre.org/cgi-bin/cvename.cgi?name=2009-2417
2
3 --- a/lib/ssluse.c
4 +++ b/lib/ssluse.c
5 @@ -1028,7 +1028,7 @@ static CURLcode verifyhost(struct connec
6 if(check->type == target) {
7 /* get data and length */
8 const char *altptr = (char *)ASN1_STRING_data(check->d.ia5);
9 - int altlen;
10 + size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5);
11
12 switch(target) {
13 case GEN_DNS: /* name/pattern comparison */
14 @@ -1042,14 +1042,16 @@ static CURLcode verifyhost(struct connec
15 "I checked the 0.9.6 and 0.9.8 sources before my patch and
16 it always 0-terminates an IA5String."
17 */
18 - if (cert_hostcheck(altptr, conn->host.name))
19 + if((altlen == strlen(altptr)) &&
20 + /* if this isn't true, there was an embedded zero in the name
21 + string and we cannot match it. */
22 + cert_hostcheck(altptr, conn->host.name))
23 matched = TRUE;
24 break;
25
26 case GEN_IPADD: /* IP address comparison */
27 /* compare alternative IP address if the data chunk is the same size
28 our server IP address is */
29 - altlen = ASN1_STRING_length(check->d.ia5);
30 if((altlen == addrlen) && !memcmp(altptr, &addr, altlen))
31 matched = TRUE;
32 break;
33 @@ -1089,18 +1091,27 @@ static CURLcode verifyhost(struct connec
34 string manually to avoid the problem. This code can be made
35 conditional in the future when OpenSSL has been fixed. Work-around
36 brought by Alexis S. L. Carvalho. */
37 - if (tmp && ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
38 - j = ASN1_STRING_length(tmp);
39 - if (j >= 0) {
40 - peer_CN = OPENSSL_malloc(j+1);
41 - if (peer_CN) {
42 - memcpy(peer_CN, ASN1_STRING_data(tmp), j);
43 - peer_CN[j] = '\0';
44 + if(tmp) {
45 + if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
46 + j = ASN1_STRING_length(tmp);
47 + if(j >= 0) {
48 + peer_CN = OPENSSL_malloc(j+1);
49 + if(peer_CN) {
50 + memcpy(peer_CN, ASN1_STRING_data(tmp), j);
51 + peer_CN[j] = '\0';
52 + }
53 }
54 }
55 + else /* not a UTF8 name */
56 + j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
57 +
58 + if(peer_CN && ((int)strlen((char *)peer_CN) != j)) {
59 + /* there was a terminating zero before the end of string, this
60 + cannot match and we return failure! */
61 + failf(data, "SSL: illegal cert name field");
62 + res = CURLE_SSL_PEER_CERTIFICATE;
63 + }
64 }
65 - else /* not a UTF8 name */
66 - j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
67 }
68
69 if (peer_CN == nulstr)
70 @@ -1118,7 +1129,10 @@ static CURLcode verifyhost(struct connec
71 }
72 #endif /* CURL_DOES_CONVERSIONS */
73
74 - if (!peer_CN) {
75 + if(res)
76 + /* error already detected, pass through */
77 + ;
78 + else if(!peer_CN) {
79 failf(data,
80 "SSL: unable to obtain common name from peer certificate");
81 return CURLE_PEER_FAILED_VERIFICATION;