summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2018-08-27 16:42:48 +0000
committerjsing <>2018-08-27 16:42:48 +0000
commit8007465805b60ee08ec66aa02d3525e1a058629c (patch)
tree71671a4717389a51b5152df1689cea13e657f8ca
parentefb4b7d294563bb79e9a64739754b78928308802 (diff)
downloadopenbsd-8007465805b60ee08ec66aa02d3525e1a058629c.tar.gz
openbsd-8007465805b60ee08ec66aa02d3525e1a058629c.tar.bz2
openbsd-8007465805b60ee08ec66aa02d3525e1a058629c.zip
Simplify new session ticket encoding/generation.
The original code did a crazy encode/malloc/encode/decode/modify/encode dance, in order to encode a session in the form needed to encrypt then add to a session ticket. By modifying the encoding functions slightly, we can do this entire dance as a single encode. Inspired by similar changes in BoringSSL. ok inoguchi@ tb@
-rw-r--r--src/lib/libssl/ssl_asn1.c69
-rw-r--r--src/lib/libssl/ssl_locl.h4
-rw-r--r--src/lib/libssl/ssl_srvr.c101
3 files changed, 90 insertions, 84 deletions
diff --git a/src/lib/libssl/ssl_asn1.c b/src/lib/libssl/ssl_asn1.c
index 0ca442faa0..94fc8685fc 100644
--- a/src/lib/libssl/ssl_asn1.c
+++ b/src/lib/libssl/ssl_asn1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_asn1.c,v 1.56 2018/03/20 16:10:57 jsing Exp $ */ 1/* $OpenBSD: ssl_asn1.c,v 1.57 2018/08/27 16:42:48 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2016 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -44,23 +44,16 @@ time_max(void)
44 return 0; 44 return 0;
45} 45}
46 46
47int 47static int
48i2d_SSL_SESSION(SSL_SESSION *s, unsigned char **pp) 48SSL_SESSION_encode(SSL_SESSION *s, unsigned char **out, size_t *out_len,
49 int ticket_encoding)
49{ 50{
50 CBB cbb, session, cipher_suite, session_id, master_key, time, timeout; 51 CBB cbb, session, cipher_suite, session_id, master_key, time, timeout;
51 CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket; 52 CBB peer_cert, sidctx, verify_result, hostname, lifetime, ticket, value;
52 CBB value; 53 unsigned char *peer_cert_bytes = NULL;
53 unsigned char *data = NULL, *peer_cert_bytes = NULL; 54 int len, rv = 0;
54 size_t data_len = 0;
55 int len, rv = -1;
56 uint16_t cid; 55 uint16_t cid;
57 56
58 if (s == NULL)
59 return (0);
60
61 if (s->cipher == NULL && s->cipher_id == 0)
62 return (0);
63
64 if (!CBB_init(&cbb, 0)) 57 if (!CBB_init(&cbb, 0))
65 goto err; 58 goto err;
66 59
@@ -87,10 +80,11 @@ i2d_SSL_SESSION(SSL_SESSION *s, unsigned char **pp)
87 if (!CBB_add_u16(&cipher_suite, cid)) 80 if (!CBB_add_u16(&cipher_suite, cid))
88 goto err; 81 goto err;
89 82
90 /* Session ID. */ 83 /* Session ID - zero length for a ticket. */
91 if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING)) 84 if (!CBB_add_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING))
92 goto err; 85 goto err;
93 if (!CBB_add_bytes(&session_id, s->session_id, s->session_id_length)) 86 if (!CBB_add_bytes(&session_id, s->session_id,
87 ticket_encoding ? 0 : s->session_id_length))
94 goto err; 88 goto err;
95 89
96 /* Master key. */ 90 /* Master key. */
@@ -173,7 +167,7 @@ i2d_SSL_SESSION(SSL_SESSION *s, unsigned char **pp)
173 } 167 }
174 168
175 /* Ticket [10]. */ 169 /* Ticket [10]. */
176 if (s->tlsext_tick) { 170 if (s->tlsext_tick != NULL) {
177 if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG)) 171 if (!CBB_add_asn1(&session, &ticket, SSLASN1_TICKET_TAG))
178 goto err; 172 goto err;
179 if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING)) 173 if (!CBB_add_asn1(&ticket, &value, CBS_ASN1_OCTETSTRING))
@@ -185,7 +179,44 @@ i2d_SSL_SESSION(SSL_SESSION *s, unsigned char **pp)
185 /* Compression method [11]. */ 179 /* Compression method [11]. */
186 /* SRP username [12]. */ 180 /* SRP username [12]. */
187 181
188 if (!CBB_finish(&cbb, &data, &data_len)) 182 if (!CBB_finish(&cbb, out, out_len))
183 goto err;
184
185 rv = 1;
186
187 err:
188 CBB_cleanup(&cbb);
189 free(peer_cert_bytes);
190
191 return rv;
192}
193
194int
195SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len)
196{
197 if (ss == NULL)
198 return 0;
199
200 if (ss->cipher == NULL && ss->cipher_id == 0)
201 return 0;
202
203 return SSL_SESSION_encode(ss, out, out_len, 1);
204}
205
206int
207i2d_SSL_SESSION(SSL_SESSION *ss, unsigned char **pp)
208{
209 unsigned char *data = NULL;
210 size_t data_len = 0;
211 int rv = -1;
212
213 if (ss == NULL)
214 return 0;
215
216 if (ss->cipher == NULL && ss->cipher_id == 0)
217 return 0;
218
219 if (!SSL_SESSION_encode(ss, &data, &data_len, 0))
189 goto err; 220 goto err;
190 221
191 if (data_len > INT_MAX) 222 if (data_len > INT_MAX)
@@ -204,9 +235,7 @@ i2d_SSL_SESSION(SSL_SESSION *s, unsigned char **pp)
204 rv = (int)data_len; 235 rv = (int)data_len;
205 236
206 err: 237 err:
207 CBB_cleanup(&cbb);
208 freezero(data, data_len); 238 freezero(data, data_len);
209 free(peer_cert_bytes);
210 239
211 return rv; 240 return rv;
212} 241}
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 44afd1717e..39aabb05fb 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.209 2018/08/24 18:10:25 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.210 2018/08/27 16:42:48 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 *
@@ -1089,6 +1089,8 @@ int ssl_has_ecc_ciphers(SSL *s);
1089int ssl_verify_alarm_type(long type); 1089int ssl_verify_alarm_type(long type);
1090void ssl_load_ciphers(void); 1090void ssl_load_ciphers(void);
1091 1091
1092int SSL_SESSION_ticket(SSL_SESSION *ss, unsigned char **out, size_t *out_len);
1093
1092const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); 1094const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
1093int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); 1095int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
1094int ssl3_send_server_certificate(SSL *s); 1096int ssl3_send_server_certificate(SSL *s);
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index f06491e558..b099fdb8b1 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.45 2018/08/24 18:10:25 jsing Exp $ */ 1/* $OpenBSD: ssl_srvr.c,v 1.46 2018/08/27 16:42:48 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 *
@@ -2526,20 +2526,21 @@ int
2526ssl3_send_newsession_ticket(SSL *s) 2526ssl3_send_newsession_ticket(SSL *s)
2527{ 2527{
2528 CBB cbb, session_ticket, ticket; 2528 CBB cbb, session_ticket, ticket;
2529 unsigned char *enc_ticket = NULL;
2530 unsigned char *senc = NULL;
2531 const unsigned char *const_p;
2532 unsigned char *p, *hmac;
2533 size_t hmac_len;
2534 int enc_ticket_len, len, slen;
2535 int slen_full = 0;
2536 SSL_SESSION *sess;
2537 unsigned int hlen;
2538 EVP_CIPHER_CTX ctx;
2539 HMAC_CTX hctx;
2540 SSL_CTX *tctx = s->initial_ctx; 2529 SSL_CTX *tctx = s->initial_ctx;
2530 size_t enc_session_len, enc_session_max_len, hmac_len;
2531 size_t session_len = 0;
2532 unsigned char *enc_session = NULL, *session = NULL;
2541 unsigned char iv[EVP_MAX_IV_LENGTH]; 2533 unsigned char iv[EVP_MAX_IV_LENGTH];
2542 unsigned char key_name[16]; 2534 unsigned char key_name[16];
2535 unsigned char *hmac;
2536 unsigned int hlen;
2537 EVP_CIPHER_CTX ctx;
2538 HMAC_CTX hctx;
2539 int len;
2540
2541 /*
2542 * New Session Ticket - RFC 5077, section 3.3.
2543 */
2543 2544
2544 EVP_CIPHER_CTX_init(&ctx); 2545 EVP_CIPHER_CTX_init(&ctx);
2545 HMAC_CTX_init(&hctx); 2546 HMAC_CTX_init(&hctx);
@@ -2551,47 +2552,17 @@ ssl3_send_newsession_ticket(SSL *s)
2551 SSL3_MT_NEWSESSION_TICKET)) 2552 SSL3_MT_NEWSESSION_TICKET))
2552 goto err; 2553 goto err;
2553 2554
2554 /* get session encoding length */ 2555 if (!SSL_SESSION_ticket(s->session, &session, &session_len))
2555 slen_full = i2d_SSL_SESSION(s->session, NULL);
2556 /*
2557 * Some length values are 16 bits, so forget it if session is
2558 * too long
2559 */
2560 if (slen_full > 0xFF00)
2561 goto err; 2556 goto err;
2562 senc = malloc(slen_full); 2557 if (session_len > 0xffff)
2563 if (!senc)
2564 goto err; 2558 goto err;
2565 p = senc;
2566 i2d_SSL_SESSION(s->session, &p);
2567 2559
2568 /* 2560 /*
2569 * Create a fresh copy (not shared with other threads) to 2561 * Initialize HMAC and cipher contexts. If callback is present
2570 * clean up 2562 * it does all the work, otherwise use generated values from
2563 * parent context.
2571 */ 2564 */
2572 const_p = senc; 2565 if (tctx->internal->tlsext_ticket_key_cb != NULL) {
2573 sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
2574 if (sess == NULL)
2575 goto err;
2576
2577 /* ID is irrelevant for the ticket */
2578 sess->session_id_length = 0;
2579
2580 slen = i2d_SSL_SESSION(sess, NULL);
2581 if (slen > slen_full) {
2582 /* shouldn't ever happen */
2583 goto err;
2584 }
2585 p = senc;
2586 i2d_SSL_SESSION(sess, &p);
2587 SSL_SESSION_free(sess);
2588
2589 /*
2590 * Initialize HMAC and cipher contexts. If callback present
2591 * it does all the work otherwise use generated values
2592 * from parent ctx.
2593 */
2594 if (tctx->internal->tlsext_ticket_key_cb) {
2595 if (tctx->internal->tlsext_ticket_key_cb(s, 2566 if (tctx->internal->tlsext_ticket_key_cb(s,
2596 key_name, iv, &ctx, &hctx, 1) < 0) { 2567 key_name, iv, &ctx, &hctx, 1) < 0) {
2597 EVP_CIPHER_CTX_cleanup(&ctx); 2568 EVP_CIPHER_CTX_cleanup(&ctx);
@@ -2606,19 +2577,21 @@ ssl3_send_newsession_ticket(SSL *s)
2606 memcpy(key_name, tctx->internal->tlsext_tick_key_name, 16); 2577 memcpy(key_name, tctx->internal->tlsext_tick_key_name, 16);
2607 } 2578 }
2608 2579
2609 /* Encrypt the session ticket. */ 2580 /* Encrypt the session state. */
2610 if ((enc_ticket = calloc(1, slen + EVP_MAX_BLOCK_LENGTH)) == NULL) 2581 enc_session_max_len = session_len + EVP_MAX_BLOCK_LENGTH;
2582 if ((enc_session = calloc(1, enc_session_max_len)) == NULL)
2611 goto err; 2583 goto err;
2612 enc_ticket_len = 0; 2584 enc_session_len = 0;
2613 if (!EVP_EncryptUpdate(&ctx, enc_ticket, &len, senc, slen)) 2585 if (!EVP_EncryptUpdate(&ctx, enc_session, &len, session,
2586 session_len))
2614 goto err; 2587 goto err;
2615 enc_ticket_len += len; 2588 enc_session_len += len;
2616 if (!EVP_EncryptFinal_ex(&ctx, enc_ticket + enc_ticket_len, &len)) 2589 if (!EVP_EncryptFinal_ex(&ctx, enc_session + enc_session_len,
2590 &len))
2617 goto err; 2591 goto err;
2618 enc_ticket_len += len; 2592 enc_session_len += len;
2619 2593
2620 if (enc_ticket_len < 0 || 2594 if (enc_session_len > enc_session_max_len)
2621 enc_ticket_len > slen + EVP_MAX_BLOCK_LENGTH)
2622 goto err; 2595 goto err;
2623 2596
2624 /* Generate the HMAC. */ 2597 /* Generate the HMAC. */
@@ -2626,7 +2599,7 @@ ssl3_send_newsession_ticket(SSL *s)
2626 goto err; 2599 goto err;
2627 if (!HMAC_Update(&hctx, iv, EVP_CIPHER_CTX_iv_length(&ctx))) 2600 if (!HMAC_Update(&hctx, iv, EVP_CIPHER_CTX_iv_length(&ctx)))
2628 goto err; 2601 goto err;
2629 if (!HMAC_Update(&hctx, enc_ticket, enc_ticket_len)) 2602 if (!HMAC_Update(&hctx, enc_session, enc_session_len))
2630 goto err; 2603 goto err;
2631 2604
2632 if ((hmac_len = HMAC_size(&hctx)) <= 0) 2605 if ((hmac_len = HMAC_size(&hctx)) <= 0)
@@ -2648,13 +2621,15 @@ ssl3_send_newsession_ticket(SSL *s)
2648 goto err; 2621 goto err;
2649 if (!CBB_add_bytes(&ticket, iv, EVP_CIPHER_CTX_iv_length(&ctx))) 2622 if (!CBB_add_bytes(&ticket, iv, EVP_CIPHER_CTX_iv_length(&ctx)))
2650 goto err; 2623 goto err;
2651 if (!CBB_add_bytes(&ticket, enc_ticket, enc_ticket_len)) 2624 if (!CBB_add_bytes(&ticket, enc_session, enc_session_len))
2652 goto err; 2625 goto err;
2653 if (!CBB_add_space(&ticket, &hmac, hmac_len)) 2626 if (!CBB_add_space(&ticket, &hmac, hmac_len))
2654 goto err; 2627 goto err;
2655 2628
2656 if (!HMAC_Final(&hctx, hmac, &hlen)) 2629 if (!HMAC_Final(&hctx, hmac, &hlen))
2657 goto err; 2630 goto err;
2631 if (hlen != hmac_len)
2632 goto err;
2658 2633
2659 if (!ssl3_handshake_msg_finish(s, &cbb)) 2634 if (!ssl3_handshake_msg_finish(s, &cbb))
2660 goto err; 2635 goto err;
@@ -2664,8 +2639,8 @@ ssl3_send_newsession_ticket(SSL *s)
2664 2639
2665 EVP_CIPHER_CTX_cleanup(&ctx); 2640 EVP_CIPHER_CTX_cleanup(&ctx);
2666 HMAC_CTX_cleanup(&hctx); 2641 HMAC_CTX_cleanup(&hctx);
2667 freezero(senc, slen_full); 2642 freezero(session, session_len);
2668 free(enc_ticket); 2643 free(enc_session);
2669 2644
2670 /* SSL3_ST_SW_SESSION_TICKET_B */ 2645 /* SSL3_ST_SW_SESSION_TICKET_B */
2671 return (ssl3_handshake_write(s)); 2646 return (ssl3_handshake_write(s));
@@ -2674,8 +2649,8 @@ ssl3_send_newsession_ticket(SSL *s)
2674 CBB_cleanup(&cbb); 2649 CBB_cleanup(&cbb);
2675 EVP_CIPHER_CTX_cleanup(&ctx); 2650 EVP_CIPHER_CTX_cleanup(&ctx);
2676 HMAC_CTX_cleanup(&hctx); 2651 HMAC_CTX_cleanup(&hctx);
2677 freezero(senc, slen_full); 2652 freezero(session, session_len);
2678 free(enc_ticket); 2653 free(enc_session);
2679 2654
2680 return (-1); 2655 return (-1);
2681} 2656}