diff options
-rw-r--r-- | src/lib/libssl/t1_lib.c | 116 |
1 files changed, 72 insertions, 44 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c index d21e6ef646..e83a9eaadf 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.160 2019/04/22 16:03:54 jsing Exp $ */ | 1 | /* $OpenBSD: t1_lib.c,v 1.161 2019/04/23 17:02:45 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 | * |
@@ -122,8 +122,8 @@ | |||
122 | #include "ssl_sigalgs.h" | 122 | #include "ssl_sigalgs.h" |
123 | #include "ssl_tlsext.h" | 123 | #include "ssl_tlsext.h" |
124 | 124 | ||
125 | static int tls_decrypt_ticket(SSL *s, CBS *session_id, | 125 | static int tls_decrypt_ticket(SSL *s, CBS *session_id, CBS *ticket, |
126 | const unsigned char *tick, int ticklen, SSL_SESSION **psess); | 126 | SSL_SESSION **psess); |
127 | 127 | ||
128 | SSL3_ENC_METHOD TLSv1_enc_data = { | 128 | SSL3_ENC_METHOD TLSv1_enc_data = { |
129 | .enc = tls1_enc, | 129 | .enc = tls1_enc, |
@@ -842,8 +842,7 @@ tls1_process_ticket(SSL *s, CBS *session_id, CBS *ext_block, SSL_SESSION **ret) | |||
842 | return 2; | 842 | return 2; |
843 | } | 843 | } |
844 | 844 | ||
845 | r = tls_decrypt_ticket(s, session_id, CBS_data(&ext_data), | 845 | r = tls_decrypt_ticket(s, session_id, &ext_data, ret); |
846 | CBS_len(&ext_data), ret); | ||
847 | switch (r) { | 846 | switch (r) { |
848 | case 2: /* ticket couldn't be decrypted */ | 847 | case 2: /* ticket couldn't be decrypted */ |
849 | s->internal->tlsext_ticket_expected = 1; | 848 | s->internal->tlsext_ticket_expected = 1; |
@@ -861,8 +860,7 @@ tls1_process_ticket(SSL *s, CBS *session_id, CBS *ext_block, SSL_SESSION **ret) | |||
861 | /* tls_decrypt_ticket attempts to decrypt a session ticket. | 860 | /* tls_decrypt_ticket attempts to decrypt a session ticket. |
862 | * | 861 | * |
863 | * session_id: a CBS containing the session ID. | 862 | * session_id: a CBS containing the session ID. |
864 | * etick: points to the body of the session ticket extension. | 863 | * ticket: a CBS containing the body of the session ticket extension. |
865 | * eticklen: the length of the session tickets extenion. | ||
866 | * psess: (output) on return, if a ticket was decrypted, then this is set to | 864 | * psess: (output) on return, if a ticket was decrypted, then this is set to |
867 | * point to the resulting session. | 865 | * point to the resulting session. |
868 | * | 866 | * |
@@ -873,15 +871,15 @@ tls1_process_ticket(SSL *s, CBS *session_id, CBS *ext_block, SSL_SESSION **ret) | |||
873 | * 4: same as 3, but the ticket needs to be renewed. | 871 | * 4: same as 3, but the ticket needs to be renewed. |
874 | */ | 872 | */ |
875 | static int | 873 | static int |
876 | tls_decrypt_ticket(SSL *s, CBS *session_id, const unsigned char *etick, | 874 | tls_decrypt_ticket(SSL *s, CBS *session_id, CBS *ticket, SSL_SESSION **psess) |
877 | int eticklen, SSL_SESSION **psess) | ||
878 | { | 875 | { |
876 | CBS ticket_name, ticket_iv, ticket_encdata, ticket_hmac; | ||
879 | SSL_SESSION *sess = NULL; | 877 | SSL_SESSION *sess = NULL; |
880 | size_t session_id_len = 0; | 878 | size_t session_id_len = 0; |
881 | unsigned char *sdec = NULL; | 879 | unsigned char *sdec = NULL; |
882 | const unsigned char *p; | 880 | const unsigned char *p; |
883 | int slen, mlen, renew_ticket = 0; | 881 | int slen, mlen, renew_ticket = 0; |
884 | unsigned char tick_hmac[EVP_MAX_MD_SIZE]; | 882 | unsigned char hmac[EVP_MAX_MD_SIZE]; |
885 | HMAC_CTX hctx; | 883 | HMAC_CTX hctx; |
886 | EVP_CIPHER_CTX ctx; | 884 | EVP_CIPHER_CTX ctx; |
887 | SSL_CTX *tctx = s->initial_ctx; | 885 | SSL_CTX *tctx = s->initial_ctx; |
@@ -890,65 +888,95 @@ tls_decrypt_ticket(SSL *s, CBS *session_id, const unsigned char *etick, | |||
890 | HMAC_CTX_init(&hctx); | 888 | HMAC_CTX_init(&hctx); |
891 | EVP_CIPHER_CTX_init(&ctx); | 889 | EVP_CIPHER_CTX_init(&ctx); |
892 | 890 | ||
891 | *psess = NULL; | ||
892 | |||
893 | if (!CBS_get_bytes(ticket, &ticket_name, 16)) | ||
894 | goto derr; | ||
895 | |||
893 | /* | 896 | /* |
894 | * The API guarantees EVP_MAX_IV_LENGTH bytes of space for | 897 | * Initialize session ticket encryption and HMAC contexts. |
895 | * the iv to tlsext_ticket_key_cb(). Since the total space | ||
896 | * required for a session cookie is never less than this, | ||
897 | * this check isn't too strict. The exact check comes later. | ||
898 | */ | 898 | */ |
899 | if (eticklen < 16 + EVP_MAX_IV_LENGTH) | 899 | if (tctx->internal->tlsext_ticket_key_cb != NULL) { |
900 | goto derr; | 900 | int rv; |
901 | |||
902 | /* | ||
903 | * The API guarantees EVP_MAX_IV_LENGTH bytes of space for | ||
904 | * the iv to tlsext_ticket_key_cb(). Since the total space | ||
905 | * required for a session cookie is never less than this, | ||
906 | * this check isn't too strict. The exact check comes later. | ||
907 | */ | ||
908 | if (CBS_len(ticket) < EVP_MAX_IV_LENGTH) | ||
909 | goto derr; | ||
901 | 910 | ||
902 | /* Initialize session ticket encryption and HMAC contexts */ | 911 | if ((rv = tctx->internal->tlsext_ticket_key_cb(s, |
903 | if (tctx->internal->tlsext_ticket_key_cb) { | 912 | (unsigned char *)CBS_data(&ticket_name), |
904 | unsigned char *nctick = (unsigned char *)etick; | 913 | (unsigned char *)CBS_data(ticket), &ctx, &hctx, 0)) < 0) |
905 | int rv = tctx->internal->tlsext_ticket_key_cb(s, | ||
906 | nctick, nctick + 16, &ctx, &hctx, 0); | ||
907 | if (rv < 0) | ||
908 | goto err; | 914 | goto err; |
909 | if (rv == 0) | 915 | if (rv == 0) |
910 | goto derr; | 916 | goto derr; |
911 | if (rv == 2) | 917 | if (rv == 2) |
912 | renew_ticket = 1; | 918 | renew_ticket = 1; |
919 | |||
920 | /* | ||
921 | * Now that the cipher context is initialised, we can extract | ||
922 | * the IV since its length is known. | ||
923 | */ | ||
924 | if (!CBS_get_bytes(ticket, &ticket_iv, | ||
925 | EVP_CIPHER_CTX_iv_length(&ctx))) | ||
926 | goto derr; | ||
913 | } else { | 927 | } else { |
914 | /* Check key name matches */ | 928 | /* Check that the key name matches. */ |
915 | if (timingsafe_memcmp(etick, | 929 | if (!CBS_mem_equal(&ticket_name, |
916 | tctx->internal->tlsext_tick_key_name, 16)) | 930 | tctx->internal->tlsext_tick_key_name, |
931 | sizeof(tctx->internal->tlsext_tick_key_name))) | ||
917 | goto derr; | 932 | goto derr; |
918 | HMAC_Init_ex(&hctx, tctx->internal->tlsext_tick_hmac_key, | 933 | HMAC_Init_ex(&hctx, tctx->internal->tlsext_tick_hmac_key, |
919 | 16, EVP_sha256(), NULL); | 934 | sizeof(tctx->internal->tlsext_tick_hmac_key), EVP_sha256(), |
935 | NULL); | ||
936 | if (!CBS_get_bytes(ticket, &ticket_iv, | ||
937 | EVP_CIPHER_iv_length(EVP_aes_128_cbc()))) | ||
938 | goto derr; | ||
920 | EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, | 939 | EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, |
921 | tctx->internal->tlsext_tick_aes_key, etick + 16); | 940 | tctx->internal->tlsext_tick_aes_key, CBS_data(&ticket_iv)); |
922 | } | 941 | } |
923 | 942 | ||
924 | /* | 943 | /* |
925 | * Attempt to process session ticket, first conduct sanity and | 944 | * Attempt to process session ticket. |
926 | * integrity checks on ticket. | ||
927 | */ | 945 | */ |
928 | mlen = HMAC_size(&hctx); | 946 | |
929 | if (mlen < 0) | 947 | if ((mlen = HMAC_size(&hctx)) < 0) |
930 | goto err; | 948 | goto err; |
931 | 949 | ||
932 | /* Sanity check ticket length: must exceed keyname + IV + HMAC */ | 950 | if (mlen > CBS_len(ticket)) |
933 | if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) | 951 | goto derr; |
952 | if (!CBS_get_bytes(ticket, &ticket_encdata, CBS_len(ticket) - mlen)) | ||
934 | goto derr; | 953 | goto derr; |
935 | eticklen -= mlen; | 954 | if (!CBS_get_bytes(ticket, &ticket_hmac, mlen)) |
955 | goto derr; | ||
956 | if (CBS_len(ticket) != 0) | ||
957 | goto err; | ||
936 | 958 | ||
937 | /* Check HMAC of encrypted ticket */ | 959 | /* Check HMAC of encrypted ticket. */ |
938 | if (HMAC_Update(&hctx, etick, eticklen) <= 0 || | 960 | if (HMAC_Update(&hctx, CBS_data(&ticket_name), |
939 | HMAC_Final(&hctx, tick_hmac, NULL) <= 0) | 961 | CBS_len(&ticket_name)) <= 0) |
962 | goto err; | ||
963 | if (HMAC_Update(&hctx, CBS_data(&ticket_iv), | ||
964 | CBS_len(&ticket_iv)) <= 0) | ||
965 | goto err; | ||
966 | if (HMAC_Update(&hctx, CBS_data(&ticket_encdata), | ||
967 | CBS_len(&ticket_encdata)) <= 0) | ||
968 | goto err; | ||
969 | if (HMAC_Final(&hctx, hmac, &mlen) <= 0) | ||
940 | goto err; | 970 | goto err; |
941 | 971 | ||
942 | if (timingsafe_memcmp(tick_hmac, etick + eticklen, mlen)) | 972 | if (!CBS_mem_equal(&ticket_hmac, hmac, mlen)) |
943 | goto derr; | 973 | goto derr; |
944 | 974 | ||
945 | /* Attempt to decrypt session data */ | 975 | /* Attempt to decrypt session data. */ |
946 | /* Move p after IV to start of encrypted ticket, update length */ | 976 | if ((sdec = malloc(CBS_len(&ticket_encdata))) == NULL) |
947 | p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); | ||
948 | eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); | ||
949 | if ((sdec = malloc(eticklen)) == NULL) | ||
950 | goto err; | 977 | goto err; |
951 | if (EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) | 978 | if (EVP_DecryptUpdate(&ctx, sdec, &slen, CBS_data(&ticket_encdata), |
979 | CBS_len(&ticket_encdata)) <= 0) | ||
952 | goto derr; | 980 | goto derr; |
953 | if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) | 981 | if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) |
954 | goto derr; | 982 | goto derr; |