summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2018-08-24 18:10:25 +0000
committerjsing <>2018-08-24 18:10:25 +0000
commit84fe391fb9021a6be2b592ffb9543ccc421a80be (patch)
treefabc473b718cb60026ab4e730baa46df5eaee4dc
parent32564ad6b169c4d391b5303bf7ed7e516be54aca (diff)
downloadopenbsd-84fe391fb9021a6be2b592ffb9543ccc421a80be.tar.gz
openbsd-84fe391fb9021a6be2b592ffb9543ccc421a80be.tar.bz2
openbsd-84fe391fb9021a6be2b592ffb9543ccc421a80be.zip
Simplify session ticket parsing/handling.
The original implementation is rather crazy and means that we effectively have two lots of code that parse a ClientHello and two lots of code that parse TLS extensions. Partially simplify this by passing a CBS containing the extension block through to the session handling functions, removing the need to reimplement the ClientHello parsing. While here standarise on naming for session_id and session_id_len. ok inoguchi@ tb@
-rw-r--r--src/lib/libssl/ssl_locl.h13
-rw-r--r--src/lib/libssl/ssl_sess.c22
-rw-r--r--src/lib/libssl/ssl_srvr.c15
-rw-r--r--src/lib/libssl/t1_lib.c65
4 files changed, 46 insertions, 69 deletions
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index e5423859af..44afd1717e 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.208 2018/08/24 17:30:32 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.209 2018/08/24 18:10:25 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 *
@@ -1056,10 +1056,11 @@ void ssl_cert_free(CERT *c);
1056SESS_CERT *ssl_sess_cert_new(void); 1056SESS_CERT *ssl_sess_cert_new(void);
1057void ssl_sess_cert_free(SESS_CERT *sc); 1057void ssl_sess_cert_free(SESS_CERT *sc);
1058int ssl_get_new_session(SSL *s, int session); 1058int ssl_get_new_session(SSL *s, int session);
1059int ssl_get_prev_session(SSL *s, unsigned char *session, int len, 1059int ssl_get_prev_session(SSL *s, const unsigned char *session_id,
1060 const unsigned char *limit); 1060 int session_id_len, CBS *ext_block);
1061int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); 1061int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
1062SSL_CIPHER *OBJ_bsearch_ssl_cipher_id(SSL_CIPHER *key, SSL_CIPHER const *base, int num); 1062SSL_CIPHER *OBJ_bsearch_ssl_cipher_id(SSL_CIPHER *key, SSL_CIPHER const *base,
1063 int num);
1063int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap, 1064int ssl_cipher_ptr_id_cmp(const SSL_CIPHER * const *ap,
1064 const SSL_CIPHER * const *bp); 1065 const SSL_CIPHER * const *bp);
1065int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb); 1066int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *ciphers, CBB *cbb);
@@ -1278,8 +1279,8 @@ int ssl_check_clienthello_tlsext_late(SSL *s);
1278int ssl_check_serverhello_tlsext(SSL *s); 1279int ssl_check_serverhello_tlsext(SSL *s);
1279 1280
1280#define tlsext_tick_md EVP_sha256 1281#define tlsext_tick_md EVP_sha256
1281int tls1_process_ticket(SSL *s, const unsigned char *session_id, int len, 1282int tls1_process_ticket(SSL *s, const unsigned char *session_id,
1282 const unsigned char *limit, SSL_SESSION **ret); 1283 int session_id_len, CBS *ext_block, SSL_SESSION **ret);
1283int tls12_get_hashid(const EVP_MD *md); 1284int tls12_get_hashid(const EVP_MD *md);
1284int tls12_get_sigid(const EVP_PKEY *pk); 1285int tls12_get_sigid(const EVP_PKEY *pk);
1285int tls12_get_hashandsig(CBB *cbb, const EVP_PKEY *pk, const EVP_MD *md); 1286int tls12_get_hashandsig(CBB *cbb, const EVP_PKEY *pk, const EVP_MD *md);
diff --git a/src/lib/libssl/ssl_sess.c b/src/lib/libssl/ssl_sess.c
index 8ebeb273fe..52a1a0cc47 100644
--- a/src/lib/libssl/ssl_sess.c
+++ b/src/lib/libssl/ssl_sess.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_sess.c,v 1.80 2018/04/25 07:10:39 tb Exp $ */ 1/* $OpenBSD: ssl_sess.c,v 1.81 2018/08/24 18:10:25 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 *
@@ -420,8 +420,8 @@ sess_id_done:
420 * session_id: points at the session ID in the ClientHello. This code will 420 * session_id: points at the session ID in the ClientHello. This code will
421 * read past the end of this in order to parse out the session ticket 421 * read past the end of this in order to parse out the session ticket
422 * extension, if any. 422 * extension, if any.
423 * len: the length of the session ID. 423 * session_id_len: the length of the session ID.
424 * limit: a pointer to the first byte after the ClientHello. 424 * ext_block: a CBS for the ClientHello extensions block.
425 * 425 *
426 * Returns: 426 * Returns:
427 * -1: error 427 * -1: error
@@ -435,8 +435,8 @@ sess_id_done:
435 * to 1 if the server should issue a new session ticket (to 0 otherwise). 435 * to 1 if the server should issue a new session ticket (to 0 otherwise).
436 */ 436 */
437int 437int
438ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, 438ssl_get_prev_session(SSL *s, const unsigned char *session_id,
439 const unsigned char *limit) 439 int session_id_len, CBS *ext_block)
440{ 440{
441 SSL_SESSION *ret = NULL; 441 SSL_SESSION *ret = NULL;
442 int fatal = 0; 442 int fatal = 0;
@@ -445,14 +445,14 @@ ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
445 445
446 /* This is used only by servers. */ 446 /* This is used only by servers. */
447 447
448 if (len > SSL_MAX_SSL_SESSION_ID_LENGTH) 448 if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH)
449 goto err; 449 goto err;
450 450
451 if (len == 0) 451 if (session_id_len == 0)
452 try_session_cache = 0; 452 try_session_cache = 0;
453 453
454 /* Sets s->internal->tlsext_ticket_expected. */ 454 /* Sets s->internal->tlsext_ticket_expected. */
455 r = tls1_process_ticket(s, session_id, len, limit, &ret); 455 r = tls1_process_ticket(s, session_id, session_id_len, ext_block, &ret);
456 switch (r) { 456 switch (r) {
457 case -1: /* Error during processing */ 457 case -1: /* Error during processing */
458 fatal = 1; 458 fatal = 1;
@@ -473,8 +473,8 @@ ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
473 SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { 473 SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
474 SSL_SESSION data; 474 SSL_SESSION data;
475 data.ssl_version = s->version; 475 data.ssl_version = s->version;
476 data.session_id_length = len; 476 data.session_id_length = session_id_len;
477 memcpy(data.session_id, session_id, len); 477 memcpy(data.session_id, session_id, session_id_len);
478 478
479 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); 479 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
480 ret = lh_SSL_SESSION_retrieve(s->session_ctx->internal->sessions, &data); 480 ret = lh_SSL_SESSION_retrieve(s->session_ctx->internal->sessions, &data);
@@ -494,7 +494,7 @@ ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
494 int copy = 1; 494 int copy = 1;
495 495
496 if ((ret = s->session_ctx->internal->get_session_cb(s, 496 if ((ret = s->session_ctx->internal->get_session_cb(s,
497 session_id, len, &copy))) { 497 session_id, session_id_len, &copy))) {
498 s->session_ctx->internal->stats.sess_cb_hit++; 498 s->session_ctx->internal->stats.sess_cb_hit++;
499 499
500 /* 500 /*
diff --git a/src/lib/libssl/ssl_srvr.c b/src/lib/libssl/ssl_srvr.c
index b9b2c58705..f06491e558 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.44 2018/08/24 17:44:22 jsing Exp $ */ 1/* $OpenBSD: ssl_srvr.c,v 1.45 2018/08/24 18:10:25 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 *
@@ -818,7 +818,6 @@ ssl3_get_client_hello(SSL *s)
818 unsigned long alg_k; 818 unsigned long alg_k;
819 const SSL_METHOD *method; 819 const SSL_METHOD *method;
820 uint16_t shared_version; 820 uint16_t shared_version;
821 unsigned char *end;
822 821
823 /* 822 /*
824 * We do this so that we will respond with our native type. 823 * We do this so that we will respond with our native type.
@@ -842,8 +841,6 @@ ssl3_get_client_hello(SSL *s)
842 if (n < 0) 841 if (n < 0)
843 goto err; 842 goto err;
844 843
845 end = (unsigned char *)s->internal->init_msg + n;
846
847 CBS_init(&cbs, s->internal->init_msg, n); 844 CBS_init(&cbs, s->internal->init_msg, n);
848 845
849 /* Parse client hello up until the extensions (if any). */ 846 /* Parse client hello up until the extensions (if any). */
@@ -928,10 +925,12 @@ ssl3_get_client_hello(SSL *s)
928 if (!ssl_get_new_session(s, 1)) 925 if (!ssl_get_new_session(s, 1))
929 goto err; 926 goto err;
930 } else { 927 } else {
931 /* XXX - pass CBS through instead... */ 928 CBS ext_block;
932 i = ssl_get_prev_session(s, 929
933 (unsigned char *)CBS_data(&session_id), 930 CBS_dup(&cbs, &ext_block);
934 CBS_len(&session_id), end); 931
932 i = ssl_get_prev_session(s, CBS_data(&session_id),
933 CBS_len(&session_id), &ext_block);
935 if (i == 1) { /* previous session */ 934 if (i == 1) { /* previous session */
936 s->internal->hit = 1; 935 s->internal->hit = 1;
937 } else if (i == -1) 936 } else if (i == -1)
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 1b2e0844fb..0a00e4da7f 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_lib.c,v 1.143 2018/08/19 15:38:03 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.144 2018/08/24 18:10:25 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 *
@@ -815,11 +815,9 @@ ssl_check_serverhello_tlsext(SSL *s)
815 * ClientHello, and other operations depend on the result, we need to handle 815 * ClientHello, and other operations depend on the result, we need to handle
816 * any TLS session ticket extension at the same time. 816 * any TLS session ticket extension at the same time.
817 * 817 *
818 * session_id: points at the session ID in the ClientHello. This code will 818 * session_id: points at the session ID in the ClientHello.
819 * read past the end of this in order to parse out the session ticket 819 * session_id_len: the length of the session ID.
820 * extension, if any. 820 * ext_block: a CBS for the ClientHello extensions block.
821 * len: the length of the session ID.
822 * limit: a pointer to the first byte after the ClientHello.
823 * ret: (output) on return, if a ticket was decrypted, then this is set to 821 * ret: (output) on return, if a ticket was decrypted, then this is set to
824 * point to the resulting session. 822 * point to the resulting session.
825 * 823 *
@@ -845,55 +843,34 @@ ssl_check_serverhello_tlsext(SSL *s)
845 * Otherwise, s->internal->tlsext_ticket_expected is set to 0. 843 * Otherwise, s->internal->tlsext_ticket_expected is set to 0.
846 */ 844 */
847int 845int
848tls1_process_ticket(SSL *s, const unsigned char *session, int session_len, 846tls1_process_ticket(SSL *s, const unsigned char *session_id, int session_id_len,
849 const unsigned char *limit, SSL_SESSION **ret) 847 CBS *ext_block, SSL_SESSION **ret)
850{ 848{
851 /* Point after session ID in client hello */ 849 CBS extensions;
852 CBS session_id, cookie, cipher_list, compress_algo, extensions;
853 850
854 *ret = NULL;
855 s->internal->tlsext_ticket_expected = 0; 851 s->internal->tlsext_ticket_expected = 0;
852 *ret = NULL;
856 853
857 /* If tickets disabled behave as if no ticket present 854 /*
858 * to permit stateful resumption. 855 * If tickets disabled behave as if no ticket present to permit stateful
856 * resumption.
859 */ 857 */
860 if (SSL_get_options(s) & SSL_OP_NO_TICKET) 858 if (SSL_get_options(s) & SSL_OP_NO_TICKET)
861 return 0; 859 return 0;
862 if (!limit)
863 return 0;
864
865 if (limit < session)
866 return -1;
867 860
868 CBS_init(&session_id, session, limit - session); 861 /*
869 862 * An empty extensions block is valid, but obviously does not contain
870 /* Skip past the session id */ 863 * a session ticket.
871 if (!CBS_skip(&session_id, session_len)) 864 */
872 return -1; 865 if (CBS_len(ext_block) == 0)
873
874 /* Skip past DTLS cookie */
875 if (SSL_IS_DTLS(s)) {
876 if (!CBS_get_u8_length_prefixed(&session_id, &cookie))
877 return -1;
878 }
879
880 /* Skip past cipher list */
881 if (!CBS_get_u16_length_prefixed(&session_id, &cipher_list))
882 return -1;
883
884 /* Skip past compression algorithm list */
885 if (!CBS_get_u8_length_prefixed(&session_id, &compress_algo))
886 return -1;
887
888 /* Now at start of extensions */
889 if (CBS_len(&session_id) == 0)
890 return 0; 866 return 0;
891 if (!CBS_get_u16_length_prefixed(&session_id, &extensions)) 867
868 if (!CBS_get_u16_length_prefixed(ext_block, &extensions))
892 return -1; 869 return -1;
893 870
894 while (CBS_len(&extensions) > 0) { 871 while (CBS_len(&extensions) > 0) {
895 CBS ext_data;
896 uint16_t ext_type; 872 uint16_t ext_type;
873 CBS ext_data;
897 874
898 if (!CBS_get_u16(&extensions, &ext_type) || 875 if (!CBS_get_u16(&extensions, &ext_type) ||
899 !CBS_get_u16_length_prefixed(&extensions, &ext_data)) 876 !CBS_get_u16_length_prefixed(&extensions, &ext_data))
@@ -907,7 +884,7 @@ tls1_process_ticket(SSL *s, const unsigned char *session, int session_len,
907 s->internal->tlsext_ticket_expected = 1; 884 s->internal->tlsext_ticket_expected = 1;
908 return 1; 885 return 1;
909 } 886 }
910 if (s->internal->tls_session_secret_cb) { 887 if (s->internal->tls_session_secret_cb != NULL) {
911 /* Indicate that the ticket couldn't be 888 /* Indicate that the ticket couldn't be
912 * decrypted rather than generating the session 889 * decrypted rather than generating the session
913 * from ticket now, trigger abbreviated 890 * from ticket now, trigger abbreviated
@@ -917,7 +894,7 @@ tls1_process_ticket(SSL *s, const unsigned char *session, int session_len,
917 } 894 }
918 895
919 r = tls_decrypt_ticket(s, CBS_data(&ext_data), 896 r = tls_decrypt_ticket(s, CBS_data(&ext_data),
920 CBS_len(&ext_data), session, session_len, ret); 897 CBS_len(&ext_data), session_id, session_id_len, ret);
921 898
922 switch (r) { 899 switch (r) {
923 case 2: /* ticket couldn't be decrypted */ 900 case 2: /* ticket couldn't be decrypted */