/src/gnutls/lib/minitasn1/coding.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2002-2025 Free Software Foundation, Inc. |
3 | | * |
4 | | * This file is part of LIBTASN1. |
5 | | * |
6 | | * The LIBTASN1 library is free software; you can redistribute it |
7 | | * and/or modify it under the terms of the GNU Lesser General Public |
8 | | * License as published by the Free Software Foundation; either |
9 | | * version 2.1 of the License, or (at your option) any later version. |
10 | | * |
11 | | * This library is distributed in the hope that it will be useful, but |
12 | | * WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | | * Lesser General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU Lesser General Public |
17 | | * License along with this library; if not, see |
18 | | * <https://www.gnu.org/licenses/>. |
19 | | */ |
20 | | |
21 | | #include <config.h> |
22 | | |
23 | | /*****************************************************/ |
24 | | /* File: coding.c */ |
25 | | /* Description: Functions to create a DER coding of */ |
26 | | /* an ASN1 type. */ |
27 | | /*****************************************************/ |
28 | | |
29 | | #include <int.h> |
30 | | #include "parser_aux.h" |
31 | | #include <gstr.h> |
32 | | #include "element.h" |
33 | | #include "minmax.h" |
34 | | #include <structure.h> |
35 | | |
36 | | #define MAX_TAG_LEN 16 |
37 | | |
38 | | /******************************************************/ |
39 | | /* Function : _asn1_error_description_value_not_found */ |
40 | | /* Description: creates the ErrorDescription string */ |
41 | | /* for the ASN1_VALUE_NOT_FOUND error. */ |
42 | | /* Parameters: */ |
43 | | /* node: node of the tree where the value is NULL. */ |
44 | | /* ErrorDescription: string returned. */ |
45 | | /* Return: */ |
46 | | /******************************************************/ |
47 | | static void |
48 | | _asn1_error_description_value_not_found (asn1_node node, |
49 | | char *ErrorDescription) |
50 | 0 | { |
51 | |
|
52 | 0 | if (ErrorDescription == NULL) |
53 | 0 | return; |
54 | | |
55 | 0 | Estrcpy (ErrorDescription, ":: value of element '"); |
56 | 0 | _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), |
57 | 0 | ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); |
58 | 0 | Estrcat (ErrorDescription, "' not found"); |
59 | |
|
60 | 0 | } |
61 | | |
62 | | /** |
63 | | * asn1_length_der: |
64 | | * @len: value to convert. |
65 | | * @der: buffer to hold the returned encoding (may be %NULL). |
66 | | * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]). |
67 | | * |
68 | | * Creates the DER encoding of the provided length value. |
69 | | * The @der buffer must have enough room for the output. The maximum |
70 | | * length this function will encode is %ASN1_MAX_LENGTH_SIZE. |
71 | | * |
72 | | * To know the size of the DER encoding use a %NULL value for @der. |
73 | | **/ |
74 | | void |
75 | | asn1_length_der (unsigned long int len, unsigned char *der, int *der_len) |
76 | 0 | { |
77 | 0 | int k; |
78 | 0 | unsigned char temp[ASN1_MAX_LENGTH_SIZE]; |
79 | | #if SIZEOF_UNSIGNED_LONG_INT > 8 |
80 | | len &= 0xFFFFFFFFFFFFFFFF; |
81 | | #endif |
82 | |
|
83 | 0 | if (len < 128) |
84 | 0 | { |
85 | | /* short form */ |
86 | 0 | if (der != NULL) |
87 | 0 | der[0] = (unsigned char) len; |
88 | 0 | *der_len = 1; |
89 | 0 | } |
90 | 0 | else |
91 | 0 | { |
92 | | /* Long form */ |
93 | 0 | k = 0; |
94 | 0 | while (len) |
95 | 0 | { |
96 | 0 | temp[k++] = len & 0xFF; |
97 | 0 | len = len >> 8; |
98 | 0 | } |
99 | 0 | *der_len = k + 1; |
100 | 0 | if (der != NULL) |
101 | 0 | { |
102 | 0 | der[0] = ((unsigned char) k & 0x7F) + 128; |
103 | 0 | while (k--) |
104 | 0 | der[*der_len - 1 - k] = temp[k]; |
105 | 0 | } |
106 | 0 | } |
107 | 0 | } |
108 | | |
109 | | /******************************************************/ |
110 | | /* Function : _asn1_tag_der */ |
111 | | /* Description: creates the DER coding for the CLASS */ |
112 | | /* and TAG parameters. */ |
113 | | /* It is limited by the ASN1_MAX_TAG_SIZE variable */ |
114 | | /* Parameters: */ |
115 | | /* class: value to convert. */ |
116 | | /* tag_value: value to convert. */ |
117 | | /* ans: string returned. */ |
118 | | /* ans_len: number of meaningful bytes of ANS */ |
119 | | /* (ans[0]..ans[ans_len-1]). */ |
120 | | /* Return: */ |
121 | | /******************************************************/ |
122 | | static void |
123 | | _asn1_tag_der (unsigned char class, unsigned int tag_value, |
124 | | unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len) |
125 | 0 | { |
126 | 0 | int k; |
127 | 0 | unsigned char temp[ASN1_MAX_TAG_SIZE]; |
128 | |
|
129 | 0 | if (tag_value < 31) |
130 | 0 | { |
131 | | /* short form */ |
132 | 0 | ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); |
133 | 0 | *ans_len = 1; |
134 | 0 | } |
135 | 0 | else |
136 | 0 | { |
137 | | /* Long form */ |
138 | 0 | ans[0] = (class & 0xE0) + 31; |
139 | 0 | k = 0; |
140 | 0 | while (tag_value != 0) |
141 | 0 | { |
142 | 0 | temp[k++] = tag_value & 0x7F; |
143 | 0 | tag_value >>= 7; |
144 | |
|
145 | 0 | if (k > ASN1_MAX_TAG_SIZE - 1) |
146 | 0 | break; /* will not encode larger tags */ |
147 | 0 | } |
148 | 0 | *ans_len = k + 1; |
149 | 0 | while (k--) |
150 | 0 | ans[*ans_len - 1 - k] = temp[k] + 128; |
151 | 0 | ans[*ans_len - 1] -= 128; |
152 | 0 | } |
153 | 0 | } |
154 | | |
155 | | /** |
156 | | * asn1_octet_der: |
157 | | * @str: the input data. |
158 | | * @str_len: STR length (str[0]..str[*str_len-1]). |
159 | | * @der: encoded string returned. |
160 | | * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]). |
161 | | * |
162 | | * Creates a length-value DER encoding for the input data. |
163 | | * The DER encoding of the input data will be placed in the @der variable. |
164 | | * |
165 | | * Note that the OCTET STRING tag is not included in the output. |
166 | | * |
167 | | * This function does not return any value because it is expected |
168 | | * that @der_len will contain enough bytes to store the string |
169 | | * plus the DER encoding. The DER encoding size can be obtained using |
170 | | * asn1_length_der(). |
171 | | **/ |
172 | | void |
173 | | asn1_octet_der (const unsigned char *str, int str_len, |
174 | | unsigned char *der, int *der_len) |
175 | 0 | { |
176 | 0 | int len_len; |
177 | |
|
178 | 0 | if (der == NULL || str_len < 0) |
179 | 0 | return; |
180 | | |
181 | 0 | asn1_length_der (str_len, der, &len_len); |
182 | 0 | memcpy (der + len_len, str, str_len); |
183 | 0 | *der_len = str_len + len_len; |
184 | 0 | } |
185 | | |
186 | | |
187 | | /** |
188 | | * asn1_encode_simple_der: |
189 | | * @etype: The type of the string to be encoded (ASN1_ETYPE_) |
190 | | * @str: the string data. |
191 | | * @str_len: the string length |
192 | | * @tl: the encoded tag and length |
193 | | * @tl_len: the bytes of the @tl field |
194 | | * |
195 | | * Creates the DER encoding for various simple ASN.1 types like strings etc. |
196 | | * It stores the tag and length in @tl, which should have space for at least |
197 | | * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl. |
198 | | * |
199 | | * The complete DER encoding should consist of the value in @tl appended |
200 | | * with the provided @str. |
201 | | * |
202 | | * Returns: %ASN1_SUCCESS if successful or an error value. |
203 | | **/ |
204 | | int |
205 | | asn1_encode_simple_der (unsigned int etype, const unsigned char *str, |
206 | | unsigned int str_len, unsigned char *tl, |
207 | | unsigned int *tl_len) |
208 | 0 | { |
209 | 0 | int tag_len, len_len; |
210 | 0 | unsigned tlen; |
211 | 0 | unsigned char der_tag[ASN1_MAX_TAG_SIZE]; |
212 | 0 | unsigned char der_length[ASN1_MAX_LENGTH_SIZE]; |
213 | 0 | unsigned char *p; |
214 | |
|
215 | 0 | if (str == NULL) |
216 | 0 | return ASN1_VALUE_NOT_VALID; |
217 | | |
218 | 0 | if (ETYPE_OK (etype) == 0) |
219 | 0 | return ASN1_VALUE_NOT_VALID; |
220 | | |
221 | | /* doesn't handle constructed classes */ |
222 | 0 | if (ETYPE_CLASS (etype) != ASN1_CLASS_UNIVERSAL) |
223 | 0 | return ASN1_VALUE_NOT_VALID; |
224 | | |
225 | 0 | _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len); |
226 | |
|
227 | 0 | asn1_length_der (str_len, der_length, &len_len); |
228 | |
|
229 | 0 | if (tag_len <= 0 || len_len <= 0) |
230 | 0 | return ASN1_VALUE_NOT_VALID; |
231 | | |
232 | 0 | tlen = tag_len + len_len; |
233 | |
|
234 | 0 | if (*tl_len < tlen) |
235 | 0 | return ASN1_MEM_ERROR; |
236 | | |
237 | 0 | p = tl; |
238 | 0 | memcpy (p, der_tag, tag_len); |
239 | 0 | p += tag_len; |
240 | 0 | memcpy (p, der_length, len_len); |
241 | |
|
242 | 0 | *tl_len = tlen; |
243 | |
|
244 | 0 | return ASN1_SUCCESS; |
245 | 0 | } |
246 | | |
247 | | /******************************************************/ |
248 | | /* Function : _asn1_time_der */ |
249 | | /* Description: creates the DER coding for a TIME */ |
250 | | /* type (length included). */ |
251 | | /* Parameters: */ |
252 | | /* str: TIME null-terminated string. */ |
253 | | /* der: string returned. */ |
254 | | /* der_len: number of meaningful bytes of DER */ |
255 | | /* (der[0]..der[ans_len-1]). Initially it */ |
256 | | /* if must store the length of DER. */ |
257 | | /* Return: */ |
258 | | /* ASN1_MEM_ERROR when DER isn't big enough */ |
259 | | /* ASN1_SUCCESS otherwise */ |
260 | | /******************************************************/ |
261 | | static int |
262 | | _asn1_time_der (unsigned char *str, int str_len, unsigned char *der, |
263 | | int *der_len) |
264 | 0 | { |
265 | 0 | int len_len; |
266 | 0 | int max_len; |
267 | |
|
268 | 0 | max_len = *der_len; |
269 | |
|
270 | 0 | asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len); |
271 | |
|
272 | 0 | if ((len_len + str_len) <= max_len) |
273 | 0 | memcpy (der + len_len, str, str_len); |
274 | 0 | *der_len = len_len + str_len; |
275 | |
|
276 | 0 | if ((*der_len) > max_len) |
277 | 0 | return ASN1_MEM_ERROR; |
278 | | |
279 | 0 | return ASN1_SUCCESS; |
280 | 0 | } |
281 | | |
282 | | |
283 | | /* |
284 | | void |
285 | | _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) |
286 | | { |
287 | | int len_len,str_len; |
288 | | char temp[20]; |
289 | | |
290 | | if(str==NULL) return; |
291 | | str_len=asn1_get_length_der(der,*der_len,&len_len); |
292 | | if (str_len<0) return; |
293 | | memcpy(temp,der+len_len,str_len); |
294 | | *der_len=str_len+len_len; |
295 | | switch(str_len) |
296 | | { |
297 | | case 11: |
298 | | temp[10]=0; |
299 | | strcat(temp,"00+0000"); |
300 | | break; |
301 | | case 13: |
302 | | temp[12]=0; |
303 | | strcat(temp,"+0000"); |
304 | | break; |
305 | | case 15: |
306 | | temp[15]=0; |
307 | | memmove(temp+12,temp+10,6); |
308 | | temp[10]=temp[11]='0'; |
309 | | break; |
310 | | case 17: |
311 | | temp[17]=0; |
312 | | break; |
313 | | default: |
314 | | return; |
315 | | } |
316 | | strcpy(str,temp); |
317 | | } |
318 | | */ |
319 | | |
320 | | static void |
321 | | encode_val (uint64_t val, unsigned char *der, int max_len, int *der_len) |
322 | 0 | { |
323 | 0 | int first, k; |
324 | 0 | unsigned char bit7; |
325 | |
|
326 | 0 | first = 0; |
327 | 0 | for (k = sizeof (val); k >= 0; k--) |
328 | 0 | { |
329 | 0 | bit7 = (val >> (k * 7)) & 0x7F; |
330 | 0 | if (bit7 || first || !k) |
331 | 0 | { |
332 | 0 | if (k) |
333 | 0 | bit7 |= 0x80; |
334 | 0 | if (max_len > (*der_len)) |
335 | 0 | der[*der_len] = bit7; |
336 | 0 | (*der_len)++; |
337 | 0 | first = 1; |
338 | 0 | } |
339 | 0 | } |
340 | 0 | } |
341 | | |
342 | | /******************************************************/ |
343 | | /* Function : _asn1_object_id_der */ |
344 | | /* Description: creates the DER coding for an */ |
345 | | /* OBJECT IDENTIFIER type (length included). */ |
346 | | /* Parameters: */ |
347 | | /* str: OBJECT IDENTIFIER null-terminated string. */ |
348 | | /* der: string returned. */ |
349 | | /* der_len: number of meaningful bytes of DER */ |
350 | | /* (der[0]..der[ans_len-1]). Initially it */ |
351 | | /* must store the length of DER. */ |
352 | | /* Return: */ |
353 | | /* ASN1_MEM_ERROR when DER isn't big enough */ |
354 | | /* ASN1_SUCCESS if successful */ |
355 | | /* or an error value. */ |
356 | | /******************************************************/ |
357 | | static int |
358 | | _asn1_object_id_der (const char *str, unsigned char *der, int *der_len) |
359 | 0 | { |
360 | 0 | int len_len, counter, max_len; |
361 | 0 | char *temp, *n_end, *n_start; |
362 | 0 | uint64_t val, val1 = 0; |
363 | 0 | int str_len = _asn1_strlen (str); |
364 | |
|
365 | 0 | max_len = *der_len; |
366 | 0 | *der_len = 0; |
367 | |
|
368 | 0 | if (der == NULL && max_len > 0) |
369 | 0 | return ASN1_VALUE_NOT_VALID; |
370 | | |
371 | 0 | temp = malloc (str_len + 2); |
372 | 0 | if (temp == NULL) |
373 | 0 | return ASN1_MEM_ALLOC_ERROR; |
374 | | |
375 | 0 | memcpy (temp, str, str_len); |
376 | 0 | temp[str_len] = '.'; |
377 | 0 | temp[str_len + 1] = 0; |
378 | |
|
379 | 0 | counter = 0; |
380 | 0 | n_start = temp; |
381 | 0 | while ((n_end = strchr (n_start, '.'))) |
382 | 0 | { |
383 | 0 | *n_end = 0; |
384 | 0 | val = _asn1_strtou64 (n_start, NULL, 10); |
385 | 0 | counter++; |
386 | |
|
387 | 0 | if (counter == 1) |
388 | 0 | { |
389 | 0 | val1 = val; |
390 | 0 | } |
391 | 0 | else if (counter == 2) |
392 | 0 | { |
393 | 0 | uint64_t val0; |
394 | |
|
395 | 0 | if (val1 > 2) |
396 | 0 | { |
397 | 0 | free (temp); |
398 | 0 | return ASN1_VALUE_NOT_VALID; |
399 | 0 | } |
400 | 0 | else if ((val1 == 0 || val1 == 1) && val > 39) |
401 | 0 | { |
402 | 0 | free (temp); |
403 | 0 | return ASN1_VALUE_NOT_VALID; |
404 | 0 | } |
405 | | |
406 | 0 | val0 = 40 * val1 + val; |
407 | 0 | encode_val (val0, der, max_len, der_len); |
408 | 0 | } |
409 | 0 | else |
410 | 0 | { |
411 | 0 | encode_val (val, der, max_len, der_len); |
412 | 0 | } |
413 | 0 | n_start = n_end + 1; |
414 | 0 | } |
415 | | |
416 | 0 | asn1_length_der (*der_len, NULL, &len_len); |
417 | 0 | if (max_len >= (*der_len + len_len)) |
418 | 0 | { |
419 | 0 | memmove (der + len_len, der, *der_len); |
420 | 0 | asn1_length_der (*der_len, der, &len_len); |
421 | 0 | } |
422 | 0 | *der_len += len_len; |
423 | |
|
424 | 0 | free (temp); |
425 | |
|
426 | 0 | if (max_len < (*der_len)) |
427 | 0 | return ASN1_MEM_ERROR; |
428 | | |
429 | 0 | return ASN1_SUCCESS; |
430 | 0 | } |
431 | | |
432 | | /** |
433 | | * asn1_object_id_der: |
434 | | * @str: An object identifier in numeric, dot format. |
435 | | * @der: buffer to hold the returned encoding (may be %NULL). |
436 | | * @der_len: initially the size of @der; will hold the final size. |
437 | | * @flags: must be zero |
438 | | * |
439 | | * Creates the DER encoding of the provided object identifier. |
440 | | * |
441 | | * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID |
442 | | * if @str is not a valid OID, %ASN1_MEM_ERROR if the @der |
443 | | * vector isn't big enough and in this case @der_len will contain the |
444 | | * length needed. |
445 | | **/ |
446 | | int |
447 | | asn1_object_id_der (const char *str, unsigned char *der, int *der_len, |
448 | | unsigned flags) |
449 | 0 | { |
450 | 0 | unsigned char tag_der[MAX_TAG_LEN]; |
451 | 0 | int tag_len = 0, r; |
452 | 0 | int max_len = *der_len; |
453 | |
|
454 | 0 | *der_len = 0; |
455 | |
|
456 | 0 | _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), |
457 | 0 | ETYPE_TAG (ASN1_ETYPE_OBJECT_ID), tag_der, &tag_len); |
458 | |
|
459 | 0 | if (max_len > tag_len) |
460 | 0 | { |
461 | 0 | memcpy (der, tag_der, tag_len); |
462 | 0 | } |
463 | 0 | max_len -= tag_len; |
464 | 0 | der += tag_len; |
465 | |
|
466 | 0 | r = _asn1_object_id_der (str, der, &max_len); |
467 | 0 | if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS) |
468 | 0 | { |
469 | 0 | *der_len = max_len + tag_len; |
470 | 0 | } |
471 | |
|
472 | 0 | return r; |
473 | 0 | } |
474 | | |
475 | | static const unsigned char bit_mask[] = |
476 | | { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; |
477 | | |
478 | | /** |
479 | | * asn1_bit_der: |
480 | | * @str: BIT string. |
481 | | * @bit_len: number of meaningful bits in STR. |
482 | | * @der: string returned. |
483 | | * @der_len: number of meaningful bytes of DER |
484 | | * (der[0]..der[ans_len-1]). |
485 | | * |
486 | | * Creates a length-value DER encoding for the input data |
487 | | * as it would have been for a BIT STRING. |
488 | | * The DER encoded data will be copied in @der. |
489 | | * |
490 | | * Note that the BIT STRING tag is not included in the output. |
491 | | * |
492 | | * This function does not return any value because it is expected |
493 | | * that @der_len will contain enough bytes to store the string |
494 | | * plus the DER encoding. The DER encoding size can be obtained using |
495 | | * asn1_length_der(). |
496 | | **/ |
497 | | void |
498 | | asn1_bit_der (const unsigned char *str, int bit_len, |
499 | | unsigned char *der, int *der_len) |
500 | 0 | { |
501 | 0 | int len_len, len_byte, len_pad; |
502 | |
|
503 | 0 | if (der == NULL) |
504 | 0 | return; |
505 | | |
506 | 0 | len_byte = bit_len >> 3; |
507 | 0 | len_pad = 8 - (bit_len & 7); |
508 | 0 | if (len_pad == 8) |
509 | 0 | len_pad = 0; |
510 | 0 | else |
511 | 0 | len_byte++; |
512 | 0 | asn1_length_der (len_byte + 1, der, &len_len); |
513 | 0 | der[len_len] = len_pad; |
514 | |
|
515 | 0 | if (str) |
516 | 0 | memcpy (der + len_len + 1, str, len_byte); |
517 | 0 | der[len_len + len_byte] &= bit_mask[len_pad]; |
518 | 0 | *der_len = len_byte + len_len + 1; |
519 | 0 | } |
520 | | |
521 | | |
522 | | /******************************************************/ |
523 | | /* Function : _asn1_complete_explicit_tag */ |
524 | | /* Description: add the length coding to the EXPLICIT */ |
525 | | /* tags. */ |
526 | | /* Parameters: */ |
527 | | /* node: pointer to the tree element. */ |
528 | | /* der: string with the DER coding of the whole tree*/ |
529 | | /* counter: number of meaningful bytes of DER */ |
530 | | /* (der[0]..der[*counter-1]). */ |
531 | | /* max_len: size of der vector */ |
532 | | /* Return: */ |
533 | | /* ASN1_MEM_ERROR if der vector isn't big enough, */ |
534 | | /* otherwise ASN1_SUCCESS. */ |
535 | | /******************************************************/ |
536 | | static int |
537 | | _asn1_complete_explicit_tag (asn1_node node, unsigned char *der, |
538 | | int *counter, int *max_len) |
539 | 0 | { |
540 | 0 | asn1_node p; |
541 | 0 | int is_tag_implicit, len2, len3; |
542 | 0 | unsigned char temp[SIZEOF_UNSIGNED_INT]; |
543 | |
|
544 | 0 | if (der == NULL && *max_len > 0) |
545 | 0 | return ASN1_VALUE_NOT_VALID; |
546 | | |
547 | 0 | is_tag_implicit = 0; |
548 | |
|
549 | 0 | if (node->type & CONST_TAG) |
550 | 0 | { |
551 | 0 | p = node->down; |
552 | 0 | if (p == NULL) |
553 | 0 | return ASN1_DER_ERROR; |
554 | | /* When there are nested tags we must complete them reverse to |
555 | | the order they were created. This is because completing a tag |
556 | | modifies all data within it, including the incomplete tags |
557 | | which store buffer positions -- simon@josefsson.org 2002-09-06 |
558 | | */ |
559 | 0 | while (p->right) |
560 | 0 | p = p->right; |
561 | 0 | while (p && p != node->down->left) |
562 | 0 | { |
563 | 0 | if (type_field (p->type) == ASN1_ETYPE_TAG) |
564 | 0 | { |
565 | 0 | if (p->type & CONST_EXPLICIT) |
566 | 0 | { |
567 | 0 | len2 = strtol (p->name, NULL, 10); |
568 | 0 | _asn1_set_name (p, NULL); |
569 | |
|
570 | 0 | asn1_length_der (*counter - len2, temp, &len3); |
571 | 0 | if (len3 <= (*max_len)) |
572 | 0 | { |
573 | 0 | memmove (der + len2 + len3, der + len2, |
574 | 0 | *counter - len2); |
575 | 0 | memcpy (der + len2, temp, len3); |
576 | 0 | } |
577 | 0 | *max_len -= len3; |
578 | 0 | *counter += len3; |
579 | 0 | is_tag_implicit = 0; |
580 | 0 | } |
581 | 0 | else |
582 | 0 | { /* CONST_IMPLICIT */ |
583 | 0 | if (!is_tag_implicit) |
584 | 0 | { |
585 | 0 | is_tag_implicit = 1; |
586 | 0 | } |
587 | 0 | } |
588 | 0 | } |
589 | 0 | p = p->left; |
590 | 0 | } |
591 | 0 | } |
592 | | |
593 | 0 | if (*max_len < 0) |
594 | 0 | return ASN1_MEM_ERROR; |
595 | | |
596 | 0 | return ASN1_SUCCESS; |
597 | 0 | } |
598 | | |
599 | | const tag_and_class_st _asn1_tags[] = { |
600 | | [ASN1_ETYPE_GENERALSTRING] = |
601 | | {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"}, |
602 | | [ASN1_ETYPE_NUMERIC_STRING] = |
603 | | {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"}, |
604 | | [ASN1_ETYPE_IA5_STRING] = |
605 | | {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"}, |
606 | | [ASN1_ETYPE_TELETEX_STRING] = |
607 | | {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"}, |
608 | | [ASN1_ETYPE_PRINTABLE_STRING] = |
609 | | {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"}, |
610 | | [ASN1_ETYPE_UNIVERSAL_STRING] = |
611 | | {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"}, |
612 | | [ASN1_ETYPE_BMP_STRING] = |
613 | | {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"}, |
614 | | [ASN1_ETYPE_UTF8_STRING] = |
615 | | {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"}, |
616 | | [ASN1_ETYPE_VISIBLE_STRING] = |
617 | | {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"}, |
618 | | [ASN1_ETYPE_OCTET_STRING] = |
619 | | {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"}, |
620 | | [ASN1_ETYPE_BIT_STRING] = |
621 | | {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"}, |
622 | | [ASN1_ETYPE_OBJECT_ID] = |
623 | | {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"}, |
624 | | [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"}, |
625 | | [ASN1_ETYPE_BOOLEAN] = |
626 | | {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"}, |
627 | | [ASN1_ETYPE_INTEGER] = |
628 | | {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"}, |
629 | | [ASN1_ETYPE_ENUMERATED] = |
630 | | {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"}, |
631 | | [ASN1_ETYPE_SEQUENCE] = |
632 | | {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, |
633 | | "type:SEQUENCE"}, |
634 | | [ASN1_ETYPE_SEQUENCE_OF] = |
635 | | {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, |
636 | | "type:SEQ_OF"}, |
637 | | [ASN1_ETYPE_SET] = |
638 | | {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"}, |
639 | | [ASN1_ETYPE_SET_OF] = |
640 | | {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, |
641 | | "type:SET_OF"}, |
642 | | [ASN1_ETYPE_GENERALIZED_TIME] = |
643 | | {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"}, |
644 | | [ASN1_ETYPE_UTC_TIME] = |
645 | | {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"}, |
646 | | }; |
647 | | |
648 | | unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); |
649 | | |
650 | | /******************************************************/ |
651 | | /* Function : _asn1_insert_tag_der */ |
652 | | /* Description: creates the DER coding of tags of one */ |
653 | | /* NODE. */ |
654 | | /* Parameters: */ |
655 | | /* node: pointer to the tree element. */ |
656 | | /* der: string returned */ |
657 | | /* counter: number of meaningful bytes of DER */ |
658 | | /* (counter[0]..der[*counter-1]). */ |
659 | | /* max_len: size of der vector */ |
660 | | /* Return: */ |
661 | | /* ASN1_GENERIC_ERROR if the type is unknown, */ |
662 | | /* ASN1_MEM_ERROR if der vector isn't big enough, */ |
663 | | /* otherwise ASN1_SUCCESS. */ |
664 | | /******************************************************/ |
665 | | static int |
666 | | _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter, |
667 | | int *max_len) |
668 | 0 | { |
669 | 0 | asn1_node p; |
670 | 0 | int tag_len, is_tag_implicit; |
671 | 0 | unsigned char class, class_implicit = |
672 | 0 | 0, temp[MAX (SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)]; |
673 | 0 | unsigned long tag_implicit = 0; |
674 | 0 | unsigned char tag_der[MAX_TAG_LEN]; |
675 | |
|
676 | 0 | is_tag_implicit = 0; |
677 | |
|
678 | 0 | if (node->type & CONST_TAG) |
679 | 0 | { |
680 | 0 | p = node->down; |
681 | 0 | while (p) |
682 | 0 | { |
683 | 0 | if (type_field (p->type) == ASN1_ETYPE_TAG) |
684 | 0 | { |
685 | 0 | if (p->type & CONST_APPLICATION) |
686 | 0 | class = ASN1_CLASS_APPLICATION; |
687 | 0 | else if (p->type & CONST_UNIVERSAL) |
688 | 0 | class = ASN1_CLASS_UNIVERSAL; |
689 | 0 | else if (p->type & CONST_PRIVATE) |
690 | 0 | class = ASN1_CLASS_PRIVATE; |
691 | 0 | else |
692 | 0 | class = ASN1_CLASS_CONTEXT_SPECIFIC; |
693 | |
|
694 | 0 | if (p->type & CONST_EXPLICIT) |
695 | 0 | { |
696 | 0 | if (is_tag_implicit) |
697 | 0 | _asn1_tag_der (class_implicit, tag_implicit, tag_der, |
698 | 0 | &tag_len); |
699 | 0 | else |
700 | 0 | _asn1_tag_der (class | ASN1_CLASS_STRUCTURED, |
701 | 0 | _asn1_strtoul (p->value, NULL, 10), |
702 | 0 | tag_der, &tag_len); |
703 | |
|
704 | 0 | *max_len -= tag_len; |
705 | 0 | if (der && *max_len >= 0) |
706 | 0 | memcpy (der + *counter, tag_der, tag_len); |
707 | 0 | *counter += tag_len; |
708 | |
|
709 | 0 | _asn1_ltostr (*counter, (char *) temp); |
710 | 0 | _asn1_set_name (p, (const char *) temp); |
711 | |
|
712 | 0 | is_tag_implicit = 0; |
713 | 0 | } |
714 | 0 | else |
715 | 0 | { /* CONST_IMPLICIT */ |
716 | 0 | if (!is_tag_implicit) |
717 | 0 | { |
718 | 0 | if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) || |
719 | 0 | (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) |
720 | 0 | || (type_field (node->type) == ASN1_ETYPE_SET) |
721 | 0 | || (type_field (node->type) == ASN1_ETYPE_SET_OF)) |
722 | 0 | class |= ASN1_CLASS_STRUCTURED; |
723 | 0 | class_implicit = class; |
724 | 0 | tag_implicit = _asn1_strtoul (p->value, NULL, 10); |
725 | 0 | is_tag_implicit = 1; |
726 | 0 | } |
727 | 0 | } |
728 | 0 | } |
729 | 0 | p = p->right; |
730 | 0 | } |
731 | 0 | } |
732 | |
|
733 | 0 | if (is_tag_implicit) |
734 | 0 | { |
735 | 0 | _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len); |
736 | 0 | } |
737 | 0 | else |
738 | 0 | { |
739 | 0 | unsigned type = type_field (node->type); |
740 | 0 | switch (type) |
741 | 0 | { |
742 | 0 | CASE_HANDLED_ETYPES: |
743 | 0 | _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag, |
744 | 0 | tag_der, &tag_len); |
745 | 0 | break; |
746 | 0 | case ASN1_ETYPE_TAG: |
747 | 0 | case ASN1_ETYPE_CHOICE: |
748 | 0 | case ASN1_ETYPE_ANY: |
749 | 0 | tag_len = 0; |
750 | 0 | break; |
751 | 0 | default: |
752 | 0 | return ASN1_GENERIC_ERROR; |
753 | 0 | } |
754 | 0 | } |
755 | | |
756 | 0 | *max_len -= tag_len; |
757 | 0 | if (der && *max_len >= 0) |
758 | 0 | memcpy (der + *counter, tag_der, tag_len); |
759 | 0 | *counter += tag_len; |
760 | |
|
761 | 0 | if (*max_len < 0) |
762 | 0 | return ASN1_MEM_ERROR; |
763 | | |
764 | 0 | return ASN1_SUCCESS; |
765 | 0 | } |
766 | | |
767 | | /******************************************************/ |
768 | | /* Function : _asn1_ordering_set */ |
769 | | /* Description: puts the elements of a SET type in */ |
770 | | /* the correct order according to DER rules. */ |
771 | | /* Parameters: */ |
772 | | /* der: string with the DER coding. */ |
773 | | /* node: pointer to the SET element. */ |
774 | | /* Return: */ |
775 | | /* ASN1_SUCCESS if successful */ |
776 | | /* or an error value. */ |
777 | | /******************************************************/ |
778 | | static int |
779 | | _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) |
780 | 0 | { |
781 | 0 | struct vet |
782 | 0 | { |
783 | 0 | int end; |
784 | 0 | unsigned long value; |
785 | 0 | struct vet *next, *prev; |
786 | 0 | }; |
787 | |
|
788 | 0 | int counter, len, len2; |
789 | 0 | struct vet *first, *last, *p_vet, *p2_vet; |
790 | 0 | asn1_node p; |
791 | 0 | unsigned char class, *temp; |
792 | 0 | unsigned long tag, t; |
793 | 0 | int err; |
794 | |
|
795 | 0 | counter = 0; |
796 | |
|
797 | 0 | if (type_field (node->type) != ASN1_ETYPE_SET) |
798 | 0 | return ASN1_VALUE_NOT_VALID; |
799 | | |
800 | 0 | p = node->down; |
801 | 0 | while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || |
802 | 0 | (type_field (p->type) == ASN1_ETYPE_SIZE))) |
803 | 0 | p = p->right; |
804 | |
|
805 | 0 | if ((p == NULL) || (p->right == NULL)) |
806 | 0 | return ASN1_SUCCESS; |
807 | | |
808 | 0 | first = last = NULL; |
809 | 0 | while (p) |
810 | 0 | { |
811 | 0 | p_vet = malloc (sizeof (struct vet)); |
812 | 0 | if (p_vet == NULL) |
813 | 0 | { |
814 | 0 | err = ASN1_MEM_ALLOC_ERROR; |
815 | 0 | goto error; |
816 | 0 | } |
817 | | |
818 | 0 | p_vet->next = NULL; |
819 | 0 | p_vet->prev = last; |
820 | 0 | if (first == NULL) |
821 | 0 | first = p_vet; |
822 | 0 | else |
823 | 0 | last->next = p_vet; |
824 | 0 | last = p_vet; |
825 | | |
826 | | /* tag value calculation */ |
827 | 0 | err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2, |
828 | 0 | &tag); |
829 | 0 | if (err != ASN1_SUCCESS) |
830 | 0 | goto error; |
831 | | |
832 | 0 | t = ((unsigned int) class) << 24; |
833 | 0 | p_vet->value = t | tag; |
834 | 0 | counter += len2; |
835 | | |
836 | | /* extraction and length */ |
837 | 0 | len2 = asn1_get_length_der (der + counter, der_len - counter, &len); |
838 | 0 | if (len2 < 0) |
839 | 0 | { |
840 | 0 | err = ASN1_DER_ERROR; |
841 | 0 | goto error; |
842 | 0 | } |
843 | 0 | counter += len + len2; |
844 | |
|
845 | 0 | p_vet->end = counter; |
846 | 0 | p = p->right; |
847 | 0 | } |
848 | | |
849 | 0 | p_vet = first; |
850 | |
|
851 | 0 | while (p_vet) |
852 | 0 | { |
853 | 0 | p2_vet = p_vet->next; |
854 | 0 | counter = 0; |
855 | 0 | while (p2_vet) |
856 | 0 | { |
857 | 0 | if (p_vet->value > p2_vet->value) |
858 | 0 | { |
859 | | /* change position */ |
860 | 0 | temp = malloc (p_vet->end - counter); |
861 | 0 | if (temp == NULL) |
862 | 0 | { |
863 | 0 | err = ASN1_MEM_ALLOC_ERROR; |
864 | 0 | goto error; |
865 | 0 | } |
866 | | |
867 | 0 | memcpy (temp, der + counter, p_vet->end - counter); |
868 | 0 | memcpy (der + counter, der + p_vet->end, |
869 | 0 | p2_vet->end - p_vet->end); |
870 | 0 | memcpy (der + counter + p2_vet->end - p_vet->end, temp, |
871 | 0 | p_vet->end - counter); |
872 | 0 | free (temp); |
873 | |
|
874 | 0 | tag = p_vet->value; |
875 | 0 | p_vet->value = p2_vet->value; |
876 | 0 | p2_vet->value = tag; |
877 | |
|
878 | 0 | p_vet->end = counter + (p2_vet->end - p_vet->end); |
879 | 0 | } |
880 | 0 | counter = p_vet->end; |
881 | |
|
882 | 0 | p2_vet = p2_vet->next; |
883 | 0 | p_vet = p_vet->next; |
884 | 0 | } |
885 | | |
886 | 0 | if (p_vet != first) |
887 | 0 | p_vet->prev->next = NULL; |
888 | 0 | else |
889 | 0 | first = NULL; |
890 | 0 | free (p_vet); |
891 | 0 | p_vet = first; |
892 | 0 | } |
893 | 0 | return ASN1_SUCCESS; |
894 | | |
895 | 0 | error: |
896 | 0 | while (first != NULL) |
897 | 0 | { |
898 | 0 | p_vet = first; |
899 | 0 | first = first->next; |
900 | 0 | free (p_vet); |
901 | 0 | } |
902 | 0 | return err; |
903 | 0 | } |
904 | | |
905 | | struct vet |
906 | | { |
907 | | unsigned char *ptr; |
908 | | int size; |
909 | | }; |
910 | | |
911 | | static int |
912 | | setof_compar (const void *_e1, const void *_e2) |
913 | 0 | { |
914 | 0 | unsigned length; |
915 | 0 | const struct vet *e1 = _e1, *e2 = _e2; |
916 | 0 | int rval; |
917 | | |
918 | | /* The encodings of the component values of a set-of value shall |
919 | | * appear in ascending order, the encodings being compared |
920 | | * as octet strings with the shorter components being |
921 | | * padded at their trailing end with 0-octets. |
922 | | * The padding octets are for comparison purposes and |
923 | | * do not appear in the encodings. |
924 | | */ |
925 | 0 | length = MIN (e1->size, e2->size); |
926 | |
|
927 | 0 | rval = memcmp (e1->ptr, e2->ptr, length); |
928 | 0 | if (rval == 0 && e1->size != e2->size) |
929 | 0 | { |
930 | 0 | if (e1->size > e2->size) |
931 | 0 | rval = 1; |
932 | 0 | else if (e2->size > e1->size) |
933 | 0 | rval = -1; |
934 | 0 | } |
935 | |
|
936 | 0 | return rval; |
937 | 0 | } |
938 | | |
939 | | /******************************************************/ |
940 | | /* Function : _asn1_ordering_set_of */ |
941 | | /* Description: puts the elements of a SET OF type in */ |
942 | | /* the correct order according to DER rules. */ |
943 | | /* Parameters: */ |
944 | | /* der: string with the DER coding. */ |
945 | | /* node: pointer to the SET OF element. */ |
946 | | /* Return: */ |
947 | | /* ASN1_SUCCESS if successful */ |
948 | | /* or an error value. */ |
949 | | /******************************************************/ |
950 | | static int |
951 | | _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) |
952 | 0 | { |
953 | 0 | int counter, len, len2; |
954 | 0 | struct vet *list = NULL, *tlist; |
955 | 0 | unsigned list_size = 0; |
956 | 0 | struct vet *p_vet; |
957 | 0 | asn1_node p; |
958 | 0 | unsigned char class; |
959 | 0 | unsigned i; |
960 | 0 | unsigned char *out = NULL; |
961 | 0 | int err; |
962 | |
|
963 | 0 | counter = 0; |
964 | |
|
965 | 0 | if (type_field (node->type) != ASN1_ETYPE_SET_OF) |
966 | 0 | return ASN1_VALUE_NOT_VALID; |
967 | | |
968 | 0 | p = node->down; |
969 | 0 | while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || |
970 | 0 | (type_field (p->type) == ASN1_ETYPE_SIZE))) |
971 | 0 | p = p->right; |
972 | 0 | if (p == NULL) |
973 | 0 | return ASN1_VALUE_NOT_VALID; |
974 | 0 | p = p->right; |
975 | |
|
976 | 0 | if ((p == NULL) || (p->right == NULL)) |
977 | 0 | return ASN1_SUCCESS; |
978 | | |
979 | 0 | while (p) |
980 | 0 | { |
981 | 0 | list_size++; |
982 | 0 | tlist = realloc (list, list_size * sizeof (struct vet)); |
983 | 0 | if (tlist == NULL) |
984 | 0 | { |
985 | 0 | err = ASN1_MEM_ALLOC_ERROR; |
986 | 0 | goto error; |
987 | 0 | } |
988 | 0 | list = tlist; |
989 | 0 | p_vet = &list[list_size - 1]; |
990 | |
|
991 | 0 | p_vet->ptr = der + counter; |
992 | 0 | p_vet->size = 0; |
993 | | |
994 | | /* extraction of tag and length */ |
995 | 0 | if (der_len - counter > 0) |
996 | 0 | { |
997 | 0 | err = asn1_get_tag_der (der + counter, der_len - counter, &class, |
998 | 0 | &len, NULL); |
999 | 0 | if (err != ASN1_SUCCESS) |
1000 | 0 | goto error; |
1001 | 0 | counter += len; |
1002 | 0 | p_vet->size += len; |
1003 | |
|
1004 | 0 | len2 = asn1_get_length_der (der + counter, der_len - counter, &len); |
1005 | 0 | if (len2 < 0) |
1006 | 0 | { |
1007 | 0 | err = ASN1_DER_ERROR; |
1008 | 0 | goto error; |
1009 | 0 | } |
1010 | 0 | counter += len + len2; |
1011 | 0 | p_vet->size += len + len2; |
1012 | |
|
1013 | 0 | } |
1014 | 0 | else |
1015 | 0 | { |
1016 | 0 | err = ASN1_DER_ERROR; |
1017 | 0 | goto error; |
1018 | 0 | } |
1019 | 0 | p = p->right; |
1020 | 0 | } |
1021 | | |
1022 | 0 | if (counter > der_len) |
1023 | 0 | { |
1024 | 0 | err = ASN1_DER_ERROR; |
1025 | 0 | goto error; |
1026 | 0 | } |
1027 | | |
1028 | 0 | qsort (list, list_size, sizeof (struct vet), setof_compar); |
1029 | |
|
1030 | 0 | out = malloc (der_len); |
1031 | 0 | if (out == NULL) |
1032 | 0 | { |
1033 | 0 | err = ASN1_MEM_ERROR; |
1034 | 0 | goto error; |
1035 | 0 | } |
1036 | | |
1037 | | /* the sum of p_vet->size == der_len */ |
1038 | 0 | counter = 0; |
1039 | 0 | for (i = 0; i < list_size; i++) |
1040 | 0 | { |
1041 | 0 | p_vet = &list[i]; |
1042 | 0 | memcpy (out + counter, p_vet->ptr, p_vet->size); |
1043 | 0 | counter += p_vet->size; |
1044 | 0 | } |
1045 | 0 | memcpy (der, out, der_len); |
1046 | 0 | free (out); |
1047 | |
|
1048 | 0 | err = ASN1_SUCCESS; |
1049 | |
|
1050 | 0 | error: |
1051 | 0 | free (list); |
1052 | 0 | return err; |
1053 | 0 | } |
1054 | | |
1055 | | /** |
1056 | | * asn1_der_coding: |
1057 | | * @element: pointer to an ASN1 element |
1058 | | * @name: the name of the structure you want to encode (it must be |
1059 | | * inside *POINTER). |
1060 | | * @ider: vector that will contain the DER encoding. DER must be a |
1061 | | * pointer to memory cells already allocated. |
1062 | | * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initially |
1063 | | * holds the sizeof of der vector. |
1064 | | * @ErrorDescription: return the error description or an empty |
1065 | | * string if success. |
1066 | | * |
1067 | | * Creates the DER encoding for the NAME structure (inside *POINTER |
1068 | | * structure). |
1069 | | * |
1070 | | * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND |
1071 | | * if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there |
1072 | | * is an element without a value, %ASN1_MEM_ERROR if the @ider |
1073 | | * vector isn't big enough and in this case @len will contain the |
1074 | | * length needed. |
1075 | | **/ |
1076 | | int |
1077 | | asn1_der_coding (asn1_node_const element, const char *name, void *ider, |
1078 | | int *len, char *ErrorDescription) |
1079 | 0 | { |
1080 | 0 | asn1_node node, p, p2; |
1081 | 0 | unsigned char temp[MAX (LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)]; |
1082 | 0 | int counter, counter_old, len2, len3, move, max_len, max_len_old; |
1083 | 0 | int err; |
1084 | 0 | unsigned char *der = ider; |
1085 | 0 | unsigned char dummy; |
1086 | |
|
1087 | 0 | if (ErrorDescription) |
1088 | 0 | ErrorDescription[0] = 0; |
1089 | |
|
1090 | 0 | node = asn1_find_node (element, name); |
1091 | 0 | if (node == NULL) |
1092 | 0 | return ASN1_ELEMENT_NOT_FOUND; |
1093 | | |
1094 | | /* Node is now a locally allocated variable. |
1095 | | * That is because in some point we modify the |
1096 | | * structure, and I don't know why! --nmav |
1097 | | */ |
1098 | 0 | node = _asn1_copy_structure3 (node); |
1099 | 0 | if (node == NULL) |
1100 | 0 | return ASN1_ELEMENT_NOT_FOUND; |
1101 | | |
1102 | 0 | max_len = *len; |
1103 | |
|
1104 | 0 | if (der == NULL && max_len > 0) |
1105 | 0 | { |
1106 | 0 | err = ASN1_VALUE_NOT_VALID; |
1107 | 0 | goto error; |
1108 | 0 | } |
1109 | | |
1110 | 0 | counter = 0; |
1111 | 0 | move = DOWN; |
1112 | 0 | p = node; |
1113 | |
|
1114 | 0 | while (1) |
1115 | 0 | { |
1116 | |
|
1117 | 0 | counter_old = counter; |
1118 | 0 | max_len_old = max_len; |
1119 | 0 | if (move != UP) |
1120 | 0 | { |
1121 | 0 | p->start = counter; |
1122 | 0 | err = _asn1_insert_tag_der (p, der, &counter, &max_len); |
1123 | 0 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) |
1124 | 0 | goto error; |
1125 | 0 | } |
1126 | 0 | switch (type_field (p->type)) |
1127 | 0 | { |
1128 | 0 | case ASN1_ETYPE_NULL: |
1129 | 0 | max_len--; |
1130 | 0 | if (der != NULL && max_len >= 0) |
1131 | 0 | der[counter] = 0; |
1132 | 0 | counter++; |
1133 | 0 | move = RIGHT; |
1134 | 0 | break; |
1135 | 0 | case ASN1_ETYPE_BOOLEAN: |
1136 | 0 | if ((p->type & CONST_DEFAULT) && (p->value == NULL)) |
1137 | 0 | { |
1138 | 0 | counter = counter_old; |
1139 | 0 | max_len = max_len_old; |
1140 | 0 | } |
1141 | 0 | else |
1142 | 0 | { |
1143 | 0 | if (p->value == NULL) |
1144 | 0 | { |
1145 | 0 | _asn1_error_description_value_not_found (p, |
1146 | 0 | ErrorDescription); |
1147 | 0 | err = ASN1_VALUE_NOT_FOUND; |
1148 | 0 | goto error; |
1149 | 0 | } |
1150 | 0 | max_len -= 2; |
1151 | 0 | if (der != NULL && max_len >= 0) |
1152 | 0 | { |
1153 | 0 | der[counter++] = 1; |
1154 | 0 | if (p->value[0] == 'F') |
1155 | 0 | der[counter++] = 0; |
1156 | 0 | else |
1157 | 0 | der[counter++] = 0xFF; |
1158 | 0 | } |
1159 | 0 | else |
1160 | 0 | counter += 2; |
1161 | 0 | } |
1162 | 0 | move = RIGHT; |
1163 | 0 | break; |
1164 | 0 | case ASN1_ETYPE_INTEGER: |
1165 | 0 | case ASN1_ETYPE_ENUMERATED: |
1166 | 0 | if ((p->type & CONST_DEFAULT) && (p->value == NULL)) |
1167 | 0 | { |
1168 | 0 | counter = counter_old; |
1169 | 0 | max_len = max_len_old; |
1170 | 0 | } |
1171 | 0 | else |
1172 | 0 | { |
1173 | 0 | if (p->value == NULL) |
1174 | 0 | { |
1175 | 0 | _asn1_error_description_value_not_found (p, |
1176 | 0 | ErrorDescription); |
1177 | 0 | err = ASN1_VALUE_NOT_FOUND; |
1178 | 0 | goto error; |
1179 | 0 | } |
1180 | 0 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); |
1181 | 0 | if (len2 < 0) |
1182 | 0 | { |
1183 | 0 | err = ASN1_DER_ERROR; |
1184 | 0 | goto error; |
1185 | 0 | } |
1186 | 0 | max_len -= len2 + len3; |
1187 | 0 | if (der != NULL && max_len >= 0) |
1188 | 0 | memcpy (der + counter, p->value, len3 + len2); |
1189 | 0 | counter += len3 + len2; |
1190 | 0 | } |
1191 | 0 | move = RIGHT; |
1192 | 0 | break; |
1193 | 0 | case ASN1_ETYPE_OBJECT_ID: |
1194 | 0 | if ((p->type & CONST_DEFAULT) && (p->value == NULL)) |
1195 | 0 | { |
1196 | 0 | counter = counter_old; |
1197 | 0 | max_len = max_len_old; |
1198 | 0 | } |
1199 | 0 | else |
1200 | 0 | { |
1201 | 0 | if (p->value == NULL) |
1202 | 0 | { |
1203 | 0 | _asn1_error_description_value_not_found (p, |
1204 | 0 | ErrorDescription); |
1205 | 0 | err = ASN1_VALUE_NOT_FOUND; |
1206 | 0 | goto error; |
1207 | 0 | } |
1208 | 0 | len2 = max_len; |
1209 | 0 | err = |
1210 | 0 | _asn1_object_id_der ((char *) p->value, |
1211 | 0 | der ? der + counter : &dummy, &len2); |
1212 | 0 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) |
1213 | 0 | goto error; |
1214 | | |
1215 | 0 | max_len -= len2; |
1216 | 0 | counter += len2; |
1217 | 0 | } |
1218 | 0 | move = RIGHT; |
1219 | 0 | break; |
1220 | 0 | case ASN1_ETYPE_GENERALIZED_TIME: |
1221 | 0 | case ASN1_ETYPE_UTC_TIME: |
1222 | 0 | if (p->value == NULL) |
1223 | 0 | { |
1224 | 0 | _asn1_error_description_value_not_found (p, ErrorDescription); |
1225 | 0 | err = ASN1_VALUE_NOT_FOUND; |
1226 | 0 | goto error; |
1227 | 0 | } |
1228 | 0 | len2 = max_len; |
1229 | 0 | err = |
1230 | 0 | _asn1_time_der (p->value, p->value_len, |
1231 | 0 | der ? der + counter : &dummy, &len2); |
1232 | 0 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) |
1233 | 0 | goto error; |
1234 | | |
1235 | 0 | max_len -= len2; |
1236 | 0 | counter += len2; |
1237 | 0 | move = RIGHT; |
1238 | 0 | break; |
1239 | 0 | case ASN1_ETYPE_OCTET_STRING: |
1240 | 0 | case ASN1_ETYPE_GENERALSTRING: |
1241 | 0 | case ASN1_ETYPE_NUMERIC_STRING: |
1242 | 0 | case ASN1_ETYPE_IA5_STRING: |
1243 | 0 | case ASN1_ETYPE_TELETEX_STRING: |
1244 | 0 | case ASN1_ETYPE_PRINTABLE_STRING: |
1245 | 0 | case ASN1_ETYPE_UNIVERSAL_STRING: |
1246 | 0 | case ASN1_ETYPE_BMP_STRING: |
1247 | 0 | case ASN1_ETYPE_UTF8_STRING: |
1248 | 0 | case ASN1_ETYPE_VISIBLE_STRING: |
1249 | 0 | case ASN1_ETYPE_BIT_STRING: |
1250 | 0 | if (p->value == NULL) |
1251 | 0 | { |
1252 | 0 | _asn1_error_description_value_not_found (p, ErrorDescription); |
1253 | 0 | err = ASN1_VALUE_NOT_FOUND; |
1254 | 0 | goto error; |
1255 | 0 | } |
1256 | 0 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); |
1257 | 0 | if (len2 < 0) |
1258 | 0 | { |
1259 | 0 | err = ASN1_DER_ERROR; |
1260 | 0 | goto error; |
1261 | 0 | } |
1262 | 0 | max_len -= len2 + len3; |
1263 | 0 | if (der != NULL && max_len >= 0) |
1264 | 0 | memcpy (der + counter, p->value, len3 + len2); |
1265 | 0 | counter += len3 + len2; |
1266 | 0 | move = RIGHT; |
1267 | 0 | break; |
1268 | 0 | case ASN1_ETYPE_SEQUENCE: |
1269 | 0 | case ASN1_ETYPE_SET: |
1270 | 0 | if (move != UP) |
1271 | 0 | { |
1272 | 0 | p->tmp_ival = counter; |
1273 | 0 | if (p->down == NULL) |
1274 | 0 | { |
1275 | 0 | move = UP; |
1276 | 0 | continue; |
1277 | 0 | } |
1278 | 0 | else |
1279 | 0 | { |
1280 | 0 | p2 = p->down; |
1281 | 0 | while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG)) |
1282 | 0 | p2 = p2->right; |
1283 | 0 | if (p2) |
1284 | 0 | { |
1285 | 0 | p = p2; |
1286 | 0 | move = RIGHT; |
1287 | 0 | continue; |
1288 | 0 | } |
1289 | 0 | move = UP; |
1290 | 0 | continue; |
1291 | 0 | } |
1292 | 0 | } |
1293 | 0 | else |
1294 | 0 | { /* move==UP */ |
1295 | 0 | len2 = p->tmp_ival; |
1296 | 0 | p->tmp_ival = 0; |
1297 | 0 | if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0)) |
1298 | 0 | { |
1299 | 0 | err = |
1300 | 0 | _asn1_ordering_set (der ? der + len2 : &dummy, |
1301 | 0 | counter - len2, p); |
1302 | 0 | if (err != ASN1_SUCCESS) |
1303 | 0 | goto error; |
1304 | 0 | } |
1305 | 0 | asn1_length_der (counter - len2, temp, &len3); |
1306 | 0 | max_len -= len3; |
1307 | 0 | if (der != NULL && max_len >= 0) |
1308 | 0 | { |
1309 | 0 | memmove (der + len2 + len3, der + len2, counter - len2); |
1310 | 0 | memcpy (der + len2, temp, len3); |
1311 | 0 | } |
1312 | 0 | counter += len3; |
1313 | 0 | move = RIGHT; |
1314 | 0 | } |
1315 | 0 | break; |
1316 | 0 | case ASN1_ETYPE_SEQUENCE_OF: |
1317 | 0 | case ASN1_ETYPE_SET_OF: |
1318 | 0 | if (move != UP) |
1319 | 0 | { |
1320 | 0 | p->tmp_ival = counter; |
1321 | 0 | p = p->down; |
1322 | 0 | while ((type_field (p->type) == ASN1_ETYPE_TAG) |
1323 | 0 | || (type_field (p->type) == ASN1_ETYPE_SIZE)) |
1324 | 0 | p = p->right; |
1325 | 0 | if (p->right) |
1326 | 0 | { |
1327 | 0 | p = p->right; |
1328 | 0 | move = RIGHT; |
1329 | 0 | continue; |
1330 | 0 | } |
1331 | 0 | else |
1332 | 0 | p = _asn1_find_up (p); |
1333 | 0 | move = UP; |
1334 | 0 | } |
1335 | 0 | if (move == UP) |
1336 | 0 | { |
1337 | 0 | len2 = p->tmp_ival; |
1338 | 0 | p->tmp_ival = 0; |
1339 | 0 | if ((type_field (p->type) == ASN1_ETYPE_SET_OF) |
1340 | 0 | && (counter - len2 > 0) && (max_len >= 0)) |
1341 | 0 | { |
1342 | 0 | err = |
1343 | 0 | _asn1_ordering_set_of (der ? der + len2 : &dummy, |
1344 | 0 | counter - len2, p); |
1345 | 0 | if (err != ASN1_SUCCESS) |
1346 | 0 | goto error; |
1347 | 0 | } |
1348 | 0 | asn1_length_der (counter - len2, temp, &len3); |
1349 | 0 | max_len -= len3; |
1350 | 0 | if (der != NULL && max_len >= 0) |
1351 | 0 | { |
1352 | 0 | memmove (der + len2 + len3, der + len2, counter - len2); |
1353 | 0 | memcpy (der + len2, temp, len3); |
1354 | 0 | } |
1355 | 0 | counter += len3; |
1356 | 0 | move = RIGHT; |
1357 | 0 | } |
1358 | 0 | break; |
1359 | 0 | case ASN1_ETYPE_ANY: |
1360 | 0 | if (p->value == NULL) |
1361 | 0 | { |
1362 | 0 | _asn1_error_description_value_not_found (p, ErrorDescription); |
1363 | 0 | err = ASN1_VALUE_NOT_FOUND; |
1364 | 0 | goto error; |
1365 | 0 | } |
1366 | 0 | len2 = asn1_get_length_der (p->value, p->value_len, &len3); |
1367 | 0 | if (len2 < 0) |
1368 | 0 | { |
1369 | 0 | err = ASN1_DER_ERROR; |
1370 | 0 | goto error; |
1371 | 0 | } |
1372 | 0 | max_len -= len2; |
1373 | 0 | if (der != NULL && max_len >= 0) |
1374 | 0 | memcpy (der + counter, p->value + len3, len2); |
1375 | 0 | counter += len2; |
1376 | 0 | move = RIGHT; |
1377 | 0 | break; |
1378 | 0 | default: |
1379 | 0 | move = (move == UP) ? RIGHT : DOWN; |
1380 | 0 | break; |
1381 | 0 | } |
1382 | | |
1383 | 0 | if ((move != DOWN) && (counter != counter_old)) |
1384 | 0 | { |
1385 | 0 | p->end = counter - 1; |
1386 | 0 | err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); |
1387 | 0 | if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) |
1388 | 0 | goto error; |
1389 | 0 | } |
1390 | | |
1391 | 0 | if (p == node && move != DOWN) |
1392 | 0 | break; |
1393 | | |
1394 | 0 | if (move == DOWN) |
1395 | 0 | { |
1396 | 0 | if (p->down) |
1397 | 0 | p = p->down; |
1398 | 0 | else |
1399 | 0 | move = RIGHT; |
1400 | 0 | } |
1401 | 0 | if (move == RIGHT) |
1402 | 0 | { |
1403 | 0 | if (p->right) |
1404 | 0 | p = p->right; |
1405 | 0 | else |
1406 | 0 | move = UP; |
1407 | 0 | } |
1408 | 0 | if (move == UP) |
1409 | 0 | p = _asn1_find_up (p); |
1410 | 0 | } |
1411 | | |
1412 | 0 | *len = counter; |
1413 | |
|
1414 | 0 | if (max_len < 0) |
1415 | 0 | { |
1416 | 0 | err = ASN1_MEM_ERROR; |
1417 | 0 | goto error; |
1418 | 0 | } |
1419 | | |
1420 | 0 | err = ASN1_SUCCESS; |
1421 | |
|
1422 | 0 | error: |
1423 | 0 | asn1_delete_structure (&node); |
1424 | 0 | return err; |
1425 | 0 | } |