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, 67 insertions, 11 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_dec.c b/src/lib/libcrypto/asn1/tasn_dec.c index 2426cb6253..c22501fc63 100644 --- a/src/lib/libcrypto/asn1/tasn_dec.c +++ b/src/lib/libcrypto/asn1/tasn_dec.c | |||
@@ -66,6 +66,7 @@ | |||
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); | ||
69 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); | 70 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass); |
70 | static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); | 71 | static int collect_data(BUF_MEM *buf, unsigned char **p, long plen); |
71 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, | 72 | static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf, char *cst, |
@@ -644,7 +645,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, unsigned char **in, long inl | |||
644 | cont = *in; | 645 | cont = *in; |
645 | /* If indefinite length constructed find the real end */ | 646 | /* If indefinite length constructed find the real end */ |
646 | if(inf) { | 647 | if(inf) { |
647 | if(!asn1_collect(NULL, &p, plen, inf, -1, -1)) goto err; | 648 | if(!asn1_find_end(&p, plen, inf)) goto err; |
648 | len = p - cont; | 649 | len = p - cont; |
649 | } else { | 650 | } else { |
650 | len = p - cont + plen; | 651 | len = p - cont + plen; |
@@ -807,12 +808,66 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char | |||
807 | return ret; | 808 | return ret; |
808 | } | 809 | } |
809 | 810 | ||
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 | |||
810 | /* This function collects the asn1 data from a constructred string | 867 | /* This function collects the asn1 data from a constructred string |
811 | * type into a buffer. The values of 'in' and 'len' should refer | 868 | * type into a buffer. The values of 'in' and 'len' should refer |
812 | * to the contents of the constructed type and 'inf' should be set | 869 | * to the contents of the constructed type and 'inf' should be set |
813 | * if it is indefinite length. If 'buf' is NULL then we just want | 870 | * if it is indefinite length. |
814 | * to find the end of the current structure: useful for indefinite | ||
815 | * length constructed stuff. | ||
816 | */ | 871 | */ |
817 | 872 | ||
818 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) | 873 | static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, int tag, int aclass) |
@@ -822,11 +877,6 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in | |||
822 | char cst, ininf; | 877 | char cst, ininf; |
823 | p = *in; | 878 | p = *in; |
824 | inf &= 1; | 879 | 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 | } | ||
830 | while(len > 0) { | 880 | while(len > 0) { |
831 | q = p; | 881 | q = p; |
832 | /* Check for EOC */ | 882 | /* Check for EOC */ |
@@ -845,9 +895,15 @@ static int asn1_collect(BUF_MEM *buf, unsigned char **in, long len, char inf, in | |||
845 | } | 895 | } |
846 | /* If indefinite length constructed update max length */ | 896 | /* If indefinite length constructed update max length */ |
847 | if(cst) { | 897 | if(cst) { |
848 | if(!asn1_collect(buf, &p, plen, ininf, tag, aclass)) return 0; | 898 | #ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS |
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 | ||
849 | } else { | 905 | } else { |
850 | if(!collect_data(buf, &p, plen)) return 0; | 906 | if(plen && !collect_data(buf, &p, plen)) return 0; |
851 | } | 907 | } |
852 | len -= p - q; | 908 | len -= p - q; |
853 | } | 909 | } |