summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2017-09-25 18:02:27 +0000
committerjsing <>2017-09-25 18:02:27 +0000
commitf54ad548bde724826978bddf2ca35ee99e62f3aa (patch)
tree42d6703c344d9eccc786a01354471588f9f39675 /src/lib
parent262ac3c2783343b86e656bc94f50df32a353cd11 (diff)
downloadopenbsd-f54ad548bde724826978bddf2ca35ee99e62f3aa.tar.gz
openbsd-f54ad548bde724826978bddf2ca35ee99e62f3aa.tar.bz2
openbsd-f54ad548bde724826978bddf2ca35ee99e62f3aa.zip
Fix various issues in the OCSP extension parsing code:
- When parsing the OCSP extension we can have multiple responder IDs - pull these out correctly. - Stop using CBS_stow() - it's unnecessary since we just need access to the data and length (which we can get via CBS_data() and CBS_len()). - Use a temporary pointer when calling d2i_*() functions, since it will increment the pointer by the number of bytes it consumed when decoding. The original code incorrectly passes the pointer allocated via CBS_stow() (using malloc()) to a d2i_*() function and then calls free() on the now incremented pointer, most likely resulting in a crash. This issue was reported by Robert Swiecki who found the issue using honggfuzz. ok beck@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/ssl_tlsext.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index 8f6ff6554a..835c413478 100644
--- a/src/lib/libssl/ssl_tlsext.c
+++ b/src/lib/libssl/ssl_tlsext.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_tlsext.c,v 1.16 2017/09/25 17:51:49 jsing Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.17 2017/09/25 18:02:27 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -764,11 +764,9 @@ int
764tlsext_ocsp_clienthello_parse(SSL *s, CBS *cbs, int *alert) 764tlsext_ocsp_clienthello_parse(SSL *s, CBS *cbs, int *alert)
765{ 765{
766 int failure = SSL_AD_DECODE_ERROR; 766 int failure = SSL_AD_DECODE_ERROR;
767 unsigned char *respid_data = NULL; 767 CBS respid_list, respid, exts;
768 unsigned char *ext_data = NULL; 768 const unsigned char *p;
769 size_t ext_len, respid_len;
770 uint8_t status_type; 769 uint8_t status_type;
771 CBS respids, exts;
772 int ret = 0; 770 int ret = 0;
773 771
774 if (!CBS_get_u8(cbs, &status_type)) 772 if (!CBS_get_u8(cbs, &status_type))
@@ -784,13 +782,13 @@ tlsext_ocsp_clienthello_parse(SSL *s, CBS *cbs, int *alert)
784 return 1; 782 return 1;
785 } 783 }
786 s->tlsext_status_type = status_type; 784 s->tlsext_status_type = status_type;
787 if (!CBS_get_u16_length_prefixed(cbs, &respids)) 785 if (!CBS_get_u16_length_prefixed(cbs, &respid_list))
788 goto err; 786 goto err;
789 787
790 /* XXX */ 788 /* XXX */
791 sk_OCSP_RESPID_pop_free(s->internal->tlsext_ocsp_ids, OCSP_RESPID_free); 789 sk_OCSP_RESPID_pop_free(s->internal->tlsext_ocsp_ids, OCSP_RESPID_free);
792 s->internal->tlsext_ocsp_ids = NULL; 790 s->internal->tlsext_ocsp_ids = NULL;
793 if (CBS_len(cbs) > 0) { 791 if (CBS_len(&respid_list) > 0) {
794 s->internal->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); 792 s->internal->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
795 if (s->internal->tlsext_ocsp_ids == NULL) { 793 if (s->internal->tlsext_ocsp_ids == NULL) {
796 failure = SSL_AD_INTERNAL_ERROR; 794 failure = SSL_AD_INTERNAL_ERROR;
@@ -798,43 +796,39 @@ tlsext_ocsp_clienthello_parse(SSL *s, CBS *cbs, int *alert)
798 } 796 }
799 } 797 }
800 798
801 while (CBS_len(&respids) > 0) { 799 while (CBS_len(&respid_list) > 0) {
802 OCSP_RESPID *id = NULL; 800 OCSP_RESPID *id;
803 801
804 if (!CBS_stow(cbs, &respid_data, &respid_len)) 802 if (!CBS_get_u16_length_prefixed(&respid_list, &respid))
805 goto err; 803 goto err;
806 if ((id = d2i_OCSP_RESPID(NULL, 804 p = CBS_data(&respid);
807 (const unsigned char **)&respid_data, respid_len)) == NULL) 805 if ((id = d2i_OCSP_RESPID(NULL, &p, CBS_len(&respid))) == NULL)
808 goto err; 806 goto err;
809 if (!sk_OCSP_RESPID_push(s->internal->tlsext_ocsp_ids, id)) { 807 if (!sk_OCSP_RESPID_push(s->internal->tlsext_ocsp_ids, id)) {
810 failure = SSL_AD_INTERNAL_ERROR; 808 failure = SSL_AD_INTERNAL_ERROR;
811 OCSP_RESPID_free(id); 809 OCSP_RESPID_free(id);
812 goto err; 810 goto err;
813 } 811 }
814 free(respid_data);
815 respid_data = NULL;
816 } 812 }
817 813
818 /* Read in request_extensions */ 814 /* Read in request_extensions */
819 if (!CBS_get_u16_length_prefixed(cbs, &exts)) 815 if (!CBS_get_u16_length_prefixed(cbs, &exts))
820 goto err; 816 goto err;
821 if (!CBS_stow(&exts, &ext_data, &ext_len)) 817 if (CBS_len(&exts) > 0) {
822 goto err;
823 if (ext_len > 0) {
824 sk_X509_EXTENSION_pop_free(s->internal->tlsext_ocsp_exts, 818 sk_X509_EXTENSION_pop_free(s->internal->tlsext_ocsp_exts,
825 X509_EXTENSION_free); 819 X509_EXTENSION_free);
820 p = CBS_data(&exts);
826 if ((s->internal->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, 821 if ((s->internal->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL,
827 (const unsigned char **)&ext_data, ext_len)) == NULL) 822 &p, CBS_len(&exts))) == NULL)
828 goto err; 823 goto err;
829 } 824 }
825
830 /* should be nothing left */ 826 /* should be nothing left */
831 if (CBS_len(cbs) > 0) 827 if (CBS_len(cbs) > 0)
832 goto err; 828 goto err;
833 829
834 ret = 1; 830 ret = 1;
835 err: 831 err:
836 free(respid_data);
837 free(ext_data);
838 if (ret == 0) 832 if (ret == 0)
839 *alert = failure; 833 *alert = failure;
840 return ret; 834 return ret;