if (!WPACKET_sub_memcpy_u8(pkt, session_id, sl)
|| !s->method->put_cipher_by_char(s->s3->tmp.new_cipher, pkt, &len)
- || !WPACKET_put_bytes_u8(pkt, compm)
- || !tls_construct_extensions(s, pkt,
- s->hello_retry_request
- == SSL_HRR_PENDING
- ? SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
- : (SSL_IS_TLS13(s)
- ? SSL_EXT_TLS1_3_SERVER_HELLO
- : SSL_EXT_TLS1_2_SERVER_HELLO),
- NULL, 0)) {
+ || !WPACKET_put_bytes_u8(pkt, compm)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_SERVER_HELLO,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (!tls_construct_extensions(s, pkt,
+ s->hello_retry_request == SSL_HRR_PENDING
+ ? SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST
+ : (SSL_IS_TLS13(s)
+ ? SSL_EXT_TLS1_3_SERVER_HELLO
+ : SSL_EXT_TLS1_2_SERVER_HELLO),
+ NULL, 0)) {
/* SSLfatal() already called */
return 0;
}
SSL_R_BN_LIB);
goto err;
}
+
cdh = EVP_PKEY_get0_DH(ckey);
pub_key = BN_bin2bn(data, i, NULL);
-
- if (pub_key == NULL || !DH_set0_key(cdh, pub_key, NULL)) {
+ if (pub_key == NULL || cdh == NULL || !DH_set0_key(cdh, pub_key, NULL)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_DHE,
ERR_R_INTERNAL_ERROR);
- if (pub_key != NULL)
- BN_free(pub_key);
+ BN_free(pub_key);
goto err;
}
*/
if (s->post_handshake_auth == SSL_PHA_REQUESTED) {
- int m = s->session_ctx->session_cache_mode;
-
if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE,
goto err;
}
- if (m & SSL_SESS_CACHE_SERVER) {
- /*
- * Remove the old session from the cache. We carry on if this fails
- */
- SSL_CTX_remove_session(s->session_ctx, s->session);
- }
-
SSL_SESSION_free(s->session);
s->session = new_sess;
}
* long
*/
if (slen_full == 0 || slen_full > 0xFF00) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_INTERNAL_ERROR);
goto err;
}
senc = OPENSSL_malloc(slen_full);
if (senc == NULL) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_MALLOC_FAILURE);
goto err;
}
ctx = EVP_CIPHER_CTX_new();
hctx = HMAC_CTX_new();
if (ctx == NULL || hctx == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_MALLOC_FAILURE);
goto err;
}
p = senc;
if (!i2d_SSL_SESSION(s->session, &p)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_INTERNAL_ERROR);
goto err;
}
const_p = senc;
sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
if (sess == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_INTERNAL_ERROR);
goto err;
}
slen = i2d_SSL_SESSION(sess, NULL);
if (slen == 0 || slen > slen_full) {
/* shouldn't ever happen */
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_INTERNAL_ERROR);
SSL_SESSION_free(sess);
goto err;
}
p = senc;
if (!i2d_SSL_SESSION(sess, &p)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_INTERNAL_ERROR);
SSL_SESSION_free(sess);
goto err;
}
if (!WPACKET_put_bytes_u32(pkt, 0)
|| !WPACKET_put_bytes_u16(pkt, 0)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
+ SSL_F_CONSTRUCT_STATELESS_TICKET,
ERR_R_INTERNAL_ERROR);
goto err;
}
return 1;
}
if (ret < 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
SSL_R_CALLBACK_FAILED);
goto err;
}
|| !HMAC_Init_ex(hctx, tctx->ext.secure->tick_hmac_key,
sizeof(tctx->ext.secure->tick_hmac_key),
EVP_sha256(), NULL)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET,
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
ERR_R_INTERNAL_ERROR);
goto err;
}
|| !WPACKET_allocate_bytes(pkt, hlen, &macdata2)
|| macdata1 != macdata2) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSL_F_CONSTRUCT_STATELESS_TICKET, ERR_R_INTERNAL_ERROR);
goto err;
}
/* Close the sub-packet created by create_ticket_prequel() */
if (!WPACKET_close(pkt)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATELESS_TICKET,
+ ERR_R_INTERNAL_ERROR);
goto err;
}
return ok;
}
+static int construct_stateful_ticket(SSL *s, WPACKET *pkt, uint32_t age_add,
+ unsigned char *tick_nonce)
+{
+ if (!create_ticket_prequel(s, pkt, age_add, tick_nonce)) {
+ /* SSLfatal() already called */
+ return 0;
+ }
+
+ if (!WPACKET_memcpy(pkt, s->session->session_id,
+ s->session->session_id_length)
+ || !WPACKET_close(pkt)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_STATEFUL_TICKET,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
{
SSL_CTX *tctx = s->session_ctx;
tctx->generate_ticket_cb(s, tctx->ticket_cb_data) == 0)
goto err;
- if (!construct_stateless_ticket(s, pkt, age_add_u.age_add, tick_nonce)) {
+ /*
+ * If we are using anti-replay protection then we behave as if
+ * SSL_OP_NO_TICKET is set - we are caching tickets anyway so there
+ * is no point in using full stateless tickets.
+ */
+ if (SSL_IS_TLS13(s)
+ && ((s->options & SSL_OP_NO_TICKET) != 0
+ || (s->max_early_data > 0
+ && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0))) {
+ if (!construct_stateful_ticket(s, pkt, age_add_u.age_add, tick_nonce)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+ } else if (!construct_stateless_ticket(s, pkt, age_add_u.age_add,
+ tick_nonce)) {
/* SSLfatal() already called */
goto err;
}