summaryrefslogtreecommitdiffstats
path: root/net/cert/cert_verify_proc.cc
diff options
context:
space:
mode:
authorrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-17 02:09:08 +0000
committerrsleevi@chromium.org <rsleevi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-17 02:09:08 +0000
commitff35321f8eb52f5f6ae54a89a07a0c729854e548 (patch)
tree876fa0f34fdf64781e7296cb1c4693c0ce96b94f /net/cert/cert_verify_proc.cc
parente806cd78897dfcb7122bc5a69993f2c6d0c1f7e2 (diff)
downloadchromium_src-ff35321f8eb52f5f6ae54a89a07a0c729854e548.zip
chromium_src-ff35321f8eb52f5f6ae54a89a07a0c729854e548.tar.gz
chromium_src-ff35321f8eb52f5f6ae54a89a07a0c729854e548.tar.bz2
Warn if a well-known/"public" CA issues a certificate for a non-TLD
In preparation for new gTLDs being issued, begin phasing out the process of permitting publicly-trusted, well-known CAs to issue certificates for names that the CA cannot verify exclusive control over, such as "webmail" or "intranet.corp". Instead, require all publicly-trusted certificates be issued for domains that chain to an ICANN-recognized root zone (registry controlled domain). For certs that fail to meet this basic criteria, do not display the page as secure, as an attacker may be able to go to another CA (or even the same CA as the 'legitimate' site) and get a valid, publicly-trusted certificate for the same name. This does not cause an interstitial to be shown, but represents the first step to phasing out the practice. BUG=119212 TEST=[to be filled in] Review URL: https://chromiumcodereview.appspot.com/15203007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200704 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/cert/cert_verify_proc.cc')
-rw-r--r--net/cert/cert_verify_proc.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/net/cert/cert_verify_proc.cc b/net/cert/cert_verify_proc.cc
index a7f56b7..9022651 100644
--- a/net/cert/cert_verify_proc.cc
+++ b/net/cert/cert_verify_proc.cc
@@ -7,7 +7,10 @@
#include "base/metrics/histogram.h"
#include "base/sha1.h"
#include "build/build_config.h"
+#include "googleurl/src/url_canon.h"
#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cert/cert_status_flags.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_result.h"
@@ -150,6 +153,14 @@ int CertVerifyProc::Verify(X509Certificate* cert,
rv = MapCertStatusToNetError(verify_result->cert_status);
}
+ // Flag certificates from publicly-trusted CAs that are issued to intranet
+ // hosts. While the CA/Browser Forum Baseline Requirements (v1.1) permit
+ // these to be issued until 1 November 2015, they represent a real risk for
+ // the deployment of gTLDs and are being phased out.
+ if (verify_result->is_issued_by_known_root && IsHostnameNonUnique(hostname)) {
+ verify_result->cert_status |= CERT_STATUS_NON_UNIQUE_NAME;
+ }
+
return rv;
}
@@ -286,4 +297,39 @@ bool CertVerifyProc::IsPublicKeyBlacklisted(
return false;
}
+// static
+bool CertVerifyProc::IsHostnameNonUnique(const std::string& hostname) {
+ // CanonicalizeHost requires surrounding brackets to parse an IPv6 address.
+ const std::string host_or_ip = hostname.find(':') != std::string::npos ?
+ "[" + hostname + "]" : hostname;
+ url_canon::CanonHostInfo host_info;
+ std::string canonical_name = CanonicalizeHost(host_or_ip, &host_info);
+
+ // If canonicalization fails, then the input is truly malformed. However,
+ // to avoid mis-reporting bad inputs as "non-unique", treat them as unique.
+ if (canonical_name.empty())
+ return false;
+
+ // If |hostname| is an IP address, presume it's unique.
+ // TODO(rsleevi): In the future, this should also reject IP addresses in
+ // IANA-reserved ranges, since those are also non-unique among publicly
+ // trusted CAs.
+ if (host_info.IsIPAddress())
+ return false;
+
+ // Check for a registry controlled portion of |hostname|, ignoring private
+ // registries, as they already chain to ICANN-administered registries,
+ // and explicitly ignoring unknown registries.
+ //
+ // Note: This means that as new gTLDs are introduced on the Internet, they
+ // will be treated as non-unique until the registry controlled domain list
+ // is updated. However, because gTLDs are expected to provide significant
+ // advance notice to deprecate older versions of this code, this an
+ // acceptable tradeoff.
+ return 0 == registry_controlled_domains::GetRegistryLength(
+ canonical_name,
+ registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
+ registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
+}
+
} // namespace net