OpenSSL interoperability broken #15 - ecc part
Karel Miko
7 years ago
33 | 33 | int err; |
34 | 34 | ltc_asn1_type type; |
35 | 35 | unsigned long size, x, y, z, i; |
36 | unsigned char tmptag[6]; | |
36 | 37 | void *data; |
37 | 38 | |
38 | 39 | LTC_ARGCHK(list != NULL); |
40 | 41 | LTC_ARGCHK(outlen != NULL); |
41 | 42 | |
42 | 43 | /* get size of output that will be required */ |
43 | y = 0; | |
44 | for (i = 0; i < inlen; i++) { | |
45 | type = list[i].type; | |
46 | size = list[i].size; | |
47 | data = list[i].data; | |
48 | ||
49 | if (type == LTC_ASN1_EOL) { | |
50 | break; | |
51 | } | |
52 | ||
53 | switch (type) { | |
54 | case LTC_ASN1_BOOLEAN: | |
55 | if ((err = der_length_boolean(&x)) != CRYPT_OK) { | |
56 | goto LBL_ERR; | |
57 | } | |
58 | y += x; | |
59 | break; | |
60 | ||
61 | case LTC_ASN1_INTEGER: | |
62 | if ((err = der_length_integer(data, &x)) != CRYPT_OK) { | |
63 | goto LBL_ERR; | |
64 | } | |
65 | y += x; | |
66 | break; | |
67 | ||
68 | case LTC_ASN1_SHORT_INTEGER: | |
69 | if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { | |
70 | goto LBL_ERR; | |
71 | } | |
72 | y += x; | |
73 | break; | |
74 | ||
75 | case LTC_ASN1_BIT_STRING: | |
76 | case LTC_ASN1_RAW_BIT_STRING: | |
77 | if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { | |
78 | goto LBL_ERR; | |
79 | } | |
80 | y += x; | |
81 | break; | |
82 | ||
83 | case LTC_ASN1_OCTET_STRING: | |
84 | if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { | |
85 | goto LBL_ERR; | |
86 | } | |
87 | y += x; | |
88 | break; | |
89 | ||
90 | case LTC_ASN1_NULL: | |
91 | y += 2; | |
92 | break; | |
93 | ||
94 | case LTC_ASN1_OBJECT_IDENTIFIER: | |
95 | if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { | |
96 | goto LBL_ERR; | |
97 | } | |
98 | y += x; | |
99 | break; | |
100 | ||
101 | case LTC_ASN1_IA5_STRING: | |
102 | if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { | |
103 | goto LBL_ERR; | |
104 | } | |
105 | y += x; | |
106 | break; | |
107 | ||
108 | case LTC_ASN1_PRINTABLE_STRING: | |
109 | if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { | |
110 | goto LBL_ERR; | |
111 | } | |
112 | y += x; | |
113 | break; | |
114 | ||
115 | case LTC_ASN1_UTF8_STRING: | |
116 | if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { | |
117 | goto LBL_ERR; | |
118 | } | |
119 | y += x; | |
120 | break; | |
121 | ||
122 | case LTC_ASN1_UTCTIME: | |
123 | if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { | |
124 | goto LBL_ERR; | |
125 | } | |
126 | y += x; | |
127 | break; | |
128 | ||
129 | case LTC_ASN1_SET: | |
130 | case LTC_ASN1_SETOF: | |
131 | case LTC_ASN1_SEQUENCE: | |
132 | if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { | |
133 | goto LBL_ERR; | |
134 | } | |
135 | y += x; | |
136 | break; | |
137 | ||
138 | case LTC_ASN1_CHOICE: | |
139 | case LTC_ASN1_CONSTRUCTED: | |
140 | case LTC_ASN1_CONTEXT_SPECIFIC: | |
141 | case LTC_ASN1_EOL: | |
142 | case LTC_ASN1_TELETEX_STRING: | |
143 | err = CRYPT_INVALID_ARG; | |
144 | goto LBL_ERR; | |
145 | } | |
146 | } | |
147 | ||
148 | /* calc header size */ | |
149 | z = y; | |
150 | if (y < 128) { | |
151 | y += 2; | |
152 | } else if (y < 256) { | |
153 | /* 0x30 0x81 LL */ | |
154 | y += 3; | |
155 | } else if (y < 65536UL) { | |
156 | /* 0x30 0x82 LL LL */ | |
157 | y += 4; | |
158 | } else if (y < 16777216UL) { | |
159 | /* 0x30 0x83 LL LL LL */ | |
160 | y += 5; | |
161 | } else { | |
162 | err = CRYPT_INVALID_ARG; | |
163 | goto LBL_ERR; | |
164 | } | |
44 | y = 0; z = 0; | |
45 | if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG; | |
165 | 46 | |
166 | 47 | /* too big ? */ |
167 | 48 | if (*outlen < y) { |
207 | 88 | if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { |
208 | 89 | goto LBL_ERR; |
209 | 90 | } |
210 | x += z; | |
211 | *outlen -= z; | |
212 | 91 | break; |
213 | 92 | |
214 | 93 | case LTC_ASN1_INTEGER: |
216 | 95 | if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { |
217 | 96 | goto LBL_ERR; |
218 | 97 | } |
219 | x += z; | |
220 | *outlen -= z; | |
221 | 98 | break; |
222 | 99 | |
223 | 100 | case LTC_ASN1_SHORT_INTEGER: |
225 | 102 | if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { |
226 | 103 | goto LBL_ERR; |
227 | 104 | } |
228 | x += z; | |
229 | *outlen -= z; | |
230 | 105 | break; |
231 | 106 | |
232 | 107 | case LTC_ASN1_BIT_STRING: |
234 | 109 | if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { |
235 | 110 | goto LBL_ERR; |
236 | 111 | } |
237 | x += z; | |
238 | *outlen -= z; | |
239 | 112 | break; |
240 | 113 | |
241 | 114 | case LTC_ASN1_RAW_BIT_STRING: |
243 | 116 | if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) { |
244 | 117 | goto LBL_ERR; |
245 | 118 | } |
246 | x += z; | |
247 | *outlen -= z; | |
248 | 119 | break; |
249 | 120 | |
250 | 121 | case LTC_ASN1_OCTET_STRING: |
252 | 123 | if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { |
253 | 124 | goto LBL_ERR; |
254 | 125 | } |
255 | x += z; | |
256 | *outlen -= z; | |
257 | 126 | break; |
258 | 127 | |
259 | 128 | case LTC_ASN1_NULL: |
260 | out[x++] = 0x05; | |
261 | out[x++] = 0x00; | |
262 | *outlen -= 2; | |
129 | out[x] = 0x05; | |
130 | out[x+1] = 0x00; | |
131 | z = 2; | |
263 | 132 | break; |
264 | 133 | |
265 | 134 | case LTC_ASN1_OBJECT_IDENTIFIER: |
267 | 136 | if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { |
268 | 137 | goto LBL_ERR; |
269 | 138 | } |
270 | x += z; | |
271 | *outlen -= z; | |
272 | 139 | break; |
273 | 140 | |
274 | 141 | case LTC_ASN1_IA5_STRING: |
276 | 143 | if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { |
277 | 144 | goto LBL_ERR; |
278 | 145 | } |
279 | x += z; | |
280 | *outlen -= z; | |
281 | 146 | break; |
282 | 147 | |
283 | 148 | case LTC_ASN1_PRINTABLE_STRING: |
285 | 150 | if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { |
286 | 151 | goto LBL_ERR; |
287 | 152 | } |
288 | x += z; | |
289 | *outlen -= z; | |
290 | 153 | break; |
291 | 154 | |
292 | 155 | case LTC_ASN1_UTF8_STRING: |
294 | 157 | if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { |
295 | 158 | goto LBL_ERR; |
296 | 159 | } |
297 | x += z; | |
298 | *outlen -= z; | |
299 | 160 | break; |
300 | 161 | |
301 | 162 | case LTC_ASN1_UTCTIME: |
303 | 164 | if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { |
304 | 165 | goto LBL_ERR; |
305 | 166 | } |
306 | x += z; | |
307 | *outlen -= z; | |
308 | 167 | break; |
309 | 168 | |
310 | 169 | case LTC_ASN1_SET: |
312 | 171 | if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { |
313 | 172 | goto LBL_ERR; |
314 | 173 | } |
315 | x += z; | |
316 | *outlen -= z; | |
317 | 174 | break; |
318 | 175 | |
319 | 176 | case LTC_ASN1_SETOF: |
321 | 178 | if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { |
322 | 179 | goto LBL_ERR; |
323 | 180 | } |
324 | x += z; | |
325 | *outlen -= z; | |
326 | 181 | break; |
327 | 182 | |
328 | 183 | case LTC_ASN1_SEQUENCE: |
330 | 185 | if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { |
331 | 186 | goto LBL_ERR; |
332 | 187 | } |
333 | x += z; | |
334 | *outlen -= z; | |
335 | 188 | break; |
336 | 189 | |
337 | 190 | case LTC_ASN1_CHOICE: |
339 | 192 | case LTC_ASN1_CONTEXT_SPECIFIC: |
340 | 193 | case LTC_ASN1_EOL: |
341 | 194 | case LTC_ASN1_TELETEX_STRING: |
195 | default: | |
342 | 196 | err = CRYPT_INVALID_ARG; |
343 | 197 | goto LBL_ERR; |
344 | 198 | } |
199 | ||
200 | if (list[i].tag > 0) { | |
201 | tmptag[0] = list[i].tag; | |
202 | y = 0; | |
203 | if (z < 128) { | |
204 | tmptag[1] = (unsigned char)z; | |
205 | y = 2; | |
206 | } else if (z < 256) { | |
207 | tmptag[1] = 0x81; | |
208 | tmptag[2] = (unsigned char)z; | |
209 | y = 3; | |
210 | } else if (z < 65536UL) { | |
211 | tmptag[1] = 0x82; | |
212 | tmptag[2] = (unsigned char)((z>>8UL)&255); | |
213 | tmptag[3] = (unsigned char)(z&255); | |
214 | y = 4; | |
215 | } else if (z < 16777216UL) { | |
216 | tmptag[1] = 0x83; | |
217 | tmptag[2] = (unsigned char)((z>>16UL)&255); | |
218 | tmptag[3] = (unsigned char)((z>>8UL)&255); | |
219 | tmptag[4] = (unsigned char)(z&255); | |
220 | y = 5; | |
221 | } | |
222 | memmove(out + x + y, out + x, z); | |
223 | memcpy(out + x, tmptag, y); | |
224 | ||
225 | z += y; | |
226 | } | |
227 | ||
228 | x += z; | |
229 | *outlen -= z; | |
345 | 230 | } |
346 | 231 | *outlen = x; |
347 | 232 | err = CRYPT_OK; |