Peter Sylvester's patch that addresses two flaws in the peer certificate name
verification: - when multiple common names are used (as in the curl tests), the last name needs to be selected. - allow comparing with encoded values, at least with BMP and ISO latin1 encoded T61strings.
This commit is contained in:
parent
f39f7c28f0
commit
a9893ca79a
65
lib/ssluse.c
65
lib/ssluse.c
@ -787,7 +787,6 @@ cert_hostcheck(const char *certname, const char *hostname)
|
|||||||
static CURLcode verifyhost(struct connectdata *conn,
|
static CURLcode verifyhost(struct connectdata *conn,
|
||||||
X509 *server_cert)
|
X509 *server_cert)
|
||||||
{
|
{
|
||||||
char peer_CN[257];
|
|
||||||
bool matched = FALSE; /* no alternative match yet */
|
bool matched = FALSE; /* no alternative match yet */
|
||||||
int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
|
int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */
|
||||||
int addrlen = 0;
|
int addrlen = 0;
|
||||||
@ -872,13 +871,36 @@ static CURLcode verifyhost(struct connectdata *conn,
|
|||||||
|
|
||||||
if(matched)
|
if(matched)
|
||||||
/* an alternative name matched the server hostname */
|
/* an alternative name matched the server hostname */
|
||||||
infof(data, "\t subjectAltName: %s matched\n", conn->host.name);
|
infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname);
|
||||||
else {
|
else {
|
||||||
bool obtain=FALSE;
|
/* we have to look to the last occurence of a commonName in the
|
||||||
if(X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert),
|
distinguished one to get the most significant one. */
|
||||||
NID_commonName,
|
int j,i=-1 ;
|
||||||
peer_CN,
|
|
||||||
sizeof(peer_CN)) < 0) {
|
/* The following is done because of a bug in 0.9.6b */
|
||||||
|
|
||||||
|
unsigned char *nulstr = (unsigned char *)"";
|
||||||
|
unsigned char *peer_CN = nulstr;
|
||||||
|
|
||||||
|
X509_NAME *name = X509_get_subject_name(server_cert) ;
|
||||||
|
if (name)
|
||||||
|
while ((j=X509_NAME_get_index_by_NID(name,NID_commonName,i))>=0)
|
||||||
|
i=j;
|
||||||
|
|
||||||
|
/* we have the name entry and we will now convert this to a string
|
||||||
|
that we can use for comparison. Doing this we support BMPstring,
|
||||||
|
UTF8 etc. */
|
||||||
|
|
||||||
|
if (i>=0) {
|
||||||
|
j = ASN1_STRING_to_UTF8(&peer_CN,
|
||||||
|
X509_NAME_ENTRY_get_data(
|
||||||
|
X509_NAME_get_entry(name,i)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peer_CN == nulstr)
|
||||||
|
peer_CN = NULL;
|
||||||
|
|
||||||
|
if (!peer_CN) {
|
||||||
if(data->set.ssl.verifyhost > 1) {
|
if(data->set.ssl.verifyhost > 1) {
|
||||||
failf(data,
|
failf(data,
|
||||||
"SSL: unable to obtain common name from peer certificate");
|
"SSL: unable to obtain common name from peer certificate");
|
||||||
@ -890,25 +912,22 @@ static CURLcode verifyhost(struct connectdata *conn,
|
|||||||
infof(data, "\t common name: WARNING couldn't obtain\n");
|
infof(data, "\t common name: WARNING couldn't obtain\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) {
|
||||||
obtain = TRUE;
|
if(data->set.ssl.verifyhost > 1) {
|
||||||
|
failf(data, "SSL: certificate subject name '%s' does not match "
|
||||||
if(obtain) {
|
"target host name '%s'", peer_CN, conn->host.dispname);
|
||||||
if(!cert_hostcheck(peer_CN, conn->host.name)) {
|
OPENSSL_free(peer_CN);
|
||||||
if(data->set.ssl.verifyhost > 1) {
|
return CURLE_SSL_PEER_CERTIFICATE ;
|
||||||
failf(data, "SSL: certificate subject name '%s' does not match "
|
|
||||||
"target host name '%s'", peer_CN, conn->host.name);
|
|
||||||
return CURLE_SSL_PEER_CERTIFICATE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
infof(data, "\t common name: %s (does not match '%s')\n",
|
|
||||||
peer_CN, conn->host.name);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
infof(data, "\t common name: %s (matched)\n", peer_CN);
|
infof(data, "\t common name: %s (does not match '%s')\n",
|
||||||
|
peer_CN, conn->host.dispname);
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
infof(data, "\t common name: %s (matched)\n", peer_CN);
|
||||||
|
OPENSSL_free(peer_CN);
|
||||||
|
}
|
||||||
|
}
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user