Enable the ability to set the number of TLSv1.3 session tickets sent
We send a session ticket automatically in TLSv1.3 at the end of the
handshake. This commit provides the ability to set how many tickets should
be sent. By default this is one.
Fixes #4978
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5227)
Matt Caswell
6 years ago
2094 | 2094 | void *SSL_get_record_padding_callback_arg(SSL *ssl); |
2095 | 2095 | int SSL_set_block_padding(SSL *ssl, size_t block_size); |
2096 | 2096 | |
2097 | int SSL_set_num_tickets(SSL *s, size_t num_tickets); | |
2098 | size_t SSL_get_num_tickets(SSL *s); | |
2099 | int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets); | |
2100 | size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx); | |
2101 | ||
2097 | 2102 | # if OPENSSL_API_COMPAT < 0x10100000L |
2098 | 2103 | # define SSL_cache_hit(s) SSL_session_reused(s) |
2099 | 2104 | # endif |
698 | 698 | s->mode = ctx->mode; |
699 | 699 | s->max_cert_list = ctx->max_cert_list; |
700 | 700 | s->max_early_data = ctx->max_early_data; |
701 | s->num_tickets = ctx->num_tickets; | |
701 | 702 | |
702 | 703 | /* Shallow copy of the ciphersuites stack */ |
703 | 704 | s->tls13_ciphersuites = sk_SSL_CIPHER_dup(ctx->tls13_ciphersuites); |
3032 | 3033 | */ |
3033 | 3034 | ret->max_early_data = 0; |
3034 | 3035 | |
3036 | /* By default we send one session ticket automatically in TLSv1.3 */ | |
3037 | ret->num_tickets = 1; | |
3038 | ||
3035 | 3039 | ssl_ctx_system_config(ret); |
3036 | 3040 | |
3037 | 3041 | return ret; |
4311 | 4315 | else |
4312 | 4316 | return 0; |
4313 | 4317 | return 1; |
4318 | } | |
4319 | ||
4320 | int SSL_set_num_tickets(SSL *s, size_t num_tickets) | |
4321 | { | |
4322 | s->num_tickets = num_tickets; | |
4323 | ||
4324 | return 1; | |
4325 | } | |
4326 | ||
4327 | size_t SSL_get_num_tickets(SSL *s) | |
4328 | { | |
4329 | return s->num_tickets; | |
4330 | } | |
4331 | ||
4332 | int SSL_CTX_set_num_tickets(SSL_CTX *ctx, size_t num_tickets) | |
4333 | { | |
4334 | ctx->num_tickets = num_tickets; | |
4335 | ||
4336 | return 1; | |
4337 | } | |
4338 | ||
4339 | size_t SSL_CTX_get_num_tickets(SSL_CTX *ctx) | |
4340 | { | |
4341 | return ctx->num_tickets; | |
4314 | 4342 | } |
4315 | 4343 | |
4316 | 4344 | /* |
1048 | 1048 | SSL_CTX_generate_session_ticket_fn generate_ticket_cb; |
1049 | 1049 | SSL_CTX_decrypt_session_ticket_fn decrypt_ticket_cb; |
1050 | 1050 | void *ticket_cb_data; |
1051 | ||
1052 | /* The number of TLS1.3 tickets to automatically send */ | |
1053 | size_t num_tickets; | |
1051 | 1054 | }; |
1052 | 1055 | |
1053 | 1056 | struct ssl_st { |
1417 | 1420 | size_t block_padding; |
1418 | 1421 | |
1419 | 1422 | CRYPTO_RWLOCK *lock; |
1423 | RAND_DRBG *drbg; | |
1424 | ||
1425 | /* The number of TLS1.3 tickets to automatically send */ | |
1426 | size_t num_tickets; | |
1427 | /* The number of TLS1.3 tickets actually sent so far */ | |
1428 | size_t sent_tickets; | |
1420 | 1429 | }; |
1421 | 1430 | |
1422 | 1431 | /* |
479 | 479 | case TLS_ST_SR_FINISHED: |
480 | 480 | /* |
481 | 481 | * Technically we have finished the handshake at this point, but we're |
482 | * going to remain "in_init" for now and write out the session ticket | |
482 | * going to remain "in_init" for now and write out any session tickets | |
483 | 483 | * immediately. |
484 | * TODO(TLS1.3): Perhaps we need to be able to control this behaviour | |
485 | * and give the application the opportunity to delay sending the | |
486 | * session ticket? | |
487 | 484 | */ |
488 | st->hand_state = TLS_ST_SW_SESSION_TICKET; | |
489 | 485 | if (s->post_handshake_auth == SSL_PHA_REQUESTED) { |
490 | 486 | s->post_handshake_auth = SSL_PHA_EXT_RECEIVED; |
491 | 487 | } else if (!s->ext.ticket_expected) { |
494 | 490 | * handshake at this point. |
495 | 491 | */ |
496 | 492 | st->hand_state = TLS_ST_OK; |
497 | } | |
493 | return WRITE_TRAN_CONTINUE; | |
494 | } | |
495 | if (s->num_tickets > s->sent_tickets) | |
496 | st->hand_state = TLS_ST_SW_SESSION_TICKET; | |
497 | else | |
498 | st->hand_state = TLS_ST_OK; | |
498 | 499 | return WRITE_TRAN_CONTINUE; |
499 | 500 | |
500 | 501 | case TLS_ST_SR_KEY_UPDATE: |
506 | 507 | |
507 | 508 | case TLS_ST_SW_KEY_UPDATE: |
508 | 509 | case TLS_ST_SW_SESSION_TICKET: |
509 | st->hand_state = TLS_ST_OK; | |
510 | /* In a resumption we only ever send a maximum of one new ticket. | |
511 | * Following an initial handshake we send the number of tickets we have | |
512 | * been configured for. | |
513 | */ | |
514 | if (s->hit || s->num_tickets <= s->sent_tickets) { | |
515 | /* We've written enough tickets out. */ | |
516 | st->hand_state = TLS_ST_OK; | |
517 | } | |
510 | 518 | return WRITE_TRAN_CONTINUE; |
511 | 519 | } |
512 | 520 | } |
3742 | 3750 | } age_add_u; |
3743 | 3751 | |
3744 | 3752 | if (SSL_IS_TLS13(s)) { |
3745 | if (s->post_handshake_auth != SSL_PHA_EXT_RECEIVED) { | |
3746 | void (*cb) (const SSL *ssl, int type, int val) = NULL; | |
3747 | ||
3753 | void (*cb) (const SSL *ssl, int type, int val) = NULL; | |
3754 | ||
3755 | if (s->info_callback != NULL) | |
3756 | cb = s->info_callback; | |
3757 | else if (s->ctx->info_callback != NULL) | |
3758 | cb = s->ctx->info_callback; | |
3759 | ||
3760 | ||
3761 | if (cb != NULL) { | |
3748 | 3762 | /* |
3749 | * This is the first session ticket we've sent. In the state | |
3750 | * machine we "cheated" and tacked this onto the end of the first | |
3751 | * handshake. From an info callback perspective this should appear | |
3752 | * like the start of a new handshake. | |
3763 | * We don't start and stop the handshake in between each ticket when | |
3764 | * sending more than one - but it should appear that way to the info | |
3765 | * callback. | |
3753 | 3766 | */ |
3754 | if (s->info_callback != NULL) | |
3755 | cb = s->info_callback; | |
3756 | else if (s->ctx->info_callback != NULL) | |
3757 | cb = s->ctx->info_callback; | |
3758 | if (cb != NULL) | |
3759 | cb(s, SSL_CB_HANDSHAKE_START, 1); | |
3767 | if (s->sent_tickets != 0) { | |
3768 | ossl_statem_set_in_init(s, 0); | |
3769 | cb(s, SSL_CB_HANDSHAKE_DONE, 1); | |
3770 | ossl_statem_set_in_init(s, 1); | |
3771 | } | |
3772 | cb(s, SSL_CB_HANDSHAKE_START, 1); | |
3773 | } | |
3774 | /* | |
3775 | * If we already sent one NewSessionTicket then we need to take a copy | |
3776 | * of it and create a new session from it. | |
3777 | */ | |
3778 | if (s->sent_tickets != 0) { | |
3779 | SSL_SESSION *new_sess = ssl_session_dup(s->session, 0); | |
3780 | ||
3781 | if (new_sess == NULL) { | |
3782 | /* SSLfatal already called */ | |
3783 | goto err; | |
3784 | } | |
3785 | ||
3786 | SSL_SESSION_free(s->session); | |
3787 | s->session = new_sess; | |
3760 | 3788 | } |
3761 | 3789 | |
3762 | 3790 | if (!ssl_generate_session_id(s, s->session)) { |
3967 | 3995 | /* SSLfatal() already called */ |
3968 | 3996 | goto err; |
3969 | 3997 | } |
3998 | s->sent_tickets++; | |
3970 | 3999 | } |
3971 | 4000 | EVP_CIPHER_CTX_free(ctx); |
3972 | 4001 | HMAC_CTX_free(hctx); |
485 | 485 | SSL_CTX_set_stateless_cookie_verify_cb 487 1_1_1 EXIST::FUNCTION: |
486 | 486 | SSL_CTX_set_ciphersuites 488 1_1_1 EXIST::FUNCTION: |
487 | 487 | SSL_set_ciphersuites 489 1_1_1 EXIST::FUNCTION: |
488 | SSL_set_num_tickets 490 1_1_1 EXIST::FUNCTION: | |
489 | SSL_CTX_get_num_tickets 491 1_1_1 EXIST::FUNCTION: | |
490 | SSL_get_num_tickets 492 1_1_1 EXIST::FUNCTION: | |
491 | SSL_CTX_set_num_tickets 493 1_1_1 EXIST::FUNCTION: |