summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/x509/policy/policy.c227
1 files changed, 223 insertions, 4 deletions
diff --git a/src/regress/lib/libcrypto/x509/policy/policy.c b/src/regress/lib/libcrypto/x509/policy/policy.c
index 593f43bed1..f5f2d42ddd 100644
--- a/src/regress/lib/libcrypto/x509/policy/policy.c
+++ b/src/regress/lib/libcrypto/x509/policy/policy.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: policy.c,v 1.2 2023/04/27 13:26:57 beck Exp $ */ 1/* $OpenBSD: policy.c,v 1.3 2023/04/28 08:15:11 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2020 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> 4 * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org>
@@ -119,7 +119,8 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc)
119static void 119static void
120verify_cert(const char *roots_file, const char *intermediate_file, 120verify_cert(const char *roots_file, const char *intermediate_file,
121 const char *leaf_file, int *chains, int *error, int *error_depth, 121 const char *leaf_file, int *chains, int *error, int *error_depth,
122 int mode, ASN1_OBJECT *policy_oid, ASN1_OBJECT *policy_oid2) 122 int mode, ASN1_OBJECT *policy_oid, ASN1_OBJECT *policy_oid2,
123 int verify_flags)
123{ 124{
124 STACK_OF(X509) *roots = NULL, *bundle = NULL; 125 STACK_OF(X509) *roots = NULL, *bundle = NULL;
125 X509_STORE_CTX *xsc = NULL; 126 X509_STORE_CTX *xsc = NULL;
@@ -153,7 +154,7 @@ verify_cert(const char *roots_file, const char *intermediate_file,
153 } 154 }
154 155
155 int flags = X509_V_FLAG_POLICY_CHECK; 156 int flags = X509_V_FLAG_POLICY_CHECK;
156 flags |= X509_V_FLAG_EXPLICIT_POLICY; 157 flags |= verify_flags;
157 // flags |= X509_V_FLAG_INHIBIT_MAP; 158 // flags |= X509_V_FLAG_INHIBIT_MAP;
158 if (mode == MODE_LEGACY_VFY) 159 if (mode == MODE_LEGACY_VFY)
159 flags |= X509_V_FLAG_LEGACY_VERIFY; 160 flags |= X509_V_FLAG_LEGACY_VERIFY;
@@ -277,9 +278,11 @@ struct verify_cert_test {
277 int want_legacy_error; 278 int want_legacy_error;
278 int want_legacy_error_depth; 279 int want_legacy_error_depth;
279 int failing; 280 int failing;
281 int verify_flags;
280}; 282};
281 283
282struct verify_cert_test verify_cert_tests[] = { 284struct verify_cert_test verify_cert_tests[] = {
285 // Comments here are from boringssl/crypto/x509/x509_test.cc
283 // The chain is good for |oid1| and |oid2|, but not |oid3|. 286 // The chain is good for |oid1| and |oid2|, but not |oid3|.
284 { 287 {
285 .id = "nothing in 1 and 2", 288 .id = "nothing in 1 and 2",
@@ -287,6 +290,7 @@ struct verify_cert_test verify_cert_tests[] = {
287 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", 290 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
288 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 291 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
289 .want_chains = 1, 292 .want_chains = 1,
293 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
290 }, 294 },
291 { 295 {
292 .id = "1, in 1 and 2", 296 .id = "1, in 1 and 2",
@@ -295,6 +299,7 @@ struct verify_cert_test verify_cert_tests[] = {
295 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 299 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
296 .policy_oid_to_check = OID1, 300 .policy_oid_to_check = OID1,
297 .want_chains = 1, 301 .want_chains = 1,
302 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
298 }, 303 },
299 { 304 {
300 .id = "2, in 1 and 2", 305 .id = "2, in 1 and 2",
@@ -303,6 +308,7 @@ struct verify_cert_test verify_cert_tests[] = {
303 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 308 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
304 .policy_oid_to_check = OID2, 309 .policy_oid_to_check = OID2,
305 .want_chains = 1, 310 .want_chains = 1,
311 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
306 }, 312 },
307 { 313 {
308 .id = "3, in 1 and 2", 314 .id = "3, in 1 and 2",
@@ -311,6 +317,7 @@ struct verify_cert_test verify_cert_tests[] = {
311 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 317 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
312 .policy_oid_to_check = OID3, 318 .policy_oid_to_check = OID3,
313 .want_chains = 0, 319 .want_chains = 0,
320 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
314 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY, 321 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
315 .want_error_depth = 0, 322 .want_error_depth = 0,
316 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY, 323 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
@@ -324,6 +331,7 @@ struct verify_cert_test verify_cert_tests[] = {
324 .policy_oid_to_check = OID1, 331 .policy_oid_to_check = OID1,
325 .policy_oid_to_check2 = OID2, 332 .policy_oid_to_check2 = OID2,
326 .want_chains = 1, 333 .want_chains = 1,
334 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
327 }, 335 },
328 { 336 {
329 .id = "1 and 3, in 1 and 2", 337 .id = "1 and 3, in 1 and 2",
@@ -342,6 +350,7 @@ struct verify_cert_test verify_cert_tests[] = {
342 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 350 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
343 .policy_oid_to_check = OID1, 351 .policy_oid_to_check = OID1,
344 .want_chains = 0, 352 .want_chains = 0,
353 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
345 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 354 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
346 .want_error_depth = 0, 355 .want_error_depth = 0,
347 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 356 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
@@ -353,6 +362,7 @@ struct verify_cert_test verify_cert_tests[] = {
353 .intermediate_file = CERTSDIR "/" "policy_intermediate_invalid.pem", 362 .intermediate_file = CERTSDIR "/" "policy_intermediate_invalid.pem",
354 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 363 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
355 .want_chains = 0, 364 .want_chains = 0,
365 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
356 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 366 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
357 .want_error_depth = 0, 367 .want_error_depth = 0,
358 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 368 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
@@ -365,6 +375,7 @@ struct verify_cert_test verify_cert_tests[] = {
365 .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem", 375 .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem",
366 .policy_oid_to_check = OID1, 376 .policy_oid_to_check = OID1,
367 .want_chains = 0, 377 .want_chains = 0,
378 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
368 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 379 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
369 .want_error_depth = 0, 380 .want_error_depth = 0,
370 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 381 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
@@ -376,6 +387,7 @@ struct verify_cert_test verify_cert_tests[] = {
376 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem", 387 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
377 .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem", 388 .leaf_file = CERTSDIR "/" "policy_leaf_invalid.pem",
378 .want_chains = 0, 389 .want_chains = 0,
390 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
379 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 391 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
380 .want_error_depth = 0, 392 .want_error_depth = 0,
381 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 393 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
@@ -389,6 +401,7 @@ struct verify_cert_test verify_cert_tests[] = {
389 .leaf_file = CERTSDIR "/" "policy_leaf_duplicate.pem", 401 .leaf_file = CERTSDIR "/" "policy_leaf_duplicate.pem",
390 .policy_oid_to_check = OID1, 402 .policy_oid_to_check = OID1,
391 .want_chains = 0, 403 .want_chains = 0,
404 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
392 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 405 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
393 .want_error_depth = 0, 406 .want_error_depth = 0,
394 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 407 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
@@ -402,11 +415,217 @@ struct verify_cert_test verify_cert_tests[] = {
402 .leaf_file = CERTSDIR "/" "policy_leaf.pem", 415 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
403 .policy_oid_to_check = OID1, 416 .policy_oid_to_check = OID1,
404 .want_chains = 0, 417 .want_chains = 0,
418 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
405 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 419 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
406 .want_error_depth = 0, 420 .want_error_depth = 0,
407 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION, 421 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
408 .want_legacy_error_depth = 0, 422 .want_legacy_error_depth = 0,
409 }, 423 },
424 // Without |X509_V_FLAG_EXPLICIT_POLICY|, the policy tree is built and
425 // intersected with user-specified policies, but it is not required to result
426 // in any valid policies.
427 {
428 .id = "nothing with explicit_policy unset",
429 .root_file = CERTSDIR "/" "policy_root.pem",
430 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
431 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
432 .want_chains = 1,
433 },
434 {
435 .id = "oid3 with explicit_policy unset",
436 .root_file = CERTSDIR "/" "policy_root.pem",
437 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
438 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
439 .policy_oid_to_check = OID3,
440 .want_chains = 1,
441 },
442 // However, a CA with policy constraints can require an explicit policy.
443 {
444 .id = "oid1 with explicit_policy unset, intermediate requiring policy",
445 .root_file = CERTSDIR "/" "policy_root.pem",
446 .intermediate_file = CERTSDIR "/" "policy_intermediate_require.pem",
447 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
448 .policy_oid_to_check = OID1,
449 .want_chains = 1,
450 },
451 {
452 .id = "oid3 with explicit_policy unset, intermediate requiring policy",
453 .root_file = CERTSDIR "/" "policy_root.pem",
454 .intermediate_file = CERTSDIR "/" "policy_intermediate_require.pem",
455 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
456 .policy_oid_to_check = OID3,
457 .want_chains = 0,
458 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
459 .want_error_depth = 0,
460 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
461 .want_legacy_error_depth = 0,
462 },
463 // requireExplicitPolicy applies even if the application does not configure a
464 // user-initial-policy-set. If the validation results in no policies, the
465 // chain is invalid.
466 {
467 .id = "nothing explict_policy unset, with intermediate requiring policy",
468 .root_file = CERTSDIR "/" "policy_root.pem",
469 .intermediate_file = CERTSDIR "/" "policy_intermediate_require.pem",
470 .leaf_file = CERTSDIR "/" "policy_leaf_none.pem",
471 .want_chains = 0,
472 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
473 .want_error_depth = 0,
474 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
475 .want_legacy_error_depth = 0,
476 },
477 // A leaf can also set requireExplicitPolicy but should work with none
478 {
479 .id = "nothing explicit_policy unset, with leaf requiring policy",
480 .root_file = CERTSDIR "/" "policy_root.pem",
481 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
482 .leaf_file = CERTSDIR "/" "policy_leaf_require.pem",
483 .want_chains = 1,
484 },
485 // A leaf can also set requireExplicitPolicy but should fail with policy
486 {
487 .id = "oid3, explicit policy unset, with leaf requiring policy",
488 .root_file = CERTSDIR "/" "policy_root.pem",
489 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
490 .leaf_file = CERTSDIR "/" "policy_leaf_require.pem",
491 .policy_oid_to_check = OID3,
492 .want_chains = 0,
493 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
494 .want_error_depth = 0,
495 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
496 .want_legacy_error_depth = 0,
497 },
498 // requireExplicitPolicy is a count of certificates to skip. If the value is
499 // not zero by the end of the chain, it doesn't count.
500 {
501 .id = "oid3, with intermediate requiring explicit depth 1",
502 .root_file = CERTSDIR "/" "policy_root.pem",
503 .intermediate_file = CERTSDIR "/" "policy_intermediate_require1.pem",
504 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
505 .policy_oid_to_check = OID3,
506 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
507 .want_chains = 0,
508 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
509 .want_error_depth = 0,
510 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
511 .want_legacy_error_depth = 0,
512 },
513 {
514 .id = "oid3, with intermediate requiring explicit depth 2",
515 .root_file = CERTSDIR "/" "policy_root.pem",
516 .intermediate_file = CERTSDIR "/" "policy_intermediate_require2.pem",
517 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
518 .policy_oid_to_check = OID3,
519 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
520 .want_chains = 1,
521 },
522 {
523 .id = "oid3, with leaf requiring explicit depth 1",
524 .root_file = CERTSDIR "/" "policy_root.pem",
525 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
526 .leaf_file = CERTSDIR "/" "policy_leaf_require1.pem",
527 .policy_oid_to_check = OID3,
528 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
529 .want_chains = 1,
530 },
531 // If multiple certificates specify the constraint, the more constrained value
532 // wins.
533 {
534 .id = "oid3, with leaf and intermediate requiring explicit depth 1",
535 .root_file = CERTSDIR "/" "policy_root.pem",
536 .intermediate_file = CERTSDIR "/" "policy_intermediate_require1.pem",
537 .leaf_file = CERTSDIR "/" "policy_leaf_require1.pem",
538 .policy_oid_to_check = OID3,
539 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
540 .want_chains = 0,
541 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
542 .want_error_depth = 0,
543 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
544 .want_legacy_error_depth = 0,
545 },
546 {
547 .id = "oid3, with leaf requiring explicit depth 1 and intermediate depth 2",
548 .root_file = CERTSDIR "/" "policy_root.pem",
549 .intermediate_file = CERTSDIR "/" "policy_intermediate_require2.pem",
550 .leaf_file = CERTSDIR "/" "policy_leaf_require.pem",
551 .policy_oid_to_check = OID3,
552 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
553 .want_chains = 0,
554 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
555 .want_error_depth = 0,
556 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
557 .want_legacy_error_depth = 0,
558 },
559 // An intermediate that requires an explicit policy, but then specifies no
560 // policies should fail verification as a result.
561 {
562 .id = "oid1 with explicit_policy unset, intermediate requiring policy but specifying none",
563 .root_file = CERTSDIR "/" "policy_root.pem",
564 .intermediate_file = CERTSDIR "/" "policy_intermediate_require_no_policies.pem",
565 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
566 .policy_oid_to_check = OID3,
567 .want_chains = 0,
568 .want_error = X509_V_ERR_NO_EXPLICIT_POLICY,
569 .want_error_depth = 0,
570 .want_legacy_error = X509_V_ERR_NO_EXPLICIT_POLICY,
571 .want_legacy_error_depth = 0,
572 },
573 // A constrained intermediate's policy extension has a duplicate policy, which
574 // is invalid. Historically this, and the above case, leaked memory.
575 {
576 .id = "oid1 with explicit_policy unset, intermediate requiring policy but has duplicate",
577 .root_file = CERTSDIR "/" "policy_root.pem",
578 .intermediate_file = CERTSDIR "/" "policy_intermediate_require_duplicate.pem",
579 .leaf_file = CERTSDIR "/" "policy_leaf.pem",
580 .policy_oid_to_check = OID3,
581 .want_chains = 0,
582 .want_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
583 .want_error_depth = 0,
584 .want_legacy_error = X509_V_ERR_INVALID_POLICY_EXTENSION,
585 .want_legacy_error_depth = 0,
586 },
587 // The leaf asserts anyPolicy, but the intermediate does not. The resulting
588 // valid policies are the intersection.
589 // (and vice versa)
590 {
591 .id = "oid1, with explicit_policy set, with leaf asserting any",
592 .root_file = CERTSDIR "/" "policy_root.pem",
593 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
594 .leaf_file = CERTSDIR "/" "policy_leaf_any.pem",
595 .policy_oid_to_check = OID1,
596 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
597 .want_chains = 1,
598 },
599 {
600 .id = "oid3, with explicit_policy set, with leaf asserting any",
601 .root_file = CERTSDIR "/" "policy_root.pem",
602 .intermediate_file = CERTSDIR "/" "policy_intermediate.pem",
603 .leaf_file = CERTSDIR "/" "policy_leaf_any.pem",
604 .policy_oid_to_check = OID1,
605 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
606 .want_chains = 1,
607 },
608 // Both assert anyPolicy. All policies are valid.
609 {
610 .id = "oid1, with explicit_policy set, with leaf and intermediate asserting any",
611 .root_file = CERTSDIR "/" "policy_root.pem",
612 .intermediate_file = CERTSDIR "/" "policy_intermediate_any.pem",
613 .leaf_file = CERTSDIR "/" "policy_leaf_any.pem",
614 .policy_oid_to_check = OID1,
615 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
616 .want_chains = 1,
617 },
618 {
619 .id = "oid3, with explicit_policy set, with leaf and intermediate asserting any",
620 .root_file = CERTSDIR "/" "policy_root.pem",
621 .intermediate_file = CERTSDIR "/" "policy_intermediate_any.pem",
622 .leaf_file = CERTSDIR "/" "policy_leaf_any.pem",
623 .policy_oid_to_check = OID1,
624 .verify_flags = X509_V_FLAG_EXPLICIT_POLICY,
625 .want_chains = 1,
626 },
627 // boring tests just a trust anchor but behaves differently in this corner case.
628 // for reasons that have nothing to do wiht policy
410}; 629};
411 630
412#define N_VERIFY_CERT_TESTS \ 631#define N_VERIFY_CERT_TESTS \
@@ -437,7 +656,7 @@ verify_cert_test(int mode)
437 else 656 else
438 verify_cert(vct->root_file, vct->intermediate_file, 657 verify_cert(vct->root_file, vct->intermediate_file,
439 vct->leaf_file, &chains, &error, &error_depth, 658 vct->leaf_file, &chains, &error, &error_depth,
440 mode, policy_oid, policy_oid2); 659 mode, policy_oid, policy_oid2, vct->verify_flags);
441 660
442 if ((mode == MODE_VERIFY && chains == vct->want_chains) || 661 if ((mode == MODE_VERIFY && chains == vct->want_chains) ||
443 (chains == 0 && vct->want_chains == 0) || 662 (chains == 0 && vct->want_chains == 0) ||