X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=ebd094df9b4553b74f3636f571ffc47e235473b4;hp=fe13a39c38cd2af7d8a787d2587854e34e161699;hb=6f892296038490a7fa24b32ac6f7305687634fb0;hpb=a51c9f637cdef7926d8a8991365e4b58975346db diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index fe13a39c38..ebd094df9b 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1,26 +1,34 @@ /* * Copyright 1995-2018 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 */ +/* We need access to the deprecated low level HMAC APIs */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include #include #include #include #include +#include #include #include #include #include #include #include "internal/nelem.h" -#include "ssl_locl.h" +#include "internal/evp.h" +#include "ssl_local.h" #include +static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey); +static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu); + SSL3_ENC_METHOD const TLSv1_enc_data = { tls1_enc, tls1_mac, @@ -121,90 +129,129 @@ 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. + * Table of group information. */ +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) 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) */ +# ifndef OPENSSL_NO_EC + {NID_sect163k1, 80, TLS_GROUP_CURVE_CHAR2, 0x0001}, /* sect163k1 (1) */ + {NID_sect163r1, 80, TLS_GROUP_CURVE_CHAR2, 0x0002}, /* sect163r1 (2) */ + {NID_sect163r2, 80, TLS_GROUP_CURVE_CHAR2, 0x0003}, /* sect163r2 (3) */ + {NID_sect193r1, 80, TLS_GROUP_CURVE_CHAR2, 0x0004}, /* sect193r1 (4) */ + {NID_sect193r2, 80, TLS_GROUP_CURVE_CHAR2, 0x0005}, /* sect193r2 (5) */ + {NID_sect233k1, 112, TLS_GROUP_CURVE_CHAR2, 0x0006}, /* sect233k1 (6) */ + {NID_sect233r1, 112, TLS_GROUP_CURVE_CHAR2, 0x0007}, /* sect233r1 (7) */ + {NID_sect239k1, 112, TLS_GROUP_CURVE_CHAR2, 0x0008}, /* sect239k1 (8) */ + {NID_sect283k1, 128, TLS_GROUP_CURVE_CHAR2, 0x0009}, /* sect283k1 (9) */ + {NID_sect283r1, 128, TLS_GROUP_CURVE_CHAR2, 0x000A}, /* sect283r1 (10) */ + {NID_sect409k1, 192, TLS_GROUP_CURVE_CHAR2, 0x000B}, /* sect409k1 (11) */ + {NID_sect409r1, 192, TLS_GROUP_CURVE_CHAR2, 0x000C}, /* sect409r1 (12) */ + {NID_sect571k1, 256, TLS_GROUP_CURVE_CHAR2, 0x000D}, /* sect571k1 (13) */ + {NID_sect571r1, 256, TLS_GROUP_CURVE_CHAR2, 0x000E}, /* sect571r1 (14) */ + {NID_secp160k1, 80, TLS_GROUP_CURVE_PRIME, 0x000F}, /* secp160k1 (15) */ + {NID_secp160r1, 80, TLS_GROUP_CURVE_PRIME, 0x0010}, /* secp160r1 (16) */ + {NID_secp160r2, 80, TLS_GROUP_CURVE_PRIME, 0x0011}, /* secp160r2 (17) */ + {NID_secp192k1, 80, TLS_GROUP_CURVE_PRIME, 0x0012}, /* secp192k1 (18) */ + {NID_X9_62_prime192v1, 80, TLS_GROUP_CURVE_PRIME, 0x0013}, /* secp192r1 (19) */ + {NID_secp224k1, 112, TLS_GROUP_CURVE_PRIME, 0x0014}, /* secp224k1 (20) */ + {NID_secp224r1, 112, TLS_GROUP_CURVE_PRIME, 0x0015}, /* secp224r1 (21) */ + {NID_secp256k1, 128, TLS_GROUP_CURVE_PRIME, 0x0016}, /* secp256k1 (22) */ + {NID_X9_62_prime256v1, 128, TLS_GROUP_CURVE_PRIME, 0x0017}, /* secp256r1 (23) */ + {NID_secp384r1, 192, TLS_GROUP_CURVE_PRIME, 0x0018}, /* secp384r1 (24) */ + {NID_secp521r1, 256, TLS_GROUP_CURVE_PRIME, 0x0019}, /* secp521r1 (25) */ + {NID_brainpoolP256r1, 128, TLS_GROUP_CURVE_PRIME, 0x001A}, /* brainpoolP256r1 (26) */ + {NID_brainpoolP384r1, 192, TLS_GROUP_CURVE_PRIME, 0x001B}, /* brainpoolP384r1 (27) */ + {NID_brainpoolP512r1, 256, TLS_GROUP_CURVE_PRIME, 0x001C}, /* brainpool512r1 (28) */ + {EVP_PKEY_X25519, 128, TLS_GROUP_CURVE_CUSTOM, 0x001D}, /* X25519 (29) */ + {EVP_PKEY_X448, 224, TLS_GROUP_CURVE_CUSTOM, 0x001E}, /* X448 (30) */ +# endif /* OPENSSL_NO_EC */ +# ifndef OPENSSL_NO_DH + /* Security bit values for FFDHE groups are updated as per RFC 7919 */ + {NID_ffdhe2048, 103, TLS_GROUP_FFDHE_FOR_TLS1_3, 0x0100}, /* ffdhe2048 (0x0100) */ + {NID_ffdhe3072, 125, TLS_GROUP_FFDHE_FOR_TLS1_3, 0x0101}, /* ffdhe3072 (0x0101) */ + {NID_ffdhe4096, 150, TLS_GROUP_FFDHE_FOR_TLS1_3, 0x0102}, /* ffdhe4096 (0x0102) */ + {NID_ffdhe6144, 175, TLS_GROUP_FFDHE_FOR_TLS1_3, 0x0103}, /* ffdhe6144 (0x0103) */ + {NID_ffdhe8192, 192, TLS_GROUP_FFDHE_FOR_TLS1_3, 0x0104}, /* ffdhe8192 (0x0104) */ +# endif /* OPENSSL_NO_DH */ }; +#endif +#ifndef OPENSSL_NO_EC static const unsigned char ecformats_default[] = { TLSEXT_ECPOINTFORMAT_uncompressed, TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 }; +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ /* The default curves */ -static const uint16_t eccurves_default[] = { +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) +static const uint16_t supported_groups_default[] = { +# ifndef OPENSSL_NO_EC 29, /* X25519 (29) */ 23, /* secp256r1 (23) */ 30, /* X448 (30) */ 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ +# endif +# ifndef OPENSSL_NO_DH + 0x100, /* ffdhe2048 (0x100) */ + 0x101, /* ffdhe3072 (0x101) */ + 0x102, /* ffdhe4096 (0x102) */ + 0x103, /* ffdhe6144 (0x103) */ + 0x104, /* ffdhe8192 (0x104) */ +# endif }; +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ +#ifndef OPENSSL_NO_EC static const uint16_t suiteb_curves[] = { TLSEXT_curve_P_256, TLSEXT_curve_P_384 }; +#endif const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id) { - /* 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]; +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) + size_t i; + + /* ECC curves from RFC 4492 and RFC 7027 FFDHE group from RFC 8446 */ + for (i = 0; i < OSSL_NELEM(nid_list); i++) { + if (nid_list[i].group_id == group_id) + return &nid_list[i]; + } +#endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */ + return NULL; +} + +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) +int tls1_group_id2nid(uint16_t group_id) +{ + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(group_id); + + return ginf == NULL ? NID_undef : ginf->nid; } static 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 nid_list[i].group_id; } return 0; } +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ /* * Set *pgroups to the supported groups list and *pgroupslen to @@ -213,9 +260,10 @@ static uint16_t tls1_nid2group_id(int nid) void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, size_t *pgroupslen) { - +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) /* For Suite B mode only include P-256, P-384 */ switch (tls1_suiteb(s)) { +# ifndef OPENSSL_NO_EC case SSL_CERT_FLAG_SUITEB_128_LOS: *pgroups = suiteb_curves; *pgroupslen = OSSL_NELEM(suiteb_curves); @@ -230,34 +278,54 @@ void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, *pgroups = suiteb_curves + 1; *pgroupslen = 1; break; +# endif default: if (s->ext.supportedgroups == NULL) { - *pgroups = eccurves_default; - *pgroupslen = OSSL_NELEM(eccurves_default); + *pgroups = supported_groups_default; + *pgroupslen = OSSL_NELEM(supported_groups_default); } else { *pgroups = s->ext.supportedgroups; *pgroupslen = s->ext.supportedgroups_len; } break; } +#else + *pgroups = NULL; + *pgroupslen = 0; +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ } -/* 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 version) { - const TLS_GROUP_INFO *cinfo = tls1_group_id_lookup(curve); - unsigned char ctmp[2]; + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(group_id); - if (cinfo == NULL) + if (version < TLS1_3_VERSION) { + if ((ginfo->flags & TLS_GROUP_ONLY_FOR_TLS1_3) != 0) + return 0; + } + return 1; +} + +/* 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(group); + unsigned char gtmp[2]; + + if (ginfo == NULL) return 0; -# ifdef OPENSSL_NO_EC2M - if (cinfo->flags & TLS_CURVE_CHAR2) +#ifdef OPENSSL_NO_EC2M + if (ginfo->flags & TLS_GROUP_CURVE_CHAR2) return 0; -# endif - ctmp[0] = curve >> 8; - ctmp[1] = curve & 0xff; - return ssl_security(s, op, cinfo->secbits, cinfo->nid, (void *)ctmp); +#endif +#ifdef OPENSSL_NO_DH + if (ginfo->flags & TLS_GROUP_FFDHE) + return 0; +#endif + gtmp[0] = group >> 8; + gtmp[1] = group & 0xff; + return ssl_security(s, op, ginfo->secbits, ginfo->nid, (void *)gtmp); } /* Return 1 if "id" is in "list" */ @@ -292,7 +360,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; @@ -320,7 +388,7 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) uint16_t id = pref[i]; if (!tls1_in_list(id, supp, num_supp) - || !tls_curve_allowed(s, id, SSL_SECOP_CURVE_SHARED)) + || !tls_group_allowed(s, id, SSL_SECOP_CURVE_SHARED)) continue; if (nmatch == k) return id; @@ -335,13 +403,16 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) int tls1_set_groups(uint16_t **pext, size_t *pextlen, int *groups, size_t ngroups) { +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) 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); @@ -354,44 +425,53 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, 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; +#else + return 0; +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ } -# define MAX_CURVELIST OSSL_NELEM(nid_list) +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) +# define MAX_GROUPLIST OSSL_NELEM(nid_list) typedef struct { size_t nidcnt; - int nid_arr[MAX_CURVELIST]; + int nid_arr[MAX_GROUPLIST]; } nid_cb_st; static int nid_cb(const char *elem, int len, void *arg) { nid_cb_st *narg = arg; size_t i; - int nid; + int nid = NID_undef; char etmp[20]; if (elem == NULL) return 0; - if (narg->nidcnt == MAX_CURVELIST) + if (narg->nidcnt == MAX_GROUPLIST) return 0; if (len > (int)(sizeof(etmp) - 1)) return 0; memcpy(etmp, elem, len); etmp[len] = 0; +# ifndef OPENSSL_NO_EC nid = EC_curve_nist2nid(etmp); +# endif if (nid == NID_undef) nid = OBJ_sn2nid(etmp); if (nid == NID_undef) @@ -404,10 +484,12 @@ static int nid_cb(const char *elem, int len, void *arg) narg->nid_arr[narg->nidcnt++] = nid; return 1; } +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ /* Set groups based on a colon separate list */ int tls1_set_groups_list(uint16_t **pext, size_t *pextlen, const char *str) { +#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) nid_cb_st ncb; ncb.nidcnt = 0; if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) @@ -415,64 +497,9 @@ int tls1_set_groups_list(uint16_t **pext, size_t *pextlen, const char *str) 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) -{ - EC_KEY *ec = EVP_PKEY_get0_EC_KEY(pkey); - const EC_GROUP *grp; - - if (ec == 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; - } - /* - * If point formats extension present check it, otherwise everything is - * supported (see RFC4492). - */ - if (s->session->ext.ecpointformats == NULL) - return 1; - - for (i = 0; i < s->session->ext.ecpointformats_len; i++) { - if (s->session->ext.ecpointformats[i] == comp_id) - return 1; - } +#else return 0; +#endif } /* Check a group id matches preferences */ @@ -485,8 +512,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) @@ -507,7 +534,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 */ @@ -528,6 +555,7 @@ int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) return tls1_in_list(group_id, groups, groups_len); } +#ifndef OPENSSL_NO_EC void tls1_get_formatlist(SSL *s, const unsigned char **pformats, size_t *num_formats) { @@ -547,6 +575,63 @@ 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) +{ + 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_is_a(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; + } + /* + * 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 = evp_pkey_get_EC_KEY_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. @@ -559,7 +644,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)) @@ -578,7 +663,6 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) if (check_ee_md && tls1_suiteb(s)) { int check_md; size_t i; - CERT *c = s->cert; /* Check to see we have necessary signing algorithm */ if (group_id == TLSEXT_curve_P_256) @@ -587,8 +671,8 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) check_md = NID_ecdsa_with_SHA384; else return 0; /* Should never happen */ - for (i = 0; i < c->shared_sigalgslen; i++) { - if (check_md == c->shared_sigalgs[i]->sigandhash) + for (i = 0; i < s->shared_sigalgslen; i++) { + if (check_md == s->shared_sigalgs[i]->sigandhash) return 1;; } return 0; @@ -668,6 +752,8 @@ static const uint16_t tls12_sigalgs[] = { 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, @@ -756,6 +842,14 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { NID_dsaWithSHA1, NID_undef}, #endif #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}, + {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}, {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, @@ -788,8 +882,8 @@ 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 */ }; @@ -808,7 +902,7 @@ static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg) 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) @@ -817,7 +911,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; } @@ -834,22 +928,26 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) * 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) +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_size(pkey) < RSA_PSS_MINIMUM_KEY_SIZE(md)) return 0; return 1; } /* - * Return a signature algorithm for TLS < 1.2 where the signature type - * is fixed by the certificate type. + * Returns a signature algorithm when the peer did not send a list of supported + * signature algorithms. The signature algorithm is fixed for the certificate + * type. |idx| is a certificate type index (SSL_PKEY_*). When |idx| is -1 the + * certificate type from |s| will be used. + * Returns the signature algorithm to use, or NULL on error. */ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) { @@ -861,7 +959,7 @@ 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->amask & s->s3.tmp.new_cipher->algorithm_auth) { idx = i; break; } @@ -870,7 +968,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; @@ -890,10 +988,14 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) { const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]); - if (!tls1_lookup_md(lu, NULL)) + if (!tls1_lookup_md(s->ctx, lu, NULL)) + return NULL; + if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu)) return NULL; return lu; } + if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, &legacy_rsa_sigalg)) + return NULL; return &legacy_rsa_sigalg; } /* Set peer sigalg based key type */ @@ -907,7 +1009,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; } @@ -949,6 +1051,7 @@ 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. @@ -979,6 +1082,32 @@ 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(SSL_CTX *ctx, const SIGALG_LOOKUP *lu) +{ + const EVP_MD *md = NULL; + int secbits = 0; + + if (!tls1_lookup_md(ctx, lu, &md)) + return 0; + if (md != NULL) + { + /* Security bits: half digest bits */ + secbits = EVP_MD_size(md) * 4; + } else { + /* Values from https://tools.ietf.org/html/rfc8032#section-8.5 */ + if (lu->sigalg == TLSEXT_SIGALG_ed25519) + secbits = 128; + else if (lu->sigalg == TLSEXT_SIGALG_ed448) + secbits = 224; + } + return secbits; +} /* * Check signature algorithm is consistent with sent supported signature @@ -991,9 +1120,22 @@ 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; + + /* + * TODO(3.0) Remove this when we adapted this function for provider + * side keys. We know that EVP_PKEY_get0() downgrades an EVP_PKEY + * to contain a legacy key. + * + * THIS IS TEMPORARY + */ + EVP_PKEY_get0(pkey); + if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) + return 0; + pkeyid = EVP_PKEY_id(pkey); /* Should never happen */ if (pkeyid == -1) return -1; @@ -1042,8 +1184,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) /* 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 = evp_pkey_get_EC_KEY_curve_nid(pkey); if (lu->curve != NID_undef && curve != lu->curve) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, @@ -1089,44 +1230,44 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - if (!tls1_lookup_md(lu, &md)) { + if (!tls1_lookup_md(s->ctx, lu, &md)) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST); return 0; } - if (md != NULL) { - /* - * Make sure security callback allows algorithm. For historical - * reasons we have to pass the sigalg as a two byte char array. - */ - sigalgstr[0] = (sig >> 8) & 0xff; - sigalgstr[1] = sig & 0xff; - if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK, - EVP_MD_size(md) * 4, EVP_MD_type(md), - (void *)sigalgstr)) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); - return 0; - } + /* + * Make sure security callback allows algorithm. For historical + * reasons we have to pass the sigalg as a two byte char array. + */ + sigalgstr[0] = (sig >> 8) & 0xff; + sigalgstr[1] = sig & 0xff; + 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, + (void *)sigalgstr)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, + 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; } @@ -1142,23 +1283,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; @@ -1173,12 +1314,12 @@ int ssl_set_client_disabled(SSL *s) * * Returns 1 when it's disabled, 0 when enabled. */ -int ssl_cipher_disabled(SSL *s, const SSL_CIPHER *c, int op, int ecdhe) +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; @@ -1191,11 +1332,11 @@ int ssl_cipher_disabled(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); @@ -1213,18 +1354,18 @@ int tls1_set_server_sigalgs(SSL *s) size_t i; /* Clear any shared signature algorithms */ - OPENSSL_free(s->cert->shared_sigalgs); - s->cert->shared_sigalgs = NULL; - s->cert->shared_sigalgslen = 0; + OPENSSL_free(s->shared_sigalgs); + s->shared_sigalgs = NULL; + 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); @@ -1237,7 +1378,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; } } @@ -1250,7 +1391,7 @@ int tls1_set_server_sigalgs(SSL *s) SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_INTERNAL_ERROR); return 0; } - if (s->cert->shared_sigalgs != NULL) + if (s->shared_sigalgs != NULL) return 1; /* Fatal error if no shared signature algorithms */ @@ -1327,7 +1468,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, 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; @@ -1357,7 +1498,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; @@ -1367,11 +1508,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; @@ -1383,21 +1541,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; } @@ -1405,7 +1571,7 @@ 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; @@ -1419,8 +1585,8 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } 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; } @@ -1483,7 +1649,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 @@ -1553,19 +1719,19 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, } /* Check to see if a signature algorithm is allowed */ -static int tls12_sigalg_allowed(SSL *s, int op, const SIGALG_LOOKUP *lu) +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 (!tls1_lookup_md(s->ctx, lu, NULL)) 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 + 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)) @@ -1583,7 +1749,7 @@ static int tls12_sigalg_allowed(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; @@ -1593,7 +1759,7 @@ static int tls12_sigalg_allowed(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); @@ -1614,11 +1780,8 @@ static int tls12_sigalg_allowed(SSL *s, int op, const SIGALG_LOOKUP *lu) } } - if (lu->hash == NID_undef) - return 1; - /* Security bits: half digest bits */ - secbits = EVP_MD_size(ssl_md(lu->hash_idx)) * 4; /* Finally see if security callback allows it */ + 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); @@ -1648,8 +1811,8 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) 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 @@ -1722,9 +1885,9 @@ static int tls1_set_shared_sigalgs(SSL *s) CERT *c = s->cert; unsigned int is_suiteb = tls1_suiteb(s); - OPENSSL_free(c->shared_sigalgs); - c->shared_sigalgs = NULL; - c->shared_sigalgslen = 0; + OPENSSL_free(s->shared_sigalgs); + s->shared_sigalgs = NULL; + s->shared_sigalgslen = 0; /* If client use client signature algorithms if not NULL */ if (!s->server && c->client_sigalgs && !is_suiteb) { conf = c->client_sigalgs; @@ -1737,13 +1900,13 @@ 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) { @@ -1755,8 +1918,8 @@ static int tls1_set_shared_sigalgs(SSL *s) } else { salgs = NULL; } - c->shared_sigalgs = salgs; - c->shared_sigalgslen = nmatch; + s->shared_sigalgs = salgs; + s->shared_sigalgslen = nmatch; return 1; } @@ -1803,11 +1966,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); } @@ -1816,8 +1979,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; - CERT *c = s->cert; + uint32_t *pvalid = s->s3.tmp.valid_flags; if (!tls1_set_shared_sigalgs(s)) return 0; @@ -1825,8 +1987,8 @@ int tls1_process_sigalgs(SSL *s) for (i = 0; i < SSL_PKEY_NUM; i++) pvalid[i] = 0; - for (i = 0; i < c->shared_sigalgslen; i++) { - const SIGALG_LOOKUP *sigptr = c->shared_sigalgs[i]; + for (i = 0; i < s->shared_sigalgslen; i++) { + const SIGALG_LOOKUP *sigptr = s->shared_sigalgs[i]; int idx = sigptr->sig_idx; /* Ignore PKCS1 based sig algs in TLSv1.3 */ @@ -1843,8 +2005,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) { @@ -1873,12 +2035,12 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, unsigned char *rsig, unsigned char *rhash) { const SIGALG_LOOKUP *shsigalgs; - if (s->cert->shared_sigalgs == NULL + if (s->shared_sigalgs == NULL || idx < 0 - || idx >= (int)s->cert->shared_sigalgslen - || s->cert->shared_sigalgslen > INT_MAX) + || idx >= (int)s->shared_sigalgslen + || s->shared_sigalgslen > INT_MAX) return 0; - shsigalgs = s->cert->shared_sigalgs[idx]; + shsigalgs = s->shared_sigalgs[idx]; if (phash != NULL) *phash = shsigalgs->hash; if (psign != NULL) @@ -1889,7 +2051,7 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, *rsig = (unsigned char)(shsigalgs->sigalg & 0xff); if (rhash != NULL) *rhash = (unsigned char)((shsigalgs->sigalg >> 8) & 0xff); - return (int)s->cert->shared_sigalgslen; + return (int)s->shared_sigalgslen; } /* Maximum possible number of unique entries in sigalgs array */ @@ -2070,25 +2232,43 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) return 0; } -static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) +static int tls1_check_sig_alg(SSL *s, X509 *x, int default_nid) { - int sig_nid; + int sig_nid, use_pc_sigalgs = 0; size_t i; + const SIGALG_LOOKUP *sigalg; + size_t sigalgslen; if (default_nid == -1) return 1; sig_nid = X509_get_signature_nid(x); if (default_nid) return sig_nid == default_nid ? 1 : 0; - for (i = 0; i < c->shared_sigalgslen; i++) - if (sig_nid == c->shared_sigalgs[i]->sigandhash) + + 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; + 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]) + : s->shared_sigalgs[i]; + if (sig_nid == sigalg->sigandhash) return 1; + } return 0; } /* 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++) { @@ -2132,7 +2312,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; @@ -2149,7 +2329,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; @@ -2176,8 +2356,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 { @@ -2238,14 +2418,21 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, } } /* Check signature algorithm of each cert in chain */ - if (!tls1_check_sig_alg(c, x, default_nid)) { + if (SSL_IS_TLS13(s)) { + /* + * We only get here if the application has called SSL_check_chain(), + * so check_flags is always set. + */ + if (find_sig_alg(s, x, pk) != NULL) + rv |= CERT_PKEY_EE_SIGNATURE; + } else if (!tls1_check_sig_alg(s, x, default_nid)) { if (!check_flags) goto end; } else rv |= CERT_PKEY_EE_SIGNATURE; rv |= CERT_PKEY_CA_SIGNATURE; for (i = 0; i < sk_X509_num(chain); i++) { - if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) { + if (!tls1_check_sig_alg(s, sk_X509_value(chain, i), default_nid)) { if (check_flags) { rv &= ~CERT_PKEY_CA_SIGNATURE; break; @@ -2282,22 +2469,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; @@ -2309,7 +2493,7 @@ 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)) rv |= CERT_PKEY_ISSUER_NAME; @@ -2384,15 +2568,15 @@ DH *ssl_get_auto_dh(SSL *s) int dh_secbits = 80; if (s->cert->dh_tmp_auto == 2) return DH_get_1024_160(); - 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_security_bits(s->s3.tmp.cert->privatekey); } if (dh_secbits >= 128) { @@ -2517,12 +2701,66 @@ 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; +} + +/* + * Checks the given cert against signature_algorithm_cert restrictions sent by + * the peer (if any) as well as whether the hash from the sigalg is usable with + * the key. + * Returns true if the cert is usable and false otherwise. + */ +static int check_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, + EVP_PKEY *pkey) +{ + const SIGALG_LOOKUP *lu; + int mdnid, pknid, supported; + size_t i; + + /* + * If the given EVP_PKEY cannot supporting signing with this sigalg, + * the answer is simply 'no'. + */ + ERR_set_mark(); + supported = EVP_PKEY_supports_digest_nid(pkey, sig->hash); + ERR_pop_to_mark(); + if (supported == 0) + return 0; + + /* + * 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->s3.tmp.peer_cert_sigalgs[i]); + if (lu == NULL) + continue; + + /* + * TODO 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. + */ + if (mdnid == lu->hash && pknid == lu->sig) + return 1; + } + return 0; + } + + /* + * Without signat_algorithms_cert, any certificate for which we have + * a viable public key is permitted. + */ + return 1; } /* @@ -2534,54 +2772,90 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) */ static int has_usable_cert(SSL *s, const SIGALG_LOOKUP *sig, int idx) { - const SIGALG_LOOKUP *lu; - int mdnid, pknid, supported; - size_t i; - - /* TLS 1.2 callers can override lu->sig_idx, but not TLS 1.3 callers. */ + /* TLS 1.2 callers can override sig->sig_idx, but not TLS 1.3 callers. */ if (idx == -1) idx = sig->sig_idx; if (!ssl_has_cert(s, idx)) 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(s->cert->pkeys[idx].x509, &mdnid, - &pknid, NULL, NULL) - /* - * TODO 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. - */ - || mdnid != lu->hash - || pknid != lu->sig) - continue; - ERR_set_mark(); - supported = EVP_PKEY_supports_digest_nid(s->cert->pkeys[idx].privatekey, - mdnid); - if (supported == 0) + return check_cert_usable(s, sig, s->cert->pkeys[idx].x509, + s->cert->pkeys[idx].privatekey); +} + +/* + * Returns true if the supplied cert |x| and key |pkey| is usable with the + * specified signature scheme |sig|, or false otherwise. + */ +static int is_cert_usable(SSL *s, const SIGALG_LOOKUP *sig, X509 *x, + EVP_PKEY *pkey) +{ + size_t idx; + + if (ssl_cert_lookup_by_pkey(pkey, &idx) == NULL) + return 0; + + /* Check the key is consistent with the sig alg */ + if ((int)idx != sig->sig_idx) + return 0; + + return check_cert_usable(s, sig, x, pkey); +} + +/* + * Find a signature scheme that works with the supplied certificate |x| and key + * |pkey|. |x| and |pkey| may be NULL in which case we additionally look at our + * available certs/keys to find one that works. + */ +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 */ + for (i = 0; i < s->shared_sigalgslen; i++) { + lu = s->shared_sigalgs[i]; + + /* Skip SHA1, SHA224, DSA and RSA if not PSS */ + if (lu->hash == NID_sha1 + || lu->hash == NID_sha224 + || lu->sig == EVP_PKEY_DSA + || lu->sig == EVP_PKEY_RSA) + continue; + /* Check that we have a cert, and signature_algorithms_cert */ + 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))) + continue; + + tmppkey = (pkey != NULL) ? pkey + : s->cert->pkeys[lu->sig_idx].privatekey; + + if (lu->sig == EVP_PKEY_EC) { +#ifndef OPENSSL_NO_EC + if (curve == -1) + curve = evp_pkey_get_EC_KEY_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(s->ctx, tmppkey, lu)) continue; - else if (supported < 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(); - } - return 1; } - return 0; + break; } - supported = EVP_PKEY_supports_digest_nid(s->cert->pkeys[idx].privatekey, - sig->hash); - if (supported == 0) - return 0; - else if (supported < 0) - ERR_clear_error(); - return 1; + if (i == s->shared_sigalgslen) + return NULL; + + return lu; } /* @@ -2600,52 +2874,12 @@ 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)) { - size_t i; -#ifndef OPENSSL_NO_EC - int curve = -1; -#endif - - /* Look for a certificate matching shared sigalgs */ - for (i = 0; i < s->cert->shared_sigalgslen; i++) { - lu = s->cert->shared_sigalgs[i]; - sig_idx = -1; - - /* Skip SHA1, SHA224, DSA and RSA if not PSS */ - if (lu->hash == NID_sha1 - || lu->hash == NID_sha224 - || lu->sig == EVP_PKEY_DSA - || lu->sig == EVP_PKEY_RSA) - continue; - /* Check that we have a cert, and signature_algorithms_cert */ - if (!tls1_lookup_md(lu, NULL) || !has_usable_cert(s, lu, -1)) - continue; - if (lu->sig == EVP_PKEY_EC) { -#ifndef OPENSSL_NO_EC - if (curve == -1) { - 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)); - } - 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 */ - EVP_PKEY *pkey; - - pkey = s->cert->pkeys[lu->sig_idx].privatekey; - if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu)) - continue; - } - break; - } - if (i == s->cert->shared_sigalgslen) { + 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, @@ -2654,32 +2888,30 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) } } 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) { + if (s->s3.tmp.peer_sigalgs != NULL) { #ifndef OPENSSL_NO_EC - int curve; + 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; - } + if (tls1_suiteb(s)) + curve = + evp_pkey_get_EC_KEY_curve_nid(s->cert->pkeys[SSL_PKEY_ECC] + .privatekey); #endif /* * Find highest preference signature algorithm matching * cert type */ - for (i = 0; i < s->cert->shared_sigalgslen; i++) { - lu = s->cert->shared_sigalgs[i]; + for (i = 0; i < s->shared_sigalgslen; i++) { + lu = s->shared_sigalgs[i]; if (s->server) { if ((sig_idx = tls12_get_cert_sigalg_idx(s, lu)) == -1) @@ -2698,7 +2930,7 @@ 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 @@ -2706,7 +2938,27 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) #endif break; } - if (i == s->cert->shared_sigalgslen) { +#ifndef OPENSSL_NO_GOST + /* + * Some Windows-based implementations do not send GOST algorithms indication + * 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 ((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 { + i = 0; + sig_idx = lu->sig_idx; + } + } +#endif + if (i == s->shared_sigalgslen) { if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, @@ -2725,7 +2977,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, - ERR_R_INTERNAL_ERROR); + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } @@ -2750,16 +3002,16 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) if (!fatalerrs) return 1; SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, - ERR_R_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; } @@ -2793,3 +3045,118 @@ 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) { + ret->old_ctx = HMAC_CTX_new(); + if (ret->old_ctx == NULL) + goto err; + return ret; + } +#endif + mac = EVP_MAC_fetch(ctx->libctx, "HMAC", NULL); + 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 + HMAC_CTX_free(ctx->old_ctx); +#endif + OPENSSL_free(ctx); + } +} + +#ifndef OPENSSL_NO_DEPRECATED_3_0 +HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx) +{ + return ctx->old_ctx; +} +#endif + +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[3], *p = params; + + if (ctx->ctx != NULL) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key, len); + *p = OSSL_PARAM_construct_end(); + if (EVP_MAC_CTX_set_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx)) + return 1; + } +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return HMAC_Init_ex(ctx->old_ctx, key, len, + EVP_get_digestbyname(md), NULL); +#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 HMAC_Update(ctx->old_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) { + unsigned int l; + + if (HMAC_Final(ctx->old_ctx, md, &l) > 0) { + if (len != NULL) + *len = l; + return 1; + } + } +#endif + return 0; +} + +size_t ssl_hmac_size(const SSL_HMAC *ctx) +{ + if (ctx->ctx != NULL) + return EVP_MAC_size(ctx->ctx); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + if (ctx->old_ctx != NULL) + return HMAC_size(ctx->old_ctx); +#endif + return 0; +} +