/* We only hit this in the case of HelloRetryRequest */
return WRITE_TRAN_FINISHED;
- case TLS_ST_CR_HELLO_RETRY_REQUEST:
- st->hand_state = TLS_ST_CW_CLNT_HELLO;
- return WRITE_TRAN_CONTINUE;
-
case TLS_ST_CR_FINISHED:
if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY
|| s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING)
*/
return WRITE_TRAN_FINISHED;
+ case TLS_ST_CR_HELLO_RETRY_REQUEST:
+ st->hand_state = TLS_ST_CW_CLNT_HELLO;
+ return WRITE_TRAN_CONTINUE;
+
case TLS_ST_EARLY_DATA:
return WRITE_TRAN_FINISHED;
break;
}
}
- } else
- i = 1;
+ } else {
+ i = s->hello_retry_request == 0;
+ }
if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random),
DOWNGRADE_NONE) <= 0)
unsigned int compression;
unsigned int sversion;
unsigned int context;
- int protverr;
+ int protverr, discard;
RAW_EXTENSION *extensions = NULL;
#ifndef OPENSSL_NO_COMP
SSL_COMP *comp;
|| (SSL_IS_TLS13(s)
&& s->session->ext.tick_identity
!= TLSEXT_PSK_BAD_IDENTITY)) {
- s->ctx->stats.sess_miss++;
+ CRYPTO_atomic_add(&s->session_ctx->stats.sess_miss, 1, &discard,
+ s->session_ctx->lock);
if (!ssl_get_new_session(s, 0)) {
goto f_err;
}
static MSG_PROCESS_RETURN tls_process_hello_retry_request(SSL *s, PACKET *pkt)
{
unsigned int sversion;
- int errorcode;
const unsigned char *cipherchars;
RAW_EXTENSION *extensions = NULL;
int al;
goto f_err;
}
- s->hello_retry_request = 1;
-
- /* This will fail if it doesn't choose TLSv1.3+ */
- errorcode = ssl_choose_client_version(s, sversion, 0, &al);
- if (errorcode != 0) {
- SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, errorcode);
+ /* TODO(TLS1.3): Remove the TLS1_3_VERSION_DRAFT clause before release */
+ if (sversion != TLS1_3_VERSION && sversion != TLS1_3_VERSION_DRAFT) {
+ SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_WRONG_SSL_VERSION);
+ al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
+ s->hello_retry_request = 1;
+
+ /*
+ * If we were sending early_data then the enc_write_ctx is now invalid and
+ * should not be used.
+ */
+ EVP_CIPHER_CTX_free(s->enc_write_ctx);
+ s->enc_write_ctx = NULL;
+
if (!PACKET_get_bytes(pkt, &cipherchars, TLS_CIPHER_LEN)) {
SSLerr(SSL_F_TLS_PROCESS_HELLO_RETRY_REQUEST, SSL_R_LENGTH_MISMATCH);
al = SSL_AD_DECODE_ERROR;
OPENSSL_free(extensions);
extensions = NULL;
- if (s->ext.tls13_cookie_len == 0 && s->s3->tmp.pkey != NULL) {
+ if (s->ext.tls13_cookie_len == 0
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
+ && s->s3->tmp.pkey != NULL
+#endif
+ ) {
/*
* We didn't receive a cookie or a new key_share so the next
* ClientHello will not change
MSG_PROCESS_RETURN tls_process_server_certificate(SSL *s, PACKET *pkt)
{
- int al, i, ret = MSG_PROCESS_ERROR;
+ int al, i;
+ MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR;
unsigned long cert_list_len, cert_len;
X509 *x = NULL;
const unsigned char *certstart, *certbytes;
*/
x = sk_X509_value(sk, 0);
sk = NULL;
- /*
- * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end
- */
pkey = X509_get0_pubkey(x);
{
#ifndef OPENSSL_NO_EC
PACKET encoded_pt;
- const unsigned char *ecparams;
- int curve_nid;
- unsigned int curve_flags;
- EVP_PKEY_CTX *pctx = NULL;
+ unsigned int curve_type, curve_id;
/*
* Extract elliptic curve parameters and the server's ephemeral ECDH
- * public key. For now we only support named (not generic) curves and
+ * public key. We only support named (not generic) curves and
* ECParameters in this case is just three bytes.
*/
- if (!PACKET_get_bytes(pkt, &ecparams, 3)) {
+ if (!PACKET_get_1(pkt, &curve_type) || !PACKET_get_net_2(pkt, &curve_id)) {
*al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_LENGTH_TOO_SHORT);
return 0;
}
/*
- * Check curve is one of our preferences, if not server has sent an
- * invalid curve. ECParameters is 3 bytes.
+ * Check curve is named curve type and one of our preferences, if not
+ * server has sent an invalid curve.
*/
- if (!tls1_check_curve(s, ecparams, 3)) {
+ if (curve_type != NAMED_CURVE_TYPE || !tls1_check_group_id(s, curve_id)) {
*al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_WRONG_CURVE);
return 0;
}
- curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2), &curve_flags);
-
- if (curve_nid == 0) {
+ if ((s->s3->peer_tmp = ssl_generate_param_group(curve_id)) == NULL) {
*al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE,
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
return 0;
}
- if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
- EVP_PKEY *key = EVP_PKEY_new();
-
- if (key == NULL || !EVP_PKEY_set_type(key, curve_nid)) {
- *al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB);
- EVP_PKEY_free(key);
- return 0;
- }
- s->s3->peer_tmp = key;
- } else {
- /* Set up EVP_PKEY with named curve as parameters */
- pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
- if (pctx == NULL
- || EVP_PKEY_paramgen_init(pctx) <= 0
- || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, curve_nid) <= 0
- || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
- *al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB);
- EVP_PKEY_CTX_free(pctx);
- return 0;
- }
- EVP_PKEY_CTX_free(pctx);
- pctx = NULL;
- }
-
if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) {
*al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_LENGTH_MISMATCH);
MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
{
- int ret = MSG_PROCESS_ERROR;
+ MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR;
int al = SSL_AD_DECODE_ERROR;
size_t i;
|| (SSL_IS_TLS13(s)
&& (!PACKET_get_net_4(pkt, &age_add)
|| !PACKET_get_length_prefixed_1(pkt, &nonce)
- || PACKET_remaining(&nonce) == 0
|| !PACKET_memdup(&nonce, &s->session->ext.tick_nonce,
&s->session->ext.tick_nonce_len)))
|| !PACKET_get_net_2(pkt, &ticklen)
* We reused an existing session, so we need to replace it with a new
* one
*/
+ if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ goto f_err;
+ }
+
if (i & SSL_SESS_CACHE_CLIENT) {
/*
* Remove the old session from the cache. We carry on if this fails
SSL_CTX_remove_session(s->session_ctx, s->session);
}
- if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
- al = SSL_AD_INTERNAL_ERROR;
- SSLerr(SSL_F_TLS_PROCESS_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
- goto f_err;
- }
-
SSL_SESSION_free(s->session);
s->session = new_sess;
}
pms[0] = s->client_version >> 8;
pms[1] = s->client_version & 0xff;
/* TODO(size_t): Convert this function */
- if (RAND_bytes(pms + 2, (int)(pmslen - 2)) <= 0) {
+ if (ssl_randbytes(s, pms + 2, (int)(pmslen - 2)) <= 0) {
goto err;
}
/* Generate session key
* TODO(size_t): Convert this function
*/
- || RAND_bytes(pms, (int)pmslen) <= 0) {
+ || ssl_randbytes(s, pms, (int)pmslen) <= 0) {
*al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
goto err;
if (i == 0) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
ossl_statem_set_error(s);
- return 0;
+ return WORK_ERROR;
}
s->rwstate = SSL_NOTHING;
}
if (!ssl3_digest_cached_records(s, 0)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
ossl_statem_set_error(s);
- return 0;
+ return WORK_ERROR;
}
}
}
ssl_set_client_disabled(s);
if (sk == NULL)
- return (0);
+ return 0;
#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
# if OPENSSL_MAX_TLS1_2_CIPHER_LENGTH < 6
if (totlen != 0) {
if (empty_reneg_info_scsv) {
static SSL_CIPHER scsv = {
- 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, NULL, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!s->method->put_cipher_by_char(&scsv, pkt, &len)) {
SSLerr(SSL_F_SSL_CIPHER_LIST_TO_BYTES, ERR_R_INTERNAL_ERROR);
}
if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
static SSL_CIPHER scsv = {
- 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 0, NULL, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (!s->method->put_cipher_by_char(&scsv, pkt, &len)) {
SSLerr(SSL_F_SSL_CIPHER_LIST_TO_BYTES, ERR_R_INTERNAL_ERROR);