diff options
Diffstat (limited to 'src/lib/libssl/t1_lib.c')
| -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; |
