Use net::verifyHostname() with gnutls.

We now don't use gnutls_x509_crt_check_hostname() any more.
pull/16/merge
Tatsuhiro Tsujikawa 2012-03-31 21:21:18 +09:00
parent e6f04416d9
commit b68e0a5527
1 changed files with 26 additions and 3 deletions

View File

@ -887,10 +887,10 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname)
(fmt(MSG_CERT_VERIFICATION_FAILED, (fmt(MSG_CERT_VERIFICATION_FAILED,
X509_verify_cert_error_string(verifyResult))); X509_verify_cert_error_string(verifyResult)));
} }
GENERAL_NAMES* altNames;
std::string commonName; std::string commonName;
std::vector<std::string> dnsNames; std::vector<std::string> dnsNames;
std::vector<std::string> ipAddrs; std::vector<std::string> ipAddrs;
GENERAL_NAMES* altNames;
altNames = reinterpret_cast<GENERAL_NAMES*> altNames = reinterpret_cast<GENERAL_NAMES*>
(X509_get_ext_d2i(peerCert, NID_subject_alt_name, NULL, NULL)); (X509_get_ext_d2i(peerCert, NID_subject_alt_name, NULL, NULL));
if(altNames) { if(altNames) {
@ -987,7 +987,7 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname)
unsigned int peerCertsLength; unsigned int peerCertsLength;
const gnutls_datum_t* peerCerts = gnutls_certificate_get_peers const gnutls_datum_t* peerCerts = gnutls_certificate_get_peers
(sslSession_, &peerCertsLength); (sslSession_, &peerCertsLength);
if(!peerCerts) { if(!peerCerts || peerCertsLength == 0 ) {
throw DL_ABORT_EX(MSG_NO_CERT_FOUND); throw DL_ABORT_EX(MSG_NO_CERT_FOUND);
} }
Time now; Time now;
@ -1008,7 +1008,30 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname)
gnutls_strerror(ret))); gnutls_strerror(ret)));
} }
if(i == 0) { if(i == 0) {
if(!gnutls_x509_crt_check_hostname(cert, hostname.c_str())) { std::string commonName;
std::vector<std::string> dnsNames;
std::vector<std::string> ipAddrs;
int ret = 0;
char altName[256];
size_t altNameLen;
for(int j = 0; !(ret < 0); ++j) {
altNameLen = sizeof(altName);
ret = gnutls_x509_crt_get_subject_alt_name(cert, j, altName,
&altNameLen, 0);
if(ret == GNUTLS_SAN_DNSNAME) {
dnsNames.push_back(std::string(altName, altNameLen));
} else if(ret == GNUTLS_SAN_IPADDRESS) {
ipAddrs.push_back(std::string(altName, altNameLen));
}
}
altNameLen = sizeof(altName);
ret = gnutls_x509_crt_get_dn_by_oid(cert,
GNUTLS_OID_X520_COMMON_NAME, 0, 0,
altName, &altNameLen);
if(ret == 0) {
commonName.assign(altName, altNameLen);
}
if(!net::verifyHostname(hostname, dnsNames, ipAddrs, commonName)) {
throw DL_ABORT_EX(MSG_HOSTNAME_NOT_MATCH); throw DL_ABORT_EX(MSG_HOSTNAME_NOT_MATCH);
} }
} }