| Index: net/cert/internal/name_constraints_unittest.cc
|
| diff --git a/net/cert/internal/name_constraints_unittest.cc b/net/cert/internal/name_constraints_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..483ca2d48943f5cacdcfd795a55fb4b2e4df73be
|
| --- /dev/null
|
| +++ b/net/cert/internal/name_constraints_unittest.cc
|
| @@ -0,0 +1,1121 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "net/cert/internal/name_constraints.h"
|
| +
|
| +#include "base/base_paths.h"
|
| +#include "base/files/file_path.h"
|
| +#include "base/files/file_util.h"
|
| +#include "base/path_service.h"
|
| +#include "net/cert/pem_tokenizer.h"
|
| +#include "net/der/parser.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace net {
|
| +namespace {
|
| +
|
| +der::Input InputFromString(const std::string& s) {
|
| + return der::Input(reinterpret_cast<const uint8_t*>(s.data()), s.size());
|
| +}
|
| +
|
| +der::Input SequenceValueFromString(const std::string& s) {
|
| + der::Parser parser(
|
| + der::Input(reinterpret_cast<const uint8_t*>(s.data()), s.size()));
|
| + der::Input data;
|
| + if (!parser.ReadTag(der::kSequence, &data)) {
|
| + EXPECT_TRUE(false);
|
| + return der::Input();
|
| + }
|
| + if (parser.HasMore()) {
|
| + EXPECT_TRUE(false);
|
| + return der::Input();
|
| + }
|
| + return data;
|
| +}
|
| +
|
| +::testing::AssertionResult LoadTestData(const std::string& token,
|
| + const std::string& basename,
|
| + std::string* result) {
|
| + base::FilePath src_root;
|
| + PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
|
| + std::string filename = basename + ".pem";
|
| + base::FilePath filepath =
|
| + src_root.Append(
|
| + FILE_PATH_LITERAL(
|
| + "net/data/name_constraints_unittest/name_constraints/"))
|
| + .AppendASCII(filename);
|
| +
|
| + std::string file_data;
|
| + if (!base::ReadFileToString(filepath, &file_data)) {
|
| + return ::testing::AssertionFailure()
|
| + << "ReadFileToString returned false on " << filename;
|
| + }
|
| +
|
| + std::vector<std::string> pem_headers;
|
| + pem_headers.push_back(token);
|
| + PEMTokenizer pem_tokenizer(file_data, pem_headers);
|
| + if (!pem_tokenizer.GetNext()) {
|
| + return ::testing::AssertionFailure() << "PEM.GetNext returned false on "
|
| + << filename << " with header "
|
| + << token;
|
| + }
|
| +
|
| + result->assign(pem_tokenizer.data());
|
| + return ::testing::AssertionSuccess();
|
| +}
|
| +
|
| +::testing::AssertionResult LoadTestName(const std::string& basename,
|
| + std::string* result) {
|
| + return LoadTestData("NAME", basename, result);
|
| +}
|
| +
|
| +::testing::AssertionResult LoadTestNameConstraint(const std::string& basename,
|
| + std::string* result) {
|
| + return LoadTestData("NAME CONSTRAINTS", basename, result);
|
| +}
|
| +
|
| +::testing::AssertionResult LoadTestSubjectAltName(const std::string& basename,
|
| + std::string* result) {
|
| + return LoadTestData("SUBJECT ALTERNATIVE NAME", basename, result);
|
| +}
|
| +
|
| +const int kOtherNameFlag = 1 << 0;
|
| +const int kRfc822NameFlag = 1 << 1;
|
| +const int kDnsNameFlag = 1 << 2;
|
| +const int kX400AddressFlag = 1 << 3;
|
| +const int kDirectoryNameFlag = 1 << 4;
|
| +const int kEdiPartyNameFlag = 1 << 5;
|
| +const int kUniformResourceIdentifierFlag = 1 << 6;
|
| +const int kIpAddressFlag = 1 << 7;
|
| +const int kRegisteredIdFlag = 1 << 8;
|
| +const int kAllFlags = (1 << 9) - 1;
|
| +::testing::AssertionResult CheckNotPresent(
|
| + const NameConstraints& name_constraints,
|
| + int flag) {
|
| + if (flag & kOtherNameFlag && !name_constraints.IsPermittedOtherName())
|
| + return ::testing::AssertionFailure() << "contained otherNames";
|
| + if (flag & kRfc822NameFlag && !name_constraints.IsPermittedRFC822Name())
|
| + return ::testing::AssertionFailure() << "contained rfc822Names";
|
| + if (flag & kDnsNameFlag) {
|
| + if (!name_constraints.IsPermittedDNSName("a") ||
|
| + !name_constraints.IsPermittedDNSName("b"))
|
| + return ::testing::AssertionFailure() << "contained dNSNames";
|
| + }
|
| + if (flag & kX400AddressFlag && !name_constraints.IsPermittedX400Address())
|
| + return ::testing::AssertionFailure() << "contained x400Addresses";
|
| + if (flag & kDirectoryNameFlag) {
|
| + std::string name_us;
|
| + ::testing::AssertionResult r(::testing::AssertionFailure());
|
| + if (!(r = LoadTestName("name-us", &name_us)))
|
| + return r;
|
| + std::string name_jp;
|
| + if (!(r = LoadTestName("name-jp", &name_jp)))
|
| + return r;
|
| + std::string name_de;
|
| + if (!(r = LoadTestName("name-de", &name_de)))
|
| + return r;
|
| + std::string name_ca;
|
| + if (!(r = LoadTestName("name-ca", &name_ca)))
|
| + return r;
|
| + if (!name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us)) ||
|
| + !name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_jp)) ||
|
| + !name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_de)) ||
|
| + !name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_ca))) {
|
| + return ::testing::AssertionFailure() << "contained directoryNames";
|
| + }
|
| + }
|
| + if (flag & kEdiPartyNameFlag && !name_constraints.IsPermittedEdiPartyName())
|
| + return ::testing::AssertionFailure() << "contained ediPartyNames";
|
| + if (flag & kUniformResourceIdentifierFlag &&
|
| + !name_constraints.IsPermittedURI()) {
|
| + return ::testing::AssertionFailure()
|
| + << "contained uniformResourceIdentifiers";
|
| + }
|
| + if (flag & kIpAddressFlag) {
|
| + const uint8_t ip4a[] = {192, 168, 0, 1};
|
| + const uint8_t ip4b[] = {255, 255, 255, 255};
|
| + // clang-format off
|
| + const uint8_t ip6a[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
| + 9, 10, 11, 12, 13, 14, 15, 16};
|
| + const uint8_t ip6b[] = {255, 255, 255, 255, 255, 255, 255, 255,
|
| + 255, 255, 255, 255, 255, 255, 255, 255};
|
| + // clang-format on
|
| + if (!name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4a, ip4a + arraysize(ip4a))) ||
|
| + !name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4b, ip4b + arraysize(ip4b))) ||
|
| + !name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6a, ip6a + arraysize(ip6a))) ||
|
| + !name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6b, ip6b + arraysize(ip6b)))) {
|
| + return ::testing::AssertionFailure() << "contained iPAddresses";
|
| + }
|
| + }
|
| + if (flag & kRegisteredIdFlag && !name_constraints.IsPermittedRegisteredId())
|
| + return ::testing::AssertionFailure() << "contained registeredIDs";
|
| +
|
| + return ::testing::AssertionSuccess();
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class ParseNameConstraints
|
| + : public ::testing::TestWithParam<::testing::tuple<bool>> {
|
| + public:
|
| + bool is_critical() const { return ::testing::get<0>(GetParam()); }
|
| +};
|
| +
|
| +// Run the tests with the name constraints marked critical and non-critical. For
|
| +// supported name types, the results should be the same for both.
|
| +INSTANTIATE_TEST_CASE_P(InstantiationName,
|
| + ParseNameConstraints,
|
| + ::testing::Values(true, false));
|
| +
|
| +TEST_P(ParseNameConstraints, DNSNames) {
|
| + std::string a;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname", &a));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(name_constraints.Parse(InputFromString(a), is_critical()));
|
| +
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("permitted.example.com"));
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("permitted.example.com."));
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("a.permitted.example.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("apermitted.example.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("apermitted.example.com."));
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("alsopermitted.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("excluded.permitted.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("a.excluded.permitted.example.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName(
|
| + "stillnotpermitted.excluded.permitted.example.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName(
|
| + "a.stillnotpermitted.excluded.permitted.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("extraneousexclusion.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("a.extraneousexclusion.example.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("other.example.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("other.com"));
|
| +
|
| + // Wildcard names:
|
| + // Pattern could match excluded.permitted.example.com, thus should not be
|
| + // allowed.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("*.permitted.example.com"));
|
| + // Entirely within excluded name, obviously not allowed.
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("*.excluded.permitted.example.com"));
|
| + // Within permitted.example.com and cannot match any exclusion, thus these are
|
| + // allowed.
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedDNSName("*.foo.permitted.example.com"));
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedDNSName("*.alsopermitted.example.com"));
|
| + // Matches permitted.example2.com, but also matches other .example2.com names
|
| + // which are not in either permitted or excluded, so not allowed.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("*.example2.com"));
|
| + // Partial wildcards are not supported, so these name are permitted even if
|
| + // it seems like they shouldn't be. It's fine, since certificate verification
|
| + // won't treat them as wildcard names either.
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedDNSName("*xcluded.permitted.example.com"));
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedDNSName("exclude*.permitted.example.com"));
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedDNSName("excl*ded.permitted.example.com"));
|
| + // Garbage wildcard data.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("*."));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("*.*"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName(".*"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("*"));
|
| + // Matches SAN with trailing dot.
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("permitted.example3.com"));
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("permitted.example3.com."));
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("a.permitted.example3.com"));
|
| + EXPECT_TRUE(name_constraints.IsPermittedDNSName("a.permitted.example3.com."));
|
| +
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags & ~kDnsNameFlag));
|
| +
|
| + std::string san;
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-permitted", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname", &san));
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, DNSNames_ExcludeOnly) {
|
| + std::string a;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname-excluded", &a));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(name_constraints.Parse(InputFromString(a), is_critical()));
|
| +
|
| + // Only "excluded.permitted.example.com" is excluded, but since no dNSNames
|
| + // are permitted, everything is excluded.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName(""));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("foo.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("permitted.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("excluded.permitted.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("a.excluded.permitted.example.com"));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, DNSNames_ExcludeAll) {
|
| + std::string a;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname-excludeall", &a));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(name_constraints.Parse(InputFromString(a), is_critical()));
|
| +
|
| + // "permitted.example.com" is in the permitted section, but since "" is
|
| + // excluded, nothing is permitted.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName(""));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("foo.com"));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDNSName("permitted.example.com"));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedDNSName("foo.permitted.example.com"));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, DirectoryNames) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("directoryname", &constraints_der));
|
| +
|
| + std::string name_us;
|
| + ASSERT_TRUE(LoadTestName("name-us", &name_us));
|
| + std::string name_us_ca;
|
| + ASSERT_TRUE(LoadTestName("name-us-california", &name_us_ca));
|
| + std::string name_us_ca_mountain_view;
|
| + ASSERT_TRUE(LoadTestName("name-us-california-mountain_view",
|
| + &name_us_ca_mountain_view));
|
| + std::string name_us_az;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona", &name_us_az));
|
| + std::string name_jp;
|
| + ASSERT_TRUE(LoadTestName("name-jp", &name_jp));
|
| + std::string name_jp_tokyo;
|
| + ASSERT_TRUE(LoadTestName("name-jp-tokyo", &name_jp_tokyo));
|
| + std::string name_de;
|
| + ASSERT_TRUE(LoadTestName("name-de", &name_de));
|
| + std::string name_ca;
|
| + ASSERT_TRUE(LoadTestName("name-ca", &name_ca));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + // Not in any permitted subtree.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_ca)));
|
| + // Within the permitted C=US subtree.
|
| + EXPECT_TRUE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us)));
|
| + // Within the permitted C=US subtree.
|
| + EXPECT_TRUE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us_az)));
|
| + // Within the permitted C=US subtree, however the excluded C=US,ST=California
|
| + // subtree takes priority.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us_ca)));
|
| + // Within the permitted C=US subtree as well as the permitted
|
| + // C=US,ST=California,L=Mountain View subtree, however the excluded
|
| + // C=US,ST=California subtree still takes priority.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us_ca_mountain_view)));
|
| + // Not in any permitted subtree, and also inside the extraneous excluded C=DE
|
| + // subtree.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_de)));
|
| + // Not in any permitted subtree.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_jp)));
|
| + // Within the permitted C=JP,ST=Tokyo subtree.
|
| + EXPECT_TRUE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_jp_tokyo)));
|
| +
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kDirectoryNameFlag));
|
| +
|
| + // Within the permitted C=US subtree.
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(SequenceValueFromString(name_us),
|
| + der::Input(),
|
| + false /* is_leaf_cert */));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us), der::Input(), true /* is_leaf_cert */));
|
| + // Within the permitted C=US subtree, however the excluded C=US,ST=California
|
| + // subtree takes priority.
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_ca),
|
| + der::Input(), false /* is_leaf_cert */));
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_ca),
|
| + der::Input(), true /* is_leaf_cert */));
|
| +
|
| + std::string san;
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-permitted", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname", &san));
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, DirectoryNames_ExcludeOnly) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("directoryname-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + std::string name_empty;
|
| + ASSERT_TRUE(LoadTestName("name-empty", &name_empty));
|
| + std::string name_us;
|
| + ASSERT_TRUE(LoadTestName("name-us", &name_us));
|
| + std::string name_us_ca;
|
| + ASSERT_TRUE(LoadTestName("name-us-california", &name_us_ca));
|
| + std::string name_us_ca_mountain_view;
|
| + ASSERT_TRUE(LoadTestName("name-us-california-mountain_view",
|
| + &name_us_ca_mountain_view));
|
| +
|
| + // Only "C=US,ST=California" is excluded, but since no directoryNames are
|
| + // permitted, everything is excluded.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_empty)));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us)));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us_ca)));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us_ca_mountain_view)));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, DirectoryNames_ExcludeAll) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("directoryname-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + std::string name_empty;
|
| + ASSERT_TRUE(LoadTestName("name-empty", &name_empty));
|
| + std::string name_us;
|
| + ASSERT_TRUE(LoadTestName("name-us", &name_us));
|
| + std::string name_us_ca;
|
| + ASSERT_TRUE(LoadTestName("name-us-california", &name_us_ca));
|
| + std::string name_us_ca_mountain_view;
|
| + ASSERT_TRUE(LoadTestName("name-us-california-mountain_view",
|
| + &name_us_ca_mountain_view));
|
| + std::string name_jp;
|
| + ASSERT_TRUE(LoadTestName("name-jp", &name_jp));
|
| +
|
| + // "C=US" is in the permitted section, but since an empty
|
| + // directoryName is excluded, nothing is permitted.
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_empty)));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us)));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_us_ca)));
|
| + EXPECT_FALSE(name_constraints.IsPermittedDirectoryName(
|
| + SequenceValueFromString(name_jp)));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IPAdresses) {
|
| + std::string a;
|
| + ASSERT_TRUE(LoadTestNameConstraint("ipaddress", &a));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(name_constraints.Parse(InputFromString(a), is_critical()));
|
| +
|
| + // IPv4 tests:
|
| + {
|
| + // Not in any permitted range.
|
| + const uint8_t ip4[] = {192, 169, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Within the permitted 192.168.0.0/255.255.0.0 range.
|
| + const uint8_t ip4[] = {192, 168, 0, 1};
|
| + EXPECT_TRUE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Within the permitted 192.168.0.0/255.255.0.0 range, however the
|
| + // excluded 192.168.5.0/255.255.255.0 takes priority.
|
| + const uint8_t ip4[] = {192, 168, 5, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Within the permitted 192.168.0.0/255.255.0.0 range as well as the
|
| + // permitted 192.168.5.32/255.255.255.96 range, however the excluded
|
| + // 192.168.5.0/255.255.255.0 still takes priority.
|
| + const uint8_t ip4[] = {192, 168, 5, 33};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Not in any permitted range. (Just outside the 192.167.5.32/255.255.255.96
|
| + // range.)
|
| + const uint8_t ip4[] = {192, 167, 5, 31};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Within the permitted 192.167.5.32/255.255.255.96 range.
|
| + const uint8_t ip4[] = {192, 167, 5, 32};
|
| + EXPECT_TRUE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Within the permitted 192.167.5.32/255.255.255.96 range.
|
| + const uint8_t ip4[] = {192, 167, 5, 63};
|
| + EXPECT_TRUE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Not in any permitted range. (Just outside the 192.167.5.32/255.255.255.96
|
| + // range.)
|
| + const uint8_t ip4[] = {192, 167, 5, 64};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + // Not in any permitted range, and also inside the extraneous excluded
|
| + // 192.166.5.32/255.255.255.96 range.
|
| + const uint8_t ip4[] = {192, 166, 5, 32};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| +
|
| + // IPv6 tests:
|
| + {
|
| + // Not in any permitted range.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Within the permitted
|
| + // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 1};
|
| + EXPECT_TRUE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Within the permitted
|
| + // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range, however
|
| + // the excluded
|
| + // 102:304:506:708:90a:b0c:500:0/ffff:ffff:ffff:ffff:ffff:ffff:ff00:0 takes
|
| + // priority.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 0, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Within the permitted
|
| + // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: range as well
|
| + // as the permitted
|
| + // 102:304:506:708:90a:b0c:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0,
|
| + // however the excluded
|
| + // 102:304:506:708:90a:b0c:500:0/ffff:ffff:ffff:ffff:ffff:ffff:ff00:0 takes
|
| + // priority.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 5, 33, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Not in any permitted range. (Just outside the
|
| + // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0
|
| + // range.)
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
| + 9, 10, 11, 11, 5, 31, 255, 255};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Within the permitted
|
| + // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 5, 32, 0, 0};
|
| + EXPECT_TRUE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Within the permitted
|
| + // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8,
|
| + 9, 10, 11, 11, 5, 63, 255, 255};
|
| + EXPECT_TRUE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Not in any permitted range. (Just outside the
|
| + // 102:304:506:708:90a:b0b:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0
|
| + // range.)
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 5, 64, 0, 0};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + // Not in any permitted range, and also inside the extraneous excluded
|
| + // 102:304:506:708:90a:b0a:520:0/ffff:ffff:ffff:ffff:ffff:ffff:ff60:0 range.
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 10, 5, 33, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| +
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags & ~kIpAddressFlag));
|
| +
|
| + std::string san;
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-permitted", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-dnsname", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-directoryname", &san));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +
|
| + ASSERT_TRUE(LoadTestSubjectAltName("san-excluded-ipaddress", &san));
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(der::Input(),
|
| + InputFromString(san), true));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IPAdresses_ExcludeOnly) {
|
| + std::string a;
|
| + ASSERT_TRUE(LoadTestNameConstraint("ipaddress-excluded", &a));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(name_constraints.Parse(InputFromString(a), is_critical()));
|
| +
|
| + // Only 192.168.5.0/255.255.255.0 is excluded, but since no iPAddresses
|
| + // are permitted, everything is excluded.
|
| + {
|
| + const uint8_t ip4[] = {192, 168, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + const uint8_t ip4[] = {192, 168, 5, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IPAdresses_ExcludeAll) {
|
| + std::string a;
|
| + ASSERT_TRUE(LoadTestNameConstraint("ipaddress-excludeall", &a));
|
| +
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(name_constraints.Parse(InputFromString(a), is_critical()));
|
| +
|
| + // 192.168.0.0/255.255.0.0 and
|
| + // 102:304:506:708:90a:b0c::/ffff:ffff:ffff:ffff:ffff:ffff:: are permitted,
|
| + // but since 0.0.0.0/0 and ::/0 are excluded nothing is permitted.
|
| + {
|
| + const uint8_t ip4[] = {192, 168, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + const uint8_t ip4[] = {1, 1, 1, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip4, ip4 + arraysize(ip4))));
|
| + }
|
| + {
|
| + const uint8_t ip6[] = {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| + {
|
| + const uint8_t ip6[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 0, 0, 0, 1};
|
| + EXPECT_FALSE(name_constraints.IsPermittedIP(
|
| + IPAddressNumber(ip6, ip6 + arraysize(ip6))));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, otherNamesInPermitted) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("othername-permitted", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedOtherName());
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags & ~kOtherNameFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, otherNamesInExcluded) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("othername-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedOtherName());
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags & ~kOtherNameFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, Rfc822NamesInPermitted) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("rfc822name-permitted", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedRFC822Name());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kRfc822NameFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, Rfc822NamesInExcluded) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("rfc822name-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedRFC822Name());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kRfc822NameFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, x400AddresssInPermitted) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("x400address-permitted", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedX400Address());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kX400AddressFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, x400AddresssInExcluded) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("x400address-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedX400Address());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kX400AddressFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, ediPartyNamesInPermitted) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("edipartyname-permitted", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedEdiPartyName());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kEdiPartyNameFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, ediPartyNamesInExcluded) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("edipartyname-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedEdiPartyName());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kEdiPartyNameFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, registeredIDsInPermitted) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("registeredid-permitted", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedRegisteredId());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kRegisteredIdFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, registeredIDsInExcluded) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("registeredid-excluded", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + if (is_critical()) {
|
| + EXPECT_FALSE(name_constraints.IsPermittedRegisteredId());
|
| + EXPECT_TRUE(
|
| + CheckNotPresent(name_constraints, kAllFlags & ~kRegisteredIdFlag));
|
| + } else {
|
| + EXPECT_TRUE(CheckNotPresent(name_constraints, kAllFlags));
|
| + }
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints,
|
| + failsOnGeneralSubtreeWithMinimumZeroEncodedUnnecessarily) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_min_0", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + // The value should not be in the DER encoding if it is the default. But this
|
| + // could be changed to allowed if there are buggy encoders out there that
|
| + // include it anyway.
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, failsOnGeneralSubtreeWithMinimum) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_min_1", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + // Could handle this more gracefully (see TODO in ParseGeneralSubtrees).
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints,
|
| + failsOnGeneralSubtreeWithMinimumZeroEncodedUnnecessarilyAndMaximum) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("dnsname-with_min_0_and_max", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + // Could handle this more gracefully (see TODO in ParseGeneralSubtrees).
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, failsOnGeneralSubtreeWithMinimumAndMaximum) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(
|
| + LoadTestNameConstraint("dnsname-with_min_1_and_max", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + // Could handle this more gracefully (see TODO in ParseGeneralSubtrees).
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, failsOnGeneralSubtreeWithMaximum) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname-with_max", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + // Could handle this more gracefully (see TODO in ParseGeneralSubtrees).
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, failsOnEmptyExtensionValue) {
|
| + std::string constraints_der = "";
|
| + NameConstraints name_constraints;
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, failsOnEmptyPermittedAndExcluded) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("invalid-no_subtrees", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_FALSE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IsPermittedCert_SubjectEmailAddress_ok) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("directoryname", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + std::string name_us_arizona_email;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-email", &name_us_arizona_email));
|
| +
|
| + // Name constraints don't contain rfc822Name, so emailAddress in subject is
|
| + // allowed regardless.
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_arizona_email), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_arizona_email), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IsPermittedCert_SubjectEmailAddress_notok) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("rfc822name-permitted", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + std::string name_us_arizona_email;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-email", &name_us_arizona_email));
|
| +
|
| + // Name constraints contain rfc822Name, so emailAddress in subject is not
|
| + // allowed if the constraints were critical.
|
| + EXPECT_EQ(!is_critical(), name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_arizona_email),
|
| + der::Input(), true /* is_leaf_cert */));
|
| + EXPECT_EQ(!is_critical(), name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_arizona_email),
|
| + der::Input(), false /* is_leaf_cert */));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IsPermittedCert_SubjectDnsNames) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + ASSERT_TRUE(LoadTestNameConstraint("directoryname", &constraints_der));
|
| + // This is a bit of a hack, but Parse can be called multiple times to load
|
| + // different constraints into the same object (doesn't do a proper merge, but
|
| + // good enough for this test).
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + std::string name_us_az;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona", &name_us_az));
|
| + std::string name_us_az_foocom;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-foo.com", &name_us_az_foocom));
|
| +
|
| + // foo.com is not within the permitted dNSName constraints:
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_foocom), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + // commonName check is only done for leaf certs, so this is allowed:
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_foocom), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + std::string name_us_az_permitted;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-permitted.example.com",
|
| + &name_us_az_permitted));
|
| + // permitted.example.com is within the permitted dNSName constraints and the
|
| + // permitted C=US directoryName constraint:
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_permitted), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_permitted), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + std::string name_us_ca_permitted;
|
| + ASSERT_TRUE(LoadTestName("name-us-california-permitted.example.com",
|
| + &name_us_ca_permitted));
|
| + // permitted.example.com is within the permitted dNSName constraints but the
|
| + // subject is within the excluded C=US,ST=California directoryName, so not
|
| + // allowed anyway:
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_ca_permitted), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_ca_permitted), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + // As a leaf cert with no SubjectAltName, the subject is expected to have a
|
| + // host in commonName, this subject has no commonName field, so fails:
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_az),
|
| + der::Input(), true /* is_leaf_cert */));
|
| + // Within the permitted C=US subtree, not a leaf cert, so does not need
|
| + // a host in commonName.
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_az),
|
| + der::Input(), false /* is_leaf_cert */));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IsPermittedCert_SubjectIpAddresses) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("ipaddress", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + ASSERT_TRUE(LoadTestNameConstraint("directoryname", &constraints_der));
|
| + // This is a bit of a hack, but Parse can be called multiple times to load
|
| + // different constraints into the same object (doesn't do a proper merge, but
|
| + // good enough for this test).
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| + ASSERT_TRUE(LoadTestNameConstraint("dnsname", &constraints_der));
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + std::string name_us_az;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona", &name_us_az));
|
| + std::string name_us_az_1_1_1_1;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-1.1.1.1", &name_us_az_1_1_1_1));
|
| +
|
| + // 1.1.1.1 is not within the permitted iPAddress constraints:
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_1_1_1_1), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + // commonName check is only done for leaf certs, so this is allowed:
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_1_1_1_1), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + std::string name_us_az_192_168_1_1;
|
| + ASSERT_TRUE(
|
| + LoadTestName("name-us-arizona-192.168.1.1", &name_us_az_192_168_1_1));
|
| + // 192.168.1.1 is within the permitted iPAddress constraints and the
|
| + // permitted C=US directoryName constraint:
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_192_168_1_1), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_192_168_1_1), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + std::string name_us_ca_192_168_1_1;
|
| + ASSERT_TRUE(
|
| + LoadTestName("name-us-california-192.168.1.1", &name_us_ca_192_168_1_1));
|
| + // 192.168.1.1 is within the permitted iPAddress constraints but the
|
| + // subject is within the excluded C=US,ST=California directoryName, so not
|
| + // allowed anyway:
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_ca_192_168_1_1), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_ca_192_168_1_1), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + std::string name_us_az_ipv6;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-ipv6", &name_us_az_ipv6));
|
| + // 102:304:506:708:90a:b0c::1 is within the permitted iPAddress constraints
|
| + // and the permitted C=US directoryName constraint, but Chrome only handles
|
| + // IPv4 addresses in commonName so the address will be checked against dNSName
|
| + // constraints instead, which will not match any permitted names.
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_az_ipv6),
|
| + der::Input(), true /* is_leaf_cert */));
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_az_ipv6),
|
| + der::Input(), false /* is_leaf_cert */));
|
| +
|
| + // As a leaf cert with no SubjectAltName, the subject is expected to have a
|
| + // host in commonName, this subject has no commonName field, so fails:
|
| + EXPECT_FALSE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_az),
|
| + der::Input(), true /* is_leaf_cert */));
|
| + // Within the permitted C=US subtree, not a leaf cert, so does not need
|
| + // a host in commonName.
|
| + EXPECT_TRUE(
|
| + name_constraints.IsPermittedCert(SequenceValueFromString(name_us_az),
|
| + der::Input(), false /* is_leaf_cert */));
|
| +}
|
| +
|
| +TEST_P(ParseNameConstraints, IsPermittedCert_Subject_commonName_encodings) {
|
| + std::string constraints_der;
|
| + ASSERT_TRUE(LoadTestNameConstraint("ipaddress", &constraints_der));
|
| + NameConstraints name_constraints;
|
| + EXPECT_TRUE(
|
| + name_constraints.Parse(InputFromString(constraints_der), is_critical()));
|
| +
|
| + // CommonName encoded as BMPString: should work since we convert to UTF8
|
| + // before parsing.
|
| + std::string name_us_az_192_168_1_1_bmp;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-192.168.1.1-bmp",
|
| + &name_us_az_192_168_1_1_bmp));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_192_168_1_1_bmp), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_192_168_1_1_bmp), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +
|
| + // CommonName encoded as TeletexString: should not work, TeletexString is not
|
| + // supported.
|
| + std::string name_us_az_192_168_1_1_t61;
|
| + ASSERT_TRUE(LoadTestName("name-us-arizona-192.168.1.1-t61",
|
| + &name_us_az_192_168_1_1_t61));
|
| + EXPECT_FALSE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_192_168_1_1_t61), der::Input(),
|
| + true /* is_leaf_cert */));
|
| + // If it's not a leaf cert, commonName is not checked, so this is allowed.
|
| + EXPECT_TRUE(name_constraints.IsPermittedCert(
|
| + SequenceValueFromString(name_us_az_192_168_1_1_t61), der::Input(),
|
| + false /* is_leaf_cert */));
|
| +}
|
| +
|
| +} // namespace net
|
|
|