diff options
author | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-03 23:07:28 +0000 |
---|---|---|
committer | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-03 23:07:28 +0000 |
commit | 7c8f18ab4383e497f0ba3663156abf81ea5af3e6 (patch) | |
tree | 55dad50fe5f4444083043ded0c259b81ae78fa67 /net/base/x509_openssl_util.cc | |
parent | a81ec206b45851a7ece856149fc6be76918b6f1d (diff) | |
download | chromium_src-7c8f18ab4383e497f0ba3663156abf81ea5af3e6.zip chromium_src-7c8f18ab4383e497f0ba3663156abf81ea5af3e6.tar.gz chromium_src-7c8f18ab4383e497f0ba3663156abf81ea5af3e6.tar.bz2 |
Add X509Certificate::VerifyCertName(string) API. This will be used
to check if a name matches a cert without doing a full certificate verify.
Use the API provided as part of NSS. For other platforms, provide a default
implementation based on GetDNSNames.
BUG=none
TEST=X509CertificateTest.WebkitCertParsing
Review URL: http://codereview.chromium.org/6612013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76824 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/base/x509_openssl_util.cc')
-rw-r--r-- | net/base/x509_openssl_util.cc | 117 |
1 files changed, 0 insertions, 117 deletions
diff --git a/net/base/x509_openssl_util.cc b/net/base/x509_openssl_util.cc index fe3d27d..31548f6 100644 --- a/net/base/x509_openssl_util.cc +++ b/net/base/x509_openssl_util.cc @@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/string_piece.h" -#include "base/string_util.h" #include "net/base/x509_cert_types.h" namespace net { @@ -70,122 +69,6 @@ bool ParseDate(ASN1_TIME* x509_time, base::Time* time) { return ParseCertificateDate(str_date, format, time); } -// TODO(joth): Investigate if we can upstream this into the OpenSSL library, -// to avoid duplicating this logic across projects. -bool VerifyHostname(const std::string& hostname, - const std::vector<std::string>& cert_names) { - DCHECK(!hostname.empty()); - - // Simple host name validation. A valid domain name must only contain - // alpha, digits, hyphens, and dots. An IP address may have digits and dots, - // and also square braces and colons for IPv6 addresses. - std::string reference_name; - reference_name.reserve(hostname.length()); - - bool found_alpha = false; - bool found_ip6_chars = false; - bool found_hyphen = false; - int dot_count = 0; - - size_t first_dot_index = std::string::npos; - for (std::string::const_iterator it = hostname.begin(); - it != hostname.end(); ++it) { - char c = *it; - if (IsAsciiAlpha(c)) { - found_alpha = true; - c = base::ToLowerASCII(c); - } else if (c == '.') { - ++dot_count; - if (first_dot_index == std::string::npos) - first_dot_index = reference_name.length(); - } else if (c == ':') { - found_ip6_chars = true; - } else if (c == '-') { - found_hyphen = true; - } else if (!IsAsciiDigit(c)) { - LOG(WARNING) << "Invalid char " << c << " in hostname " << hostname; - return false; - } - reference_name.push_back(c); - } - DCHECK(!reference_name.empty()); - - if (found_ip6_chars || !found_alpha) { - // For now we just do simple localhost IP address support, primarily as - // it's needed by the test server. TODO(joth): Replace this with full IP - // address support. See http://crbug.com/62973 - if (hostname == "127.0.0.1" && - std::find(cert_names.begin(), cert_names.end(), hostname) != - cert_names.end()) { - DVLOG(1) << "Allowing localhost IP certificate: " << hostname; - return true; - } - NOTIMPLEMENTED() << hostname; // See comment above. - return false; - } - - // |wildcard_domain| is the remainder of |host| after the leading host - // component is stripped off, but includes the leading dot e.g. - // "www.f.com" -> ".f.com". - // If there is no meaningful domain part to |host| (e.g. it is an IP address - // or contains no dots) then |wildcard_domain| will be empty. - // We required at least 3 components (i.e. 2 dots) as a basic protection - // against too-broad wild-carding. - base::StringPiece wildcard_domain; - if (found_alpha && !found_ip6_chars && dot_count >= 2) { - DCHECK(first_dot_index != std::string::npos); - wildcard_domain = reference_name; - wildcard_domain.remove_prefix(first_dot_index); - DCHECK(wildcard_domain.starts_with(".")); - } - - for (std::vector<std::string>::const_iterator it = cert_names.begin(); - it != cert_names.end(); ++it) { - // Catch badly corrupt cert names up front. - if (it->empty() || it->find('\0') != std::string::npos) { - LOG(WARNING) << "Bad name in cert: " << *it; - continue; - } - const std::string cert_name_string(StringToLowerASCII(*it)); - base::StringPiece cert_match(cert_name_string); - - // Remove trailing dot, if any. - if (cert_match.ends_with(".")) - cert_match.remove_suffix(1); - - // The hostname must be at least as long as the cert name it is matching, - // as we require the wildcard (if present) to match at least one character. - if (cert_match.length() > reference_name.length()) - continue; - - if (cert_match == reference_name) - return true; - - // Next see if this cert name starts with a wildcard, so long as the - // hostname we're matching against has a valid 'domain' part to match. - // Note the "-10" version of draft-saintandre-tls-server-id-check allows - // the wildcard to appear anywhere in the leftmost label, rather than - // requiring it to be the only character. See also http://crbug.com/60719 - if (wildcard_domain.empty() || !cert_match.starts_with("*")) - continue; - - // Erase the * but not the . from the domain, as we need to include the dot - // in the comparison. - cert_match.remove_prefix(1); - - // Do character by character comparison on the remainder to see - // if we have a wildcard match. This intentionally does no special handling - // for any other wildcard characters in |domain|; alternatively it could - // detect these and skip those candidate cert names. - if (cert_match == wildcard_domain) - return true; - } - DVLOG(1) << "Could not find any match for " << hostname - << " (canonicalized as " << reference_name - << ") in cert names " << JoinString(cert_names, '|'); - return false; -} - } // namespace x509_openssl_util } // namespace net |