diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/a_set.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_set.c | 117 |
1 files changed, 94 insertions, 23 deletions
diff --git a/src/lib/libcrypto/asn1/a_set.c b/src/lib/libcrypto/asn1/a_set.c index 17c49946cf..0f839822ff 100644 --- a/src/lib/libcrypto/asn1/a_set.c +++ b/src/lib/libcrypto/asn1/a_set.c | |||
@@ -58,21 +58,42 @@ | |||
58 | 58 | ||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | #include "asn1_mac.h" | 61 | #include <openssl/asn1_mac.h> |
62 | 62 | ||
63 | /* ASN1err(ASN1_F_ASN1_TYPE_NEW,ERR_R_MALLOC_FAILURE); | 63 | #ifndef NO_ASN1_OLD |
64 | |||
65 | typedef struct | ||
66 | { | ||
67 | unsigned char *pbData; | ||
68 | int cbData; | ||
69 | } MYBLOB; | ||
70 | |||
71 | /* SetBlobCmp | ||
72 | * This function compares two elements of SET_OF block | ||
64 | */ | 73 | */ |
74 | static int SetBlobCmp(const void *elem1, const void *elem2 ) | ||
75 | { | ||
76 | const MYBLOB *b1 = (const MYBLOB *)elem1; | ||
77 | const MYBLOB *b2 = (const MYBLOB *)elem2; | ||
78 | int r; | ||
79 | |||
80 | r = memcmp(b1->pbData, b2->pbData, | ||
81 | b1->cbData < b2->cbData ? b1->cbData : b2->cbData); | ||
82 | if(r != 0) | ||
83 | return r; | ||
84 | return b1->cbData-b2->cbData; | ||
85 | } | ||
65 | 86 | ||
66 | int i2d_ASN1_SET(a,pp,func,ex_tag,ex_class) | 87 | /* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */ |
67 | STACK *a; | 88 | int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag, |
68 | unsigned char **pp; | 89 | int ex_class, int is_set) |
69 | int (*func)(); | ||
70 | int ex_tag; | ||
71 | int ex_class; | ||
72 | { | 90 | { |
73 | int ret=0,r; | 91 | int ret=0,r; |
74 | int i; | 92 | int i; |
75 | unsigned char *p; | 93 | unsigned char *p; |
94 | unsigned char *pStart, *pTempMem; | ||
95 | MYBLOB *rgSetBlob; | ||
96 | int totSize; | ||
76 | 97 | ||
77 | if (a == NULL) return(0); | 98 | if (a == NULL) return(0); |
78 | for (i=sk_num(a)-1; i>=0; i--) | 99 | for (i=sk_num(a)-1; i>=0; i--) |
@@ -82,26 +103,64 @@ int ex_class; | |||
82 | 103 | ||
83 | p= *pp; | 104 | p= *pp; |
84 | ASN1_put_object(&p,1,ret,ex_tag,ex_class); | 105 | ASN1_put_object(&p,1,ret,ex_tag,ex_class); |
85 | for (i=0; i<sk_num(a); i++) | ||
86 | func(sk_value(a,i),&p); | ||
87 | 106 | ||
88 | *pp=p; | 107 | /* Modified by gp@nsj.co.jp */ |
89 | return(r); | 108 | /* And then again by Ben */ |
90 | } | 109 | /* And again by Steve */ |
110 | |||
111 | if(!is_set || (sk_num(a) < 2)) | ||
112 | { | ||
113 | for (i=0; i<sk_num(a); i++) | ||
114 | func(sk_value(a,i),&p); | ||
115 | |||
116 | *pp=p; | ||
117 | return(r); | ||
118 | } | ||
91 | 119 | ||
92 | STACK *d2i_ASN1_SET(a,pp,length,func,ex_tag,ex_class) | 120 | pStart = p; /* Catch the beg of Setblobs*/ |
93 | STACK **a; | 121 | if (!(rgSetBlob = (MYBLOB *)OPENSSL_malloc( sk_num(a) * sizeof(MYBLOB)))) return 0; /* In this array |
94 | unsigned char **pp; | 122 | we will store the SET blobs */ |
95 | long length; | 123 | |
96 | char *(*func)(); | 124 | for (i=0; i<sk_num(a); i++) |
97 | int ex_tag; | 125 | { |
98 | int ex_class; | 126 | rgSetBlob[i].pbData = p; /* catch each set encode blob */ |
127 | func(sk_value(a,i),&p); | ||
128 | rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this | ||
129 | SetBlob | ||
130 | */ | ||
131 | } | ||
132 | *pp=p; | ||
133 | totSize = p - pStart; /* This is the total size of all set blobs */ | ||
134 | |||
135 | /* Now we have to sort the blobs. I am using a simple algo. | ||
136 | *Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/ | ||
137 | qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp); | ||
138 | if (!(pTempMem = OPENSSL_malloc(totSize))) return 0; | ||
139 | |||
140 | /* Copy to temp mem */ | ||
141 | p = pTempMem; | ||
142 | for(i=0; i<sk_num(a); ++i) | ||
143 | { | ||
144 | memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); | ||
145 | p += rgSetBlob[i].cbData; | ||
146 | } | ||
147 | |||
148 | /* Copy back to user mem*/ | ||
149 | memcpy(pStart, pTempMem, totSize); | ||
150 | OPENSSL_free(pTempMem); | ||
151 | OPENSSL_free(rgSetBlob); | ||
152 | |||
153 | return(r); | ||
154 | } | ||
155 | |||
156 | STACK *d2i_ASN1_SET(STACK **a, unsigned char **pp, long length, | ||
157 | char *(*func)(), void (*free_func)(void *), int ex_tag, int ex_class) | ||
99 | { | 158 | { |
100 | ASN1_CTX c; | 159 | ASN1_CTX c; |
101 | STACK *ret=NULL; | 160 | STACK *ret=NULL; |
102 | 161 | ||
103 | if ((a == NULL) || ((*a) == NULL)) | 162 | if ((a == NULL) || ((*a) == NULL)) |
104 | { if ((ret=sk_new(NULL)) == NULL) goto err; } | 163 | { if ((ret=sk_new_null()) == NULL) goto err; } |
105 | else | 164 | else |
106 | ret=(*a); | 165 | ret=(*a); |
107 | 166 | ||
@@ -136,14 +195,26 @@ int ex_class; | |||
136 | char *s; | 195 | char *s; |
137 | 196 | ||
138 | if (M_ASN1_D2I_end_sequence()) break; | 197 | if (M_ASN1_D2I_end_sequence()) break; |
139 | if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) goto err; | 198 | if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) |
199 | { | ||
200 | ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT); | ||
201 | asn1_add_error(*pp,(int)(c.q- *pp)); | ||
202 | goto err; | ||
203 | } | ||
140 | if (!sk_push(ret,s)) goto err; | 204 | if (!sk_push(ret,s)) goto err; |
141 | } | 205 | } |
142 | if (a != NULL) (*a)=ret; | 206 | if (a != NULL) (*a)=ret; |
143 | *pp=c.p; | 207 | *pp=c.p; |
144 | return(ret); | 208 | return(ret); |
145 | err: | 209 | err: |
146 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) sk_free(ret); | 210 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) |
211 | { | ||
212 | if (free_func != NULL) | ||
213 | sk_pop_free(ret,free_func); | ||
214 | else | ||
215 | sk_free(ret); | ||
216 | } | ||
147 | return(NULL); | 217 | return(NULL); |
148 | } | 218 | } |
149 | 219 | ||
220 | #endif | ||