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..c025f5bfab33a7eb6fd4a83ab22ebe9776ee6eba |
--- /dev/null |
+++ b/net/cert/internal/name_constraints_unittest.cc |
@@ -0,0 +1,1095 @@ |
+// 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 "net/cert/internal/test_helpers.h" |
+#include "net/der/parser.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace net { |
+namespace { |
+ |
+der::Input SequenceValueFromString(const std::string* s) { |
eroman
2015/08/26 19:56:44
This is the same function used in verify_name_matc
mattm
2015/08/29 01:37:19
Done.
|
+ der::Parser parser(InputFromString(s)); |
+ 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) { |
+ std::string path = "net/data/name_constraints_unittest/name_constraints/" + |
+ basename + ".pem"; |
+ |
+ const PemBlockMapping mappings[] = { |
+ {token.c_str(), result}, |
eroman
2015/08/26 19:56:44
This reads funny. Can you either change the |toke|
mattm
2015/08/29 01:37:19
Done.
|
+ }; |
+ |
+ return ReadTestDataFromPemFile(path, mappings); |
+} |
+ |
+::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( |
eroman
2015/08/26 19:56:44
nit: newline
mattm
2015/08/29 01:37:19
Done.
|
+ 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) { |
eroman
2015/08/26 19:56:44
Underscores in Gtest names are discouraged/banned:
mattm
2015/08/29 01:37:19
Done.
|
+ 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)); |
eroman
2015/08/26 19:56:44
nit: I find it more readable to include the ".pem"
mattm
2015/08/29 01:37:19
Done.
|
+ |
+ 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 |