X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=ssl%2Fstatem%2Fstatem_clnt.c;h=5341a89dfc0aded01c158a1f7c45b755154dd122;hb=d204a50b898435fbf937316d5693008cebf62eef;hp=83862e076d0b950eb696edde4944c646bc827304;hpb=3bc0b621a7baf1a11bc5cad69a287ad093674d68;p=openssl.git diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 83862e076d..5341a89dfc 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "internal/cryptlib.h" static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, PACKET *pkt); static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt); @@ -168,7 +168,8 @@ static int ossl_statem_client13_read_transition(SSL *s, int mt) } if (mt == SSL3_MT_CERTIFICATE_REQUEST) { #if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION -# error TODO(DTLS1.3): Restore digest for PHA before adding message. + /* Restore digest for PHA before adding message.*/ +# error Internal DTLS version error #endif if (!SSL_IS_DTLS(s) && s->post_handshake_auth == SSL_PHA_EXT_SENT) { s->post_handshake_auth = SSL_PHA_REQUESTED; @@ -878,7 +879,7 @@ WORK_STATE ossl_statem_client_post_work(SSL *s, WORK_STATE wst) * 1: Success * 0: Error */ -int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, +int ossl_statem_client_construct_message(SSL *s, confunc_f *confunc, int *mt) { OSSL_STATEM *st = &s->statem; @@ -995,7 +996,8 @@ size_t ossl_statem_client_max_message_size(SSL *s) return CCS_MAX_LENGTH; case TLS_ST_CR_SESSION_TICKET: - return SSL3_RT_MAX_PLAIN_LENGTH; + return (SSL_IS_TLS13(s)) ? SESSION_TICKET_MAX_LENGTH_TLS13 + : SESSION_TICKET_MAX_LENGTH_TLS12; case TLS_ST_CR_FINISHED: return FINISHED_MAX_LENGTH; @@ -1191,7 +1193,7 @@ int tls_construct_client_hello(SSL *s, WPACKET *pkt) session_id = s->tmp_session_id; if (s->hello_retry_request == SSL_HRR_NONE && RAND_bytes_ex(s->ctx->libctx, s->tmp_session_id, - sess_id_len) <= 0) { + sess_id_len, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -1393,6 +1395,10 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) && sversion == TLS1_2_VERSION && PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE && memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) { + if (s->hello_retry_request != SSL_HRR_NONE) { + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto err; + } s->hello_retry_request = SSL_HRR_PENDING; hrr = 1; if (!PACKET_forward(pkt, SSL3_RANDOM_SIZE)) { @@ -1567,7 +1573,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt) * overwritten if the server refuses resumption. */ if (s->session->session_id_length > 0) { - tsan_counter(&s->session_ctx->stats.sess_miss); + ssl_tsan_counter(s->session_ctx, &s->session_ctx->stats.sess_miss); if (!ssl_get_new_session(s, 0)) { /* SSLfatal() already called */ goto err; @@ -1761,7 +1767,7 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL *s, return MSG_PROCESS_ERROR; } -/* prepare server cert verificaton by setting s->session->peer_chain from pkt */ +/* prepare server cert verification by setting s->session->peer_chain from pkt */ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) { unsigned long cert_list_len, cert_len; @@ -1839,7 +1845,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt) err: X509_free(x); - sk_X509_pop_free(s->session->peer_chain, X509_free); + OSSL_STACK_OF_X509_free(s->session->peer_chain); s->session->peer_chain = NULL; return MSG_PROCESS_ERROR; } @@ -1857,9 +1863,10 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) size_t certidx; int i; + if (s->rwstate == SSL_RETRY_VERIFY) + s->rwstate = SSL_NOTHING; i = ssl_verify_cert_chain(s, s->session->peer_chain); - if (i == -1) { - s->rwstate = SSL_RETRY_VERIFY; + if (i > 0 && s->rwstate == SSL_RETRY_VERIFY) { return WORK_MORE_A; } /* @@ -1882,10 +1889,6 @@ WORK_STATE tls_post_process_server_certificate(SSL *s, WORK_STATE wst) return WORK_ERROR; } ERR_clear_error(); /* but we keep s->verify_result */ - if (i > 1) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, i); - return WORK_ERROR; - } /* * Inconsistency alert: cert_chain does include the peer's certificate, @@ -1985,7 +1988,6 @@ static int tls_process_ske_srp(SSL *s, PACKET *pkt, EVP_PKEY **pkey) return 0; } - /* TODO(size_t): Convert BN_bin2bn() calls */ if ((s->srp_ctx.N = BN_bin2bn(PACKET_data(&prime), (int)PACKET_remaining(&prime), NULL)) == NULL @@ -2035,7 +2037,6 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) return 0; } - /* TODO(size_t): Convert these calls */ p = BN_bin2bn(PACKET_data(&prime), (int)PACKET_remaining(&prime), NULL); g = BN_bin2bn(PACKET_data(&generator), (int)PACKET_remaining(&generator), NULL); @@ -2071,13 +2072,20 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) EVP_PKEY_CTX_free(pctx); pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, peer_tmp, s->ctx->propq); if (pctx == NULL - || EVP_PKEY_param_check(pctx) != 1 + /* + * EVP_PKEY_param_check() will verify that the DH params are using + * a safe prime. In this context, because we're using ephemeral DH, + * we're ok with it not being a safe prime. + * EVP_PKEY_param_check_quick() skips the safe prime check. + */ + || EVP_PKEY_param_check_quick(pctx) != 1 || EVP_PKEY_public_check(pctx) != 1) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE); goto err; } - if (!ssl_security(s, SSL_SECOP_TMP_DH, EVP_PKEY_security_bits(peer_tmp), + if (!ssl_security(s, SSL_SECOP_TMP_DH, + EVP_PKEY_get_security_bits(peer_tmp), 0, peer_tmp)) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_DH_KEY_TOO_SMALL); goto err; @@ -2098,7 +2106,7 @@ static int tls_process_ske_dhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) err: OSSL_PARAM_BLD_free(tmpl); - OSSL_PARAM_BLD_free_params(params); + OSSL_PARAM_free(params); EVP_PKEY_free(peer_tmp); EVP_PKEY_CTX_free(pctx); BN_free(p); @@ -2161,6 +2169,8 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) *pkey = X509_get0_pubkey(s->session->peer); /* else anonymous ECDH, so no certificate or pkey. */ + /* Cache the agreed upon group in the SSL_SESSION */ + s->session->kex_group = curve_id; return 1; } @@ -2250,7 +2260,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) } if (SSL_USE_SIGALGS(s)) OSSL_TRACE1(TLS, "USING TLSv1.2 HASH %s\n", - md == NULL ? "n/a" : EVP_MD_name(md)); + md == NULL ? "n/a" : EVP_MD_get0_name(md)); if (!PACKET_get_length_prefixed_2(pkt, &signature) || PACKET_remaining(pkt) != 0) { @@ -2265,8 +2275,9 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) } if (EVP_DigestVerifyInit_ex(md_ctx, &pctx, - md == NULL ? NULL : EVP_MD_name(md), - s->ctx->libctx, s->ctx->propq, pkey) <= 0) { + md == NULL ? NULL : EVP_MD_get0_name(md), + s->ctx->libctx, s->ctx->propq, pkey, + NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB); goto err; } @@ -2345,6 +2356,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) s->s3.tmp.ctype_len = 0; OPENSSL_free(s->pha_context); s->pha_context = NULL; + s->pha_context_len = 0; if (!PACKET_get_length_prefixed_1(pkt, &reqctx) || !PACKET_memdup(&reqctx, &s->pha_context, &s->pha_context_len)) { @@ -2500,11 +2512,8 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) s->session = new_sess; } - /* - * Technically the cast to long here is not guaranteed by the C standard - - * but we use it elsewhere, so this should be ok. - */ - s->session->time = (long)time(NULL); + s->session->time = time(NULL); + ssl_session_calculate_timeout(s->session); OPENSSL_free(s->session->ext.tick); s->session->ext.tick = NULL; @@ -2562,7 +2571,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) goto err; } /* - * TODO(size_t): we use sess_len here because EVP_Digest expects an int + * We use sess_len here because EVP_Digest expects an int * but s->session->session_id_length is a size_t */ if (!EVP_Digest(s->session->ext.tick, ticklen, @@ -2579,7 +2588,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt) /* This is a standalone message in TLSv1.3, so there is no more to read */ if (SSL_IS_TLS13(s)) { const EVP_MD *md = ssl_handshake_md(s); - int hashleni = EVP_MD_size(md); + int hashleni = EVP_MD_get_size(md); size_t hashlen; static const unsigned char nonce_label[] = "resumption"; @@ -2635,14 +2644,15 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt) } s->ext.ocsp.resp = OPENSSL_malloc(resplen); if (s->ext.ocsp.resp == NULL) { + s->ext.ocsp.resp_len = 0; SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); return 0; } + s->ext.ocsp.resp_len = resplen; if (!PACKET_copy_bytes(pkt, s->ext.ocsp.resp, resplen)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - s->ext.ocsp.resp_len = resplen; return 1; } @@ -2690,7 +2700,8 @@ int tls_process_initial_server_flight(SSL *s) return 0; } if (ret < 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_R_OCSP_CALLBACK_FAILURE); return 0; } } @@ -2716,7 +2727,7 @@ MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt) } #ifndef OPENSSL_NO_SRP if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kSRP) { - if (SRP_Calc_A_param(s) <= 0) { + if (ssl_srp_calc_a_param_intern(s) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_SRP_A_CALC); return MSG_PROCESS_ERROR; } @@ -2760,6 +2771,7 @@ static int tls_construct_cke_psk_preamble(SSL *s, WPACKET *pkt) if (psklen > PSK_MAX_PSK_LEN) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); + psklen = PSK_MAX_PSK_LEN; /* Avoid overrunning the array on cleanse */ goto err; } else if (psklen == 0) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_PSK_IDENTITY_NOT_FOUND); @@ -2839,8 +2851,7 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt) pms[0] = s->client_version >> 8; pms[1] = s->client_version & 0xff; - /* TODO(size_t): Convert this function */ - if (RAND_bytes_ex(s->ctx->libctx, pms + 2, (int)(pmslen - 2)) <= 0) { + if (RAND_bytes_ex(s->ctx->libctx, pms + 2, pmslen - 2, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); goto err; } @@ -2920,7 +2931,7 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) encoded_pub_len = EVP_PKEY_get1_encoded_public_key(ckey, &encoded_pub); if (encoded_pub_len == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(skey); + EVP_PKEY_free(ckey); return EXT_RETURN_FAIL; } @@ -2929,7 +2940,7 @@ static int tls_construct_cke_dhe(SSL *s, WPACKET *pkt) * stack, we need to zero pad the DHE pub key to the same length * as the prime. */ - prime_len = EVP_PKEY_size(ckey); + prime_len = EVP_PKEY_get_size(ckey); pad_len = prime_len - encoded_pub_len; if (pad_len > 0) { if (!WPACKET_sub_allocate_bytes_u16(pkt, pad_len, &keybytes)) { @@ -3045,9 +3056,8 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 /* Generate session key - * TODO(size_t): Convert this function */ - || RAND_bytes_ex(s->ctx->libctx, pms, (int)pmslen) <= 0) { + || RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; }; @@ -3069,7 +3079,7 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) EVP_MD_CTX_free(ukm_hash); ukm_hash = NULL; if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) { + EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); goto err; } @@ -3107,7 +3117,7 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) } #ifndef OPENSSL_NO_GOST -int gost18_cke_cipher_nid(const SSL *s) +int ossl_gost18_cke_cipher_nid(const SSL *s) { if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0) return NID_magma_ctr; @@ -3117,7 +3127,7 @@ int gost18_cke_cipher_nid(const SSL *s) return NID_undef; } -int gost_ukm(const SSL *s, unsigned char *dgst_buf) +int ossl_gost_ukm(const SSL *s, unsigned char *dgst_buf) { EVP_MD_CTX * hash = NULL; unsigned int md_len; @@ -3152,14 +3162,14 @@ static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) unsigned char *pms = NULL; size_t pmslen = 0; size_t msglen; - int cipher_nid = gost18_cke_cipher_nid(s); + int cipher_nid = ossl_gost18_cke_cipher_nid(s); if (cipher_nid == NID_undef) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } - if (gost_ukm(s, rnd_dgst) <= 0) { + if (ossl_gost_ukm(s, rnd_dgst) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3172,7 +3182,7 @@ static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) goto err; } - if (RAND_bytes_ex(s->ctx->libctx, pms, (int)pmslen) <= 0) { + if (RAND_bytes_ex(s->ctx->libctx, pms, pmslen, 0) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -3182,7 +3192,7 @@ static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) if (peer_cert == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); - return 0; + goto err; } pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, @@ -3190,23 +3200,23 @@ static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) s->ctx->propq); if (pkey_ctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - return 0; + goto err; } - if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) { + if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; }; /* Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code */ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) { + EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); goto err; } if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) { + EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_LIBRARY_BUG); goto err; } @@ -3305,9 +3315,11 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) err: OPENSSL_clear_free(s->s3.tmp.pms, s->s3.tmp.pmslen); s->s3.tmp.pms = NULL; + s->s3.tmp.pmslen = 0; #ifndef OPENSSL_NO_PSK OPENSSL_clear_free(s->s3.tmp.psk, s->s3.tmp.psklen); s->s3.tmp.psk = NULL; + s->s3.tmp.psklen = 0; #endif return 0; } @@ -3379,6 +3391,7 @@ int tls_client_key_exchange_post_work(SSL *s) err: OPENSSL_clear_free(pms, pmslen); s->s3.tmp.pms = NULL; + s->s3.tmp.pmslen = 0; return 0; }