aboutsummaryrefslogtreecommitdiff
path: root/lib/ssluse.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ssluse.c')
-rw-r--r--lib/ssluse.c62
1 files changed, 30 insertions, 32 deletions
diff --git a/lib/ssluse.c b/lib/ssluse.c
index 187a7e371..0b98ba0b6 100644
--- a/lib/ssluse.c
+++ b/lib/ssluse.c
@@ -990,19 +990,14 @@ static int asn1_output(const ASN1_UTCTIME *tm,
#define HOST_NOMATCH 0
#define HOST_MATCH 1
-static int hostmatch(const char *hostname, const char *pattern, size_t plen)
+static int hostmatch(const char *hostname, const char *pattern)
{
while(1) {
char c = *pattern++;
- plen--;
- if(!plen)
+ if(c == '\0')
return (*hostname ? HOST_NOMATCH : HOST_MATCH);
- if(!c)
- /* an embedded zero in the pattern can't match a host name */
- return HOST_NOMATCH;
-
if(c == '*') {
c = *pattern;
if(c == '\0') /* "*\0" matches anything remaining */
@@ -1010,7 +1005,7 @@ static int hostmatch(const char *hostname, const char *pattern, size_t plen)
while(*hostname) {
/* The only recursive function in libcurl! */
- if(hostmatch(hostname++, pattern, plen) == HOST_MATCH)
+ if(hostmatch(hostname++,pattern) == HOST_MATCH)
return HOST_MATCH;
}
break;
@@ -1023,20 +1018,17 @@ static int hostmatch(const char *hostname, const char *pattern, size_t plen)
}
static int
-cert_hostcheck(const char *match_pattern, size_t mlen, const char *hostname)
+cert_hostcheck(const char *match_pattern, const char *hostname)
{
- size_t hlen = strlen(hostname);
if(!match_pattern || !*match_pattern ||
- !hostname || !*hostname) /* sanity check */
+ !hostname || !*hostname) /* sanity check */
return 0;
- if((hlen == mlen) && !memcmp(hostname, match_pattern, hlen))
- /* trivial case */
+ if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
return 1;
- if(hostmatch(hostname, match_pattern, mlen) == HOST_MATCH)
+ if(hostmatch(hostname,match_pattern) == HOST_MATCH)
return 1;
-
return 0;
}
@@ -1122,11 +1114,11 @@ static CURLcode verifyhost(struct connectdata *conn,
Gisle researched the OpenSSL sources:
"I checked the 0.9.6 and 0.9.8 sources before my patch and
it always 0-terminates an IA5String."
-
- To reduce the risk of an embedded zero before the final zero
- causing us trouble, we use the length OpenSSL reports!
*/
- if(cert_hostcheck(altptr, altlen, 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;
@@ -1154,7 +1146,6 @@ static CURLcode verifyhost(struct connectdata *conn,
unsigned char *nulstr = (unsigned char *)"";
unsigned char *peer_CN = nulstr;
- size_t peer_len = 0;
X509_NAME *name = X509_get_subject_name(server_cert) ;
if(name)
@@ -1174,20 +1165,25 @@ static CURLcode verifyhost(struct connectdata *conn,
conditional in the future when OpenSSL has been fixed. Work-around
brought by Alexis S. L. Carvalho. */
if(tmp) {
- /* get the length off the ASN1 to avoid problems with embedded zeroes
- */
- peer_len = ASN1_STRING_length(tmp);
+ j = ASN1_STRING_length(tmp);
if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
- if(peer_len) {
- peer_CN = OPENSSL_malloc(peer_len+1);
+ if(j >= 0) {
+ peer_CN = OPENSSL_malloc(j+1);
if(peer_CN) {
- memcpy(peer_CN, ASN1_STRING_data(tmp), peer_len);
- peer_CN[peer_len] = '\0';
+ 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((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;
+ }
}
}
@@ -1197,7 +1193,7 @@ static CURLcode verifyhost(struct connectdata *conn,
else {
/* convert peer_CN from UTF8 */
size_t rc;
- rc = Curl_convert_from_utf8(data, peer_CN, peer_len);
+ rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN));
/* Curl_convert_from_utf8 calls failf if unsuccessful */
if(rc != CURLE_OK) {
OPENSSL_free(peer_CN);
@@ -1206,13 +1202,15 @@ static CURLcode verifyhost(struct connectdata *conn,
}
#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;
+ res = CURLE_PEER_FAILED_VERIFICATION;
}
- else if(!cert_hostcheck((const char *)peer_CN, peer_len,
- conn->host.name)) {
+ else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
if(data->set.ssl.verifyhost > 1) {
failf(data, "SSL: certificate subject name '%s' does not match "
"target host name '%s'", peer_CN, conn->host.dispname);