File curl-7.19.0-CVE-2009-2417.patch of Package curl
---
lib/ssluse.c | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
--- lib/ssluse.c.orig
+++ lib/ssluse.c
@@ -1064,7 +1064,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 */
@@ -1078,14 +1078,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;
@@ -1125,18 +1127,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_PEER_FAILED_VERIFICATION;
+ }
}
- else /* not a UTF8 name */
- j = ASN1_STRING_to_UTF8(&peer_CN, tmp);
}
if(peer_CN == nulstr)
@@ -1154,7 +1165,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;