summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/x509/x509_internal.h5
-rw-r--r--src/lib/libcrypto/x509/x509_verify.c146
2 files changed, 135 insertions, 16 deletions
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h
index fe40351228..7160053a8a 100644
--- a/src/lib/libcrypto/x509/x509_internal.h
+++ b/src/lib/libcrypto/x509/x509_internal.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_internal.h,v 1.7 2021/03/12 15:53:38 tb Exp $ */ 1/* $OpenBSD: x509_internal.h,v 1.8 2021/07/10 15:52:59 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2020 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -65,6 +65,9 @@ struct x509_verify_chain {
65struct x509_verify_ctx { 65struct x509_verify_ctx {
66 X509_STORE_CTX *xsc; 66 X509_STORE_CTX *xsc;
67 struct x509_verify_chain **chains; /* Validated chains */ 67 struct x509_verify_chain **chains; /* Validated chains */
68 STACK_OF(X509) *saved_error_chain;
69 int saved_error;
70 int saved_error_depth;
68 size_t chains_count; 71 size_t chains_count;
69 int dump_chain; /* Dump current chain without erroring */ 72 int dump_chain; /* Dump current chain without erroring */
70 STACK_OF(X509) *roots; /* Trusted roots for this validation */ 73 STACK_OF(X509) *roots; /* Trusted roots for this validation */
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c
index 57c52aa240..21b391c76c 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.37 2021/04/28 17:53:34 tb Exp $ */ 1/* $OpenBSD: x509_verify.c,v 1.38 2021/07/10 15:52:59 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 *
@@ -33,7 +33,7 @@
33static int x509_verify_cert_valid(struct x509_verify_ctx *ctx, X509 *cert, 33static 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);
35static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, 35static void x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
36 struct x509_verify_chain *current_chain); 36 struct x509_verify_chain *current_chain, int full_chain);
37static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, 37static int x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert,
38 size_t depth, int error, int ok); 38 size_t depth, int error, int ok);
39static void x509_verify_chain_free(struct x509_verify_chain *chain); 39static void x509_verify_chain_free(struct x509_verify_chain *chain);
@@ -166,6 +166,9 @@ x509_verify_ctx_reset(struct x509_verify_ctx *ctx)
166 166
167 for (i = 0; i < ctx->chains_count; i++) 167 for (i = 0; i < ctx->chains_count; i++)
168 x509_verify_chain_free(ctx->chains[i]); 168 x509_verify_chain_free(ctx->chains[i]);
169 sk_X509_pop_free(ctx->saved_error_chain, X509_free);
170 ctx->saved_error = 0;
171 ctx->saved_error_depth = 0;
169 ctx->error = 0; 172 ctx->error = 0;
170 ctx->error_depth = 0; 173 ctx->error_depth = 0;
171 ctx->chains_count = 0; 174 ctx->chains_count = 0;
@@ -183,14 +186,42 @@ x509_verify_ctx_clear(struct x509_verify_ctx *ctx)
183} 186}
184 187
185static int 188static int
186x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert) 189x509_verify_cert_cache_extensions(X509 *cert) {
190 if (!(cert->ex_flags & EXFLAG_SET)) {
191 CRYPTO_w_lock(CRYPTO_LOCK_X509);
192 x509v3_cache_extensions(cert);
193 CRYPTO_w_unlock(CRYPTO_LOCK_X509);
194 }
195 if (cert->ex_flags & EXFLAG_INVALID)
196 return 0;
197 return (cert->ex_flags & EXFLAG_SET);
198}
199
200static int
201x509_verify_cert_self_signed(X509 *cert)
202{
203 return (cert->ex_flags & EXFLAG_SS) ? 1 : 0;
204}
205
206static int
207x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert,
208 int full_chain)
187{ 209{
188 int i; 210 int i;
189 211
212 if (!x509_verify_cert_cache_extensions(cert))
213 return 0;
214
190 for (i = 0; i < sk_X509_num(ctx->roots); i++) { 215 for (i = 0; i < sk_X509_num(ctx->roots); i++) {
191 if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0) 216 if (X509_cmp(sk_X509_value(ctx->roots, i), cert) == 0)
192 return 1; 217 return !full_chain ||
218 x509_verify_cert_self_signed(cert);
193 } 219 }
220 /*
221 * XXX what if this is a by_dir thing? this currently isn't
222 * handled so this case is a bit messed up for loonix with
223 * by directory trust bundles...
224 */
194 return 0; 225 return 0;
195} 226}
196 227
@@ -236,6 +267,46 @@ x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx,
236 return 1; 267 return 1;
237} 268}
238 269
270
271/*
272 * Save the error state and unvalidated chain off of the xsc for
273 * later.
274 */
275static int
276x509_verify_ctx_save_xsc_error(struct x509_verify_ctx *ctx)
277{
278 if (ctx->xsc != NULL && ctx->xsc->chain != NULL) {
279 sk_X509_pop_free(ctx->saved_error_chain, X509_free);
280 ctx->saved_error_chain = X509_chain_up_ref(ctx->xsc->chain);
281 if (ctx->saved_error_chain == NULL)
282 return x509_verify_cert_error(ctx, NULL, 0,
283 X509_V_ERR_OUT_OF_MEM, 0);
284 ctx->saved_error = ctx->xsc->error;
285 ctx->saved_error_depth = ctx->xsc->error_depth;
286 }
287 return 1;
288}
289
290/*
291 * Restore the saved error state and unvalidated chain to the xsc
292 * if we do not have a validated chain.
293 */
294static int
295x509_verify_ctx_restore_xsc_error(struct x509_verify_ctx *ctx)
296{
297 if (ctx->xsc != NULL && ctx->chains_count == 0 &&
298 ctx->saved_error_chain != NULL) {
299 sk_X509_pop_free(ctx->xsc->chain, X509_free);
300 ctx->xsc->chain = X509_chain_up_ref(ctx->saved_error_chain);
301 if (ctx->xsc->chain == NULL)
302 return x509_verify_cert_error(ctx, NULL, 0,
303 X509_V_ERR_OUT_OF_MEM, 0);
304 ctx->xsc->error = ctx->saved_error;
305 ctx->xsc->error_depth = ctx->saved_error_depth;
306 }
307 return 1;
308}
309
239/* Add a validated chain to our list of valid chains */ 310/* Add a validated chain to our list of valid chains */
240static int 311static int
241x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, 312x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx,
@@ -331,6 +402,8 @@ static int
331x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent, 402x509_verify_potential_parent(struct x509_verify_ctx *ctx, X509 *parent,
332 X509 *child) 403 X509 *child)
333{ 404{
405 if (!x509_verify_cert_cache_extensions(parent))
406 return 0;
334 if (ctx->xsc != NULL) 407 if (ctx->xsc != NULL)
335 return (ctx->xsc->check_issued(ctx->xsc, child, parent)); 408 return (ctx->xsc->check_issued(ctx->xsc, child, parent));
336 409
@@ -378,7 +451,7 @@ x509_verify_parent_signature(X509 *parent, X509 *child,
378static int 451static int
379x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, 452x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
380 unsigned char *cert_md, int is_root_cert, X509 *candidate, 453 unsigned char *cert_md, int is_root_cert, X509 *candidate,
381 struct x509_verify_chain *current_chain) 454 struct x509_verify_chain *current_chain, int full_chain)
382{ 455{
383 int depth = sk_X509_num(current_chain->certs); 456 int depth = sk_X509_num(current_chain->certs);
384 struct x509_verify_chain *new_chain; 457 struct x509_verify_chain *new_chain;
@@ -446,7 +519,7 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert,
446 } 519 }
447 } 520 }
448 521
449 x509_verify_build_chains(ctx, candidate, new_chain); 522 x509_verify_build_chains(ctx, candidate, new_chain, full_chain);
450 523
451 done: 524 done:
452 x509_verify_chain_free(new_chain); 525 x509_verify_chain_free(new_chain);
@@ -470,11 +543,11 @@ x509_verify_cert_error(struct x509_verify_ctx *ctx, X509 *cert, size_t depth,
470 543
471static void 544static void
472x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert, 545x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
473 struct x509_verify_chain *current_chain) 546 struct x509_verify_chain *current_chain, int full_chain)
474{ 547{
475 unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 }; 548 unsigned char cert_md[EVP_MAX_MD_SIZE] = { 0 };
476 X509 *candidate; 549 X509 *candidate;
477 int i, depth, count, ret; 550 int i, depth, count, ret, is_root;
478 551
479 /* 552 /*
480 * If we are finding chains with an xsc, just stop after we have 553 * If we are finding chains with an xsc, just stop after we have
@@ -519,8 +592,11 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
519 for (i = 0; i < sk_X509_num(ctx->roots); i++) { 592 for (i = 0; i < sk_X509_num(ctx->roots); i++) {
520 candidate = sk_X509_value(ctx->roots, i); 593 candidate = sk_X509_value(ctx->roots, i);
521 if (x509_verify_potential_parent(ctx, candidate, cert)) { 594 if (x509_verify_potential_parent(ctx, candidate, cert)) {
595 is_root = !full_chain ||
596 x509_verify_cert_self_signed(candidate);
522 x509_verify_consider_candidate(ctx, cert, 597 x509_verify_consider_candidate(ctx, cert,
523 cert_md, 1, candidate, current_chain); 598 cert_md, is_root, candidate, current_chain,
599 full_chain);
524 } 600 }
525 } 601 }
526 /* Check for legacy mode roots */ 602 /* Check for legacy mode roots */
@@ -532,8 +608,11 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
532 } 608 }
533 if (ret > 0) { 609 if (ret > 0) {
534 if (x509_verify_potential_parent(ctx, candidate, cert)) { 610 if (x509_verify_potential_parent(ctx, candidate, cert)) {
611 is_root = !full_chain ||
612 x509_verify_cert_self_signed(candidate);
535 x509_verify_consider_candidate(ctx, cert, 613 x509_verify_consider_candidate(ctx, cert,
536 cert_md, 1, candidate, current_chain); 614 cert_md, is_root, candidate, current_chain,
615 full_chain);
537 } 616 }
538 X509_free(candidate); 617 X509_free(candidate);
539 } 618 }
@@ -545,7 +624,8 @@ x509_verify_build_chains(struct x509_verify_ctx *ctx, X509 *cert,
545 candidate = sk_X509_value(ctx->intermediates, i); 624 candidate = sk_X509_value(ctx->intermediates, i);
546 if (x509_verify_potential_parent(ctx, candidate, cert)) { 625 if (x509_verify_potential_parent(ctx, candidate, cert)) {
547 x509_verify_consider_candidate(ctx, cert, 626 x509_verify_consider_candidate(ctx, cert,
548 cert_md, 0, candidate, current_chain); 627 cert_md, 0, candidate, current_chain,
628 full_chain);
549 } 629 }
550 } 630 }
551 } 631 }
@@ -973,6 +1053,7 @@ size_t
973x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name) 1053x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
974{ 1054{
975 struct x509_verify_chain *current_chain; 1055 struct x509_verify_chain *current_chain;
1056 int retry_chain_build, full_chain = 0;
976 1057
977 if (ctx->roots == NULL || ctx->max_depth == 0) { 1058 if (ctx->roots == NULL || ctx->max_depth == 0) {
978 ctx->error = X509_V_ERR_INVALID_CALL; 1059 ctx->error = X509_V_ERR_INVALID_CALL;
@@ -986,6 +1067,10 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
986 } 1067 }
987 leaf = ctx->xsc->cert; 1068 leaf = ctx->xsc->cert;
988 1069
1070 /* XXX */
1071 full_chain = 1;
1072 if (ctx->xsc->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
1073 full_chain = 0;
989 /* 1074 /*
990 * XXX 1075 * XXX
991 * The legacy code expects the top level cert to be 1076 * The legacy code expects the top level cert to be
@@ -1024,14 +1109,45 @@ x509_verify(struct x509_verify_ctx *ctx, X509 *leaf, char *name)
1024 x509_verify_chain_free(current_chain); 1109 x509_verify_chain_free(current_chain);
1025 goto err; 1110 goto err;
1026 } 1111 }
1027 if (x509_verify_ctx_cert_is_root(ctx, leaf)) 1112 do {
1028 x509_verify_ctx_add_chain(ctx, current_chain); 1113 retry_chain_build = 0;
1029 else 1114 if (x509_verify_ctx_cert_is_root(ctx, leaf, full_chain))
1030 x509_verify_build_chains(ctx, leaf, current_chain); 1115 x509_verify_ctx_add_chain(ctx, current_chain);
1116 else {
1117 x509_verify_build_chains(ctx, leaf, current_chain,
1118 full_chain);
1119 if (full_chain && ctx->chains_count == 0) {
1120 /*
1121 * Save the error state from the xsc
1122 * at this point to put back on the
1123 * xsc in case we do not find a chain
1124 * that is trusted but not a full
1125 * chain to a self signed root. This
1126 * is because the unvalidated chain is
1127 * used by the autochain batshittery
1128 * on failure and will be needed for
1129 * that.
1130 */
1131 if (!x509_verify_ctx_save_xsc_error(ctx)) {
1132 x509_verify_chain_free(current_chain);
1133 goto err;
1134 }
1135 full_chain = 0;
1136 retry_chain_build = 1;
1137 }
1138 }
1139 } while (retry_chain_build);
1031 1140
1032 x509_verify_chain_free(current_chain); 1141 x509_verify_chain_free(current_chain);
1033 1142
1034 /* 1143 /*
1144 * Bring back the failure case we wanted to the xsc if
1145 * we saved one.
1146 */
1147 if (!x509_verify_ctx_restore_xsc_error(ctx))
1148 goto err;
1149
1150 /*
1035 * Safety net: 1151 * Safety net:
1036 * We could not find a validated chain, and for some reason do not 1152 * We could not find a validated chain, and for some reason do not
1037 * have an error set. 1153 * have an error set.