diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libssl/ssl_srvr.c | 119 |
1 files changed, 64 insertions, 55 deletions
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c index 2fde588cb9..80c7208c13 100644 --- a/src/lib/libssl/ssl_srvr.c +++ b/src/lib/libssl/ssl_srvr.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_srvr.c,v 1.39 2018/08/16 18:13:15 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_srvr.c,v 1.40 2018/08/19 15:29:26 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -2527,10 +2527,14 @@ ssl3_send_server_certificate(SSL *s) | |||
2527 | int | 2527 | int |
2528 | ssl3_send_newsession_ticket(SSL *s) | 2528 | ssl3_send_newsession_ticket(SSL *s) |
2529 | { | 2529 | { |
2530 | unsigned char *d, *p, *macstart; | 2530 | CBB cbb, session_ticket, ticket; |
2531 | unsigned char *enc_ticket = NULL; | ||
2531 | unsigned char *senc = NULL; | 2532 | unsigned char *senc = NULL; |
2532 | const unsigned char *const_p; | 2533 | const unsigned char *const_p; |
2533 | int len, slen_full, slen; | 2534 | unsigned char *p, *hmac; |
2535 | size_t hmac_len; | ||
2536 | int enc_ticket_len, slen; | ||
2537 | int slen_full = 0; | ||
2534 | SSL_SESSION *sess; | 2538 | SSL_SESSION *sess; |
2535 | unsigned int hlen; | 2539 | unsigned int hlen; |
2536 | EVP_CIPHER_CTX ctx; | 2540 | EVP_CIPHER_CTX ctx; |
@@ -2539,7 +2543,16 @@ ssl3_send_newsession_ticket(SSL *s) | |||
2539 | unsigned char iv[EVP_MAX_IV_LENGTH]; | 2543 | unsigned char iv[EVP_MAX_IV_LENGTH]; |
2540 | unsigned char key_name[16]; | 2544 | unsigned char key_name[16]; |
2541 | 2545 | ||
2546 | EVP_CIPHER_CTX_init(&ctx); | ||
2547 | HMAC_CTX_init(&hctx); | ||
2548 | |||
2549 | memset(&cbb, 0, sizeof(cbb)); | ||
2550 | |||
2542 | if (S3I(s)->hs.state == SSL3_ST_SW_SESSION_TICKET_A) { | 2551 | if (S3I(s)->hs.state == SSL3_ST_SW_SESSION_TICKET_A) { |
2552 | if (!ssl3_handshake_msg_start_cbb(s, &cbb, &session_ticket, | ||
2553 | SSL3_MT_NEWSESSION_TICKET)) | ||
2554 | goto err; | ||
2555 | |||
2543 | /* get session encoding length */ | 2556 | /* get session encoding length */ |
2544 | slen_full = i2d_SSL_SESSION(s->session, NULL); | 2557 | slen_full = i2d_SSL_SESSION(s->session, NULL); |
2545 | /* | 2558 | /* |
@@ -2576,24 +2589,6 @@ ssl3_send_newsession_ticket(SSL *s) | |||
2576 | SSL_SESSION_free(sess); | 2589 | SSL_SESSION_free(sess); |
2577 | 2590 | ||
2578 | /* | 2591 | /* |
2579 | * Grow buffer if need be: the length calculation is as | ||
2580 | * follows 1 (size of message name) + 3 (message length | ||
2581 | * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) + | ||
2582 | * 16 (key name) + max_iv_len (iv length) + | ||
2583 | * session_length + max_enc_block_size (max encrypted session | ||
2584 | * length) + max_md_size (HMAC). | ||
2585 | */ | ||
2586 | if (!BUF_MEM_grow(s->internal->init_buf, ssl3_handshake_msg_hdr_len(s) + | ||
2587 | 22 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + | ||
2588 | EVP_MAX_MD_SIZE + slen)) | ||
2589 | goto err; | ||
2590 | |||
2591 | d = p = ssl3_handshake_msg_start(s, SSL3_MT_NEWSESSION_TICKET); | ||
2592 | |||
2593 | EVP_CIPHER_CTX_init(&ctx); | ||
2594 | HMAC_CTX_init(&hctx); | ||
2595 | |||
2596 | /* | ||
2597 | * Initialize HMAC and cipher contexts. If callback present | 2592 | * Initialize HMAC and cipher contexts. If callback present |
2598 | * it does all the work otherwise use generated values | 2593 | * it does all the work otherwise use generated values |
2599 | * from parent ctx. | 2594 | * from parent ctx. |
@@ -2613,55 +2608,69 @@ ssl3_send_newsession_ticket(SSL *s) | |||
2613 | memcpy(key_name, tctx->internal->tlsext_tick_key_name, 16); | 2608 | memcpy(key_name, tctx->internal->tlsext_tick_key_name, 16); |
2614 | } | 2609 | } |
2615 | 2610 | ||
2611 | /* Encrypt the session ticket. */ | ||
2612 | if ((enc_ticket = calloc(1, slen + EVP_MAX_BLOCK_LENGTH)) == NULL) | ||
2613 | goto err; | ||
2614 | if (!EVP_EncryptUpdate(&ctx, enc_ticket, &enc_ticket_len, senc, slen)) | ||
2615 | goto err; | ||
2616 | if (!EVP_EncryptFinal_ex(&ctx, enc_ticket, &enc_ticket_len)) | ||
2617 | goto err; | ||
2618 | |||
2619 | /* Generate the HMAC. */ | ||
2620 | if (!HMAC_Update(&hctx, key_name, sizeof(key_name))) | ||
2621 | goto err; | ||
2622 | if (!HMAC_Update(&hctx, iv, EVP_CIPHER_CTX_iv_length(&ctx))) | ||
2623 | goto err; | ||
2624 | if (!HMAC_Update(&hctx, enc_ticket, enc_ticket_len)) | ||
2625 | goto err; | ||
2626 | |||
2627 | if ((hmac_len = HMAC_size(&hctx)) <= 0) | ||
2628 | goto err; | ||
2629 | |||
2616 | /* | 2630 | /* |
2617 | * Ticket lifetime hint (advisory only): | 2631 | * Ticket lifetime hint (advisory only): |
2618 | * We leave this unspecified for resumed session | 2632 | * We leave this unspecified for resumed session |
2619 | * (for simplicity), and guess that tickets for new | 2633 | * (for simplicity), and guess that tickets for new |
2620 | * sessions will live as long as their sessions. | 2634 | * sessions will live as long as their sessions. |
2621 | */ | 2635 | */ |
2622 | l2n(s->internal->hit ? 0 : s->session->timeout, p); | 2636 | if (!CBB_add_u32(&session_ticket, |
2623 | 2637 | s->internal->hit ? 0 : s->session->timeout)) | |
2624 | /* Skip ticket length for now */ | 2638 | goto err; |
2625 | p += 2; | ||
2626 | /* Output key name */ | ||
2627 | macstart = p; | ||
2628 | memcpy(p, key_name, 16); | ||
2629 | p += 16; | ||
2630 | /* output IV */ | ||
2631 | memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); | ||
2632 | p += EVP_CIPHER_CTX_iv_length(&ctx); | ||
2633 | /* Encrypt session data */ | ||
2634 | EVP_EncryptUpdate(&ctx, p, &len, senc, slen); | ||
2635 | p += len; | ||
2636 | EVP_EncryptFinal_ex(&ctx, p, &len); | ||
2637 | p += len; | ||
2638 | EVP_CIPHER_CTX_cleanup(&ctx); | ||
2639 | |||
2640 | HMAC_Update(&hctx, macstart, p - macstart); | ||
2641 | HMAC_Final(&hctx, p, &hlen); | ||
2642 | HMAC_CTX_cleanup(&hctx); | ||
2643 | p += hlen; | ||
2644 | |||
2645 | /* Now write out lengths: p points to end of data written */ | ||
2646 | /* Total length */ | ||
2647 | len = p - d; | ||
2648 | |||
2649 | /* Skip ticket lifetime hint. */ | ||
2650 | p = d + 4; | ||
2651 | s2n(len - 6, p); /* Message length */ | ||
2652 | |||
2653 | ssl3_handshake_msg_finish(s, len); | ||
2654 | 2639 | ||
2655 | S3I(s)->hs.state = SSL3_ST_SW_SESSION_TICKET_B; | 2640 | if (!CBB_add_u16_length_prefixed(&session_ticket, &ticket)) |
2641 | goto err; | ||
2642 | if (!CBB_add_bytes(&ticket, key_name, sizeof(key_name))) | ||
2643 | goto err; | ||
2644 | if (!CBB_add_bytes(&ticket, iv, EVP_CIPHER_CTX_iv_length(&ctx))) | ||
2645 | goto err; | ||
2646 | if (!CBB_add_bytes(&ticket, enc_ticket, enc_ticket_len)) | ||
2647 | goto err; | ||
2648 | if (!CBB_add_space(&ticket, &hmac, hmac_len)) | ||
2649 | goto err; | ||
2656 | 2650 | ||
2657 | freezero(senc, slen_full); | 2651 | if (!HMAC_Final(&hctx, hmac, &hlen)) |
2652 | goto err; | ||
2653 | |||
2654 | if (!ssl3_handshake_msg_finish_cbb(s, &cbb)) | ||
2655 | goto err; | ||
2656 | |||
2657 | S3I(s)->hs.state = SSL3_ST_SW_SESSION_TICKET_B; | ||
2658 | } | 2658 | } |
2659 | 2659 | ||
2660 | EVP_CIPHER_CTX_cleanup(&ctx); | ||
2661 | HMAC_CTX_cleanup(&hctx); | ||
2662 | freezero(senc, slen_full); | ||
2663 | free(enc_ticket); | ||
2664 | |||
2660 | /* SSL3_ST_SW_SESSION_TICKET_B */ | 2665 | /* SSL3_ST_SW_SESSION_TICKET_B */ |
2661 | return (ssl3_handshake_write(s)); | 2666 | return (ssl3_handshake_write(s)); |
2662 | 2667 | ||
2663 | err: | 2668 | err: |
2669 | CBB_cleanup(&cbb); | ||
2670 | EVP_CIPHER_CTX_cleanup(&ctx); | ||
2671 | HMAC_CTX_cleanup(&hctx); | ||
2664 | freezero(senc, slen_full); | 2672 | freezero(senc, slen_full); |
2673 | free(enc_ticket); | ||
2665 | 2674 | ||
2666 | return (-1); | 2675 | return (-1); |
2667 | } | 2676 | } |