summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorbeck <>2017-01-03 05:34:48 +0000
committerbeck <>2017-01-03 05:34:48 +0000
commit9f4657d603430aebe13903d7dbdb5cd15e512f95 (patch)
tree5fc8e0a7bc7848b74f6b48f6f81b8b56ec43c714 /src/lib
parent5652b8a711562263678662d609ce7925015bce4d (diff)
downloadopenbsd-9f4657d603430aebe13903d7dbdb5cd15e512f95.tar.gz
openbsd-9f4657d603430aebe13903d7dbdb5cd15e512f95.tar.bz2
openbsd-9f4657d603430aebe13903d7dbdb5cd15e512f95.zip
bring in boring's internal check_trust function to fix a bug introduced
when we went to alternate cert chains. this correctly does not clobber the ctx->error when using an alt chain. ok jsing@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/x509/x509_vfy.c103
1 files changed, 79 insertions, 24 deletions
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index abd5c65e31..3d4121ed2a 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.52 2016/11/06 10:37:38 beck Exp $ */ 1/* $OpenBSD: x509_vfy.c,v 1.53 2017/01/03 05:34:48 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 *
@@ -775,32 +775,87 @@ check_name_constraints(X509_STORE_CTX *ctx)
775 return 1; 775 return 1;
776} 776}
777 777
778static int 778/* Given a certificate try and find an exact match in the store */
779check_trust(X509_STORE_CTX *ctx) 779
780static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
780{ 781{
781#ifdef OPENSSL_NO_CHAIN_VERIFY 782 STACK_OF(X509) *certs;
782 return 1; 783 X509 *xtmp = NULL;
783#else 784 size_t i;
784 int i, ok;
785 X509 *x;
786 int (*cb)(int xok, X509_STORE_CTX *xctx);
787 785
788 cb = ctx->verify_cb; 786 /* Lookup all certs with matching subject name */
789 /* For now just check the last certificate in the chain */ 787 certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
790 i = sk_X509_num(ctx->chain) - 1; 788 if (certs == NULL)
791 x = sk_X509_value(ctx->chain, i); 789 return NULL;
792 ok = X509_check_trust(x, ctx->param->trust, 0); 790
793 if (ok == X509_TRUST_TRUSTED) 791 /* Look for exact match */
794 return 1; 792 for (i = 0; i < sk_X509_num(certs); i++) {
795 ctx->error_depth = i; 793 xtmp = sk_X509_value(certs, i);
796 ctx->current_cert = x; 794 if (!X509_cmp(xtmp, x))
797 if (ok == X509_TRUST_REJECTED) 795 break;
798 ctx->error = X509_V_ERR_CERT_REJECTED; 796 }
797
798 if (i < sk_X509_num(certs))
799 X509_up_ref(xtmp);
799 else 800 else
800 ctx->error = X509_V_ERR_CERT_UNTRUSTED; 801 xtmp = NULL;
801 ok = cb(0, ctx); 802
802 return ok; 803 sk_X509_pop_free(certs, X509_free);
803#endif 804 return xtmp;
805}
806
807static int check_trust(X509_STORE_CTX *ctx)
808{
809 size_t i;
810 int ok;
811 X509 *x = NULL;
812 int (*cb) (int xok, X509_STORE_CTX *xctx);
813
814 cb = ctx->verify_cb;
815 /* Check all trusted certificates in chain */
816 for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
817 x = sk_X509_value(ctx->chain, i);
818 ok = X509_check_trust(x, ctx->param->trust, 0);
819
820 /* If explicitly trusted return trusted */
821 if (ok == X509_TRUST_TRUSTED)
822 return X509_TRUST_TRUSTED;
823 /*
824 * If explicitly rejected notify callback and reject if not
825 * overridden.
826 */
827 if (ok == X509_TRUST_REJECTED) {
828 ctx->error_depth = i;
829 ctx->current_cert = x;
830 ctx->error = X509_V_ERR_CERT_REJECTED;
831 ok = cb(0, ctx);
832 if (!ok)
833 return X509_TRUST_REJECTED;
834 }
835 }
836 /*
837 * If we accept partial chains and have at least one trusted certificate
838 * return success.
839 */
840 if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
841 X509 *mx;
842 if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
843 return X509_TRUST_TRUSTED;
844 x = sk_X509_value(ctx->chain, 0);
845 mx = lookup_cert_match(ctx, x);
846 if (mx) {
847 (void)sk_X509_set(ctx->chain, 0, mx);
848 X509_free(x);
849 ctx->last_untrusted = 0;
850 return X509_TRUST_TRUSTED;
851 }
852 }
853
854 /*
855 * If no trusted certs in chain at all return untrusted and allow
856 * standard (no issuer cert) etc errors to be indicated.
857 */
858 return X509_TRUST_UNTRUSTED;
804} 859}
805 860
806static int 861static int