From b68e0a5527bad4faa9bc665c3d069ddbf0bb7c1a Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 31 Mar 2012 21:21:18 +0900 Subject: [PATCH] Use net::verifyHostname() with gnutls. We now don't use gnutls_x509_crt_check_hostname() any more. --- src/SocketCore.cc | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/SocketCore.cc b/src/SocketCore.cc index beb8507f..aeac675f 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -887,10 +887,10 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname) (fmt(MSG_CERT_VERIFICATION_FAILED, X509_verify_cert_error_string(verifyResult))); } - GENERAL_NAMES* altNames; std::string commonName; std::vector dnsNames; std::vector ipAddrs; + GENERAL_NAMES* altNames; altNames = reinterpret_cast (X509_get_ext_d2i(peerCert, NID_subject_alt_name, NULL, NULL)); if(altNames) { @@ -987,7 +987,7 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname) unsigned int peerCertsLength; const gnutls_datum_t* peerCerts = gnutls_certificate_get_peers (sslSession_, &peerCertsLength); - if(!peerCerts) { + if(!peerCerts || peerCertsLength == 0 ) { throw DL_ABORT_EX(MSG_NO_CERT_FOUND); } Time now; @@ -1008,7 +1008,30 @@ bool SocketCore::initiateSecureConnection(const std::string& hostname) gnutls_strerror(ret))); } if(i == 0) { - if(!gnutls_x509_crt_check_hostname(cert, hostname.c_str())) { + std::string commonName; + std::vector dnsNames; + std::vector 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); } }