Test requireAnyPolicy being a SkipCerts value

And specifically that it also counts at the leaf, which was a bug I'd
nearly introduced. (RFC 5280 is written somewhat confusingly. The
wrap-up and prepare procedures have some duplicate processing.)

Change-Id: Iea901b96f64e12199fec426dc936bfbde16f88a4
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56035
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index a1005d7..eb26611 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -5143,6 +5143,14 @@
   bssl::UniquePtr<X509> intermediate_require(CertFromPEM(
       GetTestData("crypto/x509/test/policy_intermediate_require.pem").c_str()));
   ASSERT_TRUE(intermediate_require);
+  bssl::UniquePtr<X509> intermediate_require1(CertFromPEM(
+      GetTestData("crypto/x509/test/policy_intermediate_require1.pem")
+          .c_str()));
+  ASSERT_TRUE(intermediate_require1);
+  bssl::UniquePtr<X509> intermediate_require2(CertFromPEM(
+      GetTestData("crypto/x509/test/policy_intermediate_require2.pem")
+          .c_str()));
+  ASSERT_TRUE(intermediate_require2);
   bssl::UniquePtr<X509> intermediate_require_duplicate(CertFromPEM(
       GetTestData("crypto/x509/test/policy_intermediate_require_duplicate.pem")
           .c_str()));
@@ -5179,6 +5187,12 @@
   bssl::UniquePtr<X509> leaf_oid5(CertFromPEM(
       GetTestData("crypto/x509/test/policy_leaf_oid5.pem").c_str()));
   ASSERT_TRUE(leaf_oid5);
+  bssl::UniquePtr<X509> leaf_require(CertFromPEM(
+      GetTestData("crypto/x509/test/policy_leaf_require.pem").c_str()));
+  ASSERT_TRUE(leaf_require);
+  bssl::UniquePtr<X509> leaf_require1(CertFromPEM(
+      GetTestData("crypto/x509/test/policy_leaf_require1.pem").c_str()));
+  ASSERT_TRUE(leaf_require1);
 
   // By default, OpenSSL does not check policies, so even syntax errors in the
   // certificatePolicies extension go unnoticed. (This is probably not
@@ -5286,6 +5300,57 @@
                      set_policies(param, {oid3.get()});
                    }));
 
+  // A leaf can also set requireExplicitPolicy.
+  EXPECT_EQ(X509_V_OK, Verify(leaf_require.get(), {root.get()},
+                              {intermediate.get()}, /*crls=*/{},
+                              /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+                                set_policies(param, {oid1.get()});
+                              }));
+  EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY,
+            Verify(leaf_require.get(), {root.get()}, {intermediate.get()},
+                   /*crls=*/{},
+                   /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid3.get()});
+                   }));
+
+  // requireExplicitPolicy is a count of certificates to skip. If the value is
+  // not zero by the end of the chain, it doesn't count.
+  EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY,
+            Verify(leaf.get(), {root.get()}, {intermediate_require1.get()},
+                   /*crls=*/{},
+                   /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid3.get()});
+                   }));
+  EXPECT_EQ(X509_V_OK,
+            Verify(leaf.get(), {root.get()}, {intermediate_require2.get()},
+                   /*crls=*/{},
+                   /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid3.get()});
+                   }));
+  EXPECT_EQ(X509_V_OK,
+            Verify(leaf_require1.get(), {root.get()}, {intermediate.get()},
+                   /*crls=*/{},
+                   /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+                     set_policies(param, {oid3.get()});
+                   }));
+
+  // If multiple certificates specify the constraint, the more constrained value
+  // wins.
+  EXPECT_EQ(
+      X509_V_ERR_NO_EXPLICIT_POLICY,
+      Verify(leaf_require1.get(), {root.get()}, {intermediate_require1.get()},
+             /*crls=*/{},
+             /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+               set_policies(param, {oid3.get()});
+             }));
+  EXPECT_EQ(
+      X509_V_ERR_NO_EXPLICIT_POLICY,
+      Verify(leaf_require.get(), {root.get()}, {intermediate_require2.get()},
+             /*crls=*/{},
+             /*flags=*/0, [&](X509_VERIFY_PARAM *param) {
+               set_policies(param, {oid3.get()});
+             }));
+
   // An intermediate that requires an explicit policy, but then specifies no
   // policies should fail verification as a result.
   EXPECT_EQ(X509_V_ERR_NO_EXPLICIT_POLICY,
@@ -5306,16 +5371,18 @@
 
   // 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()});
-                   }));
+  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.