diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index 630c9f9b5a..f6959d1f3a 100644 --- a/src/lib/libcrypto/x509/x509_verify.c +++ b/src/lib/libcrypto/x509/x509_verify.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_verify.c,v 1.55 2022/04/12 10:42:35 tb Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.56 2022/06/25 20:01:43 beck Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -32,8 +32,10 @@ | |||
32 | 32 | ||
33 | static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, | 33 | static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, |
34 | struct x509_verify_chain *current_chain); | 34 | struct x509_verify_chain *current_chain); |
35 | static int x509_verify_cert_hostname(struct x509_verify_ctx *ctx, X509 *cert, | ||
36 | char *name); | ||
35 | static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | 37 | static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, |
36 | struct x509_verify_chain *current_chain, int full_chain); | 38 | struct x509_verify_chain *current_chain, int full_chain, char *name); |
37 | static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, | 39 | static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, |
38 | size_t depth, int error, int ok); | 40 | size_t depth, int error, int ok); |
39 | static void x509_verify_chain_free(struct x509_verify_chain *chain); | 41 | static void x509_verify_chain_free(struct x509_verify_chain *chain); |
@@ -233,7 +235,7 @@ x509_verify_ctx_clear(struct x509_verify_ctx *ctx) | |||
233 | x509_verify_ctx_reset(ctx); | 235 | x509_verify_ctx_reset(ctx); |
234 | sk_X509_pop_free(ctx->intermediates, X509_free); | 236 | sk_X509_pop_free(ctx->intermediates, X509_free); |
235 | free(ctx->chains); | 237 | free(ctx->chains); |
236 | memset(ctx, 0, sizeof(*ctx)); | 238 | |
237 | } | 239 | } |
238 | 240 | ||
239 | static int | 241 | static int |
@@ -453,10 +455,11 @@ x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx, | |||
453 | /* Add a validated chain to our list of valid chains */ | 455 | /* Add a validated chain to our list of valid chains */ |
454 | static int | 456 | static int |
455 | x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, | 457 | x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, |
456 | struct x509_verify_chain *chain) | 458 | struct x509_verify_chain *chain, char *name) |
457 | { | 459 | { |
458 | size_t depth; | 460 | size_t depth; |
459 | X509 *last = x509_verify_chain_last(chain); | 461 | X509 *last = x509_verify_chain_last(chain); |
462 | X509 *leaf = x509_verify_chain_leaf(chain); | ||
460 | 463 | ||
461 | depth = sk_X509_num(chain->certs); | 464 | depth = sk_X509_num(chain->certs); |
462 | if (depth > 0) | 465 | if (depth > 0) |
@@ -488,6 +491,13 @@ x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, | |||
488 | return x509_verify_cert_error(ctx, last, depth, | 491 | return x509_verify_cert_error(ctx, last, depth, |
489 | X509_V_ERR_OUT_OF_MEM, 0); | 492 | X509_V_ERR_OUT_OF_MEM, 0); |
490 | } | 493 | } |
494 | |||
495 | if (!x509_verify_cert_valid(ctx, leaf, NULL)) | ||
496 | return 0; | ||
497 | |||
498 | if (!x509_verify_cert_hostname(ctx, leaf, name)) | ||
499 | return 0; | ||
500 | |||
491 | ctx->chains_count++; | 501 | ctx->chains_count++; |
492 | ctx->error = X509_V_OK; | 502 | ctx->error = X509_V_OK; |
493 | ctx->error_depth = depth; | 503 | ctx->error_depth = depth; |
@@ -539,7 +549,7 @@ x509_verify_parent_signature(X509 *parent, X509 *child, int *error) | |||
539 | static int | 549 | static int |
540 | x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | 550 | x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, |
541 | int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain, | 551 | int is_root_cert, X509 *candidate, struct x509_verify_chain *current_chain, |
542 | int full_chain) | 552 | int full_chain, char *name) |
543 | { | 553 | { |
544 | int depth = sk_X509_num(current_chain->certs); | 554 | int depth = sk_X509_num(current_chain->certs); |
545 | struct x509_verify_chain *new_chain; | 555 | struct x509_verify_chain *new_chain; |
@@ -590,14 +600,14 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | |||
590 | x509_verify_chain_free(new_chain); | 600 | x509_verify_chain_free(new_chain); |
591 | return 0; | 601 | return 0; |
592 | } | 602 | } |
593 | if (!x509_verify_ctx_add_chain(ctx, new_chain)) { | 603 | if (!x509_verify_ctx_add_chain(ctx, new_chain, name)) { |
594 | x509_verify_chain_free(new_chain); | 604 | x509_verify_chain_free(new_chain); |
595 | return 0; | 605 | return 0; |
596 | } | 606 | } |
597 | goto done; | 607 | goto done; |
598 | } | 608 | } |
599 | 609 | ||
600 | x509_verify_build_chains(ctx, candidate, new_chain, full_chain); | 610 | x509_verify_build_chains(ctx, candidate, new_chain, full_chain, name); |
601 | 611 | ||
602 | done: | 612 | done: |
603 | x509_verify_chain_free(new_chain); | 613 | x509_verify_chain_free(new_chain); |
@@ -621,7 +631,7 @@ x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth, | |||
621 | 631 | ||
622 | static void | 632 | static void |
623 | x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | 633 | x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, |
624 | struct x509_verify_chain *current_chain, int full_chain) | 634 | struct x509_verify_chain *current_chain, int full_chain, char *name) |
625 | { | 635 | { |
626 | X509 *candidate; | 636 | X509 *candidate; |
627 | int i, depth, count, ret, is_root; | 637 | int i, depth, count, ret, is_root; |
@@ -679,7 +689,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
679 | x509_verify_cert_self_signed(candidate); | 689 | x509_verify_cert_self_signed(candidate); |
680 | x509_verify_consider_candidate(ctx, cert, | 690 | x509_verify_consider_candidate(ctx, cert, |
681 | is_root, candidate, current_chain, | 691 | is_root, candidate, current_chain, |
682 | full_chain); | 692 | full_chain, name); |
683 | } | 693 | } |
684 | X509_free(candidate); | 694 | X509_free(candidate); |
685 | } | 695 | } |
@@ -692,7 +702,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
692 | x509_verify_cert_self_signed(candidate); | 702 | x509_verify_cert_self_signed(candidate); |
693 | x509_verify_consider_candidate(ctx, cert, | 703 | x509_verify_consider_candidate(ctx, cert, |
694 | is_root, candidate, current_chain, | 704 | is_root, candidate, current_chain, |
695 | full_chain); | 705 | full_chain, name); |
696 | } | 706 | } |
697 | } | 707 | } |
698 | } | 708 | } |
@@ -704,7 +714,7 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, | |||
704 | if (x509_verify_potential_parent(ctx, candidate, cert)) { | 714 | if (x509_verify_potential_parent(ctx, candidate, cert)) { |
705 | x509_verify_consider_candidate(ctx, cert, | 715 | x509_verify_consider_candidate(ctx, cert, |
706 | 0, candidate, current_chain, | 716 | 0, candidate, current_chain, |
707 | full_chain); | 717 | full_chain, name); |
708 | } | 718 | } |
709 | } | 719 | } |
710 | } | 720 | } |
@@ -1116,16 +1126,18 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name) | |||
1116 | ctx->xsc->current_cert = leaf; | 1126 | ctx->xsc->current_cert = leaf; |
1117 | } | 1127 | } |
1118 | 1128 | ||
1119 | if (!x509_verify_cert_valid(ctx, leaf, NULL)) | ||
1120 | goto err; | ||
1121 | |||
1122 | if (!x509_verify_cert_hostname(ctx, leaf, name)) | ||
1123 | goto err; | ||
1124 | |||
1125 | if ((current_chain = x509_verify_chain_new()) == NULL) { | 1129 | if ((current_chain = x509_verify_chain_new()) == NULL) { |
1126 | ctx->error = X509_V_ERR_OUT_OF_MEM; | 1130 | ctx->error = X509_V_ERR_OUT_OF_MEM; |
1127 | goto err; | 1131 | goto err; |
1128 | } | 1132 | } |
1133 | |||
1134 | /* | ||
1135 | * Add the leaf to the chain and try to build chains from it. | ||
1136 | * Note that unlike Go's verifier, we have not yet checked | ||
1137 | * anything about the leaf, This is intentional, so that we | ||
1138 | * report failures in chain building before we report problems | ||
1139 | * with the leaf. | ||
1140 | */ | ||
1129 | if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) { | 1141 | if (!x509_verify_chain_append(current_chain, leaf, &ctx->error)) { |
1130 | x509_verify_chain_free(current_chain); | 1142 | x509_verify_chain_free(current_chain); |
1131 | goto err; | 1143 | goto err; |
@@ -1133,13 +1145,14 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name) | |||
1133 | do { | 1145 | do { |
1134 | retry_chain_build = 0; | 1146 | retry_chain_build = 0; |
1135 | if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) { | 1147 | if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain)) { |
1136 | if (!x509_verify_ctx_add_chain(ctx, current_chain)) { | 1148 | if (!x509_verify_ctx_add_chain(ctx, current_chain, |
1149 | name)) { | ||
1137 | x509_verify_chain_free(current_chain); | 1150 | x509_verify_chain_free(current_chain); |
1138 | goto err; | 1151 | goto err; |
1139 | } | 1152 | } |
1140 | } else { | 1153 | } else { |
1141 | x509_verify_build_chains(ctx, leaf, current_chain, | 1154 | x509_verify_build_chains(ctx, leaf, current_chain, |
1142 | full_chain); | 1155 | full_chain, name); |
1143 | if (full_chain && ctx->chains_count == 0) { | 1156 | if (full_chain && ctx->chains_count == 0) { |
1144 | /* | 1157 | /* |
1145 | * Save the error state from the xsc | 1158 | * Save the error state from the xsc |