Add some tests for anyPolicy.

anyPolicy causes crypto/x509 to synthesize policy nodes in places. Add
some test coverage for this.

Change-Id: I1b1dcba35088d6cabce6b40e36e478ec4756effa
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55753
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/test/make_policy_certs.go b/crypto/x509/test/make_policy_certs.go
index 73fcae3..89b1517 100644
--- a/crypto/x509/test/make_policy_certs.go
+++ b/crypto/x509/test/make_policy_certs.go
@@ -37,6 +37,7 @@
 
 	// https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.4
 	certificatePoliciesOID = asn1.ObjectIdentifier([]int{2, 5, 29, 32})
+	anyPolicyOID           = asn1.ObjectIdentifier([]int{2, 5, 29, 32, 0})
 
 	// https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.11
 	policyConstraintsOID = asn1.ObjectIdentifier([]int{2, 5, 29, 36})
@@ -171,6 +172,15 @@
 	intermediateRequire.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2}
 	mustGenerateCertificate("policy_intermediate_require_duplicate.pem", &intermediateRequire, &root)
 
+	// Corresponding certificates that instead assert the anyPolicy OID.
+	intermediateAny := intermediate
+	intermediateAny.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID}
+	mustGenerateCertificate("policy_intermediate_any.pem", &intermediateAny, &root)
+
+	leafAny := leaf
+	leafAny.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID}
+	mustGenerateCertificate("policy_leaf_any.pem", &leafAny, &intermediate)
+
 	// TODO(davidben): Generate more certificates to test policy validation more
 	// extensively, including an intermediate with constraints. For now this
 	// just tests the basic case.
diff --git a/crypto/x509/test/policy_intermediate_any.pem b/crypto/x509/test/policy_intermediate_any.pem
new file mode 100644
index 0000000..5a6b61a
--- /dev/null
+++ b/crypto/x509/test/policy_intermediate_any.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBkDCCATWgAwIBAgIBAjAKBggqhkjOPQQDAjAWMRQwEgYDVQQDEwtQb2xpY3kg
+Um9vdDAgFw0wMDAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowHjEcMBoGA1UE
+AxMTUG9saWN5IEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
+BOI6fKiM3jFLkLyAn88cvlw4SwxuygRjopP3FFBKHyUQvh3VVvfqSpSCSmp50Qia
+jQ6Dg7CTpVZVVH+bguT7JTCjajBoMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK
+BggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSQ0vf+Du6oawiE
+YcLF6z1QWoBtrjARBgNVHSAECjAIMAYGBFUdIAAwCgYIKoZIzj0EAwIDSQAwRgIh
+AOoHsgnQ3KA7e4e2BCyDoSaPo44NYXB4uQ0OFrC79O8VAiEAtIHnFBkYqdh84P44
+OYpH5jVq17Hk1wrzn62KwkICvfI=
+-----END CERTIFICATE-----
diff --git a/crypto/x509/test/policy_leaf_any.pem b/crypto/x509/test/policy_leaf_any.pem
new file mode 100644
index 0000000..21e8481
--- /dev/null
+++ b/crypto/x509/test/policy_leaf_any.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBjDCCATOgAwIBAgIBAzAKBggqhkjOPQQDAjAeMRwwGgYDVQQDExNQb2xpY3kg
+SW50ZXJtZWRpYXRlMCAXDTAwMDEwMTAwMDAwMFoYDzIxMDAwMTAxMDAwMDAwWjAa
+MRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMB
+BwNCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5w8u3SSwm7HZREvmcBCJBjVIREacR
+qI0umhzR2V5NLzBBP9yPD/A+Ch5Xo2QwYjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADAaBgNVHREEEzARgg93d3cuZXhh
+bXBsZS5jb20wEQYDVR0gBAowCDAGBgRVHSAAMAoGCCqGSM49BAMCA0cAMEQCIBs6
+kQg7CXahhSrji0B4KzW2z2QM0CLl3IiCsF7go7rrAiAya2gOki6RAPPtAavZKLFj
+fejsANmLWcQ5ctVeHoq8Gg==
+-----END CERTIFICATE-----
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index 248544a..2261dc3 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -5112,6 +5112,9 @@
   bssl::UniquePtr<X509> intermediate(CertFromPEM(
       GetTestData("crypto/x509/test/policy_intermediate.pem").c_str()));
   ASSERT_TRUE(intermediate);
+  bssl::UniquePtr<X509> intermediate_any(CertFromPEM(
+      GetTestData("crypto/x509/test/policy_intermediate_any.pem").c_str()));
+  ASSERT_TRUE(intermediate_any);
   bssl::UniquePtr<X509> intermediate_invalid(CertFromPEM(
       GetTestData("crypto/x509/test/policy_intermediate_invalid.pem").c_str()));
   ASSERT_TRUE(intermediate_invalid);
@@ -5120,8 +5123,7 @@
           .c_str()));
   ASSERT_TRUE(intermediate_duplicate);
   bssl::UniquePtr<X509> intermediate_require(CertFromPEM(
-      GetTestData("crypto/x509/test/policy_intermediate_require.pem")
-          .c_str()));
+      GetTestData("crypto/x509/test/policy_intermediate_require.pem").c_str()));
   ASSERT_TRUE(intermediate_require);
   bssl::UniquePtr<X509> intermediate_require_duplicate(CertFromPEM(
       GetTestData("crypto/x509/test/policy_intermediate_require_duplicate.pem")
@@ -5135,6 +5137,9 @@
   bssl::UniquePtr<X509> leaf(
       CertFromPEM(GetTestData("crypto/x509/test/policy_leaf.pem").c_str()));
   ASSERT_TRUE(leaf);
+  bssl::UniquePtr<X509> leaf_any(
+      CertFromPEM(GetTestData("crypto/x509/test/policy_leaf_any.pem").c_str()));
+  ASSERT_TRUE(leaf_any);
   bssl::UniquePtr<X509> leaf_invalid(CertFromPEM(
       GetTestData("crypto/x509/test/policy_leaf_invalid.pem").c_str()));
   ASSERT_TRUE(leaf_invalid);
@@ -5265,4 +5270,46 @@
                    /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
                      set_policies(param, {oid1.get()});
                    }));
+
+  // The leaf asserts anyPolicy, but the intermediate does not. The resulting
+  // valid policies are the intersection.
+  EXPECT_EQ(X509_V_OK,
+            Verify(leaf_any.get(), {root.get()}, {intermediate.get()}, /*crls=*/{},
+                   X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid1.get()});
+                   }));
+  EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY,
+            Verify(leaf_any.get(), {root.get()}, {intermediate.get()}, /*crls=*/{},
+                   X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid3.get()});
+                   }));
+
+  // The intermediate asserts anyPolicy, but the leaf does not. The resulting
+  // valid policies are the intersection.
+  EXPECT_EQ(
+      X509_V_OK,
+      Verify(leaf.get(), {root.get()}, {intermediate_any.get()}, /*crls=*/{},
+             X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) {
+               set_policies(param, {oid1.get()});
+             }));
+  EXPECT_EQ(
+      X509_V_ERR_NO_EXPLICIT_POLICY,
+      Verify(leaf.get(), {root.get()}, {intermediate_any.get()}, /*crls=*/{},
+             X509_V_FLAG_EXPLICIT_POLICY, [&](X509_VERIFY_PARAM *param) {
+               set_policies(param, {oid3.get()});
+             }));
+
+  // Both assert anyPolicy. All policies are valid.
+  EXPECT_EQ(X509_V_OK,
+            Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()},
+                   /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
+                   [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid1.get()});
+                   }));
+  EXPECT_EQ(X509_V_OK,
+            Verify(leaf_any.get(), {root.get()}, {intermediate_any.get()},
+                   /*crls=*/{}, X509_V_FLAG_EXPLICIT_POLICY,
+                   [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid3.get()});
+                   }));
 }
diff --git a/sources.cmake b/sources.cmake
index 4dcbbc1..e2e9695 100644
--- a/sources.cmake
+++ b/sources.cmake
@@ -112,12 +112,14 @@
   crypto/x509/test/many_names2.pem
   crypto/x509/test/many_names3.pem
   crypto/x509/test/policy_root.pem
+  crypto/x509/test/policy_intermediate_any.pem
   crypto/x509/test/policy_intermediate_duplicate.pem
   crypto/x509/test/policy_intermediate_invalid.pem
   crypto/x509/test/policy_intermediate_require.pem
   crypto/x509/test/policy_intermediate_require_duplicate.pem
   crypto/x509/test/policy_intermediate_require_no_policies.pem
   crypto/x509/test/policy_intermediate.pem
+  crypto/x509/test/policy_leaf_any.pem
   crypto/x509/test/policy_leaf_duplicate.pem
   crypto/x509/test/policy_leaf_invalid.pem
   crypto/x509/test/policy_leaf.pem