static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) { /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the * client makes several connections before getting a renewal. */ static const int kNumTickets = 2; SSL *const ssl = hs->ssl; /* If the client doesn't accept resumption with PSK_DHE_KE, don't send a * session ticket. */ if (!hs->accept_psk_mode) { hs->tls13_state = state_done; return ssl_hs_ok; } SSL_SESSION *session = ssl->s3->new_session; CBB cbb; CBB_zero(&cbb); for (int i = 0; i < kNumTickets; i++) { if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) { goto err; } CBB body, ticket, extensions; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_NEW_SESSION_TICKET) || !CBB_add_u32(&body, session->timeout) || !CBB_add_u32(&body, session->ticket_age_add) || !CBB_add_u16_length_prefixed(&body, &ticket) || !ssl_encrypt_ticket(ssl, &ticket, session) || !CBB_add_u16_length_prefixed(&body, &extensions)) { goto err; } if (ssl->ctx->enable_early_data) { session->ticket_max_early_data = kMaxEarlyDataAccepted; CBB early_data_info; if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) || !CBB_add_u16_length_prefixed(&extensions, &early_data_info) || !CBB_add_u32(&early_data_info, session->ticket_max_early_data) || !CBB_flush(&extensions)) { goto err; } } /* Add a fake extension. See draft-davidben-tls-grease-01. */ if (!CBB_add_u16(&extensions, ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) || !CBB_add_u16(&extensions, 0 /* empty */)) { goto err; } if (!ssl_add_message_cbb(ssl, &cbb)) { goto err; } } hs->session_tickets_sent++; hs->tls13_state = state_done; return ssl_hs_flush; err: CBB_cleanup(&cbb); return ssl_hs_error; }
static int add_new_session_tickets(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; /* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case * the client makes several connections before getting a renewal. */ static const int kNumTickets = 2; SSL_SESSION *session = hs->new_session; CBB cbb; CBB_zero(&cbb); /* Rebase the session timestamp so that it is measured from ticket * issuance. */ ssl_session_rebase_time(ssl, session); for (int i = 0; i < kNumTickets; i++) { if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) { goto err; } session->ticket_age_add_valid = 1; CBB body, ticket, extensions; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_NEW_SESSION_TICKET) || !CBB_add_u32(&body, session->timeout) || !CBB_add_u32(&body, session->ticket_age_add) || !CBB_add_u16_length_prefixed(&body, &ticket) || !ssl_encrypt_ticket(ssl, &ticket, session) || !CBB_add_u16_length_prefixed(&body, &extensions)) { goto err; } if (ssl->cert->enable_early_data) { session->ticket_max_early_data = kMaxEarlyDataAccepted; CBB early_data_info; if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) || !CBB_add_u16_length_prefixed(&extensions, &early_data_info) || !CBB_add_u32(&early_data_info, session->ticket_max_early_data) || !CBB_flush(&extensions)) { goto err; } } /* Add a fake extension. See draft-davidben-tls-grease-01. */ if (!CBB_add_u16(&extensions, ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) || !CBB_add_u16(&extensions, 0 /* empty */)) { goto err; } if (!ssl_add_message_cbb(ssl, &cbb)) { goto err; } } return 1; err: CBB_cleanup(&cbb); return 0; }