summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2020-06-10 03:56:22 +0000
committertb <>2020-06-10 03:56:22 +0000
commita91baa573ac5ab1cbde7a2761d1d1da9501f45ec (patch)
tree4521a19cf622bb9e5f326c41d51cdf799d53192e
parentf21616a5b0676fecb01b51cf6ce47840065457ef (diff)
downloadopenbsd-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.c37
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
118static int null_callback(int ok, X509_STORE_CTX *e); 118static int null_callback(int ok, X509_STORE_CTX *e);
119static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); 119static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
120static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); 120static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x,
121 int allow_expired);
121static int check_chain_extensions(X509_STORE_CTX *ctx); 122static int check_chain_extensions(X509_STORE_CTX *ctx);
122static int check_name_constraints(X509_STORE_CTX *ctx); 123static int check_name_constraints(X509_STORE_CTX *ctx);
123static int check_trust(X509_STORE_CTX *ctx); 124static 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
564static X509 * 583static X509 *
565find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) 584find_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)
603static int 624static int
604get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 625get_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;