X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=2e8de7a09cec6c1a809dbe41cacb3607eb3b183a;hb=c0638adeec58327f79d4bf549766f4cb094a1e2e;hp=d4c9086e5af1357a2fb3cfb1b65c1816bf97da1b;hpb=c589c34e619c8700ab16b152dd9c8ee58356b319;p=openssl.git diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index d4c9086e5a..2e8de7a09c 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -165,6 +165,7 @@ static const TLS_GROUP_INFO nid_list[] = { {NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */ {NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */ {EVP_PKEY_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */ + {EVP_PKEY_X448, 224, TLS_CURVE_CUSTOM}, /* X448 (30) */ }; static const unsigned char ecformats_default[] = { @@ -177,6 +178,7 @@ static const unsigned char ecformats_default[] = { static const uint16_t eccurves_default[] = { 29, /* X25519 (29) */ 23, /* secp256r1 (23) */ + 30, /* X448 (30) */ 25, /* secp521r1 (25) */ 24, /* secp384r1 (24) */ }; @@ -340,9 +342,11 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, * ids < 32 */ unsigned long dup_list = 0; - glist = OPENSSL_malloc(ngroups * sizeof(*glist)); - if (glist == NULL) + + 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; @@ -362,7 +366,7 @@ int tls1_set_groups(uint16_t **pext, size_t *pextlen, return 1; } -# define MAX_CURVELIST 28 +# define MAX_CURVELIST OSSL_NELEM(nid_list) typedef struct { size_t nidcnt; @@ -438,8 +442,11 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) 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; + /* + * 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)); @@ -465,7 +472,7 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) } /* Check a group id matches preferences */ -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; @@ -489,10 +496,12 @@ int tls1_check_group_id(SSL *s, uint16_t group_id) } } - /* 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; + 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; + } if (!tls_curve_allowed(s, group_id, SSL_SECOP_CURVE_CHECK)) return 0; @@ -552,7 +561,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 @@ -599,9 +612,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; } @@ -622,6 +635,7 @@ 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_pss_sha256, @@ -672,6 +686,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}, @@ -764,7 +781,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 */ @@ -972,7 +990,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) } if (!SSL_IS_TLS13(s)) { /* Check curve matches extensions */ - if (!tls1_check_group_id(s, tls1_get_group_id(pkey))) { + 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; @@ -1051,12 +1069,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) { @@ -1070,6 +1090,7 @@ void ssl_set_client_disabled(SSL *s) s->s3->tmp.mask_k |= SSL_kSRP; } #endif + return 1; } /* @@ -1178,15 +1199,6 @@ int tls1_set_server_sigalgs(SSL *s) * 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 @@ -1195,10 +1207,9 @@ int tls1_set_server_sigalgs(SSL *s) * 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_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, + SSL_SESSION **ret) { - int retv; size_t size; RAW_EXTENSION *ticketext; @@ -1211,11 +1222,11 @@ 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) { @@ -1224,7 +1235,7 @@ TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, * one. */ s->ext.ticket_expected = 1; - return TICKET_EMPTY; + return SSL_TICKET_EMPTY; } if (s->ext.session_secret_cb) { /* @@ -1233,26 +1244,11 @@ TICKET_RETURN tls_get_ticket_from_client(SSL *s, CLIENTHELLO_MSG *hello, * abbreviated handshake based on external mechanism to * calculate the master secret later. */ - return TICKET_NO_DECRYPT; + return SSL_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; - } } /*- @@ -1265,58 +1261,71 @@ 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_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_SESSION *sess; unsigned char *sdec; const unsigned char *p; int slen, renew_ticket = 0, declen; - TICKET_RETURN ret = TICKET_FATAL_ERR_OTHER; + SSL_TICKET_RETURN 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; + /* 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 @@ -1324,24 +1333,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 */ @@ -1350,18 +1362,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); @@ -1369,9 +1379,10 @@ 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; + ret = SSL_TICKET_NO_DECRYPT; + goto end; } /* * The session ID, if non-empty, is used by some clients to detect @@ -1379,24 +1390,54 @@ 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; + sess->session_id_length = sesslen; + } *psess = sess; 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); - return ret; + + /* + * If set, the decrypt_ticket_cb() is always called regardless of the + * return value determined above. The callback is responsible for checking + * |ret| before it performs any action + */ + if (s->session_ctx->decrypt_ticket_cb != NULL) { + size_t keyname_len = eticklen; + + if (keyname_len > TLSEXT_KEYNAME_LENGTH) + keyname_len = TLSEXT_KEYNAME_LENGTH; + ret = s->session_ctx->decrypt_ticket_cb(s, *psess, etick, keyname_len, + ret, + s->session_ctx->ticket_cb_data); + } + + switch (ret) { + case SSL_TICKET_NO_DECRYPT: + case SSL_TICKET_SUCCESS_RENEW: + case SSL_TICKET_EMPTY: + s->ext.ticket_expected = 1; + /* Fall through */ + case SSL_TICKET_SUCCESS: + case SSL_TICKET_NONE: + return ret; + } + + return SSL_TICKET_FATAL_ERR_OTHER; } /* Check to see if a signature algorithm is allowed */ @@ -1553,9 +1594,10 @@ static int tls1_set_shared_sigalgs(SSL *s) } 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; @@ -1579,9 +1621,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; @@ -1781,7 +1824,7 @@ static int sig_cb(const char *elem, int len, void *arg) /* Reject duplicates */ for (i = 0; i < sarg->sigalgcnt - 1; i++) { - if (sarg->sigalgs[i] == sarg->sigalgs[sarg->sigalgcnt]) { + if (sarg->sigalgs[i] == sarg->sigalgs[sarg->sigalgcnt - 1]) { sarg->sigalgcnt--; return 0; } @@ -1809,9 +1852,10 @@ int tls1_set_raw_sigalgs(CERT *c, const uint16_t *psigs, size_t salglen, { uint16_t *sigalgs; - sigalgs = OPENSSL_malloc(salglen * sizeof(*sigalgs)); - if (sigalgs == NULL) + 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) { @@ -1834,9 +1878,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; @@ -2171,6 +2216,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 */ @@ -2381,7 +2427,7 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) 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 */ @@ -2404,11 +2450,8 @@ int tls_choose_sigalg(SSL *s, int fatalerrs) 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;