summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/asn1/asn1_locl.h4
-rw-r--r--src/lib/libcrypto/asn1/tasn_dec.c77
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
164int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
165
166int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); 164int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
167int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); 165int 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,
95static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, 95static 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);
98static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len,
99 int utype, const ASN1_ITEM *it);
98 100
99static void 101static void
100asn1_tlc_invalidate(ASN1_TLC *ctx) 102asn1_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
796int 789static int
797asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, 790asn1_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