corrected copyright notices
[gnutls.git] / lib / minitasn1 / decoding.c
blobf02fe10686be996a71996324e933d0f2cd3d1024
1 /*
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * This file is part of LIBTASN1.
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA
23 /*****************************************************/
24 /* File: decoding.c */
25 /* Description: Functions to manage DER decoding */
26 /*****************************************************/
28 #include <int.h>
29 #include "parser_aux.h"
30 #include <gstr.h>
31 #include "structure.h"
32 #include "element.h"
33 #include <limits.h>
35 static int
36 _asn1_get_indefinite_length_string (const unsigned char *der, int *len);
38 static void
39 _asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
42 Estrcpy (ErrorDescription, ":: tag error near element '");
43 _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
44 ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
45 Estrcat (ErrorDescription, "'");
49 /**
50 * asn1_get_length_der:
51 * @der: DER data to decode.
52 * @der_len: Length of DER data to decode.
53 * @len: Output variable containing the length of the DER length field.
55 * Extract a length field from DER data.
57 * Returns: Return the decoded length value, or -1 on indefinite
58 * length, or -2 when the value was too big to fit in a int, or -4
59 * when the decoded length value plus @len would exceed @der_len.
60 **/
61 long
62 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
64 unsigned int ans, sum, last;
65 int k, punt;
67 *len = 0;
68 if (der_len <= 0)
69 return 0;
71 if (!(der[0] & 128))
73 /* short form */
74 *len = 1;
75 ans = der[0];
77 else
79 /* Long form */
80 k = der[0] & 0x7F;
81 punt = 1;
82 if (k)
83 { /* definite length method */
84 ans = 0;
85 while (punt <= k && punt < der_len)
87 last = ans;
89 ans = (ans*256) + der[punt++];
90 if (ans < last)
91 /* we wrapped around, no bignum support... */
92 return -2;
95 else
96 { /* indefinite length method */
97 *len = punt;
98 return -1;
101 *len = punt;
104 sum = ans + *len;
106 /* check for overflow as well INT_MAX as a maximum upper
107 * limit for length */
108 if (sum >= INT_MAX || sum < ans)
109 return -2;
111 if (((int) sum) > der_len)
112 return -4;
114 return ans;
118 * asn1_get_tag_der:
119 * @der: DER data to decode.
120 * @der_len: Length of DER data to decode.
121 * @cls: Output variable containing decoded class.
122 * @len: Output variable containing the length of the DER TAG data.
123 * @tag: Output variable containing the decoded tag.
125 * Decode the class and TAG from DER code.
127 * Returns: Returns %ASN1_SUCCESS on success, or an error.
130 asn1_get_tag_der (const unsigned char *der, int der_len,
131 unsigned char *cls, int *len, unsigned long *tag)
133 unsigned int ris;
134 int punt;
135 unsigned int last;
137 if (der == NULL || der_len < 2 || len == NULL)
138 return ASN1_DER_ERROR;
140 *cls = der[0] & 0xE0;
141 if ((der[0] & 0x1F) != 0x1F)
143 /* short form */
144 *len = 1;
145 ris = der[0] & 0x1F;
147 else
149 /* Long form */
150 punt = 1;
151 ris = 0;
152 while (punt <= der_len && der[punt] & 128)
154 last = ris;
156 ris = (ris * 128) + (der[punt++] & 0x7F);
157 if (ris < last)
158 /* wrapped around, and no bignums... */
159 return ASN1_DER_ERROR;
162 if (punt >= der_len)
163 return ASN1_DER_ERROR;
165 last = ris;
167 ris = (ris * 128) + (der[punt++] & 0x7F);
168 if (ris < last)
169 return ASN1_DER_ERROR;
171 *len = punt;
173 if (tag)
174 *tag = ris;
175 return ASN1_SUCCESS;
179 * asn1_get_length_ber:
180 * @ber: BER data to decode.
181 * @ber_len: Length of BER data to decode.
182 * @len: Output variable containing the length of the BER length field.
184 * Extract a length field from BER data. The difference to
185 * asn1_get_length_der() is that this function will return a length
186 * even if the value has indefinite encoding.
188 * Returns: Return the decoded length value, or negative value when
189 * the value was too big.
191 * Since: 2.0
193 long
194 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
196 int ret;
197 long err;
199 ret = asn1_get_length_der (ber, ber_len, len);
200 if (ret == -1)
201 { /* indefinite length method */
202 ret = ber_len;
203 err = _asn1_get_indefinite_length_string (ber + 1, &ret);
204 if (err != ASN1_SUCCESS)
205 return -3;
208 return ret;
212 * asn1_get_octet_der:
213 * @der: DER data to decode containing the OCTET SEQUENCE.
214 * @der_len: Length of DER data to decode.
215 * @ret_len: Output variable containing the length of the DER data.
216 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
217 * @str_size: Length of pre-allocated output buffer.
218 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
220 * Extract an OCTET SEQUENCE from DER data.
222 * Returns: Returns %ASN1_SUCCESS on success, or an error.
225 asn1_get_octet_der (const unsigned char *der, int der_len,
226 int *ret_len, unsigned char *str, int str_size,
227 int *str_len)
229 int len_len;
231 if (der_len <= 0)
232 return ASN1_GENERIC_ERROR;
234 /* if(str==NULL) return ASN1_SUCCESS; */
235 *str_len = asn1_get_length_der (der, der_len, &len_len);
237 if (*str_len < 0)
238 return ASN1_DER_ERROR;
240 *ret_len = *str_len + len_len;
241 if (str_size >= *str_len)
242 memcpy (str, der + len_len, *str_len);
243 else
245 return ASN1_MEM_ERROR;
248 return ASN1_SUCCESS;
251 /* Returns ASN1_SUCCESS on success or an error code on error.
253 static int
254 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
255 char *str, int str_size)
257 int len_len, str_len;
259 if (der_len <= 0 || str == NULL)
260 return ASN1_DER_ERROR;
261 str_len = asn1_get_length_der (der, der_len, &len_len);
262 if (str_len < 0 || str_size < str_len)
263 return ASN1_DER_ERROR;
264 memcpy (str, der + len_len, str_len);
265 str[str_len] = 0;
266 *ret_len = str_len + len_len;
268 return ASN1_SUCCESS;
271 static int
272 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
273 char *str, int str_size)
275 int len_len, len, k;
276 int leading;
277 char temp[20];
278 unsigned long val, val1, prev_val;
280 *ret_len = 0;
281 if (str && str_size > 0)
282 str[0] = 0; /* no oid */
284 if (str == NULL || der_len <= 0)
285 return ASN1_GENERIC_ERROR;
286 len = asn1_get_length_der (der, der_len, &len_len);
288 if (len < 0 || len > der_len || len_len > der_len)
289 return ASN1_DER_ERROR;
291 val1 = der[len_len] / 40;
292 val = der[len_len] - val1 * 40;
294 _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
295 _asn1_str_cat (str, str_size, ".");
296 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
298 prev_val = 0;
299 val = 0;
300 leading = 1;
301 for (k = 1; k < len; k++)
303 /* X.690 mandates that the leading byte must never be 0x80
305 if (leading != 0 && der[len_len + k] == 0x80)
306 return ASN1_DER_ERROR;
307 leading = 0;
309 /* check for wrap around */
310 val = val << 7;
311 val |= der[len_len + k] & 0x7F;
313 if (val < prev_val)
314 return ASN1_DER_ERROR;
316 prev_val = val;
318 if (!(der[len_len + k] & 0x80))
320 _asn1_str_cat (str, str_size, ".");
321 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
322 val = 0;
323 prev_val = 0;
324 leading = 1;
327 *ret_len = len + len_len;
329 return ASN1_SUCCESS;
333 * asn1_get_bit_der:
334 * @der: DER data to decode containing the BIT SEQUENCE.
335 * @der_len: Length of DER data to decode.
336 * @ret_len: Output variable containing the length of the DER data.
337 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
338 * @str_size: Length of pre-allocated output buffer.
339 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
341 * Extract a BIT SEQUENCE from DER data.
343 * Returns: Return %ASN1_SUCCESS on success, or an error.
346 asn1_get_bit_der (const unsigned char *der, int der_len,
347 int *ret_len, unsigned char *str, int str_size,
348 int *bit_len)
350 int len_len, len_byte;
352 if (der_len <= 0)
353 return ASN1_GENERIC_ERROR;
354 len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
355 if (len_byte < 0)
356 return ASN1_DER_ERROR;
358 *ret_len = len_byte + len_len + 1;
359 *bit_len = len_byte * 8 - der[len_len];
361 if (str_size >= len_byte)
362 memcpy (str, der + len_len + 1, len_byte);
363 else
365 return ASN1_MEM_ERROR;
368 return ASN1_SUCCESS;
371 static int
372 _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
373 int *ret_len)
375 asn1_node p;
376 int counter, len2, len3, is_tag_implicit;
377 unsigned long tag, tag_implicit = 0;
378 unsigned char class, class2, class_implicit = 0;
380 if (der_len <= 0)
381 return ASN1_GENERIC_ERROR;
383 counter = is_tag_implicit = 0;
385 if (node->type & CONST_TAG)
387 p = node->down;
388 while (p)
390 if (type_field (p->type) == ASN1_ETYPE_TAG)
392 if (p->type & CONST_APPLICATION)
393 class2 = ASN1_CLASS_APPLICATION;
394 else if (p->type & CONST_UNIVERSAL)
395 class2 = ASN1_CLASS_UNIVERSAL;
396 else if (p->type & CONST_PRIVATE)
397 class2 = ASN1_CLASS_PRIVATE;
398 else
399 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
401 if (p->type & CONST_EXPLICIT)
403 if (asn1_get_tag_der
404 (der + counter, der_len - counter, &class, &len2,
405 &tag) != ASN1_SUCCESS)
406 return ASN1_DER_ERROR;
408 if (counter + len2 > der_len)
409 return ASN1_DER_ERROR;
410 counter += len2;
412 len3 =
413 asn1_get_length_ber (der + counter, der_len - counter,
414 &len2);
415 if (len3 < 0)
416 return ASN1_DER_ERROR;
418 counter += len2;
419 if (counter > der_len)
420 return ASN1_DER_ERROR;
422 if (!is_tag_implicit)
424 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
425 (tag != strtoul ((char *) p->value, NULL, 10)))
426 return ASN1_TAG_ERROR;
428 else
429 { /* ASN1_TAG_IMPLICIT */
430 if ((class != class_implicit) || (tag != tag_implicit))
431 return ASN1_TAG_ERROR;
433 is_tag_implicit = 0;
435 else
436 { /* ASN1_TAG_IMPLICIT */
437 if (!is_tag_implicit)
439 if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
440 (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) ||
441 (type_field (node->type) == ASN1_ETYPE_SET) ||
442 (type_field (node->type) == ASN1_ETYPE_SET_OF))
443 class2 |= ASN1_CLASS_STRUCTURED;
444 class_implicit = class2;
445 tag_implicit = strtoul ((char *) p->value, NULL, 10);
446 is_tag_implicit = 1;
450 p = p->right;
454 if (is_tag_implicit)
456 if (asn1_get_tag_der
457 (der + counter, der_len - counter, &class, &len2,
458 &tag) != ASN1_SUCCESS)
459 return ASN1_DER_ERROR;
460 if (counter + len2 > der_len)
461 return ASN1_DER_ERROR;
463 if ((class != class_implicit) || (tag != tag_implicit))
465 if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
467 class_implicit |= ASN1_CLASS_STRUCTURED;
468 if ((class != class_implicit) || (tag != tag_implicit))
469 return ASN1_TAG_ERROR;
471 else
472 return ASN1_TAG_ERROR;
475 else
477 unsigned type = type_field (node->type);
478 if (type == ASN1_ETYPE_TAG)
480 counter = 0;
481 *ret_len = counter;
482 return ASN1_SUCCESS;
485 if (asn1_get_tag_der
486 (der + counter, der_len - counter, &class, &len2,
487 &tag) != ASN1_SUCCESS)
488 return ASN1_DER_ERROR;
490 if (counter + len2 > der_len)
491 return ASN1_DER_ERROR;
493 switch (type)
495 case ASN1_ETYPE_NULL:
496 case ASN1_ETYPE_BOOLEAN:
497 case ASN1_ETYPE_INTEGER:
498 case ASN1_ETYPE_ENUMERATED:
499 case ASN1_ETYPE_OBJECT_ID:
500 case ASN1_ETYPE_GENERALSTRING:
501 case ASN1_ETYPE_NUMERIC_STRING:
502 case ASN1_ETYPE_IA5_STRING:
503 case ASN1_ETYPE_TELETEX_STRING:
504 case ASN1_ETYPE_PRINTABLE_STRING:
505 case ASN1_ETYPE_UNIVERSAL_STRING:
506 case ASN1_ETYPE_BMP_STRING:
507 case ASN1_ETYPE_UTF8_STRING:
508 case ASN1_ETYPE_VISIBLE_STRING:
509 case ASN1_ETYPE_BIT_STRING:
510 case ASN1_ETYPE_SEQUENCE:
511 case ASN1_ETYPE_SEQUENCE_OF:
512 case ASN1_ETYPE_SET:
513 case ASN1_ETYPE_SET_OF:
514 case ASN1_ETYPE_GENERALIZED_TIME:
515 case ASN1_ETYPE_UTC_TIME:
516 if ((class != _asn1_tags[type].class) || (tag != _asn1_tags[type].tag))
517 return ASN1_DER_ERROR;
518 break;
520 case ASN1_ETYPE_OCTET_STRING:
521 /* OCTET STRING is handled differently to allow
522 * BER encodings (structured class). */
523 if (((class != ASN1_CLASS_UNIVERSAL)
524 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
525 || (tag != ASN1_TAG_OCTET_STRING))
526 return ASN1_DER_ERROR;
527 break;
528 case ASN1_ETYPE_ANY:
529 counter -= len2;
530 break;
531 default:
532 return ASN1_DER_ERROR;
533 break;
537 counter += len2;
538 *ret_len = counter;
539 return ASN1_SUCCESS;
542 static int
543 _asn1_delete_not_used (asn1_node node)
545 asn1_node p, p2;
547 if (node == NULL)
548 return ASN1_ELEMENT_NOT_FOUND;
550 p = node;
551 while (p)
553 if (p->type & CONST_NOT_USED)
555 p2 = NULL;
556 if (p != node)
558 p2 = _asn1_find_left (p);
559 if (!p2)
560 p2 = _asn1_find_up (p);
562 asn1_delete_structure (&p);
563 p = p2;
566 if (!p)
567 break; /* reach node */
569 if (p->down)
571 p = p->down;
573 else
575 if (p == node)
576 p = NULL;
577 else if (p->right)
578 p = p->right;
579 else
581 while (1)
583 p = _asn1_find_up (p);
584 if (p == node)
586 p = NULL;
587 break;
589 if (p->right)
591 p = p->right;
592 break;
598 return ASN1_SUCCESS;
601 static int
602 _asn1_extract_der_octet (asn1_node node, const unsigned char *der,
603 int der_len)
605 int len2, len3;
606 int counter2, counter_end;
608 len2 = asn1_get_length_der (der, der_len, &len3);
609 if (len2 < -1)
610 return ASN1_DER_ERROR;
612 counter2 = len3 + 1;
614 if (len2 == -1)
615 counter_end = der_len - 2;
616 else
617 counter_end = der_len;
619 while (counter2 < counter_end)
621 len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
623 if (len2 < -1)
624 return ASN1_DER_ERROR;
626 if (len2 > 0)
628 _asn1_append_value (node, der + counter2 + len3, len2);
630 else
631 { /* indefinite */
633 len2 =
634 _asn1_extract_der_octet (node, der + counter2 + len3,
635 der_len - counter2 - len3);
636 if (len2 < 0)
637 return len2;
640 counter2 += len2 + len3 + 1;
643 return ASN1_SUCCESS;
646 static int
647 _asn1_get_octet_string (const unsigned char *der, asn1_node node, int *len)
649 int len2, len3, counter, tot_len, indefinite;
651 counter = 0;
653 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
655 tot_len = 0;
656 indefinite = asn1_get_length_der (der, *len, &len3);
657 if (indefinite < -1)
658 return ASN1_DER_ERROR;
660 counter += len3;
661 if (indefinite >= 0)
662 indefinite += len3;
664 while (1)
666 if (counter > (*len))
667 return ASN1_DER_ERROR;
669 if (indefinite == -1)
671 if ((der[counter] == 0) && (der[counter + 1] == 0))
673 counter += 2;
674 break;
677 else if (counter >= indefinite)
678 break;
680 if (der[counter] != ASN1_TAG_OCTET_STRING)
681 return ASN1_DER_ERROR;
683 counter++;
685 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
686 if (len2 <= 0)
687 return ASN1_DER_ERROR;
689 counter += len3 + len2;
690 tot_len += len2;
693 /* copy */
694 if (node)
696 unsigned char temp[DER_LEN];
697 int ret;
699 len2 = sizeof (temp);
701 asn1_length_der (tot_len, temp, &len2);
702 _asn1_set_value (node, temp, len2);
704 ret = _asn1_extract_der_octet (node, der, *len);
705 if (ret != ASN1_SUCCESS)
706 return ret;
710 else
711 { /* NOT STRUCTURED */
712 len2 = asn1_get_length_der (der, *len, &len3);
713 if (len2 < 0)
714 return ASN1_DER_ERROR;
716 counter = len3 + len2;
717 if (node)
718 _asn1_set_value (node, der, counter);
721 *len = counter;
722 return ASN1_SUCCESS;
726 static int
727 _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
729 int len2, len3, counter, indefinite;
730 unsigned long tag;
731 unsigned char class;
733 counter = indefinite = 0;
735 while (1)
737 if ((*len) < counter)
738 return ASN1_DER_ERROR;
740 if ((der[counter] == 0) && (der[counter + 1] == 0))
742 counter += 2;
743 indefinite--;
744 if (indefinite <= 0)
745 break;
746 else
747 continue;
750 if (asn1_get_tag_der
751 (der + counter, *len - counter, &class, &len2,
752 &tag) != ASN1_SUCCESS)
753 return ASN1_DER_ERROR;
754 if (counter + len2 > *len)
755 return ASN1_DER_ERROR;
756 counter += len2;
757 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
758 if (len2 < -1)
759 return ASN1_DER_ERROR;
760 if (len2 == -1)
762 indefinite++;
763 counter += 1;
765 else
767 counter += len2 + len3;
771 *len = counter;
772 return ASN1_SUCCESS;
777 * asn1_der_decoding:
778 * @element: pointer to an ASN1 structure.
779 * @ider: vector that contains the DER encoding.
780 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
781 * @errorDescription: null-terminated string contains details when an
782 * error occurred.
784 * Fill the structure *@ELEMENT with values of a DER encoding
785 * string. The structure must just be created with function
786 * asn1_create_element(). If an error occurs during the decoding
787 * procedure, the *@ELEMENT is deleted and set equal to
788 * %NULL.
790 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
791 * if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
792 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
793 * name (*@ELEMENT deleted).
796 asn1_der_decoding (asn1_node * element, const void *ider, int len,
797 char *errorDescription)
799 asn1_node node, p, p2, p3;
800 char temp[128];
801 int counter, len2, len3, len4, move, ris, tlen;
802 unsigned char class;
803 unsigned long tag;
804 int indefinite, result;
805 const unsigned char *der = ider;
807 node = *element;
809 if (errorDescription != NULL)
810 errorDescription[0] = 0;
812 if (node == NULL)
813 return ASN1_ELEMENT_NOT_FOUND;
815 if (node->type & CONST_OPTION)
817 result = ASN1_GENERIC_ERROR;
818 goto cleanup;
821 counter = 0;
822 move = DOWN;
823 p = node;
824 while (1)
826 ris = ASN1_SUCCESS;
827 if (move != UP)
829 if (p->type & CONST_SET)
831 p2 = _asn1_find_up (p);
832 len2 = _asn1_strtol (p2->value, NULL, 10);
833 if (len2 == -1)
835 if (!der[counter] && !der[counter + 1])
837 p = p2;
838 move = UP;
839 counter += 2;
840 continue;
843 else if (counter == len2)
845 p = p2;
846 move = UP;
847 continue;
849 else if (counter > len2)
851 result = ASN1_DER_ERROR;
852 goto cleanup;
854 p2 = p2->down;
855 while (p2)
857 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
859 if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
860 ris =
861 _asn1_extract_tag_der (p2, der + counter,
862 len - counter, &len2);
863 else
865 p3 = p2->down;
866 while (p3)
868 ris =
869 _asn1_extract_tag_der (p3, der + counter,
870 len - counter, &len2);
871 if (ris == ASN1_SUCCESS)
872 break;
873 p3 = p3->right;
876 if (ris == ASN1_SUCCESS)
878 p2->type &= ~CONST_NOT_USED;
879 p = p2;
880 break;
883 p2 = p2->right;
885 if (p2 == NULL)
887 result = ASN1_DER_ERROR;
888 goto cleanup;
892 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
894 p2 = _asn1_find_up (p);
895 len2 = _asn1_strtol (p2->value, NULL, 10);
896 if (counter == len2)
898 if (p->right)
900 p2 = p->right;
901 move = RIGHT;
903 else
904 move = UP;
906 if (p->type & CONST_OPTION)
907 asn1_delete_structure (&p);
909 p = p2;
910 continue;
914 if (type_field (p->type) == ASN1_ETYPE_CHOICE)
916 while (p->down)
918 if (counter < len)
919 ris =
920 _asn1_extract_tag_der (p->down, der + counter,
921 len - counter, &len2);
922 else
923 ris = ASN1_DER_ERROR;
924 if (ris == ASN1_SUCCESS)
926 while (p->down->right)
928 p2 = p->down->right;
929 asn1_delete_structure (&p2);
931 break;
933 else if (ris == ASN1_ERROR_TYPE_ANY)
935 result = ASN1_ERROR_TYPE_ANY;
936 goto cleanup;
938 else
940 p2 = p->down;
941 asn1_delete_structure (&p2);
945 if (p->down == NULL)
947 if (!(p->type & CONST_OPTION))
949 result = ASN1_DER_ERROR;
950 goto cleanup;
953 else
954 p = p->down;
957 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
959 p2 = _asn1_find_up (p);
960 len2 = _asn1_strtol (p2->value, NULL, 10);
961 if ((len2 != -1) && (counter > len2))
962 ris = ASN1_TAG_ERROR;
965 if (ris == ASN1_SUCCESS)
966 ris =
967 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
968 if (ris != ASN1_SUCCESS)
970 if (p->type & CONST_OPTION)
972 p->type |= CONST_NOT_USED;
973 move = RIGHT;
975 else if (p->type & CONST_DEFAULT)
977 _asn1_set_value (p, NULL, 0);
978 move = RIGHT;
980 else
982 if (errorDescription != NULL)
983 _asn1_error_description_tag_error (p, errorDescription);
985 result = ASN1_TAG_ERROR;
986 goto cleanup;
989 else
990 counter += len2;
993 if (ris == ASN1_SUCCESS)
995 switch (type_field (p->type))
997 case ASN1_ETYPE_NULL:
998 if (der[counter])
1000 result = ASN1_DER_ERROR;
1001 goto cleanup;
1003 counter++;
1004 move = RIGHT;
1005 break;
1006 case ASN1_ETYPE_BOOLEAN:
1007 if (der[counter++] != 1)
1009 result = ASN1_DER_ERROR;
1010 goto cleanup;
1012 if (der[counter++] == 0)
1013 _asn1_set_value (p, "F", 1);
1014 else
1015 _asn1_set_value (p, "T", 1);
1016 move = RIGHT;
1017 break;
1018 case ASN1_ETYPE_INTEGER:
1019 case ASN1_ETYPE_ENUMERATED:
1020 len2 =
1021 asn1_get_length_der (der + counter, len - counter, &len3);
1022 if (len2 < 0)
1024 result = ASN1_DER_ERROR;
1025 goto cleanup;
1028 _asn1_set_value (p, der + counter, len3 + len2);
1029 counter += len3 + len2;
1030 move = RIGHT;
1031 break;
1032 case ASN1_ETYPE_OBJECT_ID:
1033 result =
1034 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1035 temp, sizeof (temp));
1036 if (result != ASN1_SUCCESS)
1037 goto cleanup;
1039 tlen = strlen (temp);
1040 if (tlen > 0)
1041 _asn1_set_value (p, temp, tlen + 1);
1042 counter += len2;
1043 move = RIGHT;
1044 break;
1045 case ASN1_ETYPE_GENERALIZED_TIME:
1046 case ASN1_ETYPE_UTC_TIME:
1047 result =
1048 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1049 sizeof (temp) - 1);
1050 if (result != ASN1_SUCCESS)
1051 goto cleanup;
1053 tlen = strlen (temp);
1054 if (tlen > 0)
1055 _asn1_set_value (p, temp, tlen);
1056 counter += len2;
1057 move = RIGHT;
1058 break;
1059 case ASN1_ETYPE_OCTET_STRING:
1060 len3 = len - counter;
1061 result = _asn1_get_octet_string (der + counter, p, &len3);
1062 if (result != ASN1_SUCCESS)
1063 goto cleanup;
1065 counter += len3;
1066 move = RIGHT;
1067 break;
1068 case ASN1_ETYPE_GENERALSTRING:
1069 case ASN1_ETYPE_NUMERIC_STRING:
1070 case ASN1_ETYPE_IA5_STRING:
1071 case ASN1_ETYPE_TELETEX_STRING:
1072 case ASN1_ETYPE_PRINTABLE_STRING:
1073 case ASN1_ETYPE_UNIVERSAL_STRING:
1074 case ASN1_ETYPE_BMP_STRING:
1075 case ASN1_ETYPE_UTF8_STRING:
1076 case ASN1_ETYPE_VISIBLE_STRING:
1077 case ASN1_ETYPE_BIT_STRING:
1078 len2 =
1079 asn1_get_length_der (der + counter, len - counter, &len3);
1080 if (len2 < 0)
1082 result = ASN1_DER_ERROR;
1083 goto cleanup;
1086 _asn1_set_value (p, der + counter, len3 + len2);
1087 counter += len3 + len2;
1088 move = RIGHT;
1089 break;
1090 case ASN1_ETYPE_SEQUENCE:
1091 case ASN1_ETYPE_SET:
1092 if (move == UP)
1094 len2 = _asn1_strtol (p->value, NULL, 10);
1095 _asn1_set_value (p, NULL, 0);
1096 if (len2 == -1)
1097 { /* indefinite length method */
1098 if (len - counter + 1 > 0)
1100 if ((der[counter]) || der[counter + 1])
1102 result = ASN1_DER_ERROR;
1103 goto cleanup;
1106 else
1108 result = ASN1_DER_ERROR;
1109 goto cleanup;
1111 counter += 2;
1113 else
1114 { /* definite length method */
1115 if (len2 != counter)
1117 result = ASN1_DER_ERROR;
1118 goto cleanup;
1121 move = RIGHT;
1123 else
1124 { /* move==DOWN || move==RIGHT */
1125 len3 =
1126 asn1_get_length_der (der + counter, len - counter, &len2);
1127 if (len3 < -1)
1129 result = ASN1_DER_ERROR;
1130 goto cleanup;
1132 counter += len2;
1133 if (len3 > 0)
1135 _asn1_ltostr (counter + len3, temp);
1136 tlen = strlen (temp);
1137 if (tlen > 0)
1138 _asn1_set_value (p, temp, tlen + 1);
1139 move = DOWN;
1141 else if (len3 == 0)
1143 p2 = p->down;
1144 while (p2)
1146 if (type_field (p2->type) != ASN1_ETYPE_TAG)
1148 p3 = p2->right;
1149 asn1_delete_structure (&p2);
1150 p2 = p3;
1152 else
1153 p2 = p2->right;
1155 move = RIGHT;
1157 else
1158 { /* indefinite length method */
1159 _asn1_set_value (p, "-1", 3);
1160 move = DOWN;
1163 break;
1164 case ASN1_ETYPE_SEQUENCE_OF:
1165 case ASN1_ETYPE_SET_OF:
1166 if (move == UP)
1168 len2 = _asn1_strtol (p->value, NULL, 10);
1169 if (len2 == -1)
1170 { /* indefinite length method */
1171 if ((counter + 2) > len)
1173 result = ASN1_DER_ERROR;
1174 goto cleanup;
1177 if ((der[counter]) || der[counter + 1])
1179 _asn1_append_sequence_set (p);
1180 p = p->down;
1181 while (p->right)
1182 p = p->right;
1183 move = RIGHT;
1184 continue;
1186 _asn1_set_value (p, NULL, 0);
1187 counter += 2;
1189 else
1190 { /* definite length method */
1191 if (len2 > counter)
1193 _asn1_append_sequence_set (p);
1194 p = p->down;
1195 while (p->right)
1196 p = p->right;
1197 move = RIGHT;
1198 continue;
1200 _asn1_set_value (p, NULL, 0);
1201 if (len2 != counter)
1203 result = ASN1_DER_ERROR;
1204 goto cleanup;
1208 else
1209 { /* move==DOWN || move==RIGHT */
1210 len3 =
1211 asn1_get_length_der (der + counter, len - counter, &len2);
1212 if (len3 < -1)
1214 result = ASN1_DER_ERROR;
1215 goto cleanup;
1217 counter += len2;
1218 if (len3)
1220 if (len3 > 0)
1221 { /* definite length method */
1222 _asn1_ltostr (counter + len3, temp);
1223 tlen = strlen (temp);
1225 if (tlen > 0)
1226 _asn1_set_value (p, temp, tlen + 1);
1228 else
1229 { /* indefinite length method */
1230 _asn1_set_value (p, "-1", 3);
1232 p2 = p->down;
1233 while ((type_field (p2->type) == ASN1_ETYPE_TAG)
1234 || (type_field (p2->type) == ASN1_ETYPE_SIZE))
1235 p2 = p2->right;
1236 if (p2->right == NULL)
1237 _asn1_append_sequence_set (p);
1238 p = p2;
1241 move = RIGHT;
1242 break;
1243 case ASN1_ETYPE_ANY:
1244 if (asn1_get_tag_der
1245 (der + counter, len - counter, &class, &len2,
1246 &tag) != ASN1_SUCCESS)
1248 result = ASN1_DER_ERROR;
1249 goto cleanup;
1252 if (counter + len2 > len)
1254 result = ASN1_DER_ERROR;
1255 goto cleanup;
1257 len4 =
1258 asn1_get_length_der (der + counter + len2,
1259 len - counter - len2, &len3);
1260 if (len4 < -1)
1262 result = ASN1_DER_ERROR;
1263 goto cleanup;
1265 if (len4 != -1)
1267 len2 += len4;
1268 _asn1_set_value_lv (p, der + counter, len2 + len3);
1269 counter += len2 + len3;
1271 else
1272 { /* indefinite length */
1273 /* Check indefinite lenth method in an EXPLICIT TAG */
1274 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1275 indefinite = 1;
1276 else
1277 indefinite = 0;
1279 len2 = len - counter;
1280 result =
1281 _asn1_get_indefinite_length_string (der + counter, &len2);
1282 if (result != ASN1_SUCCESS)
1283 goto cleanup;
1285 _asn1_set_value_lv (p, der + counter, len2);
1286 counter += len2;
1288 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1289 an indefinite length method. */
1290 if (indefinite)
1292 if (!der[counter] && !der[counter + 1])
1294 counter += 2;
1296 else
1298 result = ASN1_DER_ERROR;
1299 goto cleanup;
1303 move = RIGHT;
1304 break;
1305 default:
1306 move = (move == UP) ? RIGHT : DOWN;
1307 break;
1311 if (p == node && move != DOWN)
1312 break;
1314 if (move == DOWN)
1316 if (p->down)
1317 p = p->down;
1318 else
1319 move = RIGHT;
1321 if ((move == RIGHT) && !(p->type & CONST_SET))
1323 if (p->right)
1324 p = p->right;
1325 else
1326 move = UP;
1328 if (move == UP)
1329 p = _asn1_find_up (p);
1332 _asn1_delete_not_used (*element);
1334 if (counter != len)
1336 result = ASN1_DER_ERROR;
1337 goto cleanup;
1340 return ASN1_SUCCESS;
1342 cleanup:
1343 asn1_delete_structure (element);
1344 return result;
1347 #define FOUND 1
1348 #define SAME_BRANCH 2
1349 #define OTHER_BRANCH 3
1350 #define EXIT 4
1353 * asn1_der_decoding_element:
1354 * @structure: pointer to an ASN1 structure
1355 * @elementName: name of the element to fill
1356 * @ider: vector that contains the DER encoding of the whole structure.
1357 * @len: number of bytes of *der: der[0]..der[len-1]
1358 * @errorDescription: null-terminated string contains details when an
1359 * error occurred.
1361 * Fill the element named @ELEMENTNAME with values of a DER encoding
1362 * string. The structure must just be created with function
1363 * asn1_create_element(). The DER vector must contain the encoding
1364 * string of the whole @STRUCTURE. If an error occurs during the
1365 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1366 * %NULL.
1368 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1369 * if ELEMENT is %NULL or @elementName == NULL, and
1370 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1371 * match the structure @structure (*ELEMENT deleted).
1374 asn1_der_decoding_element (asn1_node * structure, const char *elementName,
1375 const void *ider, int len, char *errorDescription)
1377 asn1_node node, p, p2, p3, nodeFound = NULL;
1378 char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1379 int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1380 int counter, len2, len3, len4, move, ris, tlen;
1381 unsigned char class;
1382 unsigned long tag;
1383 int indefinite, result;
1384 const unsigned char *der = ider;
1386 node = *structure;
1388 if (node == NULL)
1389 return ASN1_ELEMENT_NOT_FOUND;
1391 if (elementName == NULL)
1393 result = ASN1_ELEMENT_NOT_FOUND;
1394 goto cleanup;
1397 if (node->type & CONST_OPTION)
1399 result = ASN1_GENERIC_ERROR;
1400 goto cleanup;
1403 if ((*structure)->name[0] != 0)
1404 { /* Has *structure got a name? */
1405 nameLen -= strlen ((*structure)->name);
1406 if (nameLen > 0)
1407 strcpy (currentName, (*structure)->name);
1408 else
1410 result = ASN1_MEM_ERROR;
1411 goto cleanup;
1413 if (!(strcmp (currentName, elementName)))
1415 state = FOUND;
1416 nodeFound = *structure;
1418 else if (!memcmp (currentName, elementName, strlen (currentName)))
1419 state = SAME_BRANCH;
1420 else
1421 state = OTHER_BRANCH;
1423 else
1424 { /* *structure doesn't have a name? */
1425 currentName[0] = 0;
1426 if (elementName[0] == 0)
1428 state = FOUND;
1429 nodeFound = *structure;
1431 else
1433 state = SAME_BRANCH;
1437 counter = 0;
1438 move = DOWN;
1439 p = node;
1440 while (1)
1443 ris = ASN1_SUCCESS;
1445 if (move != UP)
1447 if (p->type & CONST_SET)
1449 p2 = _asn1_find_up (p);
1450 len2 = _asn1_strtol (p2->value, NULL, 10);
1451 if (counter == len2)
1453 p = p2;
1454 move = UP;
1455 continue;
1457 else if (counter > len2)
1459 result = ASN1_DER_ERROR;
1460 goto cleanup;
1462 p2 = p2->down;
1463 while (p2)
1465 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1467 if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
1468 ris =
1469 _asn1_extract_tag_der (p2, der + counter,
1470 len - counter, &len2);
1471 else
1473 p3 = p2->down;
1474 while (p3)
1476 ris =
1477 _asn1_extract_tag_der (p3, der + counter,
1478 len - counter, &len2);
1479 if (ris == ASN1_SUCCESS)
1480 break;
1481 p3 = p3->right;
1484 if (ris == ASN1_SUCCESS)
1486 p2->type &= ~CONST_NOT_USED;
1487 p = p2;
1488 break;
1491 p2 = p2->right;
1493 if (p2 == NULL)
1495 result = ASN1_DER_ERROR;
1496 goto cleanup;
1500 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1502 p2 = _asn1_find_up (p);
1503 len2 = _asn1_strtol (p2->value, NULL, 10);
1504 if (counter == len2)
1506 if (p->right)
1508 p2 = p->right;
1509 move = RIGHT;
1511 else
1512 move = UP;
1514 if (p->type & CONST_OPTION)
1515 asn1_delete_structure (&p);
1517 p = p2;
1518 continue;
1522 if (type_field (p->type) == ASN1_ETYPE_CHOICE)
1524 while (p->down)
1526 if (counter < len)
1527 ris =
1528 _asn1_extract_tag_der (p->down, der + counter,
1529 len - counter, &len2);
1530 else
1531 ris = ASN1_DER_ERROR;
1532 if (ris == ASN1_SUCCESS)
1534 while (p->down->right)
1536 p2 = p->down->right;
1537 asn1_delete_structure (&p2);
1539 break;
1541 else if (ris == ASN1_ERROR_TYPE_ANY)
1543 result = ASN1_ERROR_TYPE_ANY;
1544 goto cleanup;
1546 else
1548 p2 = p->down;
1549 asn1_delete_structure (&p2);
1553 if (p->down == NULL)
1555 if (!(p->type & CONST_OPTION))
1557 result = ASN1_DER_ERROR;
1558 goto cleanup;
1561 else
1562 p = p->down;
1565 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1567 p2 = _asn1_find_up (p);
1568 len2 = _asn1_strtol (p2->value, NULL, 10);
1569 if (counter > len2)
1570 ris = ASN1_TAG_ERROR;
1573 if (ris == ASN1_SUCCESS)
1574 ris =
1575 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1576 if (ris != ASN1_SUCCESS)
1578 if (p->type & CONST_OPTION)
1580 p->type |= CONST_NOT_USED;
1581 move = RIGHT;
1583 else if (p->type & CONST_DEFAULT)
1585 _asn1_set_value (p, NULL, 0);
1586 move = RIGHT;
1588 else
1590 if (errorDescription != NULL)
1591 _asn1_error_description_tag_error (p, errorDescription);
1593 result = ASN1_TAG_ERROR;
1594 goto cleanup;
1597 else
1598 counter += len2;
1601 if (ris == ASN1_SUCCESS)
1603 switch (type_field (p->type))
1605 case ASN1_ETYPE_NULL:
1606 if (der[counter])
1608 result = ASN1_DER_ERROR;
1609 goto cleanup;
1612 if (p == nodeFound)
1613 state = EXIT;
1615 counter++;
1616 move = RIGHT;
1617 break;
1618 case ASN1_ETYPE_BOOLEAN:
1619 if (der[counter++] != 1)
1621 result = ASN1_DER_ERROR;
1622 goto cleanup;
1625 if (state == FOUND)
1627 if (der[counter++] == 0)
1628 _asn1_set_value (p, "F", 1);
1629 else
1630 _asn1_set_value (p, "T", 1);
1632 if (p == nodeFound)
1633 state = EXIT;
1636 else
1637 counter++;
1639 move = RIGHT;
1640 break;
1641 case ASN1_ETYPE_INTEGER:
1642 case ASN1_ETYPE_ENUMERATED:
1643 len2 =
1644 asn1_get_length_der (der + counter, len - counter, &len3);
1645 if (len2 < 0)
1647 result = ASN1_DER_ERROR;
1648 goto cleanup;
1651 if (state == FOUND)
1653 if (len3 + len2 > len - counter)
1655 result = ASN1_DER_ERROR;
1656 goto cleanup;
1658 _asn1_set_value (p, der + counter, len3 + len2);
1660 if (p == nodeFound)
1661 state = EXIT;
1663 counter += len3 + len2;
1664 move = RIGHT;
1665 break;
1666 case ASN1_ETYPE_OBJECT_ID:
1667 if (state == FOUND)
1669 result =
1670 _asn1_get_objectid_der (der + counter, len - counter,
1671 &len2, temp, sizeof (temp));
1672 if (result != ASN1_SUCCESS)
1673 goto cleanup;
1675 tlen = strlen (temp);
1677 if (tlen > 0)
1678 _asn1_set_value (p, temp, tlen + 1);
1680 if (p == nodeFound)
1681 state = EXIT;
1683 else
1685 len2 =
1686 asn1_get_length_der (der + counter, len - counter, &len3);
1687 if (len2 < 0)
1689 result = ASN1_DER_ERROR;
1690 goto cleanup;
1692 len2 += len3;
1695 counter += len2;
1696 move = RIGHT;
1697 break;
1698 case ASN1_ETYPE_GENERALIZED_TIME:
1699 case ASN1_ETYPE_UTC_TIME:
1700 if (state == FOUND)
1702 result =
1703 _asn1_get_time_der (der + counter, len - counter, &len2,
1704 temp, sizeof (temp) - 1);
1705 if (result != ASN1_SUCCESS)
1706 goto cleanup;
1708 tlen = strlen (temp);
1709 if (tlen > 0)
1710 _asn1_set_value (p, temp, tlen + 1);
1712 if (p == nodeFound)
1713 state = EXIT;
1715 else
1717 len2 =
1718 asn1_get_length_der (der + counter, len - counter, &len3);
1719 if (len2 < 0)
1721 result = ASN1_DER_ERROR;
1722 goto cleanup;
1724 len2 += len3;
1727 counter += len2;
1728 move = RIGHT;
1729 break;
1730 case ASN1_ETYPE_OCTET_STRING:
1731 len3 = len - counter;
1732 if (state == FOUND)
1734 result = _asn1_get_octet_string (der + counter, p, &len3);
1735 if (p == nodeFound)
1736 state = EXIT;
1738 else
1739 result = _asn1_get_octet_string (der + counter, NULL, &len3);
1741 if (result != ASN1_SUCCESS)
1742 goto cleanup;
1744 counter += len3;
1745 move = RIGHT;
1746 break;
1747 case ASN1_ETYPE_GENERALSTRING:
1748 case ASN1_ETYPE_NUMERIC_STRING:
1749 case ASN1_ETYPE_IA5_STRING:
1750 case ASN1_ETYPE_TELETEX_STRING:
1751 case ASN1_ETYPE_PRINTABLE_STRING:
1752 case ASN1_ETYPE_UNIVERSAL_STRING:
1753 case ASN1_ETYPE_BMP_STRING:
1754 case ASN1_ETYPE_UTF8_STRING:
1755 case ASN1_ETYPE_VISIBLE_STRING:
1756 case ASN1_ETYPE_BIT_STRING:
1757 len2 =
1758 asn1_get_length_der (der + counter, len - counter, &len3);
1759 if (len2 < 0)
1761 result = ASN1_DER_ERROR;
1762 goto cleanup;
1765 if (state == FOUND)
1767 if (len3 + len2 > len - counter)
1769 result = ASN1_DER_ERROR;
1770 goto cleanup;
1772 _asn1_set_value (p, der + counter, len3 + len2);
1774 if (p == nodeFound)
1775 state = EXIT;
1777 counter += len3 + len2;
1778 move = RIGHT;
1779 break;
1780 case ASN1_ETYPE_SEQUENCE:
1781 case ASN1_ETYPE_SET:
1782 if (move == UP)
1784 len2 = _asn1_strtol (p->value, NULL, 10);
1785 _asn1_set_value (p, NULL, 0);
1786 if (len2 == -1)
1787 { /* indefinite length method */
1788 if ((der[counter]) || der[counter + 1])
1790 result = ASN1_DER_ERROR;
1791 goto cleanup;
1793 counter += 2;
1795 else
1796 { /* definite length method */
1797 if (len2 != counter)
1799 result = ASN1_DER_ERROR;
1800 goto cleanup;
1803 if (p == nodeFound)
1804 state = EXIT;
1805 move = RIGHT;
1807 else
1808 { /* move==DOWN || move==RIGHT */
1809 if (state == OTHER_BRANCH)
1811 len3 =
1812 asn1_get_length_der (der + counter, len - counter,
1813 &len2);
1814 if (len3 < 0)
1816 result = ASN1_DER_ERROR;
1817 goto cleanup;
1819 counter += len2 + len3;
1820 move = RIGHT;
1822 else
1823 { /* state==SAME_BRANCH or state==FOUND */
1824 len3 =
1825 asn1_get_length_der (der + counter, len - counter,
1826 &len2);
1827 if (len3 < 0)
1829 result = ASN1_DER_ERROR;
1830 goto cleanup;
1832 counter += len2;
1833 if (len3 > 0)
1835 _asn1_ltostr (counter + len3, temp);
1836 tlen = strlen (temp);
1838 if (tlen > 0)
1839 _asn1_set_value (p, temp, tlen + 1);
1840 move = DOWN;
1842 else if (len3 == 0)
1844 p2 = p->down;
1845 while (p2)
1847 if (type_field (p2->type) != ASN1_ETYPE_TAG)
1849 p3 = p2->right;
1850 asn1_delete_structure (&p2);
1851 p2 = p3;
1853 else
1854 p2 = p2->right;
1856 move = RIGHT;
1858 else
1859 { /* indefinite length method */
1860 _asn1_set_value (p, "-1", 3);
1861 move = DOWN;
1865 break;
1866 case ASN1_ETYPE_SEQUENCE_OF:
1867 case ASN1_ETYPE_SET_OF:
1868 if (move == UP)
1870 len2 = _asn1_strtol (p->value, NULL, 10);
1871 if (len2 > counter)
1873 _asn1_append_sequence_set (p);
1874 p = p->down;
1875 while (p->right)
1876 p = p->right;
1877 move = RIGHT;
1878 continue;
1880 _asn1_set_value (p, NULL, 0);
1881 if (len2 != counter)
1883 result = ASN1_DER_ERROR;
1884 goto cleanup;
1887 if (p == nodeFound)
1888 state = EXIT;
1890 else
1891 { /* move==DOWN || move==RIGHT */
1892 if (state == OTHER_BRANCH)
1894 len3 =
1895 asn1_get_length_der (der + counter, len - counter,
1896 &len2);
1897 if (len3 < 0)
1899 result = ASN1_DER_ERROR;
1900 goto cleanup;
1902 counter += len2 + len3;
1903 move = RIGHT;
1905 else
1906 { /* state==FOUND or state==SAME_BRANCH */
1907 len3 =
1908 asn1_get_length_der (der + counter, len - counter,
1909 &len2);
1910 if (len3 < 0)
1912 result = ASN1_DER_ERROR;
1913 goto cleanup;
1915 counter += len2;
1916 if (len3)
1918 _asn1_ltostr (counter + len3, temp);
1919 tlen = strlen (temp);
1921 if (tlen > 0)
1922 _asn1_set_value (p, temp, tlen + 1);
1923 p2 = p->down;
1924 while ((type_field (p2->type) == ASN1_ETYPE_TAG)
1925 || (type_field (p2->type) == ASN1_ETYPE_SIZE))
1926 p2 = p2->right;
1927 if (p2->right == NULL)
1928 _asn1_append_sequence_set (p);
1929 p = p2;
1930 state = FOUND;
1935 break;
1936 case ASN1_ETYPE_ANY:
1937 if (asn1_get_tag_der
1938 (der + counter, len - counter, &class, &len2,
1939 &tag) != ASN1_SUCCESS)
1941 result = ASN1_DER_ERROR;
1942 goto cleanup;
1945 if (counter + len2 > len)
1947 result = ASN1_DER_ERROR;
1948 goto cleanup;
1951 len4 =
1952 asn1_get_length_der (der + counter + len2,
1953 len - counter - len2, &len3);
1954 if (len4 < -1)
1956 result = ASN1_DER_ERROR;
1957 goto cleanup;
1960 if (len4 != -1)
1962 len2 += len4;
1963 if (state == FOUND)
1965 _asn1_set_value_lv (p, der + counter, len2 + len3);
1967 if (p == nodeFound)
1968 state = EXIT;
1970 counter += len2 + len3;
1972 else
1973 { /* indefinite length */
1974 /* Check indefinite lenth method in an EXPLICIT TAG */
1975 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1976 indefinite = 1;
1977 else
1978 indefinite = 0;
1980 len2 = len - counter;
1981 result =
1982 _asn1_get_indefinite_length_string (der + counter, &len2);
1983 if (result != ASN1_SUCCESS)
1984 goto cleanup;
1986 if (state == FOUND)
1988 _asn1_set_value_lv (p, der + counter, len2);
1990 if (p == nodeFound)
1991 state = EXIT;
1994 counter += len2;
1996 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1997 an indefinite length method. */
1998 if (indefinite)
2000 if (!der[counter] && !der[counter + 1])
2002 counter += 2;
2004 else
2006 result = ASN1_DER_ERROR;
2007 goto cleanup;
2011 move = RIGHT;
2012 break;
2014 default:
2015 move = (move == UP) ? RIGHT : DOWN;
2016 break;
2020 if ((p == node && move != DOWN) || (state == EXIT))
2021 break;
2023 if (move == DOWN)
2025 if (p->down)
2027 p = p->down;
2029 if (state != FOUND)
2031 nameLen -= strlen (p->name) + 1;
2032 if (nameLen > 0)
2034 if (currentName[0])
2035 strcat (currentName, ".");
2036 strcat (currentName, p->name);
2038 else
2040 result = ASN1_MEM_ERROR;
2041 goto cleanup;
2043 if (!(strcmp (currentName, elementName)))
2045 state = FOUND;
2046 nodeFound = p;
2048 else
2049 if (!memcmp
2050 (currentName, elementName, strlen (currentName)))
2051 state = SAME_BRANCH;
2052 else
2053 state = OTHER_BRANCH;
2056 else
2057 move = RIGHT;
2060 if ((move == RIGHT) && !(p->type & CONST_SET))
2062 if (p->right)
2064 p = p->right;
2066 if (state != FOUND)
2068 dot_p = char_p = currentName;
2069 while ((char_p = strchr (char_p, '.')))
2071 dot_p = char_p++;
2072 dot_p++;
2075 nameLen += strlen (currentName) - (dot_p - currentName);
2076 *dot_p = 0;
2078 nameLen -= strlen (p->name);
2079 if (nameLen > 0)
2080 strcat (currentName, p->name);
2081 else
2083 result = ASN1_MEM_ERROR;
2084 goto cleanup;
2087 if (!(strcmp (currentName, elementName)))
2089 state = FOUND;
2090 nodeFound = p;
2092 else
2093 if (!memcmp
2094 (currentName, elementName, strlen (currentName)))
2095 state = SAME_BRANCH;
2096 else
2097 state = OTHER_BRANCH;
2100 else
2101 move = UP;
2104 if (move == UP)
2106 p = _asn1_find_up (p);
2108 if (state != FOUND)
2110 dot_p = char_p = currentName;
2111 while ((char_p = strchr (char_p, '.')))
2113 dot_p = char_p++;
2114 dot_p++;
2117 nameLen += strlen (currentName) - (dot_p - currentName);
2118 *dot_p = 0;
2120 if (!(strcmp (currentName, elementName)))
2122 state = FOUND;
2123 nodeFound = p;
2125 else
2126 if (!memcmp (currentName, elementName, strlen (currentName)))
2127 state = SAME_BRANCH;
2128 else
2129 state = OTHER_BRANCH;
2134 _asn1_delete_not_used (*structure);
2136 if (counter > len)
2138 result = ASN1_DER_ERROR;
2139 goto cleanup;
2142 return ASN1_SUCCESS;
2144 cleanup:
2145 asn1_delete_structure (structure);
2146 return result;
2150 * asn1_der_decoding_startEnd:
2151 * @element: pointer to an ASN1 element
2152 * @ider: vector that contains the DER encoding.
2153 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2154 * @name_element: an element of NAME structure.
2155 * @start: the position of the first byte of NAME_ELEMENT decoding
2156 * (@ider[*start])
2157 * @end: the position of the last byte of NAME_ELEMENT decoding
2158 * (@ider[*end])
2160 * Find the start and end point of an element in a DER encoding
2161 * string. I mean that if you have a der encoding and you have already
2162 * used the function asn1_der_decoding() to fill a structure, it may
2163 * happen that you want to find the piece of string concerning an
2164 * element of the structure.
2166 * One example is the sequence "tbsCertificate" inside an X509
2167 * certificate.
2169 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2170 * if ELEMENT is %asn1_node EMPTY or @name_element is not a valid
2171 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2172 * doesn't match the structure ELEMENT.
2175 asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
2176 const char *name_element, int *start, int *end)
2178 asn1_node node, node_to_find, p, p2, p3;
2179 int counter, len2, len3, len4, move, ris;
2180 unsigned char class;
2181 unsigned long tag;
2182 int indefinite;
2183 const unsigned char *der = ider;
2185 node = element;
2187 if (node == NULL)
2188 return ASN1_ELEMENT_NOT_FOUND;
2190 node_to_find = asn1_find_node (node, name_element);
2192 if (node_to_find == NULL)
2193 return ASN1_ELEMENT_NOT_FOUND;
2195 if (node_to_find == node)
2197 *start = 0;
2198 *end = len - 1;
2199 return ASN1_SUCCESS;
2202 if (node->type & CONST_OPTION)
2203 return ASN1_GENERIC_ERROR;
2205 counter = 0;
2206 move = DOWN;
2207 p = node;
2208 while (1)
2210 if (p == NULL)
2211 return ASN1_DER_ERROR;
2213 ris = ASN1_SUCCESS;
2215 if (move != UP)
2217 if (p->type & CONST_SET)
2219 p2 = _asn1_find_up (p);
2220 if (p2 == NULL)
2221 return ASN1_DER_ERROR;
2223 len2 = _asn1_strtol (p2->value, NULL, 10);
2224 if (len2 == -1)
2226 if (!der[counter] && !der[counter + 1])
2228 p = p2;
2229 move = UP;
2230 counter += 2;
2231 continue;
2234 else if (counter == len2)
2236 p = p2;
2237 move = UP;
2238 continue;
2240 else if (counter > len2)
2241 return ASN1_DER_ERROR;
2243 p2 = p2->down;
2245 while (p2)
2247 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2248 { /* CONTROLLARE */
2249 if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
2250 ris =
2251 _asn1_extract_tag_der (p2, der + counter,
2252 len - counter, &len2);
2253 else
2255 p3 = p2->down;
2256 if (p3 == NULL)
2257 return ASN1_DER_ERROR;
2259 ris =
2260 _asn1_extract_tag_der (p3, der + counter,
2261 len - counter, &len2);
2263 if (ris == ASN1_SUCCESS)
2265 p2->type &= ~CONST_NOT_USED;
2266 p = p2;
2267 break;
2270 p2 = p2->right;
2272 if (p2 == NULL)
2273 return ASN1_DER_ERROR;
2276 if (p == node_to_find)
2277 *start = counter;
2279 if (type_field (p->type) == ASN1_ETYPE_CHOICE)
2281 p = p->down;
2282 if (p == NULL)
2283 return ASN1_DER_ERROR;
2285 ris =
2286 _asn1_extract_tag_der (p, der + counter, len - counter,
2287 &len2);
2288 if (p == node_to_find)
2289 *start = counter;
2292 if (ris == ASN1_SUCCESS)
2293 ris =
2294 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2295 if (ris != ASN1_SUCCESS)
2297 if (p->type & CONST_OPTION)
2299 p->type |= CONST_NOT_USED;
2300 move = RIGHT;
2302 else if (p->type & CONST_DEFAULT)
2304 move = RIGHT;
2306 else
2308 return ASN1_TAG_ERROR;
2311 else
2312 counter += len2;
2315 if (ris == ASN1_SUCCESS)
2317 switch (type_field (p->type))
2319 case ASN1_ETYPE_NULL:
2320 if (der[counter])
2321 return ASN1_DER_ERROR;
2322 counter++;
2323 move = RIGHT;
2324 break;
2325 case ASN1_ETYPE_BOOLEAN:
2326 if (der[counter++] != 1)
2327 return ASN1_DER_ERROR;
2328 counter++;
2329 move = RIGHT;
2330 break;
2331 case ASN1_ETYPE_OCTET_STRING:
2332 len3 = len - counter;
2333 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2334 if (ris != ASN1_SUCCESS)
2335 return ris;
2336 counter += len3;
2337 move = RIGHT;
2338 break;
2339 case ASN1_ETYPE_UTC_TIME:
2340 case ASN1_ETYPE_GENERALIZED_TIME:
2341 case ASN1_ETYPE_OBJECT_ID:
2342 case ASN1_ETYPE_INTEGER:
2343 case ASN1_ETYPE_ENUMERATED:
2344 case ASN1_ETYPE_GENERALSTRING:
2345 case ASN1_ETYPE_NUMERIC_STRING:
2346 case ASN1_ETYPE_IA5_STRING:
2347 case ASN1_ETYPE_TELETEX_STRING:
2348 case ASN1_ETYPE_PRINTABLE_STRING:
2349 case ASN1_ETYPE_UNIVERSAL_STRING:
2350 case ASN1_ETYPE_BMP_STRING:
2351 case ASN1_ETYPE_UTF8_STRING:
2352 case ASN1_ETYPE_VISIBLE_STRING:
2353 case ASN1_ETYPE_BIT_STRING:
2354 len2 =
2355 asn1_get_length_der (der + counter, len - counter, &len3);
2356 if (len2 < 0)
2357 return ASN1_DER_ERROR;
2358 counter += len3 + len2;
2359 move = RIGHT;
2360 break;
2361 case ASN1_ETYPE_SEQUENCE:
2362 case ASN1_ETYPE_SET:
2363 if (move != UP)
2365 len3 =
2366 asn1_get_length_der (der + counter, len - counter, &len2);
2367 if (len3 < -1)
2368 return ASN1_DER_ERROR;
2369 counter += len2;
2370 if (len3 == 0)
2371 move = RIGHT;
2372 else
2373 move = DOWN;
2375 else
2377 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2378 counter += 2;
2379 move = RIGHT;
2381 break;
2382 case ASN1_ETYPE_SEQUENCE_OF:
2383 case ASN1_ETYPE_SET_OF:
2384 if (move != UP)
2386 len3 =
2387 asn1_get_length_der (der + counter, len - counter, &len2);
2388 if (len3 < -1)
2389 return ASN1_DER_ERROR;
2390 counter += len2;
2391 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2392 counter += 2;
2393 else if (len3)
2395 p2 = p->down;
2396 while ((type_field (p2->type) == ASN1_ETYPE_TAG) ||
2397 (type_field (p2->type) == ASN1_ETYPE_SIZE))
2398 p2 = p2->right;
2399 p = p2;
2402 else
2404 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2405 counter += 2;
2407 move = RIGHT;
2408 break;
2409 case ASN1_ETYPE_ANY:
2410 if (asn1_get_tag_der
2411 (der + counter, len - counter, &class, &len2,
2412 &tag) != ASN1_SUCCESS)
2413 return ASN1_DER_ERROR;
2414 if (counter + len2 > len)
2415 return ASN1_DER_ERROR;
2417 len4 =
2418 asn1_get_length_der (der + counter + len2,
2419 len - counter - len2, &len3);
2420 if (len4 < -1)
2421 return ASN1_DER_ERROR;
2423 if (len4 != -1)
2425 counter += len2 + len4 + len3;
2427 else
2428 { /* indefinite length */
2429 /* Check indefinite lenth method in an EXPLICIT TAG */
2430 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2431 indefinite = 1;
2432 else
2433 indefinite = 0;
2435 len2 = len - counter;
2436 ris =
2437 _asn1_get_indefinite_length_string (der + counter, &len2);
2438 if (ris != ASN1_SUCCESS)
2439 return ris;
2440 counter += len2;
2442 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2443 an indefinite length method. */
2444 if (indefinite)
2446 if (!der[counter] && !der[counter + 1])
2447 counter += 2;
2448 else
2449 return ASN1_DER_ERROR;
2452 move = RIGHT;
2453 break;
2454 default:
2455 move = (move == UP) ? RIGHT : DOWN;
2456 break;
2460 if ((p == node_to_find) && (move == RIGHT))
2462 *end = counter - 1;
2463 return ASN1_SUCCESS;
2466 if (p == node && move != DOWN)
2467 break;
2469 if (move == DOWN)
2471 if (p->down)
2472 p = p->down;
2473 else
2474 move = RIGHT;
2476 if ((move == RIGHT) && !(p->type & CONST_SET))
2478 if (p->right)
2479 p = p->right;
2480 else
2481 move = UP;
2483 if (move == UP)
2484 p = _asn1_find_up (p);
2487 return ASN1_ELEMENT_NOT_FOUND;
2491 * asn1_expand_any_defined_by:
2492 * @definitions: ASN1 definitions
2493 * @element: pointer to an ASN1 structure
2495 * Expands every "ANY DEFINED BY" element of a structure created from
2496 * a DER decoding process (asn1_der_decoding function). The element
2497 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2498 * expand the element ANY is the first one following the definition of
2499 * the actual value of the OBJECT IDENTIFIER.
2501 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2502 * some "ANY DEFINED BY" element couldn't be expanded due to a
2503 * problem in OBJECT_ID -> TYPE association, or other error codes
2504 * depending on DER decoding.
2507 asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
2509 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2510 value[ASN1_MAX_NAME_SIZE];
2511 int retCode = ASN1_SUCCESS, result;
2512 int len, len2, len3;
2513 asn1_node p, p2, p3, aux = NULL;
2514 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2516 if ((definitions == NULL) || (*element == NULL))
2517 return ASN1_ELEMENT_NOT_FOUND;
2519 strcpy (definitionsName, definitions->name);
2520 strcat (definitionsName, ".");
2522 p = *element;
2523 while (p)
2526 switch (type_field (p->type))
2528 case ASN1_ETYPE_ANY:
2529 if ((p->type & CONST_DEFINED_BY) && (p->value))
2531 /* search the "DEF_BY" element */
2532 p2 = p->down;
2533 while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
2534 p2 = p2->right;
2536 if (!p2)
2538 retCode = ASN1_ERROR_TYPE_ANY;
2539 break;
2542 p3 = _asn1_find_up (p);
2544 if (!p3)
2546 retCode = ASN1_ERROR_TYPE_ANY;
2547 break;
2550 p3 = p3->down;
2551 while (p3)
2553 if (!(strcmp (p3->name, p2->name)))
2554 break;
2555 p3 = p3->right;
2558 if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
2559 (p3->value == NULL))
2562 p3 = _asn1_find_up (p);
2563 p3 = _asn1_find_up (p3);
2565 if (!p3)
2567 retCode = ASN1_ERROR_TYPE_ANY;
2568 break;
2571 p3 = p3->down;
2573 while (p3)
2575 if (!(strcmp (p3->name, p2->name)))
2576 break;
2577 p3 = p3->right;
2580 if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
2581 (p3->value == NULL))
2583 retCode = ASN1_ERROR_TYPE_ANY;
2584 break;
2588 /* search the OBJECT_ID into definitions */
2589 p2 = definitions->down;
2590 while (p2)
2592 if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
2593 (p2->type & CONST_ASSIGN))
2595 strcpy (name, definitionsName);
2596 strcat (name, p2->name);
2598 len = ASN1_MAX_NAME_SIZE;
2599 result =
2600 asn1_read_value (definitions, name, value, &len);
2602 if ((result == ASN1_SUCCESS)
2603 && (!_asn1_strcmp (p3->value, value)))
2605 p2 = p2->right; /* pointer to the structure to
2606 use for expansion */
2607 while ((p2) && (p2->type & CONST_ASSIGN))
2608 p2 = p2->right;
2610 if (p2)
2612 strcpy (name, definitionsName);
2613 strcat (name, p2->name);
2615 result =
2616 asn1_create_element (definitions, name, &aux);
2617 if (result == ASN1_SUCCESS)
2619 _asn1_cpy_name (aux, p);
2620 len2 =
2621 asn1_get_length_der (p->value,
2622 p->value_len, &len3);
2623 if (len2 < 0)
2624 return ASN1_DER_ERROR;
2626 result =
2627 asn1_der_decoding (&aux, p->value + len3,
2628 len2,
2629 errorDescription);
2630 if (result == ASN1_SUCCESS)
2633 _asn1_set_right (aux, p->right);
2634 _asn1_set_right (p, aux);
2636 result = asn1_delete_structure (&p);
2637 if (result == ASN1_SUCCESS)
2639 p = aux;
2640 aux = NULL;
2641 break;
2643 else
2644 { /* error with asn1_delete_structure */
2645 asn1_delete_structure (&aux);
2646 retCode = result;
2647 break;
2650 else
2651 { /* error with asn1_der_decoding */
2652 retCode = result;
2653 break;
2656 else
2657 { /* error with asn1_create_element */
2658 retCode = result;
2659 break;
2662 else
2663 { /* error with the pointer to the structure to exapand */
2664 retCode = ASN1_ERROR_TYPE_ANY;
2665 break;
2669 p2 = p2->right;
2670 } /* end while */
2672 if (!p2)
2674 retCode = ASN1_ERROR_TYPE_ANY;
2675 break;
2679 break;
2680 default:
2681 break;
2685 if (p->down)
2687 p = p->down;
2689 else if (p == *element)
2691 p = NULL;
2692 break;
2694 else if (p->right)
2695 p = p->right;
2696 else
2698 while (1)
2700 p = _asn1_find_up (p);
2701 if (p == *element)
2703 p = NULL;
2704 break;
2706 if (p->right)
2708 p = p->right;
2709 break;
2715 return retCode;
2719 * asn1_expand_octet_string:
2720 * @definitions: ASN1 definitions
2721 * @element: pointer to an ASN1 structure
2722 * @octetName: name of the OCTECT STRING field to expand.
2723 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2724 * the type for expansion.
2726 * Expands an "OCTET STRING" element of a structure created from a DER
2727 * decoding process (the asn1_der_decoding() function). The type used
2728 * for expansion is the first one following the definition of the
2729 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2731 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2732 * if @objectName or @octetName are not correct,
2733 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2734 * use for expansion, or other errors depending on DER decoding.
2737 asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
2738 const char *octetName, const char *objectName)
2740 char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2741 int retCode = ASN1_SUCCESS, result;
2742 int len, len2, len3;
2743 asn1_node p2, aux = NULL;
2744 asn1_node octetNode = NULL, objectNode = NULL;
2745 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2747 if ((definitions == NULL) || (*element == NULL))
2748 return ASN1_ELEMENT_NOT_FOUND;
2750 octetNode = asn1_find_node (*element, octetName);
2751 if (octetNode == NULL)
2752 return ASN1_ELEMENT_NOT_FOUND;
2753 if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
2754 return ASN1_ELEMENT_NOT_FOUND;
2755 if (octetNode->value == NULL)
2756 return ASN1_VALUE_NOT_FOUND;
2758 objectNode = asn1_find_node (*element, objectName);
2759 if (objectNode == NULL)
2760 return ASN1_ELEMENT_NOT_FOUND;
2762 if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
2763 return ASN1_ELEMENT_NOT_FOUND;
2765 if (objectNode->value == NULL)
2766 return ASN1_VALUE_NOT_FOUND;
2769 /* search the OBJECT_ID into definitions */
2770 p2 = definitions->down;
2771 while (p2)
2773 if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
2774 (p2->type & CONST_ASSIGN))
2776 strcpy (name, definitions->name);
2777 strcat (name, ".");
2778 strcat (name, p2->name);
2780 len = sizeof (value);
2781 result = asn1_read_value (definitions, name, value, &len);
2783 if ((result == ASN1_SUCCESS)
2784 && (!_asn1_strcmp (objectNode->value, value)))
2787 p2 = p2->right; /* pointer to the structure to
2788 use for expansion */
2789 while ((p2) && (p2->type & CONST_ASSIGN))
2790 p2 = p2->right;
2792 if (p2)
2794 strcpy (name, definitions->name);
2795 strcat (name, ".");
2796 strcat (name, p2->name);
2798 result = asn1_create_element (definitions, name, &aux);
2799 if (result == ASN1_SUCCESS)
2801 _asn1_cpy_name (aux, octetNode);
2802 len2 =
2803 asn1_get_length_der (octetNode->value,
2804 octetNode->value_len, &len3);
2805 if (len2 < 0)
2806 return ASN1_DER_ERROR;
2808 result =
2809 asn1_der_decoding (&aux, octetNode->value + len3,
2810 len2, errorDescription);
2811 if (result == ASN1_SUCCESS)
2814 _asn1_set_right (aux, octetNode->right);
2815 _asn1_set_right (octetNode, aux);
2817 result = asn1_delete_structure (&octetNode);
2818 if (result == ASN1_SUCCESS)
2820 aux = NULL;
2821 break;
2823 else
2824 { /* error with asn1_delete_structure */
2825 asn1_delete_structure (&aux);
2826 retCode = result;
2827 break;
2830 else
2831 { /* error with asn1_der_decoding */
2832 retCode = result;
2833 break;
2836 else
2837 { /* error with asn1_create_element */
2838 retCode = result;
2839 break;
2842 else
2843 { /* error with the pointer to the structure to exapand */
2844 retCode = ASN1_VALUE_NOT_VALID;
2845 break;
2850 p2 = p2->right;
2854 if (!p2)
2855 retCode = ASN1_VALUE_NOT_VALID;
2857 return retCode;
2861 * asn1_decode_simple_der:
2862 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
2863 * @der: the encoded string
2864 * @der_len: the bytes of the encoded string
2865 * @str: a pointer to the data
2866 * @str_len: the length of the data
2868 * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
2869 * The output is a pointer inside the @der.
2871 * Returns: %ASN1_SUCCESS if successful or an error value.
2874 asn1_decode_simple_der (unsigned int etype, const unsigned char *der, unsigned int der_len,
2875 const unsigned char **str, unsigned int *str_len)
2877 int tag_len, len_len;
2878 const unsigned char* p;
2879 unsigned char class;
2880 unsigned long tag;
2881 long ret;
2883 if (der == NULL || der_len == 0)
2884 return ASN1_VALUE_NOT_VALID;
2886 if (ETYPE_OK(etype) == 0)
2887 return ASN1_VALUE_NOT_VALID;
2889 /* doesn't handle constructed classes */
2890 if (ETYPE_CLASS(etype) != ASN1_CLASS_UNIVERSAL)
2891 return ASN1_VALUE_NOT_VALID;
2893 p = der;
2894 ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
2895 if (ret != ASN1_SUCCESS)
2896 return ret;
2898 if (class != ETYPE_CLASS(etype) || tag != ETYPE_TAG(etype))
2899 return ASN1_DER_ERROR;
2901 p += tag_len;
2902 der_len -= tag_len;
2904 ret = asn1_get_length_der (p, der_len, &len_len);
2905 if (ret < 0)
2906 return ASN1_DER_ERROR;
2908 p += len_len;
2909 der_len -= len_len;
2911 *str_len = ret;
2912 *str = p;
2914 return ASN1_SUCCESS;