summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/x509/x509_vfy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/x509/x509_vfy.c')
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c228
1 files changed, 180 insertions, 48 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index 28dbf60c38..b1cc9b5a00 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.74 2020/09/12 14:14:02 beck Exp $ */ 1/* $OpenBSD: x509_vfy.c,v 1.75 2020/09/13 15:06:17 beck 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 *
@@ -77,6 +77,7 @@
77#include "vpm_int.h" 77#include "vpm_int.h"
78#include "x509_internal.h" 78#include "x509_internal.h"
79#include "x509_lcl.h" 79#include "x509_lcl.h"
80#include "x509_internal.h"
80 81
81/* CRL score values */ 82/* CRL score values */
82 83
@@ -124,7 +125,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx);
124static int check_name_constraints(X509_STORE_CTX *ctx); 125static int check_name_constraints(X509_STORE_CTX *ctx);
125static int check_trust(X509_STORE_CTX *ctx); 126static int check_trust(X509_STORE_CTX *ctx);
126static int check_revocation(X509_STORE_CTX *ctx); 127static int check_revocation(X509_STORE_CTX *ctx);
127static int check_cert(X509_STORE_CTX *ctx); 128static int check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth);
128static int check_policy(X509_STORE_CTX *ctx); 129static int check_policy(X509_STORE_CTX *ctx);
129 130
130static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, 131static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
@@ -144,6 +145,7 @@ static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time,
144 int clamp_notafter); 145 int clamp_notafter);
145 146
146static int internal_verify(X509_STORE_CTX *ctx); 147static int internal_verify(X509_STORE_CTX *ctx);
148static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
147 149
148int ASN1_time_tm_clamp_notafter(struct tm *tm); 150int ASN1_time_tm_clamp_notafter(struct tm *tm);
149 151
@@ -224,7 +226,21 @@ check_id(X509_STORE_CTX *ctx)
224} 226}
225 227
226int 228int
227X509_verify_cert(X509_STORE_CTX *ctx) 229x509_vfy_check_id(X509_STORE_CTX *ctx) {
230 return check_id(ctx);
231}
232
233/*
234 * This is the effectively broken legacy OpenSSL chain builder. It
235 * might find an unvalidated chain and leave it sitting in
236 * ctx->chain. It does not correctly handle many cases where multiple
237 * chains could exist.
238 *
239 * Oh no.. I know a dirty word...
240 * Oooooooh..
241 */
242static int
243X509_verify_cert_legacy_build_chain(X509_STORE_CTX *ctx, int *bad)
228{ 244{
229 X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; 245 X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
230 int bad_chain = 0; 246 int bad_chain = 0;
@@ -234,39 +250,6 @@ X509_verify_cert(X509_STORE_CTX *ctx)
234 int (*cb) (int xok, X509_STORE_CTX *xctx); 250 int (*cb) (int xok, X509_STORE_CTX *xctx);
235 STACK_OF(X509) *sktmp = NULL; 251 STACK_OF(X509) *sktmp = NULL;
236 252
237 if (ctx->cert == NULL) {
238 X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
239 ctx->error = X509_V_ERR_INVALID_CALL;
240 return -1;
241 }
242 if (ctx->chain != NULL) {
243 /*
244 * This X509_STORE_CTX has already been used to verify
245 * a cert. We cannot do another one.
246 */
247 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
248 ctx->error = X509_V_ERR_INVALID_CALL;
249 return -1;
250 }
251 if (ctx->param->id->poisoned) {
252 /*
253 * This X509_STORE_CTX had failures setting
254 * up verify parameters. We can not use it.
255 */
256 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
257 ctx->error = X509_V_ERR_INVALID_CALL;
258 return -1;
259 }
260 if (ctx->error != X509_V_ERR_INVALID_CALL) {
261 /*
262 * This X509_STORE_CTX has not been properly initialized.
263 */
264 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
265 ctx->error = X509_V_ERR_INVALID_CALL;
266 return -1;
267 }
268 ctx->error = X509_V_OK; /* Initialize to OK */
269
270 cb = ctx->verify_cb; 253 cb = ctx->verify_cb;
271 254
272 /* 255 /*
@@ -534,6 +517,23 @@ X509_verify_cert(X509_STORE_CTX *ctx)
534 if (!ok) 517 if (!ok)
535 goto end; 518 goto end;
536 } 519 }
520 end:
521 sk_X509_free(sktmp);
522 X509_free(chain_ss);
523 *bad = bad_chain;
524 return ok;
525}
526
527static int
528X509_verify_cert_legacy(X509_STORE_CTX *ctx)
529{
530 int ok = 0, bad_chain;
531
532 ctx->error = X509_V_OK; /* Initialize to OK */
533
534 ok = X509_verify_cert_legacy_build_chain(ctx, &bad_chain);
535 if (!ok)
536 goto end;
537 537
538 /* We have the chain complete: now we need to check its purpose */ 538 /* We have the chain complete: now we need to check its purpose */
539 ok = check_chain_extensions(ctx); 539 ok = check_chain_extensions(ctx);
@@ -548,6 +548,7 @@ X509_verify_cert(X509_STORE_CTX *ctx)
548 ok = check_id(ctx); 548 ok = check_id(ctx);
549 if (!ok) 549 if (!ok)
550 goto end; 550 goto end;
551
551 /* 552 /*
552 * Check revocation status: we do this after copying parameters because 553 * Check revocation status: we do this after copying parameters because
553 * they may be needed for CRL signature verification. 554 * they may be needed for CRL signature verification.
@@ -569,15 +570,125 @@ X509_verify_cert(X509_STORE_CTX *ctx)
569 ok = ctx->check_policy(ctx); 570 ok = ctx->check_policy(ctx);
570 571
571 end: 572 end:
572 sk_X509_free(sktmp);
573 X509_free(chain_ss);
574
575 /* Safety net, error returns must set ctx->error */ 573 /* Safety net, error returns must set ctx->error */
576 if (ok <= 0 && ctx->error == X509_V_OK) 574 if (ok <= 0 && ctx->error == X509_V_OK)
577 ctx->error = X509_V_ERR_UNSPECIFIED; 575 ctx->error = X509_V_ERR_UNSPECIFIED;
576
578 return ok; 577 return ok;
579} 578}
580 579
580int
581X509_verify_cert(X509_STORE_CTX *ctx)
582{
583 STACK_OF(X509) *roots = NULL;
584 struct x509_verify_ctx *vctx = NULL;
585 int chain_count = 0;
586
587 if (ctx->cert == NULL) {
588 X509error(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
589 ctx->error = X509_V_ERR_INVALID_CALL;
590 return -1;
591 }
592 if (ctx->chain != NULL) {
593 /*
594 * This X509_STORE_CTX has already been used to verify
595 * a cert. We cannot do another one.
596 */
597 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
598 ctx->error = X509_V_ERR_INVALID_CALL;
599 return -1;
600 }
601 if (ctx->param->id->poisoned) {
602 /*
603 * This X509_STORE_CTX had failures setting
604 * up verify parameters. We can not use it.
605 */
606 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
607 ctx->error = X509_V_ERR_INVALID_CALL;
608 return -1;
609 }
610 if (ctx->error != X509_V_ERR_INVALID_CALL) {
611 /*
612 * This X509_STORE_CTX has not been properly initialized.
613 */
614 X509error(ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
615 ctx->error = X509_V_ERR_INVALID_CALL;
616 return -1;
617 }
618
619 /*
620 * If flags request legacy, use the legacy verifier. If we
621 * requested "no alt chains" from the age of hammer pants, use
622 * the legacy verifier because the multi chain verifier really
623 * does find all the "alt chains".
624 *
625 * XXX deprecate the NO_ALT_CHAINS flag?
626 */
627 if ((ctx->param->flags & X509_V_FLAG_LEGACY_VERIFY) ||
628 (ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS))
629 return X509_verify_cert_legacy(ctx);
630
631 /* Use the modern multi-chain verifier from x509_verify_cert */
632
633 /* Find our trusted roots */
634 ctx->error = X509_V_ERR_OUT_OF_MEM;
635
636 if (ctx->get_issuer == get_issuer_sk) {
637 /*
638 * We are using the trusted stack method. so
639 * the roots are in the aptly named "ctx->other_ctx"
640 * pointer. (It could have been called "al")
641 */
642 if ((roots = X509_chain_up_ref(ctx->other_ctx)) == NULL)
643 return -1;
644 } else {
645 /*
646 * We have a X509_STORE and need to pull out the roots.
647 * Don't look Ethel...
648 */
649 STACK_OF(X509_OBJECT) *objs;
650 size_t i, good = 1;
651
652 if ((roots = sk_X509_new_null()) == NULL)
653 return -1;
654
655 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
656 if ((objs = X509_STORE_get0_objects(ctx->ctx)) == NULL)
657 good = 0;
658 for (i = 0; good && i < sk_X509_OBJECT_num(objs); i++) {
659 X509_OBJECT *obj;
660 X509 *root;
661 obj = sk_X509_OBJECT_value(objs, i);
662 if (obj->type != X509_LU_X509)
663 continue;
664 root = obj->data.x509;
665 if (X509_up_ref(root) == 0)
666 good = 0;
667 if (sk_X509_push(roots, root) == 0) {
668 X509_free(root);
669 good = 0;
670 }
671 }
672 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
673
674 if (!good) {
675 sk_X509_pop_free(roots, X509_free);
676 return -1;
677 }
678 }
679
680 if ((vctx = x509_verify_ctx_new_from_xsc(ctx, roots)) != NULL) {
681 ctx->error = X509_V_OK; /* Initialize to OK */
682 chain_count = x509_verify(vctx, NULL, NULL);
683 }
684
685 sk_X509_pop_free(roots, X509_free);
686 x509_verify_ctx_free(vctx);
687
688 /* if we succeed we have a chain in ctx->chain */
689 return (chain_count > 0 && ctx->chain != NULL);
690}
691
581/* Given a STACK_OF(X509) find the issuer of cert (if any) 692/* Given a STACK_OF(X509) find the issuer of cert (if any)
582 */ 693 */
583 694
@@ -637,8 +748,8 @@ get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
637 * with the supplied purpose 748 * with the supplied purpose
638 */ 749 */
639 750
640static int 751int
641check_chain_extensions(X509_STORE_CTX *ctx) 752x509_vfy_check_chain_extensions(X509_STORE_CTX *ctx)
642{ 753{
643#ifdef OPENSSL_NO_CHAIN_VERIFY 754#ifdef OPENSSL_NO_CHAIN_VERIFY
644 return 1; 755 return 1;
@@ -781,6 +892,11 @@ end:
781} 892}
782 893
783static int 894static int
895check_chain_extensions(X509_STORE_CTX *ctx) {
896 return x509_vfy_check_chain_extensions(ctx);
897}
898
899static int
784check_name_constraints(X509_STORE_CTX *ctx) 900check_name_constraints(X509_STORE_CTX *ctx)
785{ 901{
786 if (!x509_constraints_chain(ctx->chain, &ctx->error, 902 if (!x509_constraints_chain(ctx->chain, &ctx->error,
@@ -875,6 +991,11 @@ static int check_trust(X509_STORE_CTX *ctx)
875 return X509_TRUST_UNTRUSTED; 991 return X509_TRUST_UNTRUSTED;
876} 992}
877 993
994int x509_vfy_check_trust(X509_STORE_CTX *ctx)
995{
996 return check_trust(ctx);
997}
998
878static int 999static int
879check_revocation(X509_STORE_CTX *ctx) 1000check_revocation(X509_STORE_CTX *ctx)
880{ 1001{
@@ -891,24 +1012,29 @@ check_revocation(X509_STORE_CTX *ctx)
891 last = 0; 1012 last = 0;
892 } 1013 }
893 for (i = 0; i <= last; i++) { 1014 for (i = 0; i <= last; i++) {
894 ctx->error_depth = i; 1015 ok = check_cert(ctx, ctx->chain, i);
895 ok = check_cert(ctx);
896 if (!ok) 1016 if (!ok)
897 return ok; 1017 return ok;
898 } 1018 }
899 return 1; 1019 return 1;
900} 1020}
901 1021
1022int
1023x509_vfy_check_revocation(X509_STORE_CTX *ctx)
1024{
1025 return check_revocation(ctx);
1026}
1027
902static int 1028static int
903check_cert(X509_STORE_CTX *ctx) 1029check_cert(X509_STORE_CTX *ctx, STACK_OF(X509) *chain, int depth)
904{ 1030{
905 X509_CRL *crl = NULL, *dcrl = NULL; 1031 X509_CRL *crl = NULL, *dcrl = NULL;
906 X509 *x; 1032 X509 *x;
907 int ok = 0, cnum; 1033 int ok = 0, cnum;
908 unsigned int last_reasons; 1034 unsigned int last_reasons;
909 1035
910 cnum = ctx->error_depth; 1036 cnum = ctx->error_depth = depth;
911 x = sk_X509_value(ctx->chain, cnum); 1037 x = sk_X509_value(chain, cnum);
912 ctx->current_cert = x; 1038 ctx->current_cert = x;
913 ctx->current_issuer = NULL; 1039 ctx->current_issuer = NULL;
914 ctx->current_crl_score = 0; 1040 ctx->current_crl_score = 0;
@@ -1660,8 +1786,8 @@ cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
1660 return 1; 1786 return 1;
1661} 1787}
1662 1788
1663static int 1789int
1664check_policy(X509_STORE_CTX *ctx) 1790x509_vfy_check_policy(X509_STORE_CTX *ctx)
1665{ 1791{
1666 int ret; 1792 int ret;
1667 1793
@@ -1707,6 +1833,12 @@ check_policy(X509_STORE_CTX *ctx)
1707 return 1; 1833 return 1;
1708} 1834}
1709 1835
1836static int
1837check_policy(X509_STORE_CTX *ctx)
1838{
1839 return x509_vfy_check_policy(ctx);
1840}
1841
1710/* 1842/*
1711 * Inform the verify callback of an error. 1843 * Inform the verify callback of an error.
1712 * 1844 *