X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=24702704db35820bf4aed33418f9b11bd6489a75;hp=6ca99949889c49ede6b5a6778a4a7a6f979e64a3;hb=84d4b9e31d5fd63408a0a43e02ec0780673362cf;hpb=b50951d36c329b07e1c92d41cc02c9085fb567d7 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 6ca9994988..24702704db 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * 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 @@ -121,151 +121,203 @@ 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) */ +# 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 curve_id) +const TLS_GROUP_INFO *tls1_group_id_lookup(uint16_t group_id) { - /* ECC curves from RFC 4492 and RFC 7027 */ - if (curve_id < 1 || curve_id > OSSL_NELEM(nid_list)) - return NULL; - return &nid_list[curve_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 i + 1; + return nid_list[i].group_id; } return 0; } +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ /* - * Get curves list, if "sess" is set return client curves otherwise - * preferred list. - * Sets |num_curves| to the number of curves in the list, i.e., - * the length of |pcurves| is num_curves. - * Returns 1 on success and 0 if the client curves list has invalid format. - * The latter indicates an internal error: we should not be accepting such - * lists in the first place. + * Set *pgroups to the supported groups list and *pgroupslen to + * the number of groups supported. */ -void tls1_get_grouplist(SSL *s, int sess, const uint16_t **pcurves, - size_t *pcurveslen) +void tls1_get_supported_groups(SSL *s, const uint16_t **pgroups, + size_t *pgroupslen) { - - if (sess) { - *pcurves = s->session->ext.supportedgroups; - *pcurveslen = s->session->ext.supportedgroups_len; - return; - } +#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: - *pcurves = suiteb_curves; - *pcurveslen = OSSL_NELEM(suiteb_curves); + *pgroups = suiteb_curves; + *pgroupslen = OSSL_NELEM(suiteb_curves); break; case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *pcurves = suiteb_curves; - *pcurveslen = 1; + *pgroups = suiteb_curves; + *pgroupslen = 1; break; case SSL_CERT_FLAG_SUITEB_192_LOS: - *pcurves = suiteb_curves + 1; - *pcurveslen = 1; + *pgroups = suiteb_curves + 1; + *pgroupslen = 1; break; +# endif default: if (s->ext.supportedgroups == NULL) { - *pcurves = eccurves_default; - *pcurveslen = OSSL_NELEM(eccurves_default); + *pgroups = supported_groups_default; + *pgroupslen = OSSL_NELEM(supported_groups_default); } else { - *pcurves = s->ext.supportedgroups; - *pcurveslen = s->ext.supportedgroups_len; + *pgroups = s->ext.supportedgroups; + *pgroupslen = s->ext.supportedgroups_len; } break; } +#else + *pgroups = NULL; + *pgroupslen = 0; +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ +} + +int tls_valid_group(SSL *s, uint16_t group_id, int version) +{ + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(group_id); + + if (version < TLS1_3_VERSION) { + if ((ginfo->flags & TLS_GROUP_ONLY_FOR_TLS1_3) != 0) + return 0; + } + return 1; } -/* See if curve is allowed by security callback */ -int tls_curve_allowed(SSL *s, uint16_t curve, int op) +/* See if group is allowed by security callback */ +int tls_group_allowed(SSL *s, uint16_t group, int op) { - const TLS_GROUP_INFO *cinfo = tls1_group_id_lookup(curve); - unsigned char ctmp[2]; + const TLS_GROUP_INFO *ginfo = tls1_group_id_lookup(group); + unsigned char gtmp[2]; - if (cinfo == NULL) + 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" */ @@ -278,34 +330,6 @@ static int tls1_in_list(uint16_t id, const uint16_t *list, size_t listlen) return 0; } -/* Check a curve is one of our preferences */ -int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) -{ - const uint16_t *curves; - size_t num_curves; - uint16_t curve_id; - - if (len != 3 || p[0] != NAMED_CURVE_TYPE) - return 0; - curve_id = (p[1] << 8) | p[2]; - /* Check curve matches Suite B preferences */ - if (tls1_suiteb(s)) { - unsigned long cid = s->s3->tmp.new_cipher->id; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { - if (curve_id != TLSEXT_curve_P_256) - return 0; - } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { - if (curve_id != TLSEXT_curve_P_384) - return 0; - } else /* Should never happen */ - return 0; - } - tls1_get_grouplist(s, 0, &curves, &num_curves); - if (!tls1_in_list(curve_id, curves, num_curves)) - return 0; - return tls_curve_allowed(s, curve_id, SSL_SECOP_CURVE_CHECK); -} - /*- * For nmatch >= 0, return the id of the |nmatch|th shared group or 0 * if there is no match. @@ -328,7 +352,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; @@ -341,21 +365,22 @@ uint16_t tls1_shared_group(SSL *s, int nmatch) nmatch = 0; } /* - * Avoid truncation. tls1_get_grouplist takes an int - * but s->options is a long... + * If server preference set, our groups are the preference order + * otherwise peer decides. */ - tls1_get_grouplist(s, - (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, - &supp, &num_supp); - tls1_get_grouplist(s, - (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0, - &pref, &num_pref); + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + tls1_get_supported_groups(s, &pref, &num_pref); + tls1_get_peer_groups(s, &supp, &num_supp); + } else { + tls1_get_peer_groups(s, &pref, &num_pref); + tls1_get_supported_groups(s, &supp, &num_supp); + } for (k = 0, i = 0; i < num_pref; i++) { 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; @@ -370,57 +395,75 @@ 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; - glist = OPENSSL_malloc(ngroups * sizeof(*glist)); - if (glist == NULL) + 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); + return 0; + } + if ((glist = OPENSSL_malloc(ngroups * sizeof(*glist))) == NULL) { + SSLerr(SSL_F_TLS1_SET_GROUPS, 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; +#else + return 0; +#endif /* !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH) */ } -# define MAX_CURVELIST 28 +#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) @@ -433,10 +476,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)) @@ -444,65 +489,13 @@ 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)) { - /* Compression not allowed in TLS 1.3 */ - return 0; - } 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_prime_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 */ -static int tls1_check_group_id(SSL *s, uint16_t group_id) +int tls1_check_group_id(SSL *s, uint16_t group_id, int check_own_groups) { const uint16_t *groups; size_t groups_len; @@ -510,12 +503,30 @@ static int tls1_check_group_id(SSL *s, uint16_t group_id) if (group_id == 0) return 0; - if (!tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) - 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 (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { + if (group_id != TLSEXT_curve_P_256) + return 0; + } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { + if (group_id != TLSEXT_curve_P_384) + return 0; + } else { + /* Should never happen */ + return 0; + } + } + + if (check_own_groups) { + /* Check group is one of our preferences */ + tls1_get_supported_groups(s, &groups, &groups_len); + if (!tls1_in_list(group_id, groups, groups_len)) + return 0; + } - /* Check group is one of our preferences */ - tls1_get_grouplist(s, 0, &groups, &groups_len); - if (!tls1_in_list(group_id, groups, groups_len)) + if (!tls_group_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) return 0; /* For clients, nothing more to check */ @@ -523,7 +534,7 @@ static int tls1_check_group_id(SSL *s, uint16_t group_id) return 1; /* Check group is one of peers preferences */ - tls1_get_grouplist(s, 1, &groups, &groups_len); + tls1_get_peer_groups(s, &groups, &groups_len); /* * RFC 4492 does not require the supported elliptic curves extension @@ -536,6 +547,7 @@ static int tls1_check_group_id(SSL *s, uint16_t group_id) 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) { @@ -555,6 +567,65 @@ 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_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->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) +{ + 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 cert parameters compatible with extensions: currently just checks EC * certificates have compatible curves and compression. @@ -573,7 +644,11 @@ static int tls1_check_cert_param(SSL *s, X509 *x, int check_ee_md) if (!tls1_check_pkey_comp(s, pkey)) return 0; group_id = tls1_get_group_id(pkey); - if (!tls1_check_group_id(s, group_id)) + /* + * For a server we allow the certificate to not be in our list of supported + * groups. + */ + if (!tls1_check_group_id(s, group_id, !s->server)) return 0; /* * Special case for suite B. We *MUST* sign using SHA256+P-256 or @@ -582,7 +657,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) @@ -591,8 +665,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; @@ -620,9 +694,9 @@ int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) * curves permitted. */ if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - return tls1_check_group_id(s, TLSEXT_curve_P_256); + return tls1_check_group_id(s, TLSEXT_curve_P_256, 1); if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - return tls1_check_group_id(s, TLSEXT_curve_P_384); + return tls1_check_group_id(s, TLSEXT_curve_P_384, 1); return 0; } @@ -643,11 +717,15 @@ static const uint16_t tls12_sigalgs[] = { TLSEXT_SIGALG_ecdsa_secp384r1_sha384, TLSEXT_SIGALG_ecdsa_secp521r1_sha512, TLSEXT_SIGALG_ed25519, + TLSEXT_SIGALG_ed448, #endif - TLSEXT_SIGALG_rsa_pss_sha256, - TLSEXT_SIGALG_rsa_pss_sha384, - TLSEXT_SIGALG_rsa_pss_sha512, + TLSEXT_SIGALG_rsa_pss_pss_sha256, + TLSEXT_SIGALG_rsa_pss_pss_sha384, + TLSEXT_SIGALG_rsa_pss_pss_sha512, + TLSEXT_SIGALG_rsa_pss_rsae_sha256, + TLSEXT_SIGALG_rsa_pss_rsae_sha384, + TLSEXT_SIGALG_rsa_pss_rsae_sha512, TLSEXT_SIGALG_rsa_pkcs1_sha256, TLSEXT_SIGALG_rsa_pkcs1_sha384, @@ -665,7 +743,12 @@ static const uint16_t tls12_sigalgs[] = { TLSEXT_SIGALG_dsa_sha256, TLSEXT_SIGALG_dsa_sha384, - TLSEXT_SIGALG_dsa_sha512 + TLSEXT_SIGALG_dsa_sha512, +#endif +#ifndef OPENSSL_NO_GOST + TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256, + TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512, + TLSEXT_SIGALG_gostr34102001_gostr3411, #endif }; @@ -690,6 +773,9 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { {"ed25519", TLSEXT_SIGALG_ed25519, NID_undef, -1, EVP_PKEY_ED25519, SSL_PKEY_ED25519, NID_undef, NID_undef}, + {"ed448", TLSEXT_SIGALG_ed448, + NID_undef, -1, EVP_PKEY_ED448, SSL_PKEY_ED448, + NID_undef, NID_undef}, {NULL, TLSEXT_SIGALG_ecdsa_sha224, NID_sha224, SSL_MD_SHA224_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA224, NID_undef}, @@ -697,13 +783,22 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { NID_sha1, SSL_MD_SHA1_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA1, NID_undef}, #endif - {"rsa_pss_sha256", TLSEXT_SIGALG_rsa_pss_sha256, + {"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}, + {"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}, + {"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}, + {"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}, - {"rsa_pss_sha384", TLSEXT_SIGALG_rsa_pss_sha384, + {"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}, - {"rsa_pss_sha512", TLSEXT_SIGALG_rsa_pss_sha512, + {"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}, {"rsa_pkcs1_sha256", TLSEXT_SIGALG_rsa_pkcs1_sha256, @@ -773,7 +868,8 @@ static const uint16_t tls_default_sigalg[] = { 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 */ - 0 /* SSL_PKEY_ED25519 */ + 0, /* SSL_PKEY_ED25519 */ + 0, /* SSL_PKEY_ED448 */ }; /* Lookup TLS signature algorithm */ @@ -808,6 +904,27 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd) return 1; } +/* + * Check if key is large enough to generate RSA-PSS signature. + * + * The key must greater than or equal to 2 * hash length + 2. + * 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) +{ + const EVP_MD *md; + + if (rsa == NULL) + return 0; + if (!tls1_lookup_md(lu, &md) || md == NULL) + return 0; + if (RSA_size(rsa) < 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. @@ -822,11 +939,26 @@ 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; } } + + /* + * Some GOST ciphersuites allow more than one signature algorithms + * */ + 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; + real_idx--) { + if (s->cert->pkeys[real_idx].privatekey != NULL) { + idx = real_idx; + break; + } + } + } } else { idx = s->cert->key - s->cert->pkeys; } @@ -853,7 +985,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; } @@ -895,6 +1027,39 @@ 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. + */ +int tls_check_sigalg_curve(const SSL *s, int curve) +{ + const uint16_t *sigs; + size_t siglen, i; + + if (s->cert->conf_sigalgs) { + sigs = s->cert->conf_sigalgs; + siglen = s->cert->conf_sigalgslen; + } else { + sigs = tls12_sigalgs; + siglen = OSSL_NELEM(tls12_sigalgs); + } + + for (i = 0; i < siglen; i++) { + const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(sigs[i]); + + if (lu == NULL) + continue; + if (lu->sig == EVP_PKEY_EC + && lu->curve != NID_undef + && curve == lu->curve) + return 1; + } + + return 0; +} +#endif + /* * Check signature algorithm is consistent with sent supported signature * algorithms and if so set relevant digest and signature scheme in @@ -905,7 +1070,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) const uint16_t *sent_sigs; const EVP_MD *md = NULL; char sigalgstr[2]; - size_t sent_sigslen, i; + size_t sent_sigslen, i, cidx; int pkeyid = EVP_PKEY_id(pkey); const SIGALG_LOOKUP *lu; @@ -915,7 +1080,8 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) if (SSL_IS_TLS13(s)) { /* Disallow DSA for TLS 1.3 */ if (pkeyid == EVP_PKEY_DSA) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_WRONG_SIGNATURE_TYPE); return 0; } /* Only allow PSS for TLS 1.3 */ @@ -931,16 +1097,26 @@ 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))) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, + 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) + || lu->sig_idx != (int)cidx) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS12_CHECK_PEER_SIGALG, + 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)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_ILLEGAL_POINT_COMPRESSION); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, + SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_ILLEGAL_POINT_COMPRESSION); return 0; } @@ -950,27 +1126,32 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) int curve = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); if (lu->curve != NID_undef && curve != lu->curve) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, + SSL_F_TLS12_CHECK_PEER_SIGALG, 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))) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + 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); return 0; } if (tls1_suiteb(s)) { /* Check sigalg matches a permissible Suite B value */ if (sig != TLSEXT_SIGALG_ecdsa_secp256r1_sha256 && sig != TLSEXT_SIGALG_ecdsa_secp384r1_sha384) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_WRONG_SIGNATURE_TYPE); + 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); return 0; } #endif @@ -984,12 +1165,14 @@ 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)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_WRONG_SIGNATURE_TYPE); return 0; } if (!tls1_lookup_md(lu, &md)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST); - return 0; + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_UNKNOWN_DIGEST); + return 0; } if (md != NULL) { /* @@ -1001,20 +1184,29 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) if (!ssl_security(s, SSL_SECOP_SIGALG_CHECK, EVP_MD_size(md) * 4, EVP_MD_type(md), (void *)sigalgstr)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); + 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; + return 1; +} + +int SSL_get_signature_type_nid(const SSL *s, int *pnid) +{ + if (s->s3.tmp.sigalg == NULL) return 0; - *pnid = s->s3->tmp.peer_sigalg->sig; + *pnid = s->s3.tmp.sigalg->sig; return 1; } @@ -1028,25 +1220,28 @@ int SSL_get_peer_signature_type_nid(const SSL *s, int *pnid) * * Call ssl_cipher_disabled() to check that it's enabled or not. */ -void ssl_set_client_disabled(SSL *s) +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); - ssl_get_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver); + 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; } /* @@ -1060,10 +1255,10 @@ void ssl_set_client_disabled(SSL *s) */ int ssl_cipher_disabled(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; @@ -1076,11 +1271,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); @@ -1095,21 +1290,21 @@ int tls_use_ticket(SSL *s) int tls1_set_server_sigalgs(SSL *s) { - int al; 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_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); @@ -1122,7 +1317,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; } } @@ -1131,17 +1326,16 @@ int tls1_set_server_sigalgs(SSL *s) } if (!tls1_process_sigalgs(s)) { - SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE); - al = SSL_AD_INTERNAL_ERROR; - goto err; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + 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 */ - SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS); - al = SSL_AD_HANDSHAKE_FAILURE; - err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS1_SET_SERVER_SIGALGS, + SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS); return 0; } @@ -1151,32 +1345,10 @@ int tls1_set_server_sigalgs(SSL *s) * hello: The parsed ClientHello data * ret: (output) on return, if a ticket was decrypted, then this is set to * point to the resulting session. - * - * If s->tls_session_secret_cb is set then we are expecting a pre-shared key - * ciphersuite, in which case we have no use for session tickets and one will - * never be decrypted, nor will s->ext.ticket_expected be set to 1. - * - * Returns: - * -1: fatal error, either from parsing or decrypting the ticket. - * 0: no ticket was found (or was ignored, based on settings). - * 1: a zero length extension was found, indicating that the client supports - * session tickets but doesn't currently have one to offer. - * 2: either s->tls_session_secret_cb was set, or a ticket was offered but - * couldn't be decrypted because of a non-fatal error. - * 3: a ticket was successfully decrypted and *ret was set. - * - * Side effects: - * Sets s->ext.ticket_expected to 1 if the server will have to issue - * a new session ticket to the client because the client indicated support - * (and s->tls_session_secret_cb is NULL) but the client either doesn't have - * a session ticket or we couldn't use the one it gave us, or if - * s->ctx->ext.ticket_key_cb asked to renew the client's ticket. - * Otherwise, s->ext.ticket_expected is set to 0. */ -TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, - SSL_SESSION **ret) +SSL_TICKET_STATUS tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, + SSL_SESSION **ret) { - int retv; size_t size; RAW_EXTENSION *ticketext; @@ -1189,53 +1361,34 @@ TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, * resumption. */ if (s->version <= SSL3_VERSION || !tls_use_ticket(s)) - return TICKET_NONE; + return SSL_TICKET_NONE; ticketext = &hello->pre_proc_exts[TLSEXT_IDX_session_ticket]; if (!ticketext->present) - return TICKET_NONE; + return SSL_TICKET_NONE; size = PACKET_remaining(&ticketext->data); - if (size == 0) { - /* - * The client will accept a ticket but doesn't currently have - * one. - */ - s->ext.ticket_expected = 1; - return TICKET_EMPTY; - } - if (s->ext.session_secret_cb) { - /* - * Indicate that the ticket couldn't be decrypted rather than - * generating the session from ticket now, trigger - * abbreviated handshake based on external mechanism to - * calculate the master secret later. - */ - return TICKET_NO_DECRYPT; - } - retv = tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size, + return tls_decrypt_ticket(s, PACKET_data(&ticketext->data), size, hello->session_id, hello->session_id_len, ret); - switch (retv) { - case TICKET_NO_DECRYPT: - s->ext.ticket_expected = 1; - return TICKET_NO_DECRYPT; - - case TICKET_SUCCESS: - return TICKET_SUCCESS; - - case TICKET_SUCCESS_RENEW: - s->ext.ticket_expected = 1; - return TICKET_SUCCESS; - - default: - return TICKET_FATAL_ERR_OTHER; - } } /*- * tls_decrypt_ticket attempts to decrypt a session ticket. * + * If s->tls_session_secret_cb is set and we're not doing TLSv1.3 then we are + * expecting a pre-shared key ciphersuite, in which case we have no use for + * session tickets and one will never be decrypted, nor will + * s->ext.ticket_expected be set to 1. + * + * Side effects: + * Sets s->ext.ticket_expected to 1 if the server will have to issue + * a new session ticket to the client because the client indicated support + * (and s->tls_session_secret_cb is NULL) but the client either doesn't have + * a session ticket or we couldn't use the one it gave us, or if + * s->ctx->ext.ticket_key_cb asked to renew the client's ticket. + * Otherwise, s->ext.ticket_expected is set to 0. + * * etick: points to the body of the session ticket extension. * eticklen: the length of the session tickets extension. * sess_id: points at the session ID. @@ -1243,58 +1396,90 @@ TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, * psess: (output) on return, if a ticket was decrypted, then this is set to * point to the resulting session. */ -TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, - size_t eticklen, const unsigned char *sess_id, - size_t sesslen, SSL_SESSION **psess) +SSL_TICKET_STATUS tls_decrypt_ticket(SSL *s, const unsigned char *etick, + size_t eticklen, const unsigned char *sess_id, + size_t sesslen, SSL_SESSION **psess) { - SSL_SESSION *sess; + SSL_SESSION *sess = NULL; unsigned char *sdec; const unsigned char *p; int slen, renew_ticket = 0, declen; - TICKET_RETURN ret = TICKET_FATAL_ERR_OTHER; + SSL_TICKET_STATUS ret = SSL_TICKET_FATAL_ERR_OTHER; size_t mlen; unsigned char tick_hmac[EVP_MAX_MD_SIZE]; HMAC_CTX *hctx = NULL; - EVP_CIPHER_CTX *ctx; + EVP_CIPHER_CTX *ctx = NULL; SSL_CTX *tctx = s->session_ctx; + if (eticklen == 0) { + /* + * The client will accept a ticket but doesn't currently have + * one (TLSv1.2 and below), or treated as a fatal error in TLSv1.3 + */ + ret = SSL_TICKET_EMPTY; + goto end; + } + if (!SSL_IS_TLS13(s) && s->ext.session_secret_cb) { + /* + * Indicate that the ticket couldn't be decrypted rather than + * generating the session from ticket now, trigger + * abbreviated handshake based on external mechanism to + * calculate the master secret later. + */ + ret = SSL_TICKET_NO_DECRYPT; + goto end; + } + + /* Need at least keyname + iv */ + if (eticklen < TLSEXT_KEYNAME_LENGTH + EVP_MAX_IV_LENGTH) { + ret = SSL_TICKET_NO_DECRYPT; + goto end; + } + /* Initialize session ticket encryption and HMAC contexts */ hctx = HMAC_CTX_new(); - if (hctx == NULL) - return TICKET_FATAL_ERR_MALLOC; + if (hctx == NULL) { + ret = SSL_TICKET_FATAL_ERR_MALLOC; + goto end; + } ctx = EVP_CIPHER_CTX_new(); if (ctx == NULL) { - ret = TICKET_FATAL_ERR_MALLOC; - goto err; + ret = SSL_TICKET_FATAL_ERR_MALLOC; + goto end; } if (tctx->ext.ticket_key_cb) { unsigned char *nctick = (unsigned char *)etick; - int rv = tctx->ext.ticket_key_cb(s, nctick, nctick + 16, - ctx, hctx, 0); - if (rv < 0) - goto err; + int rv = tctx->ext.ticket_key_cb(s, nctick, + nctick + TLSEXT_KEYNAME_LENGTH, + ctx, hctx, 0); + if (rv < 0) { + ret = SSL_TICKET_FATAL_ERR_OTHER; + goto end; + } if (rv == 0) { - ret = TICKET_NO_DECRYPT; - goto err; + ret = SSL_TICKET_NO_DECRYPT; + goto end; } if (rv == 2) renew_ticket = 1; } else { /* Check key name matches */ if (memcmp(etick, tctx->ext.tick_key_name, - sizeof(tctx->ext.tick_key_name)) != 0) { - ret = TICKET_NO_DECRYPT; - goto err; + TLSEXT_KEYNAME_LENGTH) != 0) { + ret = SSL_TICKET_NO_DECRYPT; + goto end; } - if (HMAC_Init_ex(hctx, tctx->ext.tick_hmac_key, - sizeof(tctx->ext.tick_hmac_key), + 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, - tctx->ext.tick_aes_key, - etick - + sizeof(tctx->ext.tick_key_name)) <= 0) { - goto err; + tctx->ext.secure->tick_aes_key, + etick + TLSEXT_KEYNAME_LENGTH) <= 0) { + ret = SSL_TICKET_FATAL_ERR_OTHER; + goto end; } + if (SSL_IS_TLS13(s)) + renew_ticket = 1; } /* * Attempt to process session ticket, first conduct sanity and integrity @@ -1302,24 +1487,27 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, */ mlen = HMAC_size(hctx); if (mlen == 0) { - goto err; + 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) { - ret = TICKET_NO_DECRYPT; - goto err; + 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) { - goto err; + ret = SSL_TICKET_FATAL_ERR_OTHER; + goto end; } - HMAC_CTX_free(hctx); + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { - EVP_CIPHER_CTX_free(ctx); - return TICKET_NO_DECRYPT; + ret = SSL_TICKET_NO_DECRYPT; + goto end; } /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ @@ -1328,18 +1516,16 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, sdec = OPENSSL_malloc(eticklen); if (sdec == NULL || EVP_DecryptUpdate(ctx, sdec, &slen, p, (int)eticklen) <= 0) { - EVP_CIPHER_CTX_free(ctx); OPENSSL_free(sdec); - return TICKET_FATAL_ERR_OTHER; + ret = SSL_TICKET_FATAL_ERR_OTHER; + goto end; } if (EVP_DecryptFinal(ctx, sdec + slen, &declen) <= 0) { - EVP_CIPHER_CTX_free(ctx); OPENSSL_free(sdec); - return TICKET_NO_DECRYPT; + ret = SSL_TICKET_NO_DECRYPT; + goto end; } slen += declen; - EVP_CIPHER_CTX_free(ctx); - ctx = NULL; p = sdec; sess = d2i_SSL_SESSION(NULL, &p, slen); @@ -1347,9 +1533,11 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, OPENSSL_free(sdec); if (sess) { /* Some additional consistency checks */ - if (slen != 0 || sess->session_id_length != 0) { + if (slen != 0) { SSL_SESSION_free(sess); - return TICKET_NO_DECRYPT; + sess = NULL; + ret = SSL_TICKET_NO_DECRYPT; + goto end; } /* * The session ID, if non-empty, is used by some clients to detect @@ -1357,23 +1545,90 @@ TICKET_RETURN tls_decrypt_ticket(SSL *s, const unsigned char *etick, * structure. If it is empty set length to zero as required by * standard. */ - if (sesslen) + if (sesslen) { memcpy(sess->session_id, sess_id, sesslen); - sess->session_id_length = sesslen; - *psess = sess; + sess->session_id_length = sesslen; + } if (renew_ticket) - return TICKET_SUCCESS_RENEW; + ret = SSL_TICKET_SUCCESS_RENEW; else - return TICKET_SUCCESS; + ret = SSL_TICKET_SUCCESS; + goto end; } ERR_clear_error(); /* * For session parse failure, indicate that we need to send a new ticket. */ - return TICKET_NO_DECRYPT; - err: + ret = SSL_TICKET_NO_DECRYPT; + + end: EVP_CIPHER_CTX_free(ctx); HMAC_CTX_free(hctx); + + /* + * If set, the decrypt_ticket_cb() is called unless a fatal error was + * detected above. The callback is responsible for checking |ret| before it + * performs any action + */ + if (s->session_ctx->decrypt_ticket_cb != NULL + && (ret == SSL_TICKET_EMPTY + || ret == SSL_TICKET_NO_DECRYPT + || ret == SSL_TICKET_SUCCESS + || ret == SSL_TICKET_SUCCESS_RENEW)) { + size_t keyname_len = eticklen; + int retcb; + + if (keyname_len > TLSEXT_KEYNAME_LENGTH) + keyname_len = TLSEXT_KEYNAME_LENGTH; + retcb = s->session_ctx->decrypt_ticket_cb(s, sess, etick, keyname_len, + ret, + s->session_ctx->ticket_cb_data); + switch (retcb) { + case SSL_TICKET_RETURN_ABORT: + ret = SSL_TICKET_FATAL_ERR_OTHER; + break; + + case SSL_TICKET_RETURN_IGNORE: + ret = SSL_TICKET_NONE; + SSL_SESSION_free(sess); + sess = NULL; + break; + + case SSL_TICKET_RETURN_IGNORE_RENEW: + if (ret != SSL_TICKET_EMPTY && ret != SSL_TICKET_NO_DECRYPT) + ret = SSL_TICKET_NO_DECRYPT; + /* else the value of |ret| will already do the right thing */ + SSL_SESSION_free(sess); + sess = NULL; + break; + + case SSL_TICKET_RETURN_USE: + case SSL_TICKET_RETURN_USE_RENEW: + if (ret != SSL_TICKET_SUCCESS + && ret != SSL_TICKET_SUCCESS_RENEW) + ret = SSL_TICKET_FATAL_ERR_OTHER; + else if (retcb == SSL_TICKET_RETURN_USE) + ret = SSL_TICKET_SUCCESS; + else + ret = SSL_TICKET_SUCCESS_RENEW; + break; + + default: + ret = SSL_TICKET_FATAL_ERR_OTHER; + } + } + + if (s->ext.session_secret_cb == NULL || SSL_IS_TLS13(s)) { + switch (ret) { + case SSL_TICKET_NO_DECRYPT: + case SSL_TICKET_SUCCESS_RENEW: + case SSL_TICKET_EMPTY: + s->ext.ticket_expected = 1; + } + } + + *psess = sess; + return ret; } @@ -1390,14 +1645,55 @@ static int tls12_sigalg_allowed(SSL *s, int op, const SIGALG_LOOKUP *lu) 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)) return 0; + /* See if public key algorithm allowed */ if (ssl_cert_is_disabled(lu->sig_idx)) return 0; + + if (lu->sig == NID_id_GostR3410_2012_256 + || lu->sig == NID_id_GostR3410_2012_512 + || lu->sig == NID_id_GostR3410_2001) { + /* We never allow GOST sig algs on the server with TLSv1.3 */ + if (s->server && SSL_IS_TLS13(s)) + return 0; + if (!s->server + && s->method->version == TLS_ANY_VERSION + && s->s3.tmp.max_ver >= TLS1_3_VERSION) { + int i, num; + STACK_OF(SSL_CIPHER) *sk; + + /* + * We're a client that could negotiate TLSv1.3. We only allow GOST + * sig algs if we could negotiate TLSv1.2 or below and we have GOST + * ciphersuites enabled. + */ + + if (s->s3.tmp.min_ver >= TLS1_3_VERSION) + return 0; + + sk = SSL_get_ciphers(s); + num = sk != NULL ? sk_SSL_CIPHER_num(sk) : 0; + for (i = 0; i < num; i++) { + const SSL_CIPHER *c; + + c = sk_SSL_CIPHER_value(sk, i); + /* Skip disabled ciphers */ + if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) + continue; + + if ((c->algorithm_mkey & SSL_kGOST) != 0) + break; + } + if (i == num) + return 0; + } + } + if (lu->hash == NID_undef) return 1; /* Security bits: half digest bits */ @@ -1424,7 +1720,7 @@ void ssl_set_sig_mask(uint32_t *pmask_a, SSL *s, int op) * in disabled_mask. */ sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); - for (i = 0; i < sigalgslen; i ++, sigalgs++) { + for (i = 0; i < sigalgslen; i++, sigalgs++) { const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(*sigalgs); const SSL_CERT_LOOKUP *clu; @@ -1432,6 +1728,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 algorithm is disabled see if we can enable it */ if ((clu->amask & disabled_mask) != 0 @@ -1504,9 +1802,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; @@ -1519,25 +1817,26 @@ 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) { - salgs = OPENSSL_malloc(nmatch * sizeof(*salgs)); - if (salgs == NULL) + if ((salgs = OPENSSL_malloc(nmatch * sizeof(*salgs))) == NULL) { + SSLerr(SSL_F_TLS1_SET_SHARED_SIGALGS, ERR_R_MALLOC_FAILURE); return 0; + } nmatch = tls12_shared_sigalgs(s, salgs, pref, preflen, allow, allowlen); } else { salgs = NULL; } - c->shared_sigalgs = salgs; - c->shared_sigalgslen = nmatch; + s->shared_sigalgs = salgs; + s->shared_sigalgslen = nmatch; return 1; } @@ -1555,9 +1854,10 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen) size >>= 1; - buf = OPENSSL_malloc(size * sizeof(*buf)); - if (buf == NULL) + if ((buf = OPENSSL_malloc(size * sizeof(*buf))) == NULL) { + SSLerr(SSL_F_TLS1_SAVE_U16, ERR_R_MALLOC_FAILURE); return 0; + } for (i = 0; i < size && PACKET_get_net_2(pkt, &stmp); i++) buf[i] = stmp; @@ -1573,7 +1873,7 @@ int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen) return 1; } -int tls1_save_sigalgs(SSL *s, PACKET *pkt) +int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert) { /* Extension ignored for inappropriate versions */ if (!SSL_USE_SIGALGS(s)) @@ -1582,10 +1882,13 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt) if (s->cert == NULL) return 0; - return tls1_save_u16(pkt, &s->s3->tmp.peer_sigalgs, - &s->s3->tmp.peer_sigalgslen); + if (cert) + 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 1; } /* Set preferred digest for each key type */ @@ -1593,8 +1896,7 @@ int tls1_save_sigalgs(SSL *s, PACKET *pkt) 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; @@ -1602,8 +1904,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 */ @@ -1620,8 +1922,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) { @@ -1650,12 +1952,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) @@ -1666,7 +1968,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 */ @@ -1674,7 +1976,8 @@ int SSL_get_shared_sigalgs(SSL *s, int idx, typedef struct { size_t sigalgcnt; - int sigalgs[TLS_MAX_SIGALGCNT]; + /* TLSEXT_SIGALG_XXX values */ + uint16_t sigalgs[TLS_MAX_SIGALGCNT]; } sig_cb_st; static void get_sigorhash(int *psig, int *phash, const char *str) @@ -1700,6 +2003,7 @@ static int sig_cb(const char *elem, int len, void *arg) { sig_cb_st *sarg = arg; size_t i; + const SIGALG_LOOKUP *s; char etmp[TLS_MAX_SIGSTRING_LEN], *p; int sig_alg = NID_undef, hash_alg = NID_undef; if (elem == NULL) @@ -1711,18 +2015,25 @@ static int sig_cb(const char *elem, int len, void *arg) memcpy(etmp, elem, len); etmp[len] = 0; p = strchr(etmp, '+'); - /* See if we have a match for TLS 1.3 names */ + /* + * We only allow SignatureSchemes listed in the sigalg_lookup_tbl; + * if there's no '+' in the provided name, look for the new-style combined + * name. If not, match both sig+hash to find the needed SIGALG_LOOKUP. + * Just sig+hash is not unique since TLS 1.3 adds rsa_pss_pss_* and + * rsa_pss_rsae_* that differ only by public key OID; in such cases + * we will pick the _rsae_ variant, by virtue of them appearing earlier + * in the table. + */ if (p == NULL) { - const SIGALG_LOOKUP *s; - for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); i++, s++) { if (s->name != NULL && strcmp(etmp, s->name) == 0) { - sig_alg = s->sig; - hash_alg = s->hash; + sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg; break; } } + if (i == OSSL_NELEM(sigalg_lookup_tbl)) + return 0; } else { *p = 0; p++; @@ -1730,17 +2041,26 @@ static int sig_cb(const char *elem, int len, void *arg) return 0; get_sigorhash(&sig_alg, &hash_alg, etmp); get_sigorhash(&sig_alg, &hash_alg, p); + if (sig_alg == NID_undef || hash_alg == NID_undef) + return 0; + for (i = 0, s = sigalg_lookup_tbl; i < OSSL_NELEM(sigalg_lookup_tbl); + i++, s++) { + if (s->hash == hash_alg && s->sig == sig_alg) { + sarg->sigalgs[sarg->sigalgcnt++] = s->sigalg; + break; + } + } + if (i == OSSL_NELEM(sigalg_lookup_tbl)) + return 0; } - if (sig_alg == NID_undef || (p != NULL && hash_alg == NID_undef)) - return 0; - - for (i = 0; i < sarg->sigalgcnt; i += 2) { - if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg) + /* Reject duplicates */ + for (i = 0; i < sarg->sigalgcnt - 1; i++) { + if (sarg->sigalgs[i] == sarg->sigalgs[sarg->sigalgcnt - 1]) { + sarg->sigalgcnt--; return 0; + } } - sarg->sigalgs[sarg->sigalgcnt++] = hash_alg; - sarg->sigalgs[sarg->sigalgcnt++] = sig_alg; return 1; } @@ -1756,7 +2076,31 @@ int tls1_set_sigalgs_list(CERT *c, const char *str, int client) return 0; if (c == NULL) return 1; - return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); + return tls1_set_raw_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); +} + +int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, + int client) +{ + uint16_t *sigalgs; + + if ((sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs))) == NULL) { + SSLerr(SSL_F_TLS1_SET_RAW_SIGALGS, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(sigalgs, psigs, salglen * sizeof(*sigalgs)); + + if (client) { + OPENSSL_free(c->client_sigalgs); + c->client_sigalgs = sigalgs; + c->client_sigalgslen = salglen; + } else { + OPENSSL_free(c->conf_sigalgs); + c->conf_sigalgs = sigalgs; + c->conf_sigalgslen = salglen; + } + + return 1; } int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) @@ -1766,9 +2110,10 @@ int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, int client) if (salglen & 1) return 0; - sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs)); - if (sigalgs == NULL) + if ((sigalgs = OPENSSL_malloc((salglen / 2) * sizeof(*sigalgs))) == NULL) { + SSLerr(SSL_F_TLS1_SET_SIGALGS, ERR_R_MALLOC_FAILURE); return 0; + } for (i = 0, sptr = sigalgs; i < salglen; i += 2) { size_t j; const SIGALG_LOOKUP *curr; @@ -1804,7 +2149,7 @@ 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; size_t i; @@ -1813,8 +2158,8 @@ static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) 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) + for (i = 0; i < s->shared_sigalgslen; i++) + if (sig_nid == s->shared_sigalgs[i]->sigandhash) return 1; return 0; } @@ -1866,7 +2211,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; @@ -1883,7 +2228,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; @@ -1910,10 +2255,11 @@ 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_sigalgs) + 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 { + } else { switch (idx) { case SSL_PKEY_RSA: rsign = EVP_PKEY_RSA; @@ -1971,14 +2317,14 @@ 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 (!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; @@ -2027,10 +2373,10 @@ int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, 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; @@ -2042,7 +2388,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; @@ -2102,6 +2448,7 @@ void tls1_set_cert_validity(SSL *s) tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_256); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_GOST12_512); tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED25519); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ED448); } /* User level utility function to check a chain is suitable */ @@ -2116,15 +2463,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) { @@ -2133,13 +2480,16 @@ DH *ssl_get_auto_dh(SSL *s) if (dhp == NULL) return NULL; g = BN_new(); - if (g != NULL) - BN_set_word(g, 2); + if (g == NULL || !BN_set_word(g, 2)) { + DH_free(dhp); + BN_free(g); + return NULL; + } if (dh_secbits >= 192) p = BN_get_rfc3526_prime_8192(NULL); else p = BN_get_rfc3526_prime_3072(NULL); - if (p == NULL || g == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { + if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { DH_free(dhp); BN_free(p); BN_free(g); @@ -2245,44 +2595,103 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) const SSL_CERT_LOOKUP *clu = ssl_cert_lookup_by_idx(sig_idx); /* 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)) + if (clu == NULL + || (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)) return -1; - /* If PSS and we have no PSS cert use RSA */ - if (sig_idx == SSL_PKEY_RSA_PSS_SIGN && !ssl_has_cert(s, sig_idx)) - sig_idx = SSL_PKEY_RSA; + return s->s3.tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; +} + +/* + * Returns true if |s| has a usable certificate configured for use + * with signature scheme |sig|. + * "Usable" includes a check for presence as well as applying + * the signature_algorithm_cert restrictions sent by the peer (if any). + * Returns false if no usable certificate is found. + */ +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. */ + 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; - return s->s3->tmp.valid_flags[sig_idx] & CERT_PKEY_VALID ? sig_idx : -1; + ERR_set_mark(); + supported = EVP_PKEY_supports_digest_nid(s->cert->pkeys[idx].privatekey, + mdnid); + if (supported == 0) + 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; + } + 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; } /* * Choose an appropriate signature algorithm based on available certificates * Sets chosen certificate and signature algorithm. * - * For servers if we fail to find a required certificate it is a fatal error - * and an appropriate error code is set and the TLS alert set in *al. + * For servers if we fail to find a required certificate it is a fatal error, + * an appropriate error code is set and a TLS alert is sent. * - * For clients al is set to NULL. If a certificate is not suitable it is not + * For clients fatalerrs is set to 0. If a certificate is not suitable it is not * a fatal error: we will either try another certificate or not present one * to the server. In this case no error is set. */ -int tls_choose_sigalg(SSL *s, int *al) +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, skip_ec = 0; + 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]; + for (i = 0; i < s->shared_sigalgslen; i++) { + lu = s->shared_sigalgs[i]; + sig_idx = -1; /* Skip SHA1, SHA224, DSA and RSA if not PSS */ if (lu->hash == NID_sha1 @@ -2290,50 +2699,48 @@ int tls_choose_sigalg(SSL *s, int *al) || lu->sig == EVP_PKEY_DSA || lu->sig == EVP_PKEY_RSA) continue; - if (!tls1_lookup_md(lu, NULL)) + /* Check that we have a cert, and signature_algorithms_cert */ + if (!tls1_lookup_md(lu, NULL) || !has_usable_cert(s, lu, -1)) continue; - if (!ssl_has_cert(s, lu->sig_idx)) { - if (lu->sig_idx != SSL_PKEY_RSA_PSS_SIGN - || !ssl_has_cert(s, SSL_PKEY_RSA)) - continue; - sig_idx = SSL_PKEY_RSA; - } 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 (EC_KEY_get_conv_form(ec) - != POINT_CONVERSION_UNCOMPRESSED) - skip_ec = 1; } - if (skip_ec || (lu->curve != NID_undef && curve != lu->curve)) + 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) { - if (al == NULL) + if (i == s->shared_sigalgslen) { + if (!fatalerrs) return 1; - *al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_TLS_CHOOSE_SIGALG, - SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CHOOSE_SIGALG, + 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)) { - if (s->s3->tmp.peer_sigalgs != NULL) { - size_t i; + size_t i; + if (s->s3.tmp.peer_sigalgs != NULL) { #ifndef OPENSSL_NO_EC int curve; @@ -2350,8 +2757,8 @@ int tls_choose_sigalg(SSL *s, int *al) * 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) @@ -2360,23 +2767,30 @@ int tls_choose_sigalg(SSL *s, int *al) int cc_idx = s->cert->key - s->cert->pkeys; sig_idx = lu->sig_idx; - if (cc_idx != sig_idx) { - if (sig_idx != SSL_PKEY_RSA_PSS_SIGN - || cc_idx != SSL_PKEY_RSA) - continue; - sig_idx = SSL_PKEY_RSA; - } + if (cc_idx != sig_idx) + continue; + } + /* Check that we have a cert, and sig_algs_cert */ + if (!has_usable_cert(s, lu, sig_idx)) + continue; + if (lu->sig == EVP_PKEY_RSA_PSS) { + /* 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)) + continue; } #ifndef OPENSSL_NO_EC if (curve == -1 || lu->curve == curve) #endif break; } - if (i == s->cert->shared_sigalgslen) { - if (al == NULL) + if (i == s->shared_sigalgslen) { + if (!fatalerrs) return 1; - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + SSL_F_TLS_CHOOSE_SIGALG, + SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM); return 0; } } else { @@ -2384,44 +2798,77 @@ int tls_choose_sigalg(SSL *s, int *al) * If we have no sigalg use defaults */ const uint16_t *sent_sigs; - size_t sent_sigslen, i; + size_t sent_sigslen; if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { - if (al == NULL) + if (!fatalerrs) return 1; - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, + ERR_R_INTERNAL_ERROR); return 0; } /* Check signature matches a type we sent */ sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); for (i = 0; i < sent_sigslen; i++, sent_sigs++) { - if (lu->sigalg == *sent_sigs) + if (lu->sigalg == *sent_sigs + && has_usable_cert(s, lu, lu->sig_idx)) break; } if (i == sent_sigslen) { - if (al == NULL) + if (!fatalerrs) return 1; - SSLerr(SSL_F_TLS_CHOOSE_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); - *al = SSL_AD_ILLEGAL_PARAMETER; + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, + SSL_F_TLS_CHOOSE_SIGALG, + SSL_R_WRONG_SIGNATURE_TYPE); return 0; } } } else { if ((lu = tls1_get_legacy_sigalg(s, -1)) == NULL) { - if (al == NULL) + if (!fatalerrs) return 1; - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_CHOOSE_SIGALG, ERR_R_INTERNAL_ERROR); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CHOOSE_SIGALG, + ERR_R_INTERNAL_ERROR); 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; } + +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); + return 0; + } + + ctx->ext.max_fragment_len_mode = mode; + return 1; +} + +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); + return 0; + } + + ssl->ext.max_fragment_len_mode = mode; + return 1; +} + +uint8_t SSL_SESSION_get_max_fragment_length(const SSL_SESSION *session) +{ + return session->ext.max_fragment_len_mode; +}