diff options
| author | beck <> | 2017-01-03 05:34:48 +0000 |
|---|---|---|
| committer | beck <> | 2017-01-03 05:34:48 +0000 |
| commit | 9c1a1015b0e9cebcce01d2f3fcbf8883aa60fa38 (patch) | |
| tree | 5fc8e0a7bc7848b74f6b48f6f81b8b56ec43c714 /src | |
| parent | 76bc9d5fdc23892df18c905a250602f93843ddbc (diff) | |
| download | openbsd-9c1a1015b0e9cebcce01d2f3fcbf8883aa60fa38.tar.gz openbsd-9c1a1015b0e9cebcce01d2f3fcbf8883aa60fa38.tar.bz2 openbsd-9c1a1015b0e9cebcce01d2f3fcbf8883aa60fa38.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 '')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 103 |
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 | ||
| 778 | static int | 778 | /* Given a certificate try and find an exact match in the store */ |
| 779 | check_trust(X509_STORE_CTX *ctx) | 779 | |
| 780 | static 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 | |||
| 807 | static 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 | ||
| 806 | static int | 861 | static int |
