diff options
Diffstat (limited to 'src/lib/libcrypto/x509')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index 5ab3eaeda1..53a06b193b 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.11 2020/09/19 14:15:38 beck Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.12 2020/09/23 18:20:16 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -169,6 +169,29 @@ x509_verify_ctx_cert_is_root(struct x509_verify_ctx *ctx, X509 *cert) | |||
| 169 | return 0; | 169 | return 0; |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | static int | ||
| 173 | x509_verify_ctx_set_xsc_chain(struct x509_verify_ctx *ctx, | ||
| 174 | struct x509_verify_chain *chain) | ||
| 175 | { | ||
| 176 | size_t depth; | ||
| 177 | X509 *last = x509_verify_chain_last(chain); | ||
| 178 | |||
| 179 | if (ctx->xsc == NULL) | ||
| 180 | return 1; | ||
| 181 | |||
| 182 | depth = sk_X509_num(chain->certs); | ||
| 183 | if (depth > 0) | ||
| 184 | depth--; | ||
| 185 | |||
| 186 | ctx->xsc->last_untrusted = depth ? depth - 1 : 0; | ||
| 187 | sk_X509_pop_free(ctx->xsc->chain, X509_free); | ||
| 188 | ctx->xsc->chain = X509_chain_up_ref(chain->certs); | ||
| 189 | if (ctx->xsc->chain == NULL) | ||
| 190 | return x509_verify_cert_error(ctx, last, depth, | ||
| 191 | X509_V_ERR_OUT_OF_MEM, 0); | ||
| 192 | return 1; | ||
| 193 | } | ||
| 194 | |||
| 172 | /* Add a validated chain to our list of valid chains */ | 195 | /* Add a validated chain to our list of valid chains */ |
| 173 | static int | 196 | static int |
| 174 | x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, | 197 | x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, |
| @@ -194,12 +217,8 @@ x509_verify_ctx_add_chain(struct x509_verify_ctx *ctx, | |||
| 194 | * knobs that are there for the fiddling. | 217 | * knobs that are there for the fiddling. |
| 195 | */ | 218 | */ |
| 196 | if (ctx->xsc != NULL) { | 219 | if (ctx->xsc != NULL) { |
| 197 | ctx->xsc->last_untrusted = depth ? depth - 1 : 0; | 220 | if (!x509_verify_ctx_set_xsc_chain(ctx, chain)) |
| 198 | sk_X509_pop_free(ctx->xsc->chain, X509_free); | 221 | return 0; |
| 199 | ctx->xsc->chain = X509_chain_up_ref(chain->certs); | ||
| 200 | if (ctx->xsc->chain == NULL) | ||
| 201 | return x509_verify_cert_error(ctx, last, depth, | ||
| 202 | X509_V_ERR_OUT_OF_MEM, 0); | ||
| 203 | 222 | ||
| 204 | /* | 223 | /* |
| 205 | * XXX currently this duplicates some work done | 224 | * XXX currently this duplicates some work done |
| @@ -343,12 +362,20 @@ x509_verify_consider_candidate(struct x509_verify_ctx *ctx, X509 *cert, | |||
| 343 | * so we save it. Otherwise, recurse until we find a root or | 362 | * so we save it. Otherwise, recurse until we find a root or |
| 344 | * give up. | 363 | * give up. |
| 345 | */ | 364 | */ |
| 346 | if (is_root_cert && | 365 | if (is_root_cert) { |
| 347 | x509_verify_cert_error(ctx, candidate, depth, X509_V_OK, 1)) | 366 | if (!x509_verify_ctx_set_xsc_chain(ctx, new_chain)) { |
| 348 | (void) x509_verify_ctx_add_chain(ctx, new_chain); | 367 | x509_verify_chain_free(new_chain); |
| 349 | else | 368 | return 0; |
| 350 | x509_verify_build_chains(ctx, candidate, new_chain); | 369 | } |
| 370 | if (x509_verify_cert_error(ctx, candidate, depth, X509_V_OK, 1)) { | ||
| 371 | (void) x509_verify_ctx_add_chain(ctx, new_chain); | ||
| 372 | goto done; | ||
| 373 | } | ||
| 374 | } | ||
| 375 | |||
| 376 | x509_verify_build_chains(ctx, candidate, new_chain); | ||
| 351 | 377 | ||
| 378 | done: | ||
| 352 | x509_verify_chain_free(new_chain); | 379 | x509_verify_chain_free(new_chain); |
| 353 | return 1; | 380 | return 1; |
| 354 | } | 381 | } |
