summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2019-04-21 10:17:25 +0000
committerjsing <>2019-04-21 10:17:25 +0000
commit97b79555a90206c77bc3b25c9722207b0496b2e1 (patch)
treee6a02574dc8eebc391b57c7012b1a63b1f4a4d8d
parent3b6754802f797dc8df0764966cad58c88924eb7a (diff)
downloadopenbsd-97b79555a90206c77bc3b25c9722207b0496b2e1.tar.gz
openbsd-97b79555a90206c77bc3b25c9722207b0496b2e1.tar.bz2
openbsd-97b79555a90206c77bc3b25c9722207b0496b2e1.zip
Start cleaning up tls_decrypt_ticket().
Rather than returning from multiple places and trying to clean up as we go, move to a single exit point and clean/free in one place. Also invert the logic that handles NULL sessions - fail early, rather than having an indented if test for success. ok tb@
-rw-r--r--src/lib/libssl/t1_lib.c121
1 files changed, 63 insertions, 58 deletions
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 5dbbdb7866..2147908819 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.154 2019/03/25 17:27:31 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.155 2019/04/21 10:17: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 *
@@ -877,13 +877,17 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
877 const unsigned char *sess_id, int sesslen, SSL_SESSION **psess) 877 const unsigned char *sess_id, int sesslen, SSL_SESSION **psess)
878{ 878{
879 SSL_SESSION *sess; 879 SSL_SESSION *sess;
880 unsigned char *sdec; 880 unsigned char *sdec = NULL;
881 const unsigned char *p; 881 const unsigned char *p;
882 int slen, mlen, renew_ticket = 0; 882 int slen, mlen, renew_ticket = 0;
883 unsigned char tick_hmac[EVP_MAX_MD_SIZE]; 883 unsigned char tick_hmac[EVP_MAX_MD_SIZE];
884 HMAC_CTX hctx; 884 HMAC_CTX hctx;
885 EVP_CIPHER_CTX ctx; 885 EVP_CIPHER_CTX ctx;
886 SSL_CTX *tctx = s->initial_ctx; 886 SSL_CTX *tctx = s->initial_ctx;
887 int ret = -1;
888
889 HMAC_CTX_init(&hctx);
890 EVP_CIPHER_CTX_init(&ctx);
887 891
888 /* 892 /*
889 * The API guarantees EVP_MAX_IV_LENGTH bytes of space for 893 * The API guarantees EVP_MAX_IV_LENGTH bytes of space for
@@ -891,33 +895,31 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
891 * required for a session cookie is never less than this, 895 * required for a session cookie is never less than this,
892 * this check isn't too strict. The exact check comes later. 896 * this check isn't too strict. The exact check comes later.
893 */ 897 */
894 if (eticklen < 16 + EVP_MAX_IV_LENGTH) 898 if (eticklen < 16 + EVP_MAX_IV_LENGTH) {
895 return 2; 899 ret = 2;
900 goto done;
901 }
896 902
897 /* Initialize session ticket encryption and HMAC contexts */ 903 /* Initialize session ticket encryption and HMAC contexts */
898 HMAC_CTX_init(&hctx);
899 EVP_CIPHER_CTX_init(&ctx);
900 if (tctx->internal->tlsext_ticket_key_cb) { 904 if (tctx->internal->tlsext_ticket_key_cb) {
901 unsigned char *nctick = (unsigned char *)etick; 905 unsigned char *nctick = (unsigned char *)etick;
902 int rv = tctx->internal->tlsext_ticket_key_cb(s, 906 int rv = tctx->internal->tlsext_ticket_key_cb(s,
903 nctick, nctick + 16, &ctx, &hctx, 0); 907 nctick, nctick + 16, &ctx, &hctx, 0);
904 if (rv < 0) { 908 if (rv < 0)
905 HMAC_CTX_cleanup(&hctx); 909 goto err;
906 EVP_CIPHER_CTX_cleanup(&ctx);
907 return -1;
908 }
909 if (rv == 0) { 910 if (rv == 0) {
910 HMAC_CTX_cleanup(&hctx); 911 ret = 2;
911 EVP_CIPHER_CTX_cleanup(&ctx); 912 goto done;
912 return 2;
913 } 913 }
914 if (rv == 2) 914 if (rv == 2)
915 renew_ticket = 1; 915 renew_ticket = 1;
916 } else { 916 } else {
917 /* Check key name matches */ 917 /* Check key name matches */
918 if (timingsafe_memcmp(etick, 918 if (timingsafe_memcmp(etick,
919 tctx->internal->tlsext_tick_key_name, 16)) 919 tctx->internal->tlsext_tick_key_name, 16)) {
920 return 2; 920 ret = 2;
921 goto done;
922 }
921 HMAC_Init_ex(&hctx, tctx->internal->tlsext_tick_hmac_key, 923 HMAC_Init_ex(&hctx, tctx->internal->tlsext_tick_hmac_key,
922 16, tlsext_tick_md(), NULL); 924 16, tlsext_tick_md(), NULL);
923 EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, 925 EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
@@ -929,32 +931,24 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
929 * integrity checks on ticket. 931 * integrity checks on ticket.
930 */ 932 */
931 mlen = HMAC_size(&hctx); 933 mlen = HMAC_size(&hctx);
932 if (mlen < 0) { 934 if (mlen < 0)
933 HMAC_CTX_cleanup(&hctx); 935 goto err;
934 EVP_CIPHER_CTX_cleanup(&ctx);
935 return -1;
936 }
937 936
938 /* Sanity check ticket length: must exceed keyname + IV + HMAC */ 937 /* Sanity check ticket length: must exceed keyname + IV + HMAC */
939 if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { 938 if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) {
940 HMAC_CTX_cleanup(&hctx); 939 ret = 2;
941 EVP_CIPHER_CTX_cleanup(&ctx); 940 goto done;
942 return 2;
943 } 941 }
944 eticklen -= mlen; 942 eticklen -= mlen;
945 943
946 /* Check HMAC of encrypted ticket */ 944 /* Check HMAC of encrypted ticket */
947 if (HMAC_Update(&hctx, etick, eticklen) <= 0 || 945 if (HMAC_Update(&hctx, etick, eticklen) <= 0 ||
948 HMAC_Final(&hctx, tick_hmac, NULL) <= 0) { 946 HMAC_Final(&hctx, tick_hmac, NULL) <= 0)
949 HMAC_CTX_cleanup(&hctx); 947 goto err;
950 EVP_CIPHER_CTX_cleanup(&ctx);
951 return -1;
952 }
953 948
954 HMAC_CTX_cleanup(&hctx);
955 if (timingsafe_memcmp(tick_hmac, etick + eticklen, mlen)) { 949 if (timingsafe_memcmp(tick_hmac, etick + eticklen, mlen)) {
956 EVP_CIPHER_CTX_cleanup(&ctx); 950 ret = 2;
957 return 2; 951 goto done;
958 } 952 }
959 953
960 /* Attempt to decrypt session data */ 954 /* Attempt to decrypt session data */
@@ -964,38 +958,49 @@ tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
964 sdec = malloc(eticklen); 958 sdec = malloc(eticklen);
965 if (sdec == NULL || 959 if (sdec == NULL ||
966 EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { 960 EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
967 free(sdec); 961 ret = -1;
968 EVP_CIPHER_CTX_cleanup(&ctx); 962 goto done;
969 return -1;
970 } 963 }
971 if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) { 964 if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) {
972 free(sdec); 965 ret = 2;
973 EVP_CIPHER_CTX_cleanup(&ctx); 966 goto done;
974 return 2;
975 } 967 }
976 slen += mlen; 968 slen += mlen;
977 EVP_CIPHER_CTX_cleanup(&ctx);
978 p = sdec; 969 p = sdec;
979 970
980 sess = d2i_SSL_SESSION(NULL, &p, slen); 971 if ((sess = d2i_SSL_SESSION(NULL, &p, slen)) == NULL) {
981 free(sdec); 972 /*
982 if (sess) { 973 * For session parse failure, indicate that we need to send a
983 /* The session ID, if non-empty, is used by some clients to 974 * new ticket.
984 * detect that the ticket has been accepted. So we copy it to
985 * the session structure. If it is empty set length to zero
986 * as required by standard.
987 */ 975 */
988 if (sesslen) 976 ERR_clear_error();
989 memcpy(sess->session_id, sess_id, sesslen); 977 ret = 2;
990 sess->session_id_length = sesslen; 978 goto done;
991 *psess = sess;
992 if (renew_ticket)
993 return 4;
994 else
995 return 3;
996 } 979 }
997 ERR_clear_error(); 980
998 /* For session parse failure, indicate that we need to send a new 981 /*
999 * ticket. */ 982 * The session ID, if non-empty, is used by some clients to detect that
1000 return 2; 983 * the ticket has been accepted. So we copy it to the session structure.
984 * If it is empty set length to zero as required by standard.
985 */
986 if (sesslen)
987 memcpy(sess->session_id, sess_id, sesslen);
988 sess->session_id_length = sesslen;
989 *psess = sess;
990 if (renew_ticket)
991 ret = 4;
992 else
993 ret = 3;
994
995 goto done;
996
997 err:
998 ret = -1;
999
1000 done:
1001 free(sdec);
1002 HMAC_CTX_cleanup(&hctx);
1003 EVP_CIPHER_CTX_cleanup(&ctx);
1004
1005 return ret;
1001} 1006}