diff options
author | tb <> | 2020-06-10 03:56:22 +0000 |
---|---|---|
committer | tb <> | 2020-06-10 03:56:22 +0000 |
commit | a91baa573ac5ab1cbde7a2761d1d1da9501f45ec (patch) | |
tree | 4521a19cf622bb9e5f326c41d51cdf799d53192e | |
parent | f21616a5b0676fecb01b51cf6ce47840065457ef (diff) | |
download | openbsd-a91baa573ac5ab1cbde7a2761d1d1da9501f45ec.tar.gz openbsd-a91baa573ac5ab1cbde7a2761d1d1da9501f45ec.tar.bz2 openbsd-a91baa573ac5ab1cbde7a2761d1d1da9501f45ec.zip |
OpenBSD 6.7 errata 010, June 11, 2020 (6.7/010_x509.patch.sig)libressl-v3.1.3
original commit:
CVSROOT: /cvs
Module name: src
Changes by: jsing@cvs.openbsd.org 2020/05/31 11:23:39
Modified files:
lib/libcrypto/x509: x509_vfy.c
Log message:
When building a chain look for non-expired certificates first.
Currently, when building a certificate chain we look up an issuer and if
it is the only issuer certificate available we still use it even if it has
expired. When X509_V_FLAG_TRUSTED_FIRST is not in use, untrusted
certificates are processed first and if one of these happens to be expired
it will be used to build the chain, even if there is another non-expired
option in the trusted store.
Rework this code so that we first look for a non-expired untrusted
certificate. If one does not exist then we take a look in the trusted
store to see if we would be able to build the chain and only if there is
not, do we then look for an expired untrusted certificate.
This makes certificate validation possible for various sites that are
serving expired AddTrust certificates.
Issue reported by Christian Heimes via GitHub.
ok beck@ tb@
-rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index ea35ce791d..43da4ecf25 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: x509_vfy.c,v 1.72 2019/03/06 05:06:58 tb Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.72.6.1 2020/06/10 03:56:22 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -117,7 +117,8 @@ | |||
117 | 117 | ||
118 | static int null_callback(int ok, X509_STORE_CTX *e); | 118 | static int null_callback(int ok, X509_STORE_CTX *e); |
119 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); | 119 | static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); |
120 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); | 120 | static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x, |
121 | int allow_expired); | ||
121 | static int check_chain_extensions(X509_STORE_CTX *ctx); | 122 | static int check_chain_extensions(X509_STORE_CTX *ctx); |
122 | static int check_name_constraints(X509_STORE_CTX *ctx); | 123 | static int check_name_constraints(X509_STORE_CTX *ctx); |
123 | static int check_trust(X509_STORE_CTX *ctx); | 124 | static int check_trust(X509_STORE_CTX *ctx); |
@@ -324,7 +325,25 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
324 | } | 325 | } |
325 | /* If we were passed a cert chain, use it first */ | 326 | /* If we were passed a cert chain, use it first */ |
326 | if (ctx->untrusted != NULL) { | 327 | if (ctx->untrusted != NULL) { |
327 | xtmp = find_issuer(ctx, sktmp, x); | 328 | /* |
329 | * If we do not find a non-expired untrusted cert, peek | ||
330 | * ahead and see if we can satisify this from the trusted | ||
331 | * store. If not, see if we have an expired untrusted cert. | ||
332 | */ | ||
333 | xtmp = find_issuer(ctx, sktmp, x, 0); | ||
334 | if (xtmp == NULL && | ||
335 | !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)) { | ||
336 | ok = ctx->get_issuer(&xtmp, ctx, x); | ||
337 | if (ok < 0) { | ||
338 | ctx->error = X509_V_ERR_STORE_LOOKUP; | ||
339 | goto end; | ||
340 | } | ||
341 | if (ok > 0) { | ||
342 | X509_free(xtmp); | ||
343 | break; | ||
344 | } | ||
345 | xtmp = find_issuer(ctx, sktmp, x, 1); | ||
346 | } | ||
328 | if (xtmp != NULL) { | 347 | if (xtmp != NULL) { |
329 | if (!sk_X509_push(ctx->chain, xtmp)) { | 348 | if (!sk_X509_push(ctx->chain, xtmp)) { |
330 | X509error(ERR_R_MALLOC_FAILURE); | 349 | X509error(ERR_R_MALLOC_FAILURE); |
@@ -562,7 +581,8 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
562 | */ | 581 | */ |
563 | 582 | ||
564 | static X509 * | 583 | static X509 * |
565 | find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) | 584 | find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x, |
585 | int allow_expired) | ||
566 | { | 586 | { |
567 | int i; | 587 | int i; |
568 | X509 *issuer, *rv = NULL; | 588 | X509 *issuer, *rv = NULL; |
@@ -570,9 +590,10 @@ find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) | |||
570 | for (i = 0; i < sk_X509_num(sk); i++) { | 590 | for (i = 0; i < sk_X509_num(sk); i++) { |
571 | issuer = sk_X509_value(sk, i); | 591 | issuer = sk_X509_value(sk, i); |
572 | if (ctx->check_issued(ctx, x, issuer)) { | 592 | if (ctx->check_issued(ctx, x, issuer)) { |
573 | rv = issuer; | 593 | if (x509_check_cert_time(ctx, issuer, -1)) |
574 | if (x509_check_cert_time(ctx, rv, -1)) | 594 | return issuer; |
575 | break; | 595 | if (allow_expired) |
596 | rv = issuer; | ||
576 | } | 597 | } |
577 | } | 598 | } |
578 | return rv; | 599 | return rv; |
@@ -603,7 +624,7 @@ check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) | |||
603 | static int | 624 | static int |
604 | get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) | 625 | get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) |
605 | { | 626 | { |
606 | *issuer = find_issuer(ctx, ctx->other_ctx, x); | 627 | *issuer = find_issuer(ctx, ctx->other_ctx, x, 1); |
607 | if (*issuer) { | 628 | if (*issuer) { |
608 | CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); | 629 | CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); |
609 | return 1; | 630 | return 1; |