diff options
author | jsing <> | 2017-09-25 18:02:27 +0000 |
---|---|---|
committer | jsing <> | 2017-09-25 18:02:27 +0000 |
commit | f54ad548bde724826978bddf2ca35ee99e62f3aa (patch) | |
tree | 42d6703c344d9eccc786a01354471588f9f39675 /src/lib | |
parent | 262ac3c2783343b86e656bc94f50df32a353cd11 (diff) | |
download | openbsd-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.c | 34 |
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 | |||
764 | tlsext_ocsp_clienthello_parse(SSL *s, CBS *cbs, int *alert) | 764 | tlsext_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; |