diff options
Diffstat (limited to 'crypto/openssl/ssl/t1_lib.c')
-rw-r--r-- | crypto/openssl/ssl/t1_lib.c | 1545 |
1 files changed, 1076 insertions, 469 deletions
diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c index b1d3add18743..8be00a4f3405 100644 --- a/crypto/openssl/ssl/t1_lib.c +++ b/crypto/openssl/ssl/t1_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html @@ -12,12 +12,18 @@ #include <openssl/objects.h> #include <openssl/evp.h> #include <openssl/hmac.h> +#include <openssl/core_names.h> #include <openssl/ocsp.h> #include <openssl/conf.h> #include <openssl/x509v3.h> #include <openssl/dh.h> #include <openssl/bn.h> +#include <openssl/provider.h> +#include <openssl/param_build.h> #include "internal/nelem.h" +#include "internal/sizes.h" +#include "internal/tlsgroups.h" +#include "internal/cryptlib.h" #include "ssl_local.h" #include <openssl/ct.h> @@ -124,51 +130,60 @@ int tls1_clear(SSL *s) return 0; if (s->method->version == TLS_ANY_VERSION) - s->version = TLS_MAX_VERSION; + s->version = TLS_MAX_VERSION_INTERNAL; else s->version = s->method->version; return 1; } -#ifndef OPENSSL_NO_EC - -/* - * Table of curve information. - * Do not delete entries or reorder this array! It is used as a lookup - * table: the index of each entry is one less than the TLS curve id. - */ -static const TLS_GROUP_INFO nid_list[] = { - {NID_sect163k1, 80, TLS_CURVE_CHAR2}, /* sect163k1 (1) */ - {NID_sect163r1, 80, TLS_CURVE_CHAR2}, /* sect163r1 (2) */ - {NID_sect163r2, 80, TLS_CURVE_CHAR2}, /* sect163r2 (3) */ - {NID_sect193r1, 80, TLS_CURVE_CHAR2}, /* sect193r1 (4) */ - {NID_sect193r2, 80, TLS_CURVE_CHAR2}, /* sect193r2 (5) */ - {NID_sect233k1, 112, TLS_CURVE_CHAR2}, /* sect233k1 (6) */ - {NID_sect233r1, 112, TLS_CURVE_CHAR2}, /* sect233r1 (7) */ - {NID_sect239k1, 112, TLS_CURVE_CHAR2}, /* sect239k1 (8) */ - {NID_sect283k1, 128, TLS_CURVE_CHAR2}, /* sect283k1 (9) */ - {NID_sect283r1, 128, TLS_CURVE_CHAR2}, /* sect283r1 (10) */ - {NID_sect409k1, 192, TLS_CURVE_CHAR2}, /* sect409k1 (11) */ - {NID_sect409r1, 192, TLS_CURVE_CHAR2}, /* sect409r1 (12) */ - {NID_sect571k1, 256, TLS_CURVE_CHAR2}, /* sect571k1 (13) */ - {NID_sect571r1, 256, TLS_CURVE_CHAR2}, /* sect571r1 (14) */ - {NID_secp160k1, 80, TLS_CURVE_PRIME}, /* secp160k1 (15) */ - {NID_secp160r1, 80, TLS_CURVE_PRIME}, /* secp160r1 (16) */ - {NID_secp160r2, 80, TLS_CURVE_PRIME}, /* secp160r2 (17) */ - {NID_secp192k1, 80, TLS_CURVE_PRIME}, /* secp192k1 (18) */ - {NID_X9_62_prime192v1, 80, TLS_CURVE_PRIME}, /* secp192r1 (19) */ - {NID_secp224k1, 112, TLS_CURVE_PRIME}, /* secp224k1 (20) */ - {NID_secp224r1, 112, TLS_CURVE_PRIME}, /* secp224r1 (21) */ - {NID_secp256k1, 128, TLS_CURVE_PRIME}, /* secp256k1 (22) */ - {NID_X9_62_prime256v1, 128, TLS_CURVE_PRIME}, /* secp256r1 (23) */ - {NID_secp384r1, 192, TLS_CURVE_PRIME}, /* secp384r1 (24) */ - {NID_secp521r1, 256, TLS_CURVE_PRIME}, /* secp521r1 (25) */ - {NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */ - {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ - {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ - {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ - {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ +/* Legacy NID to group_id mapping. Only works for groups we know about */ +static struct { + int nid; + uint16_t group_id; +} nid_to_group[] = { + {NID_sect163k1, OSSL_TLS_GROUP_ID_sect163k1}, + {NID_sect163r1, OSSL_TLS_GROUP_ID_sect163r1}, + {NID_sect163r2, OSSL_TLS_GROUP_ID_sect163r2}, + {NID_sect193r1, OSSL_TLS_GROUP_ID_sect193r1}, + {NID_sect193r2, OSSL_TLS_GROUP_ID_sect193r2}, + {NID_sect233k1, OSSL_TLS_GROUP_ID_sect233k1}, + {NID_sect233r1, OSSL_TLS_GROUP_ID_sect233r1}, + {NID_sect239k1, OSSL_TLS_GROUP_ID_sect239k1}, + {NID_sect283k1, OSSL_TLS_GROUP_ID_sect283k1}, + {NID_sect283r1, OSSL_TLS_GROUP_ID_sect283r1}, + {NID_sect409k1, OSSL_TLS_GROUP_ID_sect409k1}, + {NID_sect409r1, OSSL_TLS_GROUP_ID_sect409r1}, + {NID_sect571k1, OSSL_TLS_GROUP_ID_sect571k1}, + {NID_sect571r1, OSSL_TLS_GROUP_ID_sect571r1}, + {NID_secp160k1, OSSL_TLS_GROUP_ID_secp160k1}, + {NID_secp160r1, OSSL_TLS_GROUP_ID_secp160r1}, + {NID_secp160r2, OSSL_TLS_GROUP_ID_secp160r2}, + {NID_secp192k1, OSSL_TLS_GROUP_ID_secp192k1}, + {NID_X9_62_prime192v1, OSSL_TLS_GROUP_ID_secp192r1}, + {NID_secp224k1, OSSL_TLS_GROUP_ID_secp224k1}, + {NID_secp224r1, OSSL_TLS_GROUP_ID_secp224r1}, + {NID_secp256k1, OSSL_TLS_GROUP_ID_secp256k1}, + {NID_X9_62_prime256v1, OSSL_TLS_GROUP_ID_secp256r1}, + {NID_secp384r1, OSSL_TLS_GROUP_ID_secp384r1}, + {NID_secp521r1, OSSL_TLS_GROUP_ID_secp521r1}, + {NID_brainpoolP256r1, OSSL_TLS_GROUP_ID_brainpoolP256r1}, + {NID_brainpoolP384r1, OSSL_TLS_GROUP_ID_brainpoolP384r1}, + {NID_brainpoolP512r1, OSSL_TLS_GROUP_ID_brainpoolP512r1}, + {EVP_PKEY_X25519, OSSL_TLS_GROUP_ID_x25519}, + {EVP_PKEY_X448, OSSL_TLS_GROUP_ID_x448}, + {NID_id_tc26_gost_3410_2012_256_paramSetA, 0x0022}, + {NID_id_tc26_gost_3410_2012_256_paramSetB, 0x0023}, + {NID_id_tc26_gost_3410_2012_256_paramSetC, 0x0024}, + {NID_id_tc26_gost_3410_2012_256_paramSetD, 0x0025}, + {NID_id_tc26_gost_3410_2012_512_paramSetA, 0x0026}, + {NID_id_tc26_gost_3410_2012_512_paramSetB, 0x0027}, + {NID_id_tc26_gost_3410_2012_512_paramSetC, 0x0028}, + {NID_ffdhe2048, OSSL_TLS_GROUP_ID_ffdhe2048}, + {NID_ffdhe3072, OSSL_TLS_GROUP_ID_ffdhe3072}, + {NID_ffdhe4096, OSSL_TLS_GROUP_ID_ffdhe4096}, + {NID_ffdhe6144, OSSL_TLS_GROUP_ID_ffdhe6144}, + {NID_ffdhe8192, OSSL_TLS_GROUP_ID_ffdhe8192} }; static const unsigned char ecformats_default[] = { @@ -178,12 +193,24 @@ static const unsigned char ecformats_default[] = { }; /* The default curves */ -static const uint16_t eccurves_default[] = { +static const uint16_t supported_groups_default[] = { 29, /* X25519 (29) */ 23, /* secp256r1 (23) */ 30, /* X448 (30) */ 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ + 34, /* GC256A (34) */ + 35, /* GC256B (35) */ + 36, /* GC256C (36) */ + 37, /* GC256D (37) */ + 38, /* GC512A (38) */ + 39, /* GC512B (39) */ + 40, /* GC512C (40) */ + 0x100, /* ffdhe2048 (0x100) */ + 0x101, /* ffdhe3072 (0x101) */ + 0x102, /* ffdhe4096 (0x102) */ + 0x103, /* ffdhe6144 (0x103) */ + 0x104, /* ffdhe8192 (0x104) */ }; static const uint16_t suiteb_curves[] = { @@ -191,21 +218,271 @@ static const uint16_t suiteb_curves[] = { TLSEXT_curve_P_384 }; -const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id) +struct provider_group_data_st { + SSL_CTX *ctx; + OSSL_PROVIDER *provider; +}; + +#define TLS_GROUP_LIST_MALLOC_BLOCK_SIZE 10 +static OSSL_CALLBACK add_provider_groups; +static int add_provider_groups(const OSSL_PARAM params[], void *data) +{ + struct provider_group_data_st *pgd = data; + SSL_CTX *ctx = pgd->ctx; + OSSL_PROVIDER *provider = pgd->provider; + const OSSL_PARAM *p; + TLS_GROUP_INFO *ginf = NULL; + EVP_KEYMGMT *keymgmt; + unsigned int gid; + unsigned int is_kem = 0; + int ret = 0; + + if (ctx->group_list_max_len == ctx->group_list_len) { + TLS_GROUP_INFO *tmp = NULL; + + if (ctx->group_list_max_len == 0) + tmp = OPENSSL_malloc(sizeof(TLS_GROUP_INFO) + * TLS_GROUP_LIST_MALLOC_BLOCK_SIZE); + else + tmp = OPENSSL_realloc(ctx->group_list, + (ctx->group_list_max_len + + TLS_GROUP_LIST_MALLOC_BLOCK_SIZE) + * sizeof(TLS_GROUP_INFO)); + if (tmp == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->group_list = tmp; + memset(tmp + ctx->group_list_max_len, + 0, + sizeof(TLS_GROUP_INFO) * TLS_GROUP_LIST_MALLOC_BLOCK_SIZE); + ctx->group_list_max_len += TLS_GROUP_LIST_MALLOC_BLOCK_SIZE; + } + + ginf = &ctx->group_list[ctx->group_list_len]; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->tlsname = OPENSSL_strdup(p->data); + if (ginf->tlsname == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->realname = OPENSSL_strdup(p->data); + if (ginf->realname == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ID); + if (p == NULL || !OSSL_PARAM_get_uint(p, &gid) || gid > UINT16_MAX) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->group_id = (uint16_t)gid; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_ALG); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->algorithm = OPENSSL_strdup(p->data); + if (ginf->algorithm == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS); + if (p == NULL || !OSSL_PARAM_get_uint(p, &ginf->secbits)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM); + if (p != NULL && (!OSSL_PARAM_get_uint(p, &is_kem) || is_kem > 1)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + ginf->is_kem = 1 & is_kem; + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_TLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mintls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_TLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->mindtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + + p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS); + if (p == NULL || !OSSL_PARAM_get_int(p, &ginf->maxdtls)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + goto err; + } + /* + * Now check that the algorithm is actually usable for our property query + * string. Regardless of the result we still return success because we have + * successfully processed this group, even though we may decide not to use + * it. + */ + ret = 1; + ERR_set_mark(); + keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ginf->algorithm, ctx->propq); + if (keymgmt != NULL) { + /* + * We have successfully fetched the algorithm - however if the provider + * doesn't match this one then we ignore it. + * + * Note: We're cheating a little here. Technically if the same algorithm + * is available from more than one provider then it is undefined which + * implementation you will get back. Theoretically this could be + * different every time...we assume here that you'll always get the + * same one back if you repeat the exact same fetch. Is this a reasonable + * assumption to make (in which case perhaps we should document this + * behaviour)? + */ + if (EVP_KEYMGMT_get0_provider(keymgmt) == provider) { + /* We have a match - so we will use this group */ + ctx->group_list_len++; + ginf = NULL; + } + EVP_KEYMGMT_free(keymgmt); + } + ERR_pop_to_mark(); + err: + if (ginf != NULL) { + OPENSSL_free(ginf->tlsname); + OPENSSL_free(ginf->realname); + OPENSSL_free(ginf->algorithm); + ginf->algorithm = ginf->tlsname = ginf->realname = NULL; + } + return ret; +} + +static int discover_provider_groups(OSSL_PROVIDER *provider, void *vctx) { - /* ECC curves from RFC 4492 and RFC 7027 */ - if (group_id < 1 || group_id > OSSL_NELEM(nid_list)) - return NULL; - return &nid_list[group_id - 1]; + struct provider_group_data_st pgd; + + pgd.ctx = vctx; + pgd.provider = provider; + return OSSL_PROVIDER_get_capabilities(provider, "TLS-GROUP", + add_provider_groups, &pgd); } -static uint16_t tls1_nid2group_id(int nid) +int ssl_load_groups(SSL_CTX *ctx) +{ + size_t i, j, num_deflt_grps = 0; + uint16_t tmp_supp_groups[OSSL_NELEM(supported_groups_default)]; + + if (!OSSL_PROVIDER_do_all(ctx->libctx, discover_provider_groups, ctx)) + return 0; + + for (i = 0; i < OSSL_NELEM(supported_groups_default); i++) { + for (j = 0; j < ctx->group_list_len; j++) { + if (ctx->group_list[j].group_id == supported_groups_default[i]) { + tmp_supp_groups[num_deflt_grps++] = ctx->group_list[j].group_id; + break; + } + } + } + + if (num_deflt_grps == 0) + return 1; + + ctx->ext.supported_groups_default + = OPENSSL_malloc(sizeof(uint16_t) * num_deflt_grps); + + if (ctx->ext.supported_groups_default == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + memcpy(ctx->ext.supported_groups_default, + tmp_supp_groups, + num_deflt_grps * sizeof(tmp_supp_groups[0])); + ctx->ext.supported_groups_default_len = num_deflt_grps; + + return 1; +} + +static uint16_t tls1_group_name2id(SSL_CTX *ctx, const char *name) +{ + size_t i; + + for (i = 0; i < ctx->group_list_len; i++) { + if (strcmp(ctx->group_list[i].tlsname, name) == 0 + || strcmp(ctx->group_list[i].realname, name) == 0) + return ctx->group_list[i].group_id; + } + + return 0; +} + +const TLS_GROUP_INFO *tls1_group_id_lookup(SSL_CTX *ctx, uint16_t group_id) +{ + size_t i; + + for (i = 0; i < ctx->group_list_len; i++) { + if (ctx->group_list[i].group_id == group_id) + return &ctx->group_list[i]; + } + + return NULL; +} + +int tls1_group_id2nid(uint16_t group_id, int include_unknown) +{ + size_t i; + + if (group_id == 0) + return NID_undef; + + /* + * Return well known Group NIDs - for backwards compatibility. This won't + * work for groups we don't know about. + */ + for (i = 0; i < OSSL_NELEM(nid_to_group); i++) + { + if (nid_to_group[i].group_id == group_id) + return nid_to_group[i].nid; + } + if (!include_unknown) + return NID_undef; + return TLSEXT_nid_unknown | (int)group_id; +} + +uint16_t tls1_nid2group_id(int nid) { size_t i; - for (i = 0; i < OSSL_NELEM(nid_list); i++) { - if (nid_list[i].nid == nid) - return (uint16_t)(i + 1); + + /* + * Return well known Group ids - for backwards compatibility. This won't + * work for groups we don't know about. + */ + for (i = 0; i < OSSL_NELEM(nid_to_group); i++) + { + if (nid_to_group[i].nid == nid) + return nid_to_group[i].group_id; } + return 0; } @@ -216,7 +493,6 @@ static uint16_t tls1_nid2group_id(int nid) void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, size_t *pgroupslen) { - /* For Suite B mode only include P-256, P-384 */ switch (tls1_suiteb(s)) { case SSL_CERT_FLAG_SUITEB_128_LOS: @@ -236,8 +512,8 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, default: if (s->ext.supportedgroups == NULL) { - *pgroups = eccurves_default; - *pgroupslen = OSSL_NELEM(eccurves_default); + *pgroups = s->ctx->ext.supported_groups_default; + *pgroupslen = s->ctx->ext.supported_groups_default_len; } else { *pgroups = s->ext.supportedgroups; *pgroupslen = s->ext.supportedgroups_len; @@ -246,21 +522,61 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, } } -/* See if curve is allowed by security callback */ -int tls_curve_allowed(SSL *s, uint16_t curve, int op) +int tls_valid_group(SSL *s, uint16_t group_id, int minversion, int maxversion, + int isec, int *okfortls13) { - const TLS_GROUP_INFO *cinfo = tls1_group_id_lookup(curve); - unsigned char ctmp[2]; + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group_id); + int ret; - if (cinfo == NULL) + if (okfortls13 != NULL) + *okfortls13 = 0; + + if (ginfo == NULL) return 0; -# ifdef OPENSSL_NO_EC2M - if (cinfo->flags & TLS_CURVE_CHAR2) + + if (SSL_IS_DTLS(s)) { + if (ginfo->mindtls < 0 || ginfo->maxdtls < 0) + return 0; + if (ginfo->maxdtls == 0) + ret = 1; + else + ret = DTLS_VERSION_LE(minversion, ginfo->maxdtls); + if (ginfo->mindtls > 0) + ret &= DTLS_VERSION_GE(maxversion, ginfo->mindtls); + } else { + if (ginfo->mintls < 0 || ginfo->maxtls < 0) + return 0; + if (ginfo->maxtls == 0) + ret = 1; + else + ret = (minversion <= ginfo->maxtls); + if (ginfo->mintls > 0) + ret &= (maxversion >= ginfo->mintls); + if (ret && okfortls13 != NULL && maxversion == TLS1_3_VERSION) + *okfortls13 = (ginfo->maxtls == 0) + || (ginfo->maxtls >= TLS1_3_VERSION); + } + ret &= !isec + || strcmp(ginfo->algorithm, "EC") == 0 + || strcmp(ginfo->algorithm, "X25519") == 0 + || strcmp(ginfo->algorithm, "X448") == 0; + + return ret; +} + +/* See if group is allowed by security callback */ +int tls_group_allowed(SSL *s, uint16_t group, int op) +{ + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(s->ctx, group); + unsigned char gtmp[2]; + + if (ginfo == NULL) return 0; -# endif - ctmp[0] = curve >> 8; - ctmp[1] = curve & 0xff; - return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)ctmp); + + gtmp[0] = group >> 8; + gtmp[1] = group & 0xff; + return ssl_security(s, op, ginfo->secbits, + tls1_group_id2nid(ginfo->group_id, 0), (void *)gtmp); } /* Return 1 if "id" is in "list" */ @@ -285,6 +601,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) const uint16_t *pref, *supp; size_t num_pref, num_supp, i; int k; + SSL_CTX *ctx = s->ctx; /* Can't do anything on client side */ if (s->server == 0) @@ -295,7 +612,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) * For Suite B ciphersuite determines curve: we already know * these are acceptable due to previous checks. */ - unsigned long cid = s->s3->tmp.new_cipher->id; + unsigned long cid = s->s3.tmp.new_cipher->id; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) return TLSEXT_curve_P_256; @@ -321,10 +638,29 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) for (k = 0, i = 0; i < num_pref; i++) { uint16_t id = pref[i]; + const TLS_GROUP_INFO *inf; if (!tls1_in_list(id, supp, num_supp) - || !tls_curve_allowed(s, id, SSL_SECOP_CURVE_SHARED)) - continue; + || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED)) + continue; + inf = tls1_group_id_lookup(ctx, id); + if (!ossl_assert(inf != NULL)) + return 0; + if (SSL_IS_DTLS(s)) { + if (inf->maxdtls == -1) + continue; + if ((inf->mindtls != 0 && DTLS_VERSION_LT(s->version, inf->mindtls)) + || (inf->maxdtls != 0 + && DTLS_VERSION_GT(s->version, inf->maxdtls))) + continue; + } else { + if (inf->maxtls == -1) + continue; + if ((inf->mintls != 0 && s->version < inf->mintls) + || (inf->maxtls != 0 && s->version > inf->maxtls)) + continue; + } + if (nmatch == k) return id; k++; @@ -341,141 +677,122 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, uint16_t *glist; size_t i; /* - * Bitmap of groups included to detect duplicates: only works while group - * ids < 32 + * Bitmap of groups included to detect duplicates: two variables are added + * to detect duplicates as some values are more than 32. */ - unsigned long dup_list = 0; + unsigned long *dup_list = NULL; + unsigned long dup_list_egrp = 0; + unsigned long dup_list_dhgrp = 0; if (ngroups == 0) { - SSLerr(SSL_F_TLS1_SET_GROUPS, SSL_R_BAD_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_BAD_LENGTH); return 0; } if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) { - SSLerr(SSL_F_TLS1_SET_GROUPS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < ngroups; i++) { unsigned long idmask; uint16_t id; - /* TODO(TLS1.3): Convert for DH groups */ id = tls1_nid2group_id(groups[i]); - idmask = 1L << id; - if (!id || (dup_list & idmask)) { - OPENSSL_free(glist); - return 0; - } - dup_list |= idmask; + if ((id & 0x00FF) >= (sizeof(unsigned long) * 8)) + goto err; + idmask = 1L << (id & 0x00FF); + dup_list = (id < 0x100) ? &dup_list_egrp : &dup_list_dhgrp; + if (!id || ((*dup_list) & idmask)) + goto err; + *dup_list |= idmask; glist[i] = id; } OPENSSL_free(*pext); *pext = glist; *pextlen = ngroups; return 1; +err: + OPENSSL_free(glist); + return 0; } -# define MAX_CURVELIST OSSL_NELEM(nid_list) - +# define GROUPLIST_INCREMENT 40 +# define GROUP_NAME_BUFFER_LENGTH 64 typedef struct { - size_t nidcnt; - int nid_arr[MAX_CURVELIST]; -} nid_cb_st; + SSL_CTX *ctx; + size_t gidcnt; + size_t gidmax; + uint16_t *gid_arr; +} gid_cb_st; -static int nid_cb(const char *elem, int len, void *arg) +static int gid_cb(const char *elem, int len, void *arg) { - nid_cb_st *narg = arg; + gid_cb_st *garg = arg; size_t i; - int nid; - char etmp[20]; + uint16_t gid = 0; + char etmp[GROUP_NAME_BUFFER_LENGTH]; + if (elem == NULL) return 0; - if (narg->nidcnt == MAX_CURVELIST) - return 0; + if (garg->gidcnt == garg->gidmax) { + uint16_t *tmp = + OPENSSL_realloc(garg->gid_arr, garg->gidmax + GROUPLIST_INCREMENT); + if (tmp == NULL) + return 0; + garg->gidmax += GROUPLIST_INCREMENT; + garg->gid_arr = tmp; + } if (len > (int)(sizeof(etmp) - 1)) return 0; memcpy(etmp, elem, len); etmp[len] = 0; - nid = EC_curve_nist2nid(etmp); - if (nid == NID_undef) - nid = OBJ_sn2nid(etmp); - if (nid == NID_undef) - nid = OBJ_ln2nid(etmp); - if (nid == NID_undef) + + gid = tls1_group_name2id(garg->ctx, etmp); + if (gid == 0) { + ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT, + "group '%s' cannot be set", etmp); return 0; - for (i = 0; i < narg->nidcnt; i++) - if (narg->nid_arr[i] == nid) + } + for (i = 0; i < garg->gidcnt; i++) + if (garg->gid_arr[i] == gid) return 0; - narg->nid_arr[narg->nidcnt++] = nid; + garg->gid_arr[garg->gidcnt++] = gid; return 1; } -/* Set groups based on a colon separate list */ -int tls1_set_groups_list(uint16_t **pext, size_t *pextlen, const char *str) -{ - nid_cb_st ncb; - ncb.nidcnt = 0; - if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) - return 0; - if (pext == NULL) - return 1; - return tls1_set_groups(pext, pextlen, ncb.nid_arr, ncb.nidcnt); -} -/* Return group id of a key */ -static uint16_t tls1_get_group_id(EVP_PKEY *pkey) +/* Set groups based on a colon separated list */ +int tls1_set_groups_list(SSL_CTX *ctx, uint16_t **pext, size_t *pextlen, + const char *str) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - const EC_GROUP *grp; + gid_cb_st gcb; + uint16_t *tmparr; + int ret = 0; - if (ec == NULL) + gcb.gidcnt = 0; + gcb.gidmax = GROUPLIST_INCREMENT; + gcb.gid_arr = OPENSSL_malloc(gcb.gidmax * sizeof(*gcb.gid_arr)); + if (gcb.gid_arr == NULL) return 0; - grp = EC_KEY_get0_group(ec); - return tls1_nid2group_id(EC_GROUP_get_curve_name(grp)); -} - -/* Check a key is compatible with compression extension */ -static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) -{ - const EC_KEY *ec; - const EC_GROUP *grp; - unsigned char comp_id; - size_t i; - - /* If not an EC key nothing to check */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) - return 1; - ec = EVP_PKEY_get0_EC_KEY(pkey); - grp = EC_KEY_get0_group(ec); - - /* Get required compression id */ - if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_UNCOMPRESSED) { - comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; - } else if (SSL_IS_TLS13(s)) { - /* - * ec_point_formats extension is not used in TLSv1.3 so we ignore - * this check. - */ - return 1; - } else { - int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(grp)); - - if (field_type == NID_X9_62_prime_field) - comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; - else if (field_type == NID_X9_62_characteristic_two_field) - comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; - else - return 0; + gcb.ctx = ctx; + if (!CONF_parse_list(str, ':', 1, gid_cb, &gcb)) + goto end; + if (pext == NULL) { + ret = 1; + goto end; } + /* - * If point formats extension present check it, otherwise everything is - * supported (see RFC4492). + * gid_cb ensurse there are no duplicates so we can just go ahead and set + * the result */ - if (s->ext.peer_ecpointformats == NULL) - return 1; - - for (i = 0; i < s->ext.peer_ecpointformats_len; i++) { - if (s->ext.peer_ecpointformats[i] == comp_id) - return 1; - } - return 0; + tmparr = OPENSSL_memdup(gcb.gid_arr, gcb.gidcnt * sizeof(*tmparr)); + if (tmparr == NULL) + goto end; + OPENSSL_free(*pext); + *pext = tmparr; + *pextlen = gcb.gidcnt; + ret = 1; + end: + OPENSSL_free(gcb.gid_arr); + return ret; } /* Check a group id matches preferences */ @@ -488,8 +805,8 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) return 0; /* Check for Suite B compliance */ - if (tls1_suiteb(s) && s->s3->tmp.new_cipher != NULL) { - unsigned long cid = s->s3->tmp.new_cipher->id; + if (tls1_suiteb(s) && s->s3.tmp.new_cipher != NULL) { + unsigned long cid = s->s3.tmp.new_cipher->id; if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { if (group_id != TLSEXT_curve_P_256) @@ -510,7 +827,7 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) return 0; } - if (!tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) + if (!tls_group_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) return 0; /* For clients, nothing more to check */ @@ -550,6 +867,64 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, } } +/* Check a key is compatible with compression extension */ +static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) +{ + unsigned char comp_id; + size_t i; + int point_conv; + + /* If not an EC key nothing to check */ + if (!EVP_PKEY_is_a(pkey, "EC")) + return 1; + + + /* Get required compression id */ + point_conv = EVP_PKEY_get_ec_point_conv_form(pkey); + if (point_conv == 0) + return 0; + if (point_conv == POINT_CONVERSION_UNCOMPRESSED) { + comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; + } else if (SSL_IS_TLS13(s)) { + /* + * ec_point_formats extension is not used in TLSv1.3 so we ignore + * this check. + */ + return 1; + } else { + int field_type = EVP_PKEY_get_field_type(pkey); + + if (field_type == NID_X9_62_prime_field) + comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + else if (field_type == NID_X9_62_characteristic_two_field) + comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + else + return 0; + } + /* + * If point formats extension present check it, otherwise everything is + * supported (see RFC4492). + */ + if (s->ext.peer_ecpointformats == NULL) + return 1; + + for (i = 0; i < s->ext.peer_ecpointformats_len; i++) { + if (s->ext.peer_ecpointformats[i] == comp_id) + return 1; + } + return 0; +} + +/* Return group id of a key */ +static uint16_t tls1_get_group_id(EVP_PKEY *pkey) +{ + int curve_nid = ssl_get_EC_curve_nid(pkey); + + if (curve_nid == NID_undef) + return 0; + return tls1_nid2group_id(curve_nid); +} + /* * Check cert parameters compatible with extensions: currently just checks EC * certificates have compatible curves and compression. @@ -562,7 +937,7 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) if (pkey == NULL) return 0; /* If not EC nothing to do */ - if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) + if (!EVP_PKEY_is_a(pkey, "EC")) return 1; /* Check compression */ if (!tls1_check_pkey_comp(s, pkey)) @@ -625,24 +1000,13 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) return 0; } -#else - -static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) -{ - return 1; -} - -#endif /* OPENSSL_NO_EC */ - /* Default sigalg schemes */ static const uint16_t tls12_sigalgs[] = { -#ifndef OPENSSL_NO_EC TLSEXT_SIGALG_ecdsa_secp256r1_sha256, TLSEXT_SIGALG_ecdsa_secp384r1_sha384, TLSEXT_SIGALG_ecdsa_secp521r1_sha512, TLSEXT_SIGALG_ed25519, TLSEXT_SIGALG_ed448, -#endif TLSEXT_SIGALG_rsa_pss_pss_sha256, TLSEXT_SIGALG_rsa_pss_pss_sha384, @@ -655,121 +1019,125 @@ static const uint16_t tls12_sigalgs[] = { TLSEXT_SIGALG_rsa_pkcs1_sha384, TLSEXT_SIGALG_rsa_pkcs1_sha512, -#ifndef OPENSSL_NO_EC TLSEXT_SIGALG_ecdsa_sha224, TLSEXT_SIGALG_ecdsa_sha1, -#endif + TLSEXT_SIGALG_rsa_pkcs1_sha224, TLSEXT_SIGALG_rsa_pkcs1_sha1, -#ifndef OPENSSL_NO_DSA + TLSEXT_SIGALG_dsa_sha224, TLSEXT_SIGALG_dsa_sha1, TLSEXT_SIGALG_dsa_sha256, TLSEXT_SIGALG_dsa_sha384, TLSEXT_SIGALG_dsa_sha512, -#endif + #ifndef OPENSSL_NO_GOST + TLSEXT_SIGALG_gostr34102012_256_intrinsic, + TLSEXT_SIGALG_gostr34102012_512_intrinsic, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, TLSEXT_SIGALG_gostr34102001_gostr3411, #endif }; -#ifndef OPENSSL_NO_EC + static const uint16_t suiteb_sigalgs[] = { TLSEXT_SIGALG_ecdsa_secp256r1_sha256, TLSEXT_SIGALG_ecdsa_secp384r1_sha384 }; -#endif static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { -#ifndef OPENSSL_NO_EC {"ecdsa_secp256r1_sha256", TLSEXT_SIGALG_ecdsa_secp256r1_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA256, NID_X9_62_prime256v1}, + NID_ecdsa_with_SHA256, NID_X9_62_prime256v1, 1}, {"ecdsa_secp384r1_sha384", TLSEXT_SIGALG_ecdsa_secp384r1_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA384, NID_secp384r1}, + NID_ecdsa_with_SHA384, NID_secp384r1, 1}, {"ecdsa_secp521r1_sha512", TLSEXT_SIGALG_ecdsa_secp521r1_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA512, NID_secp521r1}, + NID_ecdsa_with_SHA512, NID_secp521r1, 1}, {"ed25519", TLSEXT_SIGALG_ed25519, NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"ed448", TLSEXT_SIGALG_ed448, NID_undef, -1, EVP_PKEY_ED448, SSL_PKEY_ED448, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_ecdsa_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA224, NID_undef}, + NID_ecdsa_with_SHA224, NID_undef, 1}, {NULL, TLSEXT_SIGALG_ecdsa_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, - NID_ecdsa_with_SHA1, NID_undef}, -#endif + NID_ecdsa_with_SHA1, NID_undef, 1}, {"rsa_pss_rsae_sha256", TLSEXT_SIGALG_rsa_pss_rsae_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_rsae_sha384", TLSEXT_SIGALG_rsa_pss_rsae_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_rsae_sha512", TLSEXT_SIGALG_rsa_pss_rsae_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_pss_sha256", TLSEXT_SIGALG_rsa_pss_pss_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_pss_sha384", TLSEXT_SIGALG_rsa_pss_pss_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pss_pss_sha512", TLSEXT_SIGALG_rsa_pss_pss_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA_PSS, SSL_PKEY_RSA_PSS_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha256WithRSAEncryption, NID_undef}, + NID_sha256WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha384", TLSEXT_SIGALG_rsa_pkcs1_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha384WithRSAEncryption, NID_undef}, + NID_sha384WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha512", TLSEXT_SIGALG_rsa_pkcs1_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha512WithRSAEncryption, NID_undef}, + NID_sha512WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha224", TLSEXT_SIGALG_rsa_pkcs1_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha224WithRSAEncryption, NID_undef}, + NID_sha224WithRSAEncryption, NID_undef, 1}, {"rsa_pkcs1_sha1", TLSEXT_SIGALG_rsa_pkcs1_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_sha1WithRSAEncryption, NID_undef}, -#ifndef OPENSSL_NO_DSA + NID_sha1WithRSAEncryption, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_dsa_with_SHA256, NID_undef}, + NID_dsa_with_SHA256, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_dsa_sha1, NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_DSA, SSL_PKEY_DSA_SIGN, - NID_dsaWithSHA1, NID_undef}, -#endif + NID_dsaWithSHA1, NID_undef, 1}, #ifndef OPENSSL_NO_GOST + {NULL, TLSEXT_SIGALG_gostr34102012_256_intrinsic, + NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, + NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, + NID_undef, NID_undef, 1}, + {NULL, TLSEXT_SIGALG_gostr34102012_512_intrinsic, + NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, + NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, NID_id_GostR3411_2012_256, SSL_MD_GOST12_256_IDX, NID_id_GostR3410_2012_256, SSL_PKEY_GOST12_256, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, NID_id_GostR3411_2012_512, SSL_MD_GOST12_512_IDX, NID_id_GostR3410_2012_512, SSL_PKEY_GOST12_512, - NID_undef, NID_undef}, + NID_undef, NID_undef, 1}, {NULL, TLSEXT_SIGALG_gostr34102001_gostr3411, NID_id_GostR3411_94, SSL_MD_GOST94_IDX, NID_id_GostR3410_2001, SSL_PKEY_GOST01, - NID_undef, NID_undef} + NID_undef, NID_undef, 1} #endif }; /* Legacy sigalgs for TLS < 1.2 RSA TLS signatures */ @@ -777,7 +1145,7 @@ static const SIGALG_LOOKUP legacy_rsa_sigalg = { "rsa_pkcs1_md5_sha1", 0, NID_md5_sha1, SSL_MD_MD5_SHA1_IDX, EVP_PKEY_RSA, SSL_PKEY_RSA, - NID_undef, NID_undef + NID_undef, NID_undef, 1 }; /* @@ -790,27 +1158,86 @@ static const uint16_t tls_default_sigalg[] = { TLSEXT_SIGALG_dsa_sha1, /* SSL_PKEY_DSA_SIGN */ TLSEXT_SIGALG_ecdsa_sha1, /* SSL_PKEY_ECC */ TLSEXT_SIGALG_gostr34102001_gostr3411, /* SSL_PKEY_GOST01 */ - TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, /* SSL_PKEY_GOST12_256 */ - TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, /* SSL_PKEY_GOST12_512 */ + TLSEXT_SIGALG_gostr34102012_256_intrinsic, /* SSL_PKEY_GOST12_256 */ + TLSEXT_SIGALG_gostr34102012_512_intrinsic, /* SSL_PKEY_GOST12_512 */ 0, /* SSL_PKEY_ED25519 */ 0, /* SSL_PKEY_ED448 */ }; +int ssl_setup_sig_algs(SSL_CTX *ctx) +{ + size_t i; + const SIGALG_LOOKUP *lu; + SIGALG_LOOKUP *cache + = OPENSSL_malloc(sizeof(*lu) * OSSL_NELEM(sigalg_lookup_tbl)); + EVP_PKEY *tmpkey = EVP_PKEY_new(); + int ret = 0; + + if (cache == NULL || tmpkey == NULL) + goto err; + + ERR_set_mark(); + for (i = 0, lu = sigalg_lookup_tbl; + i < OSSL_NELEM(sigalg_lookup_tbl); lu++, i++) { + EVP_PKEY_CTX *pctx; + + cache[i] = *lu; + + /* + * Check hash is available. + * This test is not perfect. A provider could have support + * for a signature scheme, but not a particular hash. However the hash + * could be available from some other loaded provider. In that case it + * could be that the signature is available, and the hash is available + * independently - but not as a combination. We ignore this for now. + */ + if (lu->hash != NID_undef + && ctx->ssl_digest_methods[lu->hash_idx] == NULL) { + cache[i].enabled = 0; + continue; + } + + if (!EVP_PKEY_set_type(tmpkey, lu->sig)) { + cache[i].enabled = 0; + continue; + } + pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, tmpkey, ctx->propq); + /* If unable to create pctx we assume the sig algorithm is unavailable */ + if (pctx == NULL) + cache[i].enabled = 0; + EVP_PKEY_CTX_free(pctx); + } + ERR_pop_to_mark(); + ctx->sigalg_lookup_cache = cache; + cache = NULL; + + ret = 1; + err: + OPENSSL_free(cache); + EVP_PKEY_free(tmpkey); + return ret; +} + /* Lookup TLS signature algorithm */ -static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg) +static const SIGALG_LOOKUP *tls1_lookup_sigalg(const SSL *s, uint16_t sigalg) { size_t i; - const SIGALG_LOOKUP *s; + const SIGALG_LOOKUP *lu; - for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); - i++, s++) { - if (s->sigalg == sigalg) - return s; + for (i = 0, lu = s->ctx->sigalg_lookup_cache; + /* cache should have the same number of elements as sigalg_lookup_tbl */ + i < OSSL_NELEM(sigalg_lookup_tbl); + lu++, i++) { + if (lu->sigalg == sigalg) { + if (!lu->enabled) + return NULL; + return lu; + } } return NULL; } /* Lookup hash: return 0 if invalid or not enabled */ -int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) +int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd) { const EVP_MD *md; if (lu == NULL) @@ -819,7 +1246,7 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) if (lu->hash == NID_undef) { md = NULL; } else { - md = ssl_md(lu->hash_idx); + md = ssl_md(ctx, lu->hash_idx); if (md == NULL) return 0; } @@ -835,16 +1262,17 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) * SHA512 has a hash length of 64 bytes, which is incompatible * with a 128 byte (1024 bit) key. */ -#define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_size(md) + 2) -static int rsa_pss_check_min_key_size(const RSA *rsa, const SIGALG_LOOKUP *lu) +#define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_get_size(md) + 2) +static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const EVP_PKEY *pkey, + const SIGALG_LOOKUP *lu) { const EVP_MD *md; - if (rsa == NULL) + if (pkey == NULL) return 0; - if (!tls1_lookup_md(lu, &md) || md == NULL) + if (!tls1_lookup_md(ctx, lu, &md) || md == NULL) return 0; - if (RSA_size(rsa) < RSA_PSS_MINIMUM_KEY_SIZE(md)) + if (EVP_PKEY_get_size(pkey) < RSA_PSS_MINIMUM_KEY_SIZE(md)) return 0; return 1; } @@ -866,7 +1294,9 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) for (i = 0; i < SSL_PKEY_NUM; i++) { const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(i); - if (clu->amask & s->s3->tmp.new_cipher->algorithm_auth) { + if (clu == NULL) + continue; + if (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) { idx = i; break; } @@ -875,7 +1305,7 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) /* * Some GOST ciphersuites allow more than one signature algorithms * */ - if (idx == SSL_PKEY_GOST01 && s->s3->tmp.new_cipher->algorithm_auth != SSL_aGOST01) { + if (idx == SSL_PKEY_GOST01 && s->s3.tmp.new_cipher->algorithm_auth != SSL_aGOST01) { int real_idx; for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST01; @@ -886,6 +1316,21 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) } } } + /* + * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used + * with new (aGOST12-only) ciphersuites, we should find out which one is available really. + */ + else if (idx == SSL_PKEY_GOST12_256) { + int real_idx; + + for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256; + real_idx--) { + if (s->cert->pkeys[real_idx].privatekey != NULL) { + idx = real_idx; + break; + } + } + } } else { idx = s->cert->key - s->cert->pkeys; } @@ -893,9 +1338,11 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) if (idx < 0 || idx >= (int)OSSL_NELEM(tls_default_sigalg)) return NULL; if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, tls_default_sigalg[idx]); - if (!tls1_lookup_md(lu, NULL)) + if (lu == NULL) + return NULL; + if (!tls1_lookup_md(s->ctx, lu, NULL)) return NULL; if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) return NULL; @@ -916,7 +1363,7 @@ int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey) lu = tls1_get_legacy_sigalg(s, idx); if (lu == NULL) return 0; - s->s3->tmp.peer_sigalg = lu; + s->s3.tmp.peer_sigalg = lu; return 1; } @@ -926,7 +1373,6 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) * If Suite B mode use Suite B sigalgs only, ignore any other * preferences. */ -#ifndef OPENSSL_NO_EC switch (tls1_suiteb(s)) { case SSL_CERT_FLAG_SUITEB_128_LOS: *psigs = suiteb_sigalgs; @@ -940,7 +1386,6 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) *psigs = suiteb_sigalgs + 1; return 1; } -#endif /* * We use client_sigalgs (if not NULL) if we're a server * and sending a certificate request or if we're a client and @@ -958,7 +1403,6 @@ size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs) } } -#ifndef OPENSSL_NO_EC /* * Called by servers only. Checks that we have a sig alg that supports the * specified EC curve. @@ -977,7 +1421,7 @@ int tls_check_sigalg_curve(const SSL *s, int curve) } for (i = 0; i < siglen; i++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, sigs[i]); if (lu == NULL) continue; @@ -989,23 +1433,40 @@ int tls_check_sigalg_curve(const SSL *s, int curve) return 0; } -#endif /* * Return the number of security bits for the signature algorithm, or 0 on * error. */ -static int sigalg_security_bits(const SIGALG_LOOKUP *lu) +static int sigalg_security_bits(SSL_CTX *ctx, const SIGALG_LOOKUP *lu) { const EVP_MD *md = NULL; int secbits = 0; - if (!tls1_lookup_md(lu, &md)) + if (!tls1_lookup_md(ctx, lu, &md)) return 0; if (md != NULL) { + int md_type = EVP_MD_get_type(md); + /* Security bits: half digest bits */ - secbits = EVP_MD_size(md) * 4; + secbits = EVP_MD_get_size(md) * 4; + /* + * SHA1 and MD5 are known to be broken. Reduce security bits so that + * they're no longer accepted at security level 1. The real values don't + * really matter as long as they're lower than 80, which is our + * security level 1. + * https://eprint.iacr.org/2020/014 puts a chosen-prefix attack for + * SHA1 at 2^63.4 and MD5+SHA1 at 2^67.2 + * https://documents.epfl.ch/users/l/le/lenstra/public/papers/lat.pdf + * puts a chosen-prefix attack for MD5 at 2^39. + */ + if (md_type == NID_sha1) + secbits = 64; + else if (md_type == NID_md5_sha1) + secbits = 67; + else if (md_type == NID_md5) + secbits = 39; } else { /* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */ if (lu->sigalg == TLSEXT_SIGALG_ed25519) @@ -1027,25 +1488,25 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) const EVP_MD *md = NULL; char sigalgstr[2]; size_t sent_sigslen, i, cidx; - int pkeyid = EVP_PKEY_id(pkey); + int pkeyid = -1; const SIGALG_LOOKUP *lu; int secbits = 0; + pkeyid = EVP_PKEY_get_id(pkey); /* Should never happen */ if (pkeyid == -1) return -1; if (SSL_IS_TLS13(s)) { /* Disallow DSA for TLS 1.3 */ if (pkeyid == EVP_PKEY_DSA) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Only allow PSS for TLS 1.3 */ if (pkeyid == EVP_PKEY_RSA) pkeyid = EVP_PKEY_RSA_PSS; } - lu = tls1_lookup_sigalg(sig); + lu = tls1_lookup_sigalg(s, sig); /* * Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type * is consistent with signature: RSA keys can be used for RSA-PSS @@ -1054,45 +1515,38 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) || (SSL_IS_TLS13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) || (pkeyid != lu->sig && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Check the sigalg is consistent with the key OID */ - if (!ssl_cert_lookup_by_nid(EVP_PKEY_id(pkey), &cidx) + if (!ssl_cert_lookup_by_nid(EVP_PKEY_get_id(pkey), &cidx) || lu->sig_idx != (int)cidx) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } -#ifndef OPENSSL_NO_EC if (pkeyid == EVP_PKEY_EC) { /* Check point compression is permitted */ if (!tls1_check_pkey_comp(s, pkey)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_ILLEGAL_POINT_COMPRESSION); return 0; } /* For TLS 1.3 or Suite B check curve matches signature algorithm */ if (SSL_IS_TLS13(s) || tls1_suiteb(s)) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + int curve = ssl_get_EC_curve_nid(pkey); if (lu->curve != NID_undef && curve != lu->curve) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); return 0; } } if (!SSL_IS_TLS13(s)) { /* Check curve matches extensions */ if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); return 0; } if (tls1_suiteb(s)) { @@ -1100,18 +1554,15 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256 && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } } } } else if (tls1_suiteb(s)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } -#endif /* Check signature matches a type we sent */ sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); @@ -1122,13 +1573,11 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) /* Allow fallback to SHA1 if not strict mode */ if (i == sent_sigslen && (lu->hash != NID_sha1 || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - if (!tls1_lookup_md(lu, &md)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_UNKNOWN_DIGEST); + if (!tls1_lookup_md(s->ctx, lu, &md)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_DIGEST); return 0; } /* @@ -1137,33 +1586,32 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) */ sigalgstr[0] = (sig >> 8) & 0xff; sigalgstr[1] = sig & 0xff; - secbits = sigalg_security_bits(lu); + secbits = sigalg_security_bits(s->ctx, lu); if (secbits == 0 || !ssl_security(s, SSL_SECOP_SIGALG_CHECK, secbits, - md != NULL ? EVP_MD_type(md) : NID_undef, + md != NULL ? EVP_MD_get_type(md) : NID_undef, (void *)sigalgstr)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Store the sigalg the peer uses */ - s->s3->tmp.peer_sigalg = lu; + s->s3.tmp.peer_sigalg = lu; return 1; } int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3->tmp.peer_sigalg == NULL) + if (s->s3.tmp.peer_sigalg == NULL) return 0; - *pnid = s->s3->tmp.peer_sigalg->sig; + *pnid = s->s3.tmp.peer_sigalg->sig; return 1; } int SSL_get_signature_type_nid(const SSL *s, int *pnid) { - if (s->s3->tmp.sigalg == NULL) + if (s->s3.tmp.sigalg == NULL) return 0; - *pnid = s->s3->tmp.sigalg->sig; + *pnid = s->s3.tmp.sigalg->sig; return 1; } @@ -1179,23 +1627,23 @@ int SSL_get_signature_type_nid(const SSL *s, int *pnid) */ int ssl_set_client_disabled(SSL *s) { - s->s3->tmp.mask_a = 0; - s->s3->tmp.mask_k = 0; - ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK); - if (ssl_get_min_max_version(s, &s->s3->tmp.min_ver, - &s->s3->tmp.max_ver, NULL) != 0) + s->s3.tmp.mask_a = 0; + s->s3.tmp.mask_k = 0; + ssl_set_sig_mask(&s->s3.tmp.mask_a, s, SSL_SECOP_SIGALG_MASK); + if (ssl_get_min_max_version(s, &s->s3.tmp.min_ver, + &s->s3.tmp.max_ver, NULL) != 0) return 0; #ifndef OPENSSL_NO_PSK /* with PSK there must be client callback set */ if (!s->psk_client_callback) { - s->s3->tmp.mask_a |= SSL_aPSK; - s->s3->tmp.mask_k |= SSL_PSK; + s->s3.tmp.mask_a |= SSL_aPSK; + s->s3.tmp.mask_k |= SSL_PSK; } #endif /* OPENSSL_NO_PSK */ #ifndef OPENSSL_NO_SRP if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) { - s->s3->tmp.mask_a |= SSL_aSRP; - s->s3->tmp.mask_k |= SSL_kSRP; + s->s3.tmp.mask_a |= SSL_aSRP; + s->s3.tmp.mask_k |= SSL_kSRP; } #endif return 1; @@ -1212,10 +1660,10 @@ int ssl_set_client_disabled(SSL *s) */ int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe) { - if (c->algorithm_mkey & s->s3->tmp.mask_k - || c->algorithm_auth & s->s3->tmp.mask_a) + if (c->algorithm_mkey & s->s3.tmp.mask_k + || c->algorithm_auth & s->s3.tmp.mask_a) return 1; - if (s->s3->tmp.max_ver == 0) + if (s->s3.tmp.max_ver == 0) return 1; if (!SSL_IS_DTLS(s)) { int min_tls = c->min_tls; @@ -1228,11 +1676,11 @@ int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ecdhe) && (c->algorithm_mkey & (SSL_kECDHE | SSL_kECDHEPSK)) != 0) min_tls = SSL3_VERSION; - if ((min_tls > s->s3->tmp.max_ver) || (c->max_tls < s->s3->tmp.min_ver)) + if ((min_tls > s->s3.tmp.max_ver) || (c->max_tls < s->s3.tmp.min_ver)) return 1; } - if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3->tmp.max_ver) - || DTLS_VERSION_LT(c->max_dtls, s->s3->tmp.min_ver))) + if (SSL_IS_DTLS(s) && (DTLS_VERSION_GT(c->min_dtls, s->s3.tmp.max_ver) + || DTLS_VERSION_LT(c->max_dtls, s->s3.tmp.min_ver))) return 1; return !ssl_security(s, op, c->strength_bits, 0, (void *)c); @@ -1255,13 +1703,13 @@ int tls1_set_server_sigalgs(SSL *s) s->shared_sigalgslen = 0; /* Clear certificate validity flags */ for (i = 0; i < SSL_PKEY_NUM; i++) - s->s3->tmp.valid_flags[i] = 0; + s->s3.tmp.valid_flags[i] = 0; /* * If peer sent no signature algorithms check to see if we support * the default algorithm for each certificate type */ - if (s->s3->tmp.peer_cert_sigalgs == NULL - && s->s3->tmp.peer_sigalgs == NULL) { + if (s->s3.tmp.peer_cert_sigalgs == NULL + && s->s3.tmp.peer_sigalgs == NULL) { const uint16_t *sent_sigs; size_t sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); @@ -1274,7 +1722,7 @@ int tls1_set_server_sigalgs(SSL *s) /* Check default matches a type we sent */ for (j = 0; j < sent_sigslen; j++) { if (lu->sigalg == sent_sigs[j]) { - s->s3->tmp.valid_flags[i] = CERT_PKEY_SIGN; + s->s3.tmp.valid_flags[i] = CERT_PKEY_SIGN; break; } } @@ -1283,15 +1731,14 @@ int tls1_set_server_sigalgs(SSL *s) } if (!tls1_process_sigalgs(s)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } if (s->shared_sigalgs != NULL) return 1; /* Fatal error if no shared signature algorithms */ - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS1_SET_SERVER_SIGALGS, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS); return 0; } @@ -1360,11 +1807,11 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, SSL_SESSION *sess = NULL; unsigned char *sdec; const unsigned char *p; - int slen, renew_ticket = 0, declen; + int slen, ivlen, renew_ticket = 0, declen; SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER; size_t mlen; unsigned char tick_hmac[EVP_MAX_MD_SIZE]; - HMAC_CTX *hctx = NULL; + SSL_HMAC *hctx = NULL; EVP_CIPHER_CTX *ctx = NULL; SSL_CTX *tctx = s->session_ctx; @@ -1394,7 +1841,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Initialize session ticket encryption and HMAC contexts */ - hctx = HMAC_CTX_new(); + hctx = ssl_hmac_new(tctx); if (hctx == NULL) { ret = SSL_TICKET_FATAL_ERR_MALLOC; goto end; @@ -1404,11 +1851,28 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, ret = SSL_TICKET_FATAL_ERR_MALLOC; goto end; } - if (tctx->ext.ticket_key_cb) { +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (tctx->ext.ticket_key_evp_cb != NULL || tctx->ext.ticket_key_cb != NULL) +#else + if (tctx->ext.ticket_key_evp_cb != NULL) +#endif + { unsigned char *nctick = (unsigned char *)etick; - int rv = tctx->ext.ticket_key_cb(s, nctick, + int rv = 0; + + if (tctx->ext.ticket_key_evp_cb != NULL) + rv = tctx->ext.ticket_key_evp_cb(s, nctick, + nctick + TLSEXT_KEYNAME_LENGTH, + ctx, + ssl_hmac_get0_EVP_MAC_CTX(hctx), + 0); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + else if (tctx->ext.ticket_key_cb != NULL) + /* if 0 is returned, write an empty ticket */ + rv = tctx->ext.ticket_key_cb(s, nctick, nctick + TLSEXT_KEYNAME_LENGTH, - ctx, hctx, 0); + ctx, ssl_hmac_get0_HMAC_CTX(hctx), 0); +#endif if (rv < 0) { ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; @@ -1420,21 +1884,29 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (rv == 2) renew_ticket = 1; } else { + EVP_CIPHER *aes256cbc = NULL; + /* Check key name matches */ if (memcmp(etick, tctx->ext.tick_key_name, TLSEXT_KEYNAME_LENGTH) != 0) { ret = SSL_TICKET_NO_DECRYPT; goto end; } - if (HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key, - sizeof(tctx->ext.secure->tick_hmac_key), - EVP_sha256(), NULL) <= 0 - || EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, + + aes256cbc = EVP_CIPHER_fetch(s->ctx->libctx, "AES-256-CBC", + s->ctx->propq); + if (aes256cbc == NULL + || ssl_hmac_init(hctx, tctx->ext.secure->tick_hmac_key, + sizeof(tctx->ext.secure->tick_hmac_key), + "SHA256") <= 0 + || EVP_DecryptInit_ex(ctx, aes256cbc, NULL, tctx->ext.secure->tick_aes_key, etick + TLSEXT_KEYNAME_LENGTH) <= 0) { + EVP_CIPHER_free(aes256cbc); ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } + EVP_CIPHER_free(aes256cbc); if (SSL_IS_TLS13(s)) renew_ticket = 1; } @@ -1442,22 +1914,27 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, * Attempt to process session ticket, first conduct sanity and integrity * checks on ticket. */ - mlen = HMAC_size(hctx); + mlen = ssl_hmac_size(hctx); if (mlen == 0) { ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } + ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); + if (ivlen < 0) { + ret = SSL_TICKET_FATAL_ERR_OTHER; + goto end; + } + /* Sanity check ticket length: must exceed keyname + IV + HMAC */ - if (eticklen <= - TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx) + mlen) { + if (eticklen <= TLSEXT_KEYNAME_LENGTH + ivlen + mlen) { ret = SSL_TICKET_NO_DECRYPT; goto end; } eticklen -= mlen; /* Check HMAC of encrypted ticket */ - if (HMAC_Update(hctx, etick, eticklen) <= 0 - || HMAC_Final(hctx, tick_hmac, NULL) <= 0) { + if (ssl_hmac_update(hctx, etick, eticklen) <= 0 + || ssl_hmac_final(hctx, tick_hmac, NULL, sizeof(tick_hmac)) <= 0) { ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } @@ -1468,8 +1945,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ - p = etick + TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx); - eticklen -= TLSEXT_KEYNAME_LENGTH + EVP_CIPHER_CTX_iv_length(ctx); + p = etick + TLSEXT_KEYNAME_LENGTH + ivlen; + eticklen -= TLSEXT_KEYNAME_LENGTH + ivlen; sdec = OPENSSL_malloc(eticklen); if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p, (int)eticklen) <= 0) { @@ -1520,7 +1997,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, end: EVP_CIPHER_CTX_free(ctx); - HMAC_CTX_free(hctx); + ssl_hmac_free(hctx); /* * If set, the decrypt_ticket_cb() is called unless a fatal error was @@ -1595,21 +2072,23 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) unsigned char sigalgstr[2]; int secbits; - /* See if sigalgs is recognised and if hash is enabled */ - if (!tls1_lookup_md(lu, NULL)) + if (lu == NULL || !lu->enabled) return 0; /* DSA is not allowed in TLS 1.3 */ if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA) return 0; - /* TODO(OpenSSL1.2) fully axe DSA/etc. in ClientHello per TLS 1.3 spec */ - if (!s->server && !SSL_IS_DTLS(s) && s->s3->tmp.min_ver >= TLS1_3_VERSION + /* + * At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3 + * spec + */ + if (!s->server && !SSL_IS_DTLS(s) && s->s3.tmp.min_ver >= TLS1_3_VERSION && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX || lu->hash_idx == SSL_MD_MD5_IDX || lu->hash_idx == SSL_MD_SHA224_IDX)) return 0; /* See if public key algorithm allowed */ - if (ssl_cert_is_disabled(lu->sig_idx)) + if (ssl_cert_is_disabled(s->ctx, lu->sig_idx)) return 0; if (lu->sig == NID_id_GostR3410_2012_256 @@ -1620,7 +2099,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) return 0; if (!s->server && s->method->version == TLS_ANY_VERSION - && s->s3->tmp.max_ver >= TLS1_3_VERSION) { + && s->s3.tmp.max_ver >= TLS1_3_VERSION) { int i, num; STACK_OF(SSL_CIPHER) *sk; @@ -1630,7 +2109,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) * ciphersuites enabled. */ - if (s->s3->tmp.min_ver >= TLS1_3_VERSION) + if (s->s3.tmp.min_ver >= TLS1_3_VERSION) return 0; sk = SSL_get_ciphers(s); @@ -1643,7 +2122,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) continue; - if ((c->algorithm_mkey & SSL_kGOST) != 0) + if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0) break; } if (i == num) @@ -1652,7 +2131,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) } /* Finally see if security callback allows it */ - secbits = sigalg_security_bits(lu); + secbits = sigalg_security_bits(s->ctx, lu); sigalgstr[0] = (lu->sigalg >> 8) & 0xff; sigalgstr[1] = lu->sigalg & 0xff; return ssl_security(s, op, secbits, lu->hash, (void *)sigalgstr); @@ -1675,15 +2154,15 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) */ sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); for (i = 0; i < sigalgslen; i++, sigalgs++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*sigalgs); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *sigalgs); const SSL_CERT_LOOKUP *clu; if (lu == NULL) continue; clu = ssl_cert_lookup_by_idx(lu->sig_idx); - if (clu == NULL) - continue; + if (clu == NULL) + continue; /* If algorithm is disabled see if we can enable it */ if ((clu->amask & disabled_mask) != 0 @@ -1700,9 +2179,10 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, int rv = 0; for (i = 0; i < psiglen; i++, psig++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*psig); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *psig); - if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) + if (lu == NULL + || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) continue; if (!WPACKET_put_bytes_u16(pkt, *psig)) return 0; @@ -1717,7 +2197,7 @@ int tls12_copy_sigalgs(SSL *s, WPACKET *pkt, rv = 1; } if (rv == 0) - SSLerr(SSL_F_TLS12_COPY_SIGALGS, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); + ERR_raise(ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return rv; } @@ -1729,10 +2209,11 @@ static size_t tls12_shared_sigalgs(SSL *s, const SIGALG_LOOKUP **shsig, const uint16_t *ptmp, *atmp; size_t i, j, nmatch = 0; for (i = 0, ptmp = pref; i < preflen; i++, ptmp++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*ptmp); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *ptmp); /* Skip disabled hashes or signature algorithms */ - if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu)) + if (lu == NULL + || !tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SHARED, lu)) continue; for (j = 0, atmp = allow; j < allowlen; j++, atmp++) { if (*ptmp == *atmp) { @@ -1771,18 +2252,18 @@ static int tls1_set_shared_sigalgs(SSL *s) if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; - allow = s->s3->tmp.peer_sigalgs; - allowlen = s->s3->tmp.peer_sigalgslen; + allow = s->s3.tmp.peer_sigalgs; + allowlen = s->s3.tmp.peer_sigalgslen; } else { allow = conf; allowlen = conflen; - pref = s->s3->tmp.peer_sigalgs; - preflen = s->s3->tmp.peer_sigalgslen; + pref = s->s3.tmp.peer_sigalgs; + preflen = s->s3.tmp.peer_sigalgslen; } nmatch = tls12_shared_sigalgs(s, NULL, pref, preflen, allow, allowlen); if (nmatch) { if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) { - SSLerr(SSL_F_TLS1_SET_SHARED_SIGALGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); @@ -1809,7 +2290,7 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen) size >>= 1; if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL) { - SSLerr(SSL_F_TLS1_SAVE_U16, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++) @@ -1837,11 +2318,11 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) return 0; if (cert) - return tls1_save_u16(pkt, &s->s3->tmp.peer_cert_sigalgs, - &s->s3->tmp.peer_cert_sigalgslen); + return tls1_save_u16(pkt, &s->s3.tmp.peer_cert_sigalgs, + &s->s3.tmp.peer_cert_sigalgslen); else - return tls1_save_u16(pkt, &s->s3->tmp.peer_sigalgs, - &s->s3->tmp.peer_sigalgslen); + return tls1_save_u16(pkt, &s->s3.tmp.peer_sigalgs, + &s->s3.tmp.peer_sigalgslen); } @@ -1850,7 +2331,7 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) int tls1_process_sigalgs(SSL *s) { size_t i; - uint32_t *pvalid = s->s3->tmp.valid_flags; + uint32_t *pvalid = s->s3.tmp.valid_flags; if (!tls1_set_shared_sigalgs(s)) return 0; @@ -1866,7 +2347,7 @@ int tls1_process_sigalgs(SSL *s) if (SSL_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) continue; /* If not disabled indicate we can explicitly sign */ - if (pvalid[idx] == 0 && !ssl_cert_is_disabled(idx)) + if (pvalid[idx] == 0 && !ssl_cert_is_disabled(s->ctx, idx)) pvalid[idx] = CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; } return 1; @@ -1876,8 +2357,8 @@ int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash, unsigned char *rsig, unsigned char *rhash) { - uint16_t *psig = s->s3->tmp.peer_sigalgs; - size_t numsigalgs = s->s3->tmp.peer_sigalgslen; + uint16_t *psig = s->s3.tmp.peer_sigalgs; + size_t numsigalgs = s->s3.tmp.peer_sigalgslen; if (psig == NULL || numsigalgs > INT_MAX) return 0; if (idx >= 0) { @@ -1890,7 +2371,7 @@ int SSL_get_sigalgs(SSL *s, int idx, *rhash = (unsigned char)((*psig >> 8) & 0xff); if (rsig != NULL) *rsig = (unsigned char)(*psig & 0xff); - lu = tls1_lookup_sigalg(*psig); + lu = tls1_lookup_sigalg(s, *psig); if (psign != NULL) *psign = lu != NULL ? lu->sig : NID_undef; if (phash != NULL) @@ -2039,7 +2520,7 @@ int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, uint16_t *sigalgs; if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) { - SSLerr(SSL_F_TLS1_SET_RAW_SIGALGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs)); @@ -2065,7 +2546,7 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) if (salglen & 1) return 0; if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) { - SSLerr(SSL_F_TLS1_SET_SIGALGS, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE); return 0; } for (i = 0, sptr = sigalgs; i < salglen; i += 2) { @@ -2115,20 +2596,20 @@ static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) if (default_nid) return sig_nid == default_nid ? 1 : 0; - if (SSL_IS_TLS13(s) && s->s3->tmp.peer_cert_sigalgs != NULL) { + if (SSL_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) { /* * If we're in TLSv1.3 then we only get here if we're checking the * chain. If the peer has specified peer_cert_sigalgs then we use them * otherwise we default to normal sigalgs. */ - sigalgslen = s->s3->tmp.peer_cert_sigalgslen; + sigalgslen = s->s3.tmp.peer_cert_sigalgslen; use_pc_sigalgs = 1; } else { sigalgslen = s->shared_sigalgslen; } for (i = 0; i < sigalgslen; i++) { sigalg = use_pc_sigalgs - ? tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]) + ? tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]) : s->shared_sigalgs[i]; if (sigalg != NULL && sig_nid == sigalg->sigandhash) return 1; @@ -2139,7 +2620,7 @@ static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) /* Check to see if a certificate issuer name matches list of CA names */ static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) { - X509_NAME *nm; + const X509_NAME *nm; int i; nm = X509_get_issuer_name(x); for (i = 0; i < sk_X509_NAME_num(names); i++) { @@ -2183,7 +2664,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, idx = (int)(cpk - c->pkeys); } else cpk = c->pkeys + idx; - pvalid = s->s3->tmp.valid_flags + idx; + pvalid = s->s3.tmp.valid_flags + idx; x = cpk->x509; pk = cpk->privatekey; chain = cpk->chain; @@ -2200,7 +2681,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (ssl_cert_lookup_by_pkey(pk, &certidx) == NULL) return 0; idx = certidx; - pvalid = s->s3->tmp.valid_flags + idx; + pvalid = s->s3.tmp.valid_flags + idx; if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) check_flags = CERT_PKEY_STRICT_FLAGS; @@ -2227,8 +2708,8 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { int default_nid; int rsign = 0; - if (s->s3->tmp.peer_cert_sigalgs != NULL - || s->s3->tmp.peer_sigalgs != NULL) { + if (s->s3.tmp.peer_cert_sigalgs != NULL + || s->s3.tmp.peer_sigalgs != NULL) { default_nid = 0; /* If no sigalgs extension use defaults from RFC5246 */ } else { @@ -2276,7 +2757,7 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, size_t j; const uint16_t *p = c->conf_sigalgs; for (j = 0; j < c->conf_sigalgslen; j++, p++) { - const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*p); + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(s, *p); if (lu != NULL && lu->hash == NID_sha1 && lu->sig == rsign) break; @@ -2340,22 +2821,19 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, if (!s->server && strict_mode) { STACK_OF(X509_NAME) *ca_dn; int check_type = 0; - switch (EVP_PKEY_id(pk)) { - case EVP_PKEY_RSA: + + if (EVP_PKEY_is_a(pk, "RSA")) check_type = TLS_CT_RSA_SIGN; - break; - case EVP_PKEY_DSA: + else if (EVP_PKEY_is_a(pk, "DSA")) check_type = TLS_CT_DSS_SIGN; - break; - case EVP_PKEY_EC: + else if (EVP_PKEY_is_a(pk, "EC")) check_type = TLS_CT_ECDSA_SIGN; - break; - } + if (check_type) { - const uint8_t *ctypes = s->s3->tmp.ctype; + const uint8_t *ctypes = s->s3.tmp.ctype; size_t j; - for (j = 0; j < s->s3->tmp.ctype_len; j++, ctypes++) { + for (j = 0; j < s->s3.tmp.ctype_len; j++, ctypes++) { if (*ctypes == check_type) { rv |= CERT_PKEY_CERT_TYPE; break; @@ -2367,24 +2845,22 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, rv |= CERT_PKEY_CERT_TYPE; } - ca_dn = s->s3->tmp.peer_ca_names; + ca_dn = s->s3.tmp.peer_ca_names; - if (!sk_X509_NAME_num(ca_dn)) + if (ca_dn == NULL + || sk_X509_NAME_num(ca_dn) == 0 + || ssl_check_ca_name(ca_dn, x)) rv |= CERT_PKEY_ISSUER_NAME; - - if (!(rv & CERT_PKEY_ISSUER_NAME)) { - if (ssl_check_ca_name(ca_dn, x)) - rv |= CERT_PKEY_ISSUER_NAME; - } - if (!(rv & CERT_PKEY_ISSUER_NAME)) { + else for (i = 0; i < sk_X509_num(chain); i++) { X509 *xtmp = sk_X509_value(chain, i); + if (ssl_check_ca_name(ca_dn, xtmp)) { rv |= CERT_PKEY_ISSUER_NAME; break; } } - } + if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME)) goto end; } else @@ -2436,36 +2912,28 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) return tls1_check_chain(s, x, pk, chain, -1); } -#ifndef OPENSSL_NO_DH -DH *ssl_get_auto_dh(SSL *s) +EVP_PKEY *ssl_get_auto_dh(SSL *s) { - DH *dhp = NULL; - BIGNUM *p = NULL, *g = NULL; + EVP_PKEY *dhp = NULL; + BIGNUM *p; int dh_secbits = 80, sec_level_bits; + EVP_PKEY_CTX *pctx = NULL; + OSSL_PARAM_BLD *tmpl = NULL; + OSSL_PARAM *params = NULL; if (s->cert->dh_tmp_auto != 2) { - if (s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { - if (s->s3->tmp.new_cipher->strength_bits == 256) + if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { + if (s->s3.tmp.new_cipher->strength_bits == 256) dh_secbits = 128; else dh_secbits = 80; } else { - if (s->s3->tmp.cert == NULL) + if (s->s3.tmp.cert == NULL) return NULL; - dh_secbits = EVP_PKEY_security_bits(s->s3->tmp.cert->privatekey); + dh_secbits = EVP_PKEY_get_security_bits(s->s3.tmp.cert->privatekey); } } - dhp = DH_new(); - if (dhp == NULL) - return NULL; - g = BN_new(); - if (g == NULL || !BN_set_word(g, 2)) { - DH_free(dhp); - BN_free(g); - return NULL; - } - /* Do not pick a prime that is too weak for the current security level */ sec_level_bits = ssl_get_security_level_bits(s, NULL, NULL); if (dh_secbits < sec_level_bits) @@ -2481,15 +2949,32 @@ DH *ssl_get_auto_dh(SSL *s) p = BN_get_rfc3526_prime_2048(NULL); else p = BN_get_rfc2409_prime_1024(NULL); - if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { - DH_free(dhp); - BN_free(p); - BN_free(g); - return NULL; - } + if (p == NULL) + goto err; + + pctx = EVP_PKEY_CTX_new_from_name(s->ctx->libctx, "DH", s->ctx->propq); + if (pctx == NULL + || EVP_PKEY_fromdata_init(pctx) != 1) + goto err; + + tmpl = OSSL_PARAM_BLD_new(); + if (tmpl == NULL + || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) + || !OSSL_PARAM_BLD_push_uint(tmpl, OSSL_PKEY_PARAM_FFC_G, 2)) + goto err; + + params = OSSL_PARAM_BLD_to_param(tmpl); + if (params == NULL + || EVP_PKEY_fromdata(pctx, &dhp, EVP_PKEY_KEY_PARAMETERS, params) != 1) + goto err; + +err: + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(tmpl); + EVP_PKEY_CTX_free(pctx); + BN_free(p); return dhp; } -#endif static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op) { @@ -2502,7 +2987,7 @@ static int ssl_security_cert_key(SSL *s, SSL_CTX *ctx, X509 *x, int op) * reject keys which omit parameters but this only affects DSA and * omission of parameters is never (?) done in practice. */ - secbits = EVP_PKEY_security_bits(pkey); + secbits = EVP_PKEY_get_security_bits(pkey); } if (s) return ssl_security(s, op, secbits, 0, x); @@ -2555,6 +3040,8 @@ int ssl_security_cert_chain(SSL *s, STACK_OF(X509) *sk, X509 *x, int vfy) int rv, start_idx, i; if (x == NULL) { x = sk_X509_value(sk, 0); + if (x == NULL) + return ERR_R_INTERNAL_ERROR; start_idx = 1; } else start_idx = 0; @@ -2584,12 +3071,12 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) /* If not recognised or not supported by cipher mask it is not suitable */ if (clu == NULL - || (clu->amask & s->s3->tmp.new_cipher->algorithm_auth) == 0 + || (clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0 || (clu->nid == EVP_PKEY_RSA_PSS - && (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0)) + && (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kRSA) != 0)) return -1; - return s->s3->tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; + return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; } /* @@ -2602,27 +3089,36 @@ static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu; - int mdnid, pknid, default_mdnid; + int mdnid, pknid, supported; size_t i; + const char *mdname = NULL; - /* If the EVP_PKEY reports a mandatory digest, allow nothing else. */ - ERR_set_mark(); - if (EVP_PKEY_get_default_digest_nid(pkey, &default_mdnid) == 2 && - sig->hash != default_mdnid) - return 0; - - /* If it didn't report a mandatory NID, for whatever reasons, - * just clear the error and allow all hashes to be used. */ - ERR_pop_to_mark(); + /* + * If the given EVP_PKEY cannot support signing with this digest, + * the answer is simply 'no'. + */ + if (sig->hash != NID_undef) + mdname = OBJ_nid2sn(sig->hash); + supported = EVP_PKEY_digestsign_supports_digest(pkey, s->ctx->libctx, + mdname, + s->ctx->propq); + if (supported <= 0) + return 0; - if (s->s3->tmp.peer_cert_sigalgs != NULL) { - for (i = 0; i < s->s3->tmp.peer_cert_sigalgslen; i++) { - lu = tls1_lookup_sigalg(s->s3->tmp.peer_cert_sigalgs[i]); - if (lu == NULL - || !X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL)) + /* + * The TLS 1.3 signature_algorithms_cert extension places restrictions + * on the sigalg with which the certificate was signed (by its issuer). + */ + if (s->s3.tmp.peer_cert_sigalgs != NULL) { + if (!X509_get_signature_info(x, &mdnid, &pknid, NULL, NULL)) + return 0; + for (i = 0; i < s->s3.tmp.peer_cert_sigalgslen; i++) { + lu = tls1_lookup_sigalg(s, s->s3.tmp.peer_cert_sigalgs[i]); + if (lu == NULL) continue; + /* - * TODO this does not differentiate between the + * This does not differentiate between the * rsa_pss_pss_* and rsa_pss_rsae_* schemes since we do not * have a chain here that lets us look at the key OID in the * signing certificate. @@ -2632,6 +3128,11 @@ static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, } return 0; } + + /* + * Without signat_algorithms_cert, any certificate for which we have + * a viable public key is permitted. + */ return 1; } @@ -2682,9 +3183,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) { const SIGALG_LOOKUP *lu = NULL; size_t i; -#ifndef OPENSSL_NO_EC int curve = -1; -#endif EVP_PKEY *tmppkey; /* Look for a shared sigalgs matching possible certificates */ @@ -2698,7 +3197,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) || lu->sig == EVP_PKEY_RSA) continue; /* Check that we have a cert, and signature_algorithms_cert */ - if (!tls1_lookup_md(lu, NULL)) + if (!tls1_lookup_md(s->ctx, lu, NULL)) continue; if ((pkey == NULL && !has_usable_cert(s, lu, -1)) || (pkey != NULL && !is_cert_usable(s, lu, x, pkey))) @@ -2708,19 +3207,13 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey) : s->cert->pkeys[lu->sig_idx].privatekey; if (lu->sig == EVP_PKEY_EC) { -#ifndef OPENSSL_NO_EC - if (curve == -1) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(tmppkey); - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } + if (curve == -1) + curve = ssl_get_EC_curve_nid(tmppkey); if (lu->curve != NID_undef && curve != lu->curve) continue; -#else - continue; -#endif } else if (lu->sig == EVP_PKEY_RSA_PSS) { /* validate that key is large enough for the signature algorithm */ - if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu)) + if (!rsa_pss_check_min_key_size(s->ctx, tmppkey, lu)) continue; } break; @@ -2748,39 +3241,34 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) const SIGALG_LOOKUP *lu = NULL; int sig_idx = -1; - s->s3->tmp.cert = NULL; - s->s3->tmp.sigalg = NULL; + s->s3.tmp.cert = NULL; + s->s3.tmp.sigalg = NULL; if (SSL_IS_TLS13(s)) { lu = find_sig_alg(s, NULL, NULL); if (lu == NULL) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CHOOSE_SIGALG, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } } else { /* If ciphersuite doesn't require a cert nothing to do */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aCERT)) + if (!(s->s3.tmp.new_cipher->algorithm_auth & SSL_aCERT)) return 1; if (!s->server && !ssl_has_cert(s, s->cert->key - s->cert->pkeys)) return 1; if (SSL_USE_SIGALGS(s)) { size_t i; - if (s->s3->tmp.peer_sigalgs != NULL) { -#ifndef OPENSSL_NO_EC - int curve; + if (s->s3.tmp.peer_sigalgs != NULL) { + int curve = -1; /* For Suite B need to match signature algorithm to curve */ - if (tls1_suiteb(s)) { - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(s->cert->pkeys[SSL_PKEY_ECC].privatekey); - curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - } else { - curve = -1; - } -#endif + if (tls1_suiteb(s)) + curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC] + .privatekey); /* * Find highest preference signature algorithm matching @@ -2806,12 +3294,10 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) /* validate that key is large enough for the signature algorithm */ EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey; - if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu)) + if (!rsa_pss_check_min_key_size(s->ctx, pkey, lu)) continue; } -#ifndef OPENSSL_NO_EC if (curve == -1 || lu->curve == curve) -#endif break; } #ifndef OPENSSL_NO_GOST @@ -2820,12 +3306,11 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) * in supported_algorithms extension, so when we have GOST-based ciphersuite, * we have to assume GOST support. */ - if (i == s->shared_sigalgslen && s->s3->tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) { + if (i == s->shared_sigalgslen && s->s3.tmp.new_cipher->algorithm_auth & (SSL_aGOST01 | SSL_aGOST12)) { if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CHOOSE_SIGALG, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } else { @@ -2838,7 +3323,6 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_F_TLS_CHOOSE_SIGALG, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } @@ -2852,8 +3336,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } @@ -2867,8 +3351,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if (i == sent_sigslen) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, - SSL_F_TLS_CHOOSE_SIGALG, + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } @@ -2877,17 +3360,17 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { if (!fatalerrs) return 1; - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, - ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } } } if (sig_idx == -1) sig_idx = lu->sig_idx; - s->s3->tmp.cert = &s->cert->pkeys[sig_idx]; - s->cert->key = s->s3->tmp.cert; - s->s3->tmp.sigalg = lu; + s->s3.tmp.cert = &s->cert->pkeys[sig_idx]; + s->cert->key = s->s3.tmp.cert; + s->s3.tmp.sigalg = lu; return 1; } @@ -2895,8 +3378,7 @@ int SSL_CTX_set_tlsext_max_fragment_length(SSL_CTX *ctx, uint8_t mode) { if (mode != TLSEXT_max_fragment_length_DISABLED && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) { - SSLerr(SSL_F_SSL_CTX_SET_TLSEXT_MAX_FRAGMENT_LENGTH, - SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -2908,8 +3390,7 @@ int SSL_set_tlsext_max_fragment_length(SSL *ssl, uint8_t mode) { if (mode != TLSEXT_max_fragment_length_DISABLED && !IS_MAX_FRAGMENT_LENGTH_EXT_VALID(mode)) { - SSLerr(SSL_F_SSL_SET_TLSEXT_MAX_FRAGMENT_LENGTH, - SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); + ERR_raise(ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH); return 0; } @@ -2921,3 +3402,129 @@ uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *session) { return session->ext.max_fragment_len_mode; } + +/* + * Helper functions for HMAC access with legacy support included. + */ +SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx) +{ + SSL_HMAC *ret = OPENSSL_zalloc(sizeof(*ret)); + EVP_MAC *mac = NULL; + + if (ret == NULL) + return NULL; +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->ext.ticket_key_evp_cb == NULL + && ctx->ext.ticket_key_cb != NULL) { + if (!ssl_hmac_old_new(ret)) + goto err; + return ret; + } +#endif + mac = EVP_MAC_fetch(ctx->libctx, "HMAC", ctx->propq); + if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL) + goto err; + EVP_MAC_free(mac); + return ret; + err: + EVP_MAC_CTX_free(ret->ctx); + EVP_MAC_free(mac); + OPENSSL_free(ret); + return NULL; +} + +void ssl_hmac_free(SSL_HMAC *ctx) +{ + if (ctx != NULL) { + EVP_MAC_CTX_free(ctx->ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + ssl_hmac_old_free(ctx); +#endif + OPENSSL_free(ctx); + } +} + +EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx) +{ + return ctx->ctx; +} + +int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md) +{ + OSSL_PARAM params[2], *p = params; + + if (ctx->ctx != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_MAC_init(ctx->ctx, key, len, params)) + return 1; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_init(ctx, key, len, md); +#endif + return 0; +} + +int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len) +{ + if (ctx->ctx != NULL) + return EVP_MAC_update(ctx->ctx, data, len); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_update(ctx, data, len); +#endif + return 0; +} + +int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len, + size_t max_size) +{ + if (ctx->ctx != NULL) + return EVP_MAC_final(ctx->ctx, md, len, max_size); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_final(ctx, md, len); +#endif + return 0; +} + +size_t ssl_hmac_size(const SSL_HMAC *ctx) +{ + if (ctx->ctx != NULL) + return EVP_MAC_CTX_get_mac_size(ctx->ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return ssl_hmac_old_size(ctx); +#endif + return 0; +} + +int ssl_get_EC_curve_nid(const EVP_PKEY *pkey) +{ + char gname[OSSL_MAX_NAME_SIZE]; + + if (EVP_PKEY_get_group_name(pkey, gname, sizeof(gname), NULL) > 0) + return OBJ_txt2nid(gname); + + return NID_undef; +} + +__owur int tls13_set_encoded_pub_key(EVP_PKEY *pkey, + const unsigned char *enckey, + size_t enckeylen) +{ + if (EVP_PKEY_is_a(pkey, "DH")) { + int bits = EVP_PKEY_get_bits(pkey); + + if (bits <= 0 || enckeylen != (size_t)bits / 8) + /* the encoded key must be padded to the length of the p */ + return 0; + } else if (EVP_PKEY_is_a(pkey, "EC")) { + if (enckeylen < 3 /* point format and at least 1 byte for x and y */ + || enckey[0] != 0x04) + return 0; + } + + return EVP_PKEY_set1_encoded_public_key(pkey, enckey, enckeylen); +} |