X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=3965be9d907b83a3d5920ae0c53edc4e20cfc065;hp=28b25e122f511485826b80a62fe595b9673708c4;hb=1d0c08b4963f5f7e1d1855e360417a11973d8455;hpb=b2555168ecf6e88ad9aeb0ad4f7b7a714901d575 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 28b25e122f..3965be9d90 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -1,5 +1,5 @@ /* - * 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 * this file except in compliance with the License. You can obtain a copy @@ -199,7 +199,7 @@ 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 (uint16_t)(i + 1); } return 0; } @@ -624,9 +624,12 @@ static const uint16_t tls12_sigalgs[] = { TLSEXT_SIGALG_ed25519, #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, @@ -676,13 +679,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, @@ -787,6 +799,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. @@ -894,7 +927,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 */ @@ -910,7 +944,8 @@ 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; } #ifndef OPENSSL_NO_EC @@ -918,8 +953,9 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) /* 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; } @@ -929,27 +965,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); + 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 @@ -963,12 +1004,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) { /* @@ -980,7 +1023,8 @@ 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; } } @@ -1007,12 +1051,14 @@ 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); + if (ssl_get_min_max_version(s, &s->s3->tmp.min_ver, + &s->s3->tmp.max_ver) != 0) + return 0; #ifndef OPENSSL_NO_PSK /* with PSK there must be client callback set */ if (!s->psk_client_callback) { @@ -1026,6 +1072,7 @@ void ssl_set_client_disabled(SSL *s) s->s3->tmp.mask_k |= SSL_kSRP; } #endif + return 1; } /* @@ -1074,7 +1121,6 @@ int tls_use_ticket(SSL *s) int tls1_set_server_sigalgs(SSL *s) { - int al; size_t i; /* Clear any shared signature algorithms */ @@ -1088,7 +1134,8 @@ int tls1_set_server_sigalgs(SSL *s) * 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); @@ -1110,17 +1157,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) 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; } @@ -1554,7 +1600,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)) @@ -1563,10 +1609,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 */ @@ -1655,7 +1704,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) @@ -1681,6 +1731,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) @@ -1692,18 +1743,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++; @@ -1711,17 +1769,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; } @@ -1737,7 +1804,30 @@ 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; + + sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs)); + if (sigalgs == NULL) + 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) @@ -1891,10 +1981,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; @@ -2229,25 +2320,60 @@ static int tls12_get_cert_sigalg_idx(const SSL *s, const SIGALG_LOOKUP *lu) if (clu == NULL || !(clu->amask & s->s3->tmp.new_cipher->algorithm_auth)) 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; + 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)) + 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; + } + 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; @@ -2264,6 +2390,7 @@ int tls_choose_sigalg(SSL *s, int *al) /* 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 @@ -2271,14 +2398,9 @@ 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) { @@ -2294,15 +2416,21 @@ int tls_choose_sigalg(SSL *s, int *al) #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 (!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 { @@ -2313,8 +2441,8 @@ int tls_choose_sigalg(SSL *s, int *al) return 1; if (SSL_USE_SIGALGS(s)) { + size_t i; if (s->s3->tmp.peer_sigalgs != NULL) { - size_t i; #ifndef OPENSSL_NO_EC int curve; @@ -2341,12 +2469,18 @@ 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) @@ -2354,10 +2488,10 @@ int tls_choose_sigalg(SSL *s, int *al) break; } if (i == s->cert->shared_sigalgslen) { - 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; } } else { @@ -2365,36 +2499,38 @@ 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; } } @@ -2406,3 +2542,34 @@ int tls_choose_sigalg(SSL *s, int *al) 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; +}