diff options
| -rw-r--r-- | src/lib/libcrypto/asn1/tasn_dec.c | 98 |
1 files changed, 59 insertions, 39 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index 103774fc19..f04ec66bc7 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.58 2022/05/05 19:18:56 jsing Exp $ */ | 1 | /* $OpenBSD: tasn_dec.c,v 1.59 2022/05/07 10:03:49 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 | */ |
| @@ -771,47 +771,21 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, | |||
| 771 | return ret; | 771 | return ret; |
| 772 | } | 772 | } |
| 773 | 773 | ||
| 774 | /* Translate ASN.1 content octets into a structure. */ | ||
| 775 | static int | 774 | static int |
| 776 | asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | 775 | asn1_ex_c2i_primitive(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) |
| 777 | { | 776 | { |
| 778 | ASN1_VALUE **opval = NULL; | ||
| 779 | ASN1_STRING *stmp; | 777 | ASN1_STRING *stmp; |
| 780 | ASN1_TYPE *typ = NULL; | ||
| 781 | ASN1_INTEGER **tint; | 778 | ASN1_INTEGER **tint; |
| 782 | ASN1_BOOLEAN *tbool; | 779 | ASN1_BOOLEAN *tbool; |
| 783 | uint8_t u8val; | 780 | uint8_t u8val; |
| 784 | int ret = 0; | 781 | int ret = 0; |
| 785 | 782 | ||
| 786 | if (CBS_len(content) > INT_MAX) | 783 | if (it->funcs != NULL) |
| 787 | return 0; | 784 | return 0; |
| 788 | 785 | ||
| 789 | if (it->funcs != NULL) { | 786 | if (CBS_len(content) > INT_MAX) |
| 790 | const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; | 787 | return 0; |
| 791 | char free_content = 0; | ||
| 792 | |||
| 793 | if (pf->prim_c2i == NULL) | ||
| 794 | return 0; | ||
| 795 | |||
| 796 | return pf->prim_c2i(pval, CBS_data(content), CBS_len(content), | ||
| 797 | utype, &free_content, it); | ||
| 798 | } | ||
| 799 | 788 | ||
| 800 | /* If ANY type clear type and set pointer to internal value */ | ||
| 801 | if (it->utype == V_ASN1_ANY) { | ||
| 802 | if (!*pval) { | ||
| 803 | typ = ASN1_TYPE_new(); | ||
| 804 | if (typ == NULL) | ||
| 805 | goto err; | ||
| 806 | *pval = (ASN1_VALUE *)typ; | ||
| 807 | } else | ||
| 808 | typ = (ASN1_TYPE *)*pval; | ||
| 809 | |||
| 810 | if (utype != typ->type) | ||
| 811 | ASN1_TYPE_set(typ, utype, NULL); | ||
| 812 | opval = pval; | ||
| 813 | pval = &typ->value.asn1_value; | ||
| 814 | } | ||
| 815 | switch (utype) { | 789 | switch (utype) { |
| 816 | case V_ASN1_OBJECT: | 790 | case V_ASN1_OBJECT: |
| 817 | if (!c2i_ASN1_OBJECT_cbs((ASN1_OBJECT **)pval, content)) | 791 | if (!c2i_ASN1_OBJECT_cbs((ASN1_OBJECT **)pval, content)) |
| @@ -895,21 +869,67 @@ asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | |||
| 895 | } | 869 | } |
| 896 | break; | 870 | break; |
| 897 | } | 871 | } |
| 898 | /* If ASN1_ANY and NULL type fix up value */ | ||
| 899 | if (typ && (utype == V_ASN1_NULL)) | ||
| 900 | typ->value.ptr = NULL; | ||
| 901 | 872 | ||
| 902 | ret = 1; | 873 | ret = 1; |
| 903 | 874 | ||
| 904 | err: | 875 | err: |
| 905 | if (!ret) { | ||
| 906 | ASN1_TYPE_free(typ); | ||
| 907 | if (opval) | ||
| 908 | *opval = NULL; | ||
| 909 | } | ||
| 910 | return ret; | 876 | return ret; |
| 911 | } | 877 | } |
| 912 | 878 | ||
| 879 | static int | ||
| 880 | asn1_ex_c2i_any(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | ||
| 881 | { | ||
| 882 | ASN1_TYPE *atype; | ||
| 883 | |||
| 884 | if (it->utype != V_ASN1_ANY || it->funcs != NULL) | ||
| 885 | return 0; | ||
| 886 | |||
| 887 | if (*pval != NULL) { | ||
| 888 | ASN1_TYPE_free((ASN1_TYPE *)*pval); | ||
| 889 | *pval = NULL; | ||
| 890 | } | ||
| 891 | |||
| 892 | if ((atype = ASN1_TYPE_new()) == NULL) | ||
| 893 | return 0; | ||
| 894 | |||
| 895 | if (!asn1_ex_c2i_primitive(&atype->value.asn1_value, content, utype, it)) { | ||
| 896 | ASN1_TYPE_free(atype); | ||
| 897 | return 0; | ||
| 898 | } | ||
| 899 | atype->type = utype; | ||
| 900 | |||
| 901 | /* Fix up value for ASN.1 NULL. */ | ||
| 902 | if (atype->type == V_ASN1_NULL) | ||
| 903 | atype->value.ptr = NULL; | ||
| 904 | |||
| 905 | *pval = (ASN1_VALUE *)atype; | ||
| 906 | |||
| 907 | return 1; | ||
| 908 | } | ||
| 909 | |||
| 910 | static int | ||
| 911 | asn1_ex_c2i(ASN1_VALUE **pval, CBS *content, int utype, const ASN1_ITEM *it) | ||
| 912 | { | ||
| 913 | if (CBS_len(content) > INT_MAX) | ||
| 914 | return 0; | ||
| 915 | |||
| 916 | if (it->funcs != NULL) { | ||
| 917 | const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; | ||
| 918 | char free_content = 0; | ||
| 919 | |||
| 920 | if (pf->prim_c2i == NULL) | ||
| 921 | return 0; | ||
| 922 | |||
| 923 | return pf->prim_c2i(pval, CBS_data(content), CBS_len(content), | ||
| 924 | utype, &free_content, it); | ||
| 925 | } | ||
| 926 | |||
| 927 | if (it->utype == V_ASN1_ANY) | ||
| 928 | return asn1_ex_c2i_any(pval, content, utype, it); | ||
| 929 | |||
| 930 | return asn1_ex_c2i_primitive(pval, content, utype, it); | ||
| 931 | } | ||
| 932 | |||
| 913 | /* Find the end of an ASN.1 object. */ | 933 | /* Find the end of an ASN.1 object. */ |
| 914 | static int | 934 | static int |
| 915 | asn1_find_end(CBS *cbs, size_t length, char indefinite) | 935 | asn1_find_end(CBS *cbs, size_t length, char indefinite) |
