提交 30f05b19 编写于 作者: M Matt Caswell

Create the NewSessionTicket message in TLSv1.3

Reviewed-by: NRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2259)
上级 b2f7e8c0
......@@ -602,7 +602,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL *s, WORK_STATE wst)
break;
case TLS_ST_OK:
return tls_finish_handshake(s, wst);
return tls_finish_handshake(s, wst, 1);
}
return WORK_FINISHED_CONTINUE;
......
......@@ -821,7 +821,12 @@ unsigned long ssl3_output_cert_chain(SSL *s, WPACKET *pkt, CERT_PKEY *cpk,
return 1;
}
WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
/*
* Tidy up after the end of a handshake. In the case of SCTP this may result
* in NBIO events. If |clearbufs| is set then init_buf and the wbio buffer is
* freed up as well.
*/
WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs)
{
void (*cb) (const SSL *ssl, int type, int val) = NULL;
......@@ -834,28 +839,27 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
}
#endif
/* clean a few things up */
ssl3_cleanup_key_block(s);
if (!SSL_IS_DTLS(s)) {
/*
* We don't do this in DTLS because we may still need the init_buf
* in case there are any unexpected retransmits
*/
BUF_MEM_free(s->init_buf);
s->init_buf = NULL;
if (clearbufs) {
if (!SSL_IS_DTLS(s)) {
/*
* We don't do this in DTLS because we may still need the init_buf
* in case there are any unexpected retransmits
*/
BUF_MEM_free(s->init_buf);
s->init_buf = NULL;
}
ssl_free_wbio_buffer(s);
s->init_num = 0;
}
ssl_free_wbio_buffer(s);
s->init_num = 0;
if (s->statem.cleanuphand) {
/* skipped if we just sent a HelloRequest */
s->renegotiate = 0;
s->new_session = 0;
s->statem.cleanuphand = 0;
ssl3_cleanup_key_block(s);
if (s->server) {
ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
......@@ -887,6 +891,13 @@ WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst)
}
}
/*
* If we've not cleared the buffers its because we've got more work to do,
* so continue.
*/
if (!clearbufs)
return WORK_FINISHED_CONTINUE;
return WORK_FINISHED_STOP;
}
......
......@@ -107,7 +107,7 @@ __owur int tls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);
__owur int dtls_construct_change_cipher_spec(SSL *s, WPACKET *pkt);
__owur int tls_construct_finished(SSL *s, WPACKET *pkt);
__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst);
__owur WORK_STATE tls_finish_handshake(SSL *s, WORK_STATE wst, int clearbufs);
__owur WORK_STATE dtls_wait_for_dry(SSL *s);
/* some client-only functions */
......
......@@ -439,6 +439,18 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL *s)
return WRITE_TRAN_FINISHED;
case TLS_ST_SR_FINISHED:
/*
* Technically we have finished the handshake at this point, but we're
* going to remain "in_init" for now and write out the session ticket
* immediately.
* TODO(TLS1.3): Perhaps we need to be able to control this behaviour
* and give the application the opportunity to delay sending the
* session ticket?
*/
st->hand_state = TLS_ST_SW_SESSION_TICKET;
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_SESSION_TICKET:
st->hand_state = TLS_ST_OK;
ossl_statem_set_in_init(s, 0);
return WRITE_TRAN_CONTINUE;
......@@ -626,7 +638,14 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
return WORK_FINISHED_CONTINUE;
case TLS_ST_SW_SESSION_TICKET:
if (SSL_IS_DTLS(s)) {
if (SSL_IS_TLS13(s)) {
/*
* Actually this is the end of the handshake, but we're going
* straight into writing the session ticket out. So we finish off
* the handshake, but keep the various buffers active.
*/
return tls_finish_handshake(s, wst, 0);
} if (SSL_IS_DTLS(s)) {
/*
* We're into the last flight. We don't retransmit the last flight
* unless we need to, so we don't use the timer
......@@ -653,7 +672,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL *s, WORK_STATE wst)
return WORK_FINISHED_CONTINUE;
case TLS_ST_OK:
return tls_finish_handshake(s, wst);
return tls_finish_handshake(s, wst, 1);
}
return WORK_FINISHED_CONTINUE;
......@@ -788,6 +807,11 @@ WORK_STATE ossl_statem_server_post_work(SSL *s, WORK_STATE wst)
return WORK_ERROR;
}
break;
case TLS_ST_SW_SESSION_TICKET:
if (SSL_IS_TLS13(s) && statem_flush(s) != 1)
return WORK_MORE_A;
break;
}
return WORK_FINISHED_CONTINUE;
......@@ -3219,8 +3243,12 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
SSL_CTX *tctx = s->initial_ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
int iv_len;
int iv_len, al = SSL_AD_INTERNAL_ERROR;
size_t macoffset, macendoffset;
union {
unsigned char age_add_c[sizeof(uint32_t)];
uint32_t age_add;
} age_add_u;
/* get session encoding length */
slen_full = i2d_SSL_SESSION(s->session, NULL);
......@@ -3313,12 +3341,18 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
sizeof(tctx->ext.tick_key_name));
}
if (SSL_IS_TLS13(s) && RAND_bytes(age_add_u.age_add_c,
sizeof(age_add_u)) <= 0)
goto err;
/*
* Ticket lifetime hint (advisory only): We leave this unspecified
* for resumed session (for simplicity), and guess that tickets for
* new sessions will live as long as their sessions.
*/
if (!WPACKET_put_bytes_u32(pkt, s->hit ? 0 : s->session->timeout)
|| (SSL_IS_TLS13(s)
&& !WPACKET_put_bytes_u32(pkt, age_add_u.age_add))
/* Now the actual ticket data */
|| !WPACKET_start_sub_packet_u16(pkt)
|| !WPACKET_get_total_written(pkt, &macoffset)
......@@ -3345,7 +3379,11 @@ int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt)
|| hlen > EVP_MAX_MD_SIZE
|| !WPACKET_allocate_bytes(pkt, hlen, &macdata2)
|| macdata1 != macdata2
|| !WPACKET_close(pkt)) {
|| !WPACKET_close(pkt)
|| (SSL_IS_TLS13(s)
&& !tls_construct_extensions(s, pkt,
EXT_TLS1_3_NEW_SESSION_TICKET,
NULL, 0, &al))) {
SSLerr(SSL_F_TLS_CONSTRUCT_NEW_SESSION_TICKET, ERR_R_INTERNAL_ERROR);
goto err;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册