diff options
| author | jsing <> | 2022-03-13 14:58:14 +0000 |
|---|---|---|
| committer | jsing <> | 2022-03-13 14:58:14 +0000 |
| commit | fa2518a98adbc41d019ee1af4e3eb7fd994861b2 (patch) | |
| tree | 36f685d9bd7666801c581d5dd900e750fd99b22a /src | |
| parent | 8eb1efc13e25a74ea09b172249b5103c0855f2ee (diff) | |
| download | openbsd-fa2518a98adbc41d019ee1af4e3eb7fd994861b2.tar.gz openbsd-fa2518a98adbc41d019ee1af4e3eb7fd994861b2.tar.bz2 openbsd-fa2518a98adbc41d019ee1af4e3eb7fd994861b2.zip | |
Remove free_cont from asn1_d2i_ex_primitive()/asn1_ex_c2i().
The constructed ASN.1 handling in asn1_d2i_ex_primitive() and asn1_ex_c2i()
currently has code to potentially avoid a malloc/memcpy - this is a less
common code path and it introduces a bunch of complexity for minimal gain.
In particular, we're manually adding a trailing NUL when ASN1_STRING_set()
would already do that for us, plus we currently manually free() the data on
an ASN1_STRING, rather than using freezero().
ok inoguchi@ tb@
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/asn1/asn1_locl.h | 4 | ||||
| -rw-r--r-- | src/lib/libcrypto/asn1/tasn_dec.c | 77 |
2 files changed, 31 insertions, 50 deletions
diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h index bb6a9fc91a..9a29a2b13f 100644 --- a/src/lib/libcrypto/asn1/asn1_locl.h +++ b/src/lib/libcrypto/asn1/asn1_locl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: asn1_locl.h,v 1.21 2022/03/02 11:28:00 jsing Exp $ */ | 1 | /* $OpenBSD: asn1_locl.h,v 1.22 2022/03/13 14:58:14 jsing Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2006. | 3 | * project 2006. |
| 4 | */ | 4 | */ |
| @@ -161,8 +161,6 @@ struct x509_crl_method_st { | |||
| 161 | int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk); | 161 | int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk); |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
| 164 | int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it); | ||
| 165 | |||
| 166 | int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); | 164 | int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); |
| 167 | int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); | 165 | int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); |
| 168 | 166 | ||
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index 8f41deef8d..d475c99676 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tasn_dec.c,v 1.48 2022/01/07 12:24:17 tb Exp $ */ | 1 | /* $OpenBSD: tasn_dec.c,v 1.49 2022/03/13 14:58:14 jsing Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 2000. | 3 | * project 2000. |
| 4 | */ | 4 | */ |
| @@ -95,6 +95,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, | |||
| 95 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, | 95 | static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, |
| 96 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, | 96 | long len, const ASN1_ITEM *it, int tag, int aclass, char opt, |
| 97 | ASN1_TLC *ctx); | 97 | ASN1_TLC *ctx); |
| 98 | static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, | ||
| 99 | int utype, const ASN1_ITEM *it); | ||
| 98 | 100 | ||
| 99 | static void | 101 | static void |
| 100 | asn1_tlc_invalidate(ASN1_TLC *ctx) | 102 | asn1_tlc_invalidate(ASN1_TLC *ctx) |
| @@ -662,9 +664,9 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
| 662 | { | 664 | { |
| 663 | int ret = 0, utype; | 665 | int ret = 0, utype; |
| 664 | long plen; | 666 | long plen; |
| 665 | char cst, inf, free_cont = 0; | 667 | char cst, inf; |
| 666 | const unsigned char *p; | 668 | const unsigned char *p; |
| 667 | const unsigned char *cont = NULL; | 669 | const unsigned char *content = NULL; |
| 668 | uint8_t *data = NULL; | 670 | uint8_t *data = NULL; |
| 669 | size_t data_len = 0; | 671 | size_t data_len = 0; |
| 670 | CBB cbb; | 672 | CBB cbb; |
| @@ -732,14 +734,14 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
| 732 | return 0; | 734 | return 0; |
| 733 | } | 735 | } |
| 734 | 736 | ||
| 735 | cont = *in; | 737 | content = *in; |
| 736 | /* If indefinite length constructed find the real end */ | 738 | /* If indefinite length constructed find the real end */ |
| 737 | if (inf) { | 739 | if (inf) { |
| 738 | if (!asn1_find_end(&p, plen, inf)) | 740 | if (!asn1_find_end(&p, plen, inf)) |
| 739 | goto err; | 741 | goto err; |
| 740 | len = p - cont; | 742 | len = p - content; |
| 741 | } else { | 743 | } else { |
| 742 | len = p - cont + plen; | 744 | len = p - content + plen; |
| 743 | p += plen; | 745 | p += plen; |
| 744 | } | 746 | } |
| 745 | } else if (cst) { | 747 | } else if (cst) { |
| @@ -754,29 +756,22 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
| 754 | goto err; | 756 | goto err; |
| 755 | if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) | 757 | if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) |
| 756 | goto err; | 758 | goto err; |
| 757 | |||
| 758 | /* Append a final NUL to string. */ | ||
| 759 | if (!CBB_add_u8(&cbb, 0)) | ||
| 760 | goto err; | ||
| 761 | |||
| 762 | if (!CBB_finish(&cbb, &data, &data_len)) | 759 | if (!CBB_finish(&cbb, &data, &data_len)) |
| 763 | goto err; | 760 | goto err; |
| 764 | 761 | ||
| 765 | free_cont = 1; | 762 | if (data_len > LONG_MAX) |
| 766 | |||
| 767 | if (data_len < 1 || data_len > LONG_MAX) | ||
| 768 | goto err; | 763 | goto err; |
| 769 | 764 | ||
| 770 | cont = data; | 765 | content = data; |
| 771 | len = data_len - 1; | 766 | len = data_len; |
| 772 | } else { | 767 | } else { |
| 773 | cont = p; | 768 | content = p; |
| 774 | len = plen; | 769 | len = plen; |
| 775 | p += plen; | 770 | p += plen; |
| 776 | } | 771 | } |
| 777 | 772 | ||
| 778 | /* We now have content length and type: translate into a structure */ | 773 | /* We now have content length and type: translate into a structure */ |
| 779 | if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) | 774 | if (!asn1_ex_c2i(pval, content, len, utype, it)) |
| 780 | goto err; | 775 | goto err; |
| 781 | 776 | ||
| 782 | *in = p; | 777 | *in = p; |
| @@ -784,18 +779,16 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
| 784 | 779 | ||
| 785 | err: | 780 | err: |
| 786 | CBB_cleanup(&cbb); | 781 | CBB_cleanup(&cbb); |
| 787 | 782 | freezero(data, data_len); | |
| 788 | if (free_cont) | ||
| 789 | freezero(data, data_len); | ||
| 790 | 783 | ||
| 791 | return ret; | 784 | return ret; |
| 792 | } | 785 | } |
| 793 | 786 | ||
| 794 | /* Translate ASN1 content octets into a structure */ | 787 | /* Translate ASN1 content octets into a structure */ |
| 795 | 788 | ||
| 796 | int | 789 | static int |
| 797 | asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | 790 | asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, int utype, |
| 798 | char *free_cont, const ASN1_ITEM *it) | 791 | const ASN1_ITEM *it) |
| 799 | { | 792 | { |
| 800 | ASN1_VALUE **opval = NULL; | 793 | ASN1_VALUE **opval = NULL; |
| 801 | ASN1_STRING *stmp; | 794 | ASN1_STRING *stmp; |
| @@ -805,10 +798,11 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
| 805 | 798 | ||
| 806 | if (it->funcs != NULL) { | 799 | if (it->funcs != NULL) { |
| 807 | const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; | 800 | const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; |
| 801 | char free_content = 0; | ||
| 808 | 802 | ||
| 809 | if (pf->prim_c2i == NULL) | 803 | if (pf->prim_c2i == NULL) |
| 810 | return 0; | 804 | return 0; |
| 811 | return pf->prim_c2i(pval, cont, len, utype, free_cont, it); | 805 | return pf->prim_c2i(pval, content, len, utype, &free_content, it); |
| 812 | } | 806 | } |
| 813 | 807 | ||
| 814 | /* If ANY type clear type and set pointer to internal value */ | 808 | /* If ANY type clear type and set pointer to internal value */ |
| @@ -828,7 +822,7 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
| 828 | } | 822 | } |
| 829 | switch (utype) { | 823 | switch (utype) { |
| 830 | case V_ASN1_OBJECT: | 824 | case V_ASN1_OBJECT: |
| 831 | if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) | 825 | if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &content, len)) |
| 832 | goto err; | 826 | goto err; |
| 833 | break; | 827 | break; |
| 834 | 828 | ||
| @@ -847,19 +841,19 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
| 847 | } else { | 841 | } else { |
| 848 | ASN1_BOOLEAN *tbool; | 842 | ASN1_BOOLEAN *tbool; |
| 849 | tbool = (ASN1_BOOLEAN *)pval; | 843 | tbool = (ASN1_BOOLEAN *)pval; |
| 850 | *tbool = *cont; | 844 | *tbool = *content; |
| 851 | } | 845 | } |
| 852 | break; | 846 | break; |
| 853 | 847 | ||
| 854 | case V_ASN1_BIT_STRING: | 848 | case V_ASN1_BIT_STRING: |
| 855 | if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) | 849 | if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &content, len)) |
| 856 | goto err; | 850 | goto err; |
| 857 | break; | 851 | break; |
| 858 | 852 | ||
| 859 | case V_ASN1_INTEGER: | 853 | case V_ASN1_INTEGER: |
| 860 | case V_ASN1_ENUMERATED: | 854 | case V_ASN1_ENUMERATED: |
| 861 | tint = (ASN1_INTEGER **)pval; | 855 | tint = (ASN1_INTEGER **)pval; |
| 862 | if (!c2i_ASN1_INTEGER(tint, &cont, len)) | 856 | if (!c2i_ASN1_INTEGER(tint, &content, len)) |
| 863 | goto err; | 857 | goto err; |
| 864 | /* Fixup type to match the expected form */ | 858 | /* Fixup type to match the expected form */ |
| 865 | (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); | 859 | (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); |
| @@ -891,10 +885,9 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
| 891 | ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); | 885 | ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); |
| 892 | goto err; | 886 | goto err; |
| 893 | } | 887 | } |
| 894 | /* All based on ASN1_STRING and handled the same */ | 888 | /* All based on ASN1_STRING and handled the same way. */ |
| 895 | if (!*pval) { | 889 | if (*pval == NULL) { |
| 896 | stmp = ASN1_STRING_type_new(utype); | 890 | if ((stmp = ASN1_STRING_type_new(utype)) == NULL) { |
| 897 | if (!stmp) { | ||
| 898 | ASN1error(ERR_R_MALLOC_FAILURE); | 891 | ASN1error(ERR_R_MALLOC_FAILURE); |
| 899 | goto err; | 892 | goto err; |
| 900 | } | 893 | } |
| @@ -903,19 +896,10 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
| 903 | stmp = (ASN1_STRING *)*pval; | 896 | stmp = (ASN1_STRING *)*pval; |
| 904 | stmp->type = utype; | 897 | stmp->type = utype; |
| 905 | } | 898 | } |
| 906 | /* If we've already allocated a buffer use it */ | 899 | if (!ASN1_STRING_set(stmp, content, len)) { |
| 907 | if (*free_cont) { | 900 | ASN1_STRING_free(stmp); |
| 908 | free(stmp->data); | 901 | *pval = NULL; |
| 909 | stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ | 902 | goto err; |
| 910 | stmp->length = len; | ||
| 911 | *free_cont = 0; | ||
| 912 | } else { | ||
| 913 | if (!ASN1_STRING_set(stmp, cont, len)) { | ||
| 914 | ASN1error(ERR_R_MALLOC_FAILURE); | ||
| 915 | ASN1_STRING_free(stmp); | ||
| 916 | *pval = NULL; | ||
| 917 | goto err; | ||
| 918 | } | ||
| 919 | } | 903 | } |
| 920 | break; | 904 | break; |
| 921 | } | 905 | } |
| @@ -934,7 +918,6 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, | |||
| 934 | return ret; | 918 | return ret; |
| 935 | } | 919 | } |
| 936 | 920 | ||
| 937 | |||
| 938 | /* This function finds the end of an ASN1 structure when passed its maximum | 921 | /* This function finds the end of an ASN1 structure when passed its maximum |
| 939 | * length, whether it is indefinite length and a pointer to the content. | 922 | * length, whether it is indefinite length and a pointer to the content. |
| 940 | * This is more efficient than calling asn1_collect because it does not | 923 | * This is more efficient than calling asn1_collect because it does not |
