diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/x509/x509_internal.h | 3 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_verify.c | 5 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.c | 143 | ||||
| -rw-r--r-- | src/lib/libcrypto/x509/x509_vfy.h | 9 |
4 files changed, 156 insertions, 4 deletions
diff --git a/src/lib/libcrypto/x509/x509_internal.h b/src/lib/libcrypto/x509/x509_internal.h index c6ce5229ad..030f24c470 100644 --- a/src/lib/libcrypto/x509/x509_internal.h +++ b/src/lib/libcrypto/x509/x509_internal.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_internal.h,v 1.18 2022/03/14 21:15:49 tb Exp $ */ | 1 | /* $OpenBSD: x509_internal.h,v 1.19 2022/06/27 14:10:22 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -135,6 +135,7 @@ int x509_constraints_check(struct x509_constraints_names *names, | |||
| 135 | int x509_constraints_chain(STACK_OF(X509) *chain, int *error, | 135 | int x509_constraints_chain(STACK_OF(X509) *chain, int *error, |
| 136 | int *depth); | 136 | int *depth); |
| 137 | void x509_verify_cert_info_populate(X509 *cert); | 137 | void x509_verify_cert_info_populate(X509 *cert); |
| 138 | int x509_vfy_check_security_level(X509_STORE_CTX *ctx); | ||
| 138 | 139 | ||
| 139 | __END_HIDDEN_DECLS | 140 | __END_HIDDEN_DECLS |
| 140 | 141 | ||
diff --git a/src/lib/libcrypto/x509/x509_verify.c b/src/lib/libcrypto/x509/x509_verify.c index f6959d1f3a..83030672ef 100644 --- a/src/lib/libcrypto/x509/x509_verify.c +++ b/src/lib/libcrypto/x509/x509_verify.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_verify.c,v 1.56 2022/06/25 20:01:43 beck Exp $ */ | 1 | /* $OpenBSD: x509_verify.c,v 1.57 2022/06/27 14:10:22 tb Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
| 4 | * | 4 | * |
| @@ -415,6 +415,9 @@ x509_verify_ctx_validate_legacy_chain(struct x509_verify_ctx *ctx, | |||
| 415 | goto err; | 415 | goto err; |
| 416 | #endif | 416 | #endif |
| 417 | 417 | ||
| 418 | if (!x509_vfy_check_security_level(ctx->xsc)) | ||
| 419 | goto err; | ||
| 420 | |||
| 418 | if (!x509_constraints_chain(ctx->xsc->chain, | 421 | if (!x509_constraints_chain(ctx->xsc->chain, |
| 419 | &ctx->xsc->error, &ctx->xsc->error_depth)) { | 422 | &ctx->xsc->error, &ctx->xsc->error_depth)) { |
| 420 | X509 *cert = sk_X509_value(ctx->xsc->chain, depth); | 423 | X509 *cert = sk_X509_value(ctx->xsc->chain, depth); |
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 9a929963f3..18cf08a07c 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.101 2022/01/22 00:36:46 inoguchi Exp $ */ | 1 | /* $OpenBSD: x509_vfy.c,v 1.102 2022/06/27 14:10: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 | * |
| @@ -144,6 +144,8 @@ static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, | |||
| 144 | 144 | ||
| 145 | static int internal_verify(X509_STORE_CTX *ctx); | 145 | static int internal_verify(X509_STORE_CTX *ctx); |
| 146 | static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); | 146 | static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); |
| 147 | static int check_key_level(X509_STORE_CTX *ctx, X509 *cert); | ||
| 148 | static int verify_cb_cert(X509_STORE_CTX *ctx, X509 *x, int depth, int err); | ||
| 147 | 149 | ||
| 148 | int ASN1_time_tm_clamp_notafter(struct tm *tm); | 150 | int ASN1_time_tm_clamp_notafter(struct tm *tm); |
| 149 | 151 | ||
| @@ -542,6 +544,11 @@ X509_verify_cert_legacy(X509_STORE_CTX *ctx) | |||
| 542 | if (!ok) | 544 | if (!ok) |
| 543 | goto end; | 545 | goto end; |
| 544 | 546 | ||
| 547 | /* Check that the chain satisfies the security level. */ | ||
| 548 | ok = x509_vfy_check_security_level(ctx); | ||
| 549 | if (!ok) | ||
| 550 | goto end; | ||
| 551 | |||
| 545 | /* Check name constraints */ | 552 | /* Check name constraints */ |
| 546 | ok = check_name_constraints(ctx); | 553 | ok = check_name_constraints(ctx); |
| 547 | if (!ok) | 554 | if (!ok) |
| @@ -629,6 +636,14 @@ X509_verify_cert(X509_STORE_CTX *ctx) | |||
| 629 | } | 636 | } |
| 630 | 637 | ||
| 631 | /* | 638 | /* |
| 639 | * If the certificate's public key is too weak, don't bother | ||
| 640 | * continuing. | ||
| 641 | */ | ||
| 642 | if (!check_key_level(ctx, ctx->cert) && | ||
| 643 | !verify_cb_cert(ctx, ctx->cert, 0, X509_V_ERR_EE_KEY_TOO_SMALL)) | ||
| 644 | return 0; | ||
| 645 | |||
| 646 | /* | ||
| 632 | * If flags request legacy, use the legacy verifier. If we | 647 | * If flags request legacy, use the legacy verifier. If we |
| 633 | * requested "no alt chains" from the age of hammer pants, use | 648 | * requested "no alt chains" from the age of hammer pants, use |
| 634 | * the legacy verifier because the multi chain verifier really | 649 | * the legacy verifier because the multi chain verifier really |
| @@ -2596,3 +2611,129 @@ X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) | |||
| 2596 | X509_VERIFY_PARAM_free(ctx->param); | 2611 | X509_VERIFY_PARAM_free(ctx->param); |
| 2597 | ctx->param = param; | 2612 | ctx->param = param; |
| 2598 | } | 2613 | } |
| 2614 | |||
| 2615 | /* | ||
| 2616 | * Check if |bits| are adequate for |security level|. | ||
| 2617 | * Returns 1 if ok, 0 otherwise. | ||
| 2618 | */ | ||
| 2619 | static int | ||
| 2620 | enough_bits_for_security_level(int bits, int level) | ||
| 2621 | { | ||
| 2622 | /* | ||
| 2623 | * Sigh. OpenSSL does this silly squashing, so we will | ||
| 2624 | * too. Derp for Derp compatibility being important. | ||
| 2625 | */ | ||
| 2626 | if (level < 0) | ||
| 2627 | level = 0; | ||
| 2628 | if (level > 5) | ||
| 2629 | level = 5; | ||
| 2630 | |||
| 2631 | switch (level) { | ||
| 2632 | case 0: | ||
| 2633 | return 1; | ||
| 2634 | case 1: | ||
| 2635 | return bits >= 80; | ||
| 2636 | case 2: | ||
| 2637 | return bits >= 112; | ||
| 2638 | case 3: | ||
| 2639 | return bits >= 128; | ||
| 2640 | case 4: | ||
| 2641 | return bits >= 192; | ||
| 2642 | case 5: | ||
| 2643 | return bits >= 256; | ||
| 2644 | default: | ||
| 2645 | return 0; | ||
| 2646 | } | ||
| 2647 | } | ||
| 2648 | |||
| 2649 | /* | ||
| 2650 | * Check whether the public key of |cert| meets the security level of |ctx|. | ||
| 2651 | * | ||
| 2652 | * Returns 1 on success, 0 otherwise. | ||
| 2653 | */ | ||
| 2654 | static int | ||
| 2655 | check_key_level(X509_STORE_CTX *ctx, X509 *cert) | ||
| 2656 | { | ||
| 2657 | EVP_PKEY *pkey; | ||
| 2658 | int bits; | ||
| 2659 | |||
| 2660 | /* Unsupported or malformed keys are not secure */ | ||
| 2661 | if ((pkey = X509_get0_pubkey(cert)) == NULL) | ||
| 2662 | return 0; | ||
| 2663 | |||
| 2664 | if ((bits = EVP_PKEY_security_bits(pkey)) <= 0) | ||
| 2665 | return 0; | ||
| 2666 | |||
| 2667 | return enough_bits_for_security_level(bits, ctx->param->security_level); | ||
| 2668 | } | ||
| 2669 | |||
| 2670 | /* | ||
| 2671 | * Check whether the signature digest algorithm of |cert| meets the security | ||
| 2672 | * level of |ctx|. Do not check trust anchors (self-signed or not). | ||
| 2673 | * | ||
| 2674 | * Returns 1 on success, 0 otherwise. | ||
| 2675 | */ | ||
| 2676 | static int | ||
| 2677 | check_sig_level(X509_STORE_CTX *ctx, X509 *cert) | ||
| 2678 | { | ||
| 2679 | const EVP_MD *md; | ||
| 2680 | int bits, nid, md_nid; | ||
| 2681 | |||
| 2682 | if ((nid = X509_get_signature_nid(cert)) == NID_undef) | ||
| 2683 | return 0; | ||
| 2684 | |||
| 2685 | /* | ||
| 2686 | * Look up signature algorithm digest. | ||
| 2687 | */ | ||
| 2688 | |||
| 2689 | if (!OBJ_find_sigid_algs(nid, &md_nid, NULL)) | ||
| 2690 | return 0; | ||
| 2691 | |||
| 2692 | if (md_nid == NID_undef) | ||
| 2693 | return 0; | ||
| 2694 | |||
| 2695 | if ((md = EVP_get_digestbynid(md_nid)) == NULL) | ||
| 2696 | return 0; | ||
| 2697 | |||
| 2698 | /* Assume 4 bits of collision resistance for each hash octet. */ | ||
| 2699 | bits = EVP_MD_size(md) * 4; | ||
| 2700 | |||
| 2701 | return enough_bits_for_security_level(bits, ctx->param->security_level); | ||
| 2702 | } | ||
| 2703 | |||
| 2704 | int | ||
| 2705 | x509_vfy_check_security_level(X509_STORE_CTX *ctx) | ||
| 2706 | { | ||
| 2707 | int num = sk_X509_num(ctx->chain); | ||
| 2708 | int i; | ||
| 2709 | |||
| 2710 | if (ctx->param->security_level <= 0) | ||
| 2711 | return 1; | ||
| 2712 | |||
| 2713 | for (i = 0; i < num; i++) { | ||
| 2714 | X509 *cert = sk_X509_value(ctx->chain, i); | ||
| 2715 | |||
| 2716 | /* | ||
| 2717 | * We've already checked the security of the leaf key, so here | ||
| 2718 | * we only check the security of issuer keys. | ||
| 2719 | */ | ||
| 2720 | if (i > 0) { | ||
| 2721 | if (!check_key_level(ctx, cert) && | ||
| 2722 | !verify_cb_cert(ctx, cert, i, | ||
| 2723 | X509_V_ERR_CA_KEY_TOO_SMALL)) | ||
| 2724 | return 0; | ||
| 2725 | } | ||
| 2726 | |||
| 2727 | /* | ||
| 2728 | * We also check the signature algorithm security of all certs | ||
| 2729 | * except those of the trust anchor at index num - 1. | ||
| 2730 | */ | ||
| 2731 | if (i == num - 1) | ||
| 2732 | break; | ||
| 2733 | |||
| 2734 | if (!check_sig_level(ctx, cert) && | ||
| 2735 | !verify_cb_cert(ctx, cert, i, X509_V_ERR_CA_MD_TOO_WEAK)) | ||
| 2736 | return 0; | ||
| 2737 | } | ||
| 2738 | return 1; | ||
| 2739 | } | ||
diff --git a/src/lib/libcrypto/x509/x509_vfy.h b/src/lib/libcrypto/x509/x509_vfy.h index a007fe4795..d31e779aae 100644 --- a/src/lib/libcrypto/x509/x509_vfy.h +++ b/src/lib/libcrypto/x509/x509_vfy.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: x509_vfy.h,v 1.51 2022/06/27 14:00:09 tb Exp $ */ | 1 | /* $OpenBSD: x509_vfy.h,v 1.52 2022/06/27 14:10: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 | * |
| @@ -205,6 +205,13 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); | |||
| 205 | /* Issuer lookup error */ | 205 | /* Issuer lookup error */ |
| 206 | #define X509_V_ERR_STORE_LOOKUP 66 | 206 | #define X509_V_ERR_STORE_LOOKUP 66 |
| 207 | 207 | ||
| 208 | #if defined(LIBRESSL_INTERNAL) | ||
| 209 | /* Security level errors */ | ||
| 210 | #define X509_V_ERR_EE_KEY_TOO_SMALL 67 | ||
| 211 | #define X509_V_ERR_CA_KEY_TOO_SMALL 68 | ||
| 212 | #define X509_V_ERR_CA_MD_TOO_WEAK 69 | ||
| 213 | #endif | ||
| 214 | |||
| 208 | /* Certificate verify flags */ | 215 | /* Certificate verify flags */ |
| 209 | 216 | ||
| 210 | /* Send issuer+subject checks to verify_cb */ | 217 | /* Send issuer+subject checks to verify_cb */ |
