diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/tasn_dec.c')
-rw-r--r-- | src/lib/libcrypto/asn1/tasn_dec.c | 78 |
1 files changed, 11 insertions, 67 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index c22501fc63..2426cb6253 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include <openssl/err.h> | 66 | #include <openssl/err.h> |
67 | 67 | ||
68 | static int asn1_check_eoc(unsigned char **in, long len); | 68 | static int asn1_check_eoc(unsigned char **in, long len); |
69 | static int asn1_find_end(unsigned char **in, long len, char inf); | ||
70 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); | 69 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); |
71 | static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); | 70 | static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); |
72 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, | 71 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, |
@@ -645,7 +644,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl | |||
645 | cont = *in; | 644 | cont = *in; |
646 | /* If indefinite length constructed find the real end */ | 645 | /* If indefinite length constructed find the real end */ |
647 | if(inf) { | 646 | if(inf) { |
648 | if(!asn1_find_end(&p, plen, inf)) goto err; | 647 | if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err; |
649 | len = p - cont; | 648 | len = p - cont; |
650 | } else { | 649 | } else { |
651 | len = p - cont + plen; | 650 | len = p - cont + plen; |
@@ -808,66 +807,12 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char | |||
808 | return ret; | 807 | return ret; |
809 | } | 808 | } |
810 | 809 | ||
811 | /* This function finds the end of an ASN1 structure when passed its maximum | ||
812 | * length, whether it is indefinite length and a pointer to the content. | ||
813 | * This is more efficient than calling asn1_collect because it does not | ||
814 | * recurse on each indefinite length header. | ||
815 | */ | ||
816 | |||
817 | static int asn1_find_end(unsigned char **in, long len, char inf) | ||
818 | { | ||
819 | int expected_eoc; | ||
820 | long plen; | ||
821 | unsigned char *p = *in, *q; | ||
822 | /* If not indefinite length constructed just add length */ | ||
823 | if (inf == 0) | ||
824 | { | ||
825 | *in += len; | ||
826 | return 1; | ||
827 | } | ||
828 | expected_eoc = 1; | ||
829 | /* Indefinite length constructed form. Find the end when enough EOCs | ||
830 | * are found. If more indefinite length constructed headers | ||
831 | * are encountered increment the expected eoc count otherwise justi | ||
832 | * skip to the end of the data. | ||
833 | */ | ||
834 | while (len > 0) | ||
835 | { | ||
836 | if(asn1_check_eoc(&p, len)) | ||
837 | { | ||
838 | expected_eoc--; | ||
839 | if (expected_eoc == 0) | ||
840 | break; | ||
841 | len -= 2; | ||
842 | continue; | ||
843 | } | ||
844 | q = p; | ||
845 | /* Just read in a header: only care about the length */ | ||
846 | if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, | ||
847 | -1, 0, 0, NULL)) | ||
848 | { | ||
849 | ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); | ||
850 | return 0; | ||
851 | } | ||
852 | if (inf) | ||
853 | expected_eoc++; | ||
854 | else | ||
855 | p += plen; | ||
856 | len -= p - q; | ||
857 | } | ||
858 | if (expected_eoc) | ||
859 | { | ||
860 | ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); | ||
861 | return 0; | ||
862 | } | ||
863 | *in = p; | ||
864 | return 1; | ||
865 | } | ||
866 | |||
867 | /* This function collects the asn1 data from a constructred string | 810 | /* This function collects the asn1 data from a constructred string |
868 | * type into a buffer. The values of 'in' and 'len' should refer | 811 | * type into a buffer. The values of 'in' and 'len' should refer |
869 | * to the contents of the constructed type and 'inf' should be set | 812 | * to the contents of the constructed type and 'inf' should be set |
870 | * if it is indefinite length. | 813 | * if it is indefinite length. If 'buf' is NULL then we just want |
814 | * to find the end of the current structure: useful for indefinite | ||
815 | * length constructed stuff. | ||
871 | */ | 816 | */ |
872 | 817 | ||
873 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) | 818 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) |
@@ -877,6 +822,11 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in | |||
877 | char cst, ininf; | 822 | char cst, ininf; |
878 | p = *in; | 823 | p = *in; |
879 | inf &= 1; | 824 | inf &= 1; |
825 | /* If no buffer and not indefinite length constructed just pass over the encoded data */ | ||
826 | if(!buf && !inf) { | ||
827 | *in += len; | ||
828 | return 1; | ||
829 | } | ||
880 | while(len > 0) { | 830 | while(len > 0) { |
881 | q = p; | 831 | q = p; |
882 | /* Check for EOC */ | 832 | /* Check for EOC */ |
@@ -895,15 +845,9 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in | |||
895 | } | 845 | } |
896 | /* If indefinite length constructed update max length */ | 846 | /* If indefinite length constructed update max length */ |
897 | if(cst) { | 847 | if(cst) { |
898 | #ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS | 848 | if(!asn1_collect(buf, &p, plen, ininf, tag, aclass)) return 0; |
899 | if (!asn1_collect(buf, &p, plen, ininf, tag, aclass)) | ||
900 | return 0; | ||
901 | #else | ||
902 | ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); | ||
903 | return 0; | ||
904 | #endif | ||
905 | } else { | 849 | } else { |
906 | if(plen && !collect_data(buf, &p, plen)) return 0; | 850 | if(!collect_data(buf, &p, plen)) return 0; |
907 | } | 851 | } |
908 | len -= p - q; | 852 | len -= p - q; |
909 | } | 853 | } |