2 * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 /*****************************************************/
25 /* File: decoding.c */
26 /* Description: Functions to manage DER decoding */
27 /*****************************************************/
30 #include "parser_aux.h"
32 #include "structure.h"
36 _asn1_get_indefinite_length_string (const unsigned char *der, int *len);
39 _asn1_error_description_tag_error (ASN1_TYPE 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, "'");
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.
61 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
82 { /* definite length method */
84 while (punt <= k && punt < der_len)
86 unsigned long last = ans;
88 ans = ans * 256 + der[punt++];
90 /* we wrapped around, no bignum support... */
95 { /* indefinite length method */
106 * @der: DER data to decode.
107 * @der_len: Length of DER data to decode.
108 * @cls: Output variable containing decoded class.
109 * @len: Output variable containing the length of the DER TAG data.
110 * @tag: Output variable containing the decoded tag.
112 * Decode the class and TAG from DER code.
114 * Returns: Returns %ASN1_SUCCESS on success, or an error.
117 asn1_get_tag_der (const unsigned char *der, int der_len,
118 unsigned char *cls, int *len, unsigned long *tag)
122 if (der == NULL || der_len < 2 || len == NULL)
123 return ASN1_DER_ERROR;
125 *cls = der[0] & 0xE0;
126 if ((der[0] & 0x1F) != 0x1F)
137 while (punt <= der_len && der[punt] & 128)
140 ris = ris * 128 + (der[punt++] & 0x7F);
142 /* wrapper around, and no bignums... */
143 return ASN1_DER_ERROR;
146 return ASN1_DER_ERROR;
149 ris = ris * 128 + (der[punt++] & 0x7F);
151 /* wrapper around, and no bignums... */
152 return ASN1_DER_ERROR;
162 * asn1_get_length_ber:
163 * @ber: BER data to decode.
164 * @ber_len: Length of BER data to decode.
165 * @len: Output variable containing the length of the BER length field.
167 * Extract a length field from BER data. The difference to
168 * asn1_get_length_der() is that this function will return a length
169 * even if the value has indefinite encoding.
171 * Returns: Return the decoded length value, or negative value when
172 * the value was too big.
177 asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
182 ret = asn1_get_length_der (ber, ber_len, len);
184 { /* indefinite length method */
186 err = _asn1_get_indefinite_length_string (ber + 1, &ret);
187 if (err != ASN1_SUCCESS)
195 * asn1_get_octet_der:
196 * @der: DER data to decode containing the OCTET SEQUENCE.
197 * @der_len: Length of DER data to decode.
198 * @ret_len: Output variable containing the length of the DER data.
199 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
200 * @str_size: Length of pre-allocated output buffer.
201 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
203 * Extract an OCTET SEQUENCE from DER data.
205 * Returns: Returns %ASN1_SUCCESS on success, or an error.
208 asn1_get_octet_der (const unsigned char *der, int der_len,
209 int *ret_len, unsigned char *str, int str_size,
215 return ASN1_GENERIC_ERROR;
217 /* if(str==NULL) return ASN1_SUCCESS; */
218 *str_len = asn1_get_length_der (der, der_len, &len_len);
221 return ASN1_DER_ERROR;
223 *ret_len = *str_len + len_len;
224 if (str_size >= *str_len)
225 memcpy (str, der + len_len, *str_len);
228 return ASN1_MEM_ERROR;
234 /* Returns ASN1_SUCCESS on success or an error code on error.
237 _asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
238 char *str, int str_size)
240 int len_len, str_len;
242 if (der_len <= 0 || str == NULL)
243 return ASN1_DER_ERROR;
244 str_len = asn1_get_length_der (der, der_len, &len_len);
245 if (str_len < 0 || str_size < str_len)
246 return ASN1_DER_ERROR;
247 memcpy (str, der + len_len, str_len);
249 *ret_len = str_len + len_len;
255 _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
256 char *str, int str_size)
261 unsigned long val, val1, prev_val;
264 if (str && str_size > 0)
265 str[0] = 0; /* no oid */
267 if (str == NULL || der_len <= 0)
268 return ASN1_GENERIC_ERROR;
269 len = asn1_get_length_der (der, der_len, &len_len);
271 if (len < 0 || len > der_len || len_len > der_len)
272 return ASN1_DER_ERROR;
274 val1 = der[len_len] / 40;
275 val = der[len_len] - val1 * 40;
277 _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
278 _asn1_str_cat (str, str_size, ".");
279 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
284 for (k = 1; k < len; k++)
286 /* X.690 mandates that the leading byte must never be 0x80
288 if (leading != 0 && der[len_len + k] == 0x80)
289 return ASN1_DER_ERROR;
292 /* check for wrap around */
294 val |= der[len_len + k] & 0x7F;
297 return ASN1_DER_ERROR;
301 if (!(der[len_len + k] & 0x80))
303 _asn1_str_cat (str, str_size, ".");
304 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
310 *ret_len = len + len_len;
317 * @der: DER data to decode containing the BIT SEQUENCE.
318 * @der_len: Length of DER data to decode.
319 * @ret_len: Output variable containing the length of the DER data.
320 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
321 * @str_size: Length of pre-allocated output buffer.
322 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
324 * Extract a BIT SEQUENCE from DER data.
326 * Returns: Return %ASN1_SUCCESS on success, or an error.
329 asn1_get_bit_der (const unsigned char *der, int der_len,
330 int *ret_len, unsigned char *str, int str_size,
333 int len_len, len_byte;
336 return ASN1_GENERIC_ERROR;
337 len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
339 return ASN1_DER_ERROR;
341 *ret_len = len_byte + len_len + 1;
342 *bit_len = len_byte * 8 - der[len_len];
344 if (str_size >= len_byte)
345 memcpy (str, der + len_len + 1, len_byte);
348 return ASN1_MEM_ERROR;
355 _asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
359 int counter, len2, len3, is_tag_implicit;
360 unsigned long tag, tag_implicit = 0;
361 unsigned char class, class2, class_implicit = 0;
364 return ASN1_GENERIC_ERROR;
366 counter = is_tag_implicit = 0;
368 if (node->type & CONST_TAG)
373 if (type_field (p->type) == TYPE_TAG)
375 if (p->type & CONST_APPLICATION)
376 class2 = ASN1_CLASS_APPLICATION;
377 else if (p->type & CONST_UNIVERSAL)
378 class2 = ASN1_CLASS_UNIVERSAL;
379 else if (p->type & CONST_PRIVATE)
380 class2 = ASN1_CLASS_PRIVATE;
382 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
384 if (p->type & CONST_EXPLICIT)
387 (der + counter, der_len - counter, &class, &len2,
388 &tag) != ASN1_SUCCESS)
389 return ASN1_DER_ERROR;
391 if (counter + len2 > der_len)
392 return ASN1_DER_ERROR;
396 asn1_get_length_ber (der + counter, der_len - counter,
399 return ASN1_DER_ERROR;
402 if (counter > der_len)
403 return ASN1_DER_ERROR;
405 if (!is_tag_implicit)
407 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
408 (tag != strtoul ((char *) p->value, NULL, 10)))
409 return ASN1_TAG_ERROR;
412 { /* ASN1_TAG_IMPLICIT */
413 if ((class != class_implicit) || (tag != tag_implicit))
414 return ASN1_TAG_ERROR;
419 { /* ASN1_TAG_IMPLICIT */
420 if (!is_tag_implicit)
422 if ((type_field (node->type) == TYPE_SEQUENCE) ||
423 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
424 (type_field (node->type) == TYPE_SET) ||
425 (type_field (node->type) == TYPE_SET_OF))
426 class2 |= ASN1_CLASS_STRUCTURED;
427 class_implicit = class2;
428 tag_implicit = strtoul ((char *) p->value, NULL, 10);
440 (der + counter, der_len - counter, &class, &len2,
441 &tag) != ASN1_SUCCESS)
442 return ASN1_DER_ERROR;
443 if (counter + len2 > der_len)
444 return ASN1_DER_ERROR;
446 if ((class != class_implicit) || (tag != tag_implicit))
448 if (type_field (node->type) == TYPE_OCTET_STRING)
450 class_implicit |= ASN1_CLASS_STRUCTURED;
451 if ((class != class_implicit) || (tag != tag_implicit))
452 return ASN1_TAG_ERROR;
455 return ASN1_TAG_ERROR;
460 if (type_field (node->type) == TYPE_TAG)
468 (der + counter, der_len - counter, &class, &len2,
469 &tag) != ASN1_SUCCESS)
470 return ASN1_DER_ERROR;
472 if (counter + len2 > der_len)
473 return ASN1_DER_ERROR;
475 switch (type_field (node->type))
478 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
479 return ASN1_DER_ERROR;
482 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
483 return ASN1_DER_ERROR;
486 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
487 return ASN1_DER_ERROR;
489 case TYPE_ENUMERATED:
490 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
491 return ASN1_DER_ERROR;
494 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
495 return ASN1_DER_ERROR;
498 if (node->type & CONST_UTC)
500 if ((class != ASN1_CLASS_UNIVERSAL)
501 || (tag != ASN1_TAG_UTCTime))
502 return ASN1_DER_ERROR;
506 if ((class != ASN1_CLASS_UNIVERSAL)
507 || (tag != ASN1_TAG_GENERALIZEDTime))
508 return ASN1_DER_ERROR;
511 case TYPE_OCTET_STRING:
512 if (((class != ASN1_CLASS_UNIVERSAL)
513 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
514 || (tag != ASN1_TAG_OCTET_STRING))
515 return ASN1_DER_ERROR;
517 case TYPE_GENERALSTRING:
518 if ((class != ASN1_CLASS_UNIVERSAL)
519 || (tag != ASN1_TAG_GENERALSTRING))
520 return ASN1_DER_ERROR;
522 case TYPE_BIT_STRING:
523 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
524 return ASN1_DER_ERROR;
527 case TYPE_SEQUENCE_OF:
528 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
529 || (tag != ASN1_TAG_SEQUENCE))
530 return ASN1_DER_ERROR;
534 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
535 || (tag != ASN1_TAG_SET))
536 return ASN1_DER_ERROR;
542 return ASN1_DER_ERROR;
553 _asn1_delete_not_used (ASN1_TYPE node)
558 return ASN1_ELEMENT_NOT_FOUND;
563 if (p->type & CONST_NOT_USED)
568 p2 = _asn1_find_left (p);
570 p2 = _asn1_find_up (p);
572 asn1_delete_structure (&p);
577 break; /* reach node */
593 p = _asn1_find_up (p);
612 _asn1_extract_der_octet (ASN1_TYPE node, const unsigned char *der,
616 int counter2, counter_end;
618 len2 = asn1_get_length_der (der, der_len, &len3);
620 return ASN1_DER_ERROR;
625 counter_end = der_len - 2;
627 counter_end = der_len;
629 while (counter2 < counter_end)
631 len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3);
634 return ASN1_DER_ERROR;
638 _asn1_append_value (node, der + counter2 + len3, len2);
644 _asn1_extract_der_octet (node, der + counter2 + len3,
645 der_len - counter2 - len3);
650 counter2 += len2 + len3 + 1;
657 _asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
659 int len2, len3, counter, tot_len, indefinite;
663 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
666 indefinite = asn1_get_length_der (der, *len, &len3);
668 return ASN1_DER_ERROR;
676 if (counter > (*len))
677 return ASN1_DER_ERROR;
679 if (indefinite == -1)
681 if ((der[counter] == 0) && (der[counter + 1] == 0))
687 else if (counter >= indefinite)
690 if (der[counter] != ASN1_TAG_OCTET_STRING)
691 return ASN1_DER_ERROR;
695 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
697 return ASN1_DER_ERROR;
699 counter += len3 + len2;
706 unsigned char temp[DER_LEN];
709 len2 = sizeof (temp);
711 asn1_length_der (tot_len, temp, &len2);
712 _asn1_set_value (node, temp, len2);
716 ret = _asn1_extract_der_octet (node, der, *len);
717 if (ret != ASN1_SUCCESS)
723 { /* NOT STRUCTURED */
724 len2 = asn1_get_length_der (der, *len, &len3);
726 return ASN1_DER_ERROR;
727 if (len3 + len2 > *len)
728 return ASN1_DER_ERROR;
730 _asn1_set_value (node, der, len3 + len2);
731 counter = len3 + len2;
740 _asn1_get_indefinite_length_string (const unsigned char *der, int *len)
742 int len2, len3, counter, indefinite;
746 counter = indefinite = 0;
750 if ((*len) < counter)
751 return ASN1_DER_ERROR;
753 if ((der[counter] == 0) && (der[counter + 1] == 0))
764 (der + counter, *len - counter, &class, &len2,
765 &tag) != ASN1_SUCCESS)
766 return ASN1_DER_ERROR;
767 if (counter + len2 > *len)
768 return ASN1_DER_ERROR;
770 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
772 return ASN1_DER_ERROR;
780 counter += len2 + len3;
791 * @element: pointer to an ASN1 structure.
792 * @ider: vector that contains the DER encoding.
793 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
794 * @errorDescription: null-terminated string contains details when an
797 * Fill the structure *@ELEMENT with values of a DER encoding
798 * string. The structure must just be created with function
799 * asn1_create_element(). If an error occurs during the decoding
800 * procedure, the *@ELEMENT is deleted and set equal to
803 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
804 * if @ELEMENT is %ASN1_TYPE_EMPTY, and %ASN1_TAG_ERROR or
805 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
806 * name (*@ELEMENT deleted).
809 asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
810 char *errorDescription)
812 ASN1_TYPE node, p, p2, p3;
814 int counter, len2, len3, len4, move, ris, tlen;
817 int indefinite, result;
818 const unsigned char *der = ider;
822 if (node == ASN1_TYPE_EMPTY)
823 return ASN1_ELEMENT_NOT_FOUND;
825 if (node->type & CONST_OPTION)
827 asn1_delete_structure (element);
828 return ASN1_GENERIC_ERROR;
839 if (p->type & CONST_SET)
841 p2 = _asn1_find_up (p);
842 len2 = strtol (p2->value, NULL, 10);
845 if (!der[counter] && !der[counter + 1])
853 else if (counter == len2)
859 else if (counter > len2)
861 asn1_delete_structure (element);
862 return ASN1_DER_ERROR;
867 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
869 if (type_field (p2->type) != TYPE_CHOICE)
871 _asn1_extract_tag_der (p2, der + counter,
872 len - counter, &len2);
879 _asn1_extract_tag_der (p3, der + counter,
880 len - counter, &len2);
881 if (ris == ASN1_SUCCESS)
886 if (ris == ASN1_SUCCESS)
888 p2->type &= ~CONST_NOT_USED;
897 asn1_delete_structure (element);
898 return ASN1_DER_ERROR;
902 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
904 p2 = _asn1_find_up (p);
905 len2 = strtol (p2->value, NULL, 10);
916 if (p->type & CONST_OPTION)
917 asn1_delete_structure (&p);
924 if (type_field (p->type) == TYPE_CHOICE)
930 _asn1_extract_tag_der (p->down, der + counter,
931 len - counter, &len2);
933 ris = ASN1_DER_ERROR;
934 if (ris == ASN1_SUCCESS)
936 while (p->down->right)
939 asn1_delete_structure (&p2);
943 else if (ris == ASN1_ERROR_TYPE_ANY)
945 asn1_delete_structure (element);
946 return ASN1_ERROR_TYPE_ANY;
951 asn1_delete_structure (&p2);
957 if (!(p->type & CONST_OPTION))
959 asn1_delete_structure (element);
960 return ASN1_DER_ERROR;
967 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
969 p2 = _asn1_find_up (p);
970 len2 = strtol (p2->value, NULL, 10);
971 if ((len2 != -1) && (counter > len2))
972 ris = ASN1_TAG_ERROR;
975 if (ris == ASN1_SUCCESS)
977 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
978 if (ris != ASN1_SUCCESS)
980 if (p->type & CONST_OPTION)
982 p->type |= CONST_NOT_USED;
985 else if (p->type & CONST_DEFAULT)
987 _asn1_set_value (p, NULL, 0);
992 if (errorDescription != NULL)
993 _asn1_error_description_tag_error (p, errorDescription);
995 asn1_delete_structure (element);
996 return ASN1_TAG_ERROR;
1003 if (ris == ASN1_SUCCESS)
1005 switch (type_field (p->type))
1010 asn1_delete_structure (element);
1011 return ASN1_DER_ERROR;
1017 if (der[counter++] != 1)
1019 asn1_delete_structure (element);
1020 return ASN1_DER_ERROR;
1022 if (der[counter++] == 0)
1023 _asn1_set_value (p, "F", 1);
1025 _asn1_set_value (p, "T", 1);
1029 case TYPE_ENUMERATED:
1031 asn1_get_length_der (der + counter, len - counter, &len3);
1033 return ASN1_DER_ERROR;
1034 if (len2 + len3 > len - counter)
1035 return ASN1_DER_ERROR;
1036 _asn1_set_value (p, der + counter, len3 + len2);
1037 counter += len3 + len2;
1040 case TYPE_OBJECT_ID:
1042 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1043 temp, sizeof (temp));
1044 if (result != ASN1_SUCCESS)
1046 asn1_delete_structure (element);
1050 tlen = strlen (temp);
1052 _asn1_set_value (p, temp, tlen + 1);
1058 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
1060 if (result != ASN1_SUCCESS)
1062 asn1_delete_structure (element);
1065 tlen = strlen (temp);
1067 _asn1_set_value (p, temp, tlen + 1);
1071 case TYPE_OCTET_STRING:
1072 len3 = len - counter;
1073 ris = _asn1_get_octet_string (der + counter, p, &len3);
1074 if (ris != ASN1_SUCCESS)
1079 case TYPE_GENERALSTRING:
1081 asn1_get_length_der (der + counter, len - counter, &len3);
1083 return ASN1_DER_ERROR;
1084 if (len3 + len2 > len - counter)
1085 return ASN1_DER_ERROR;
1086 _asn1_set_value (p, der + counter, len3 + len2);
1087 counter += len3 + len2;
1090 case TYPE_BIT_STRING:
1092 asn1_get_length_der (der + counter, len - counter, &len3);
1094 return ASN1_DER_ERROR;
1095 if (len3 + len2 > len - counter)
1096 return ASN1_DER_ERROR;
1097 _asn1_set_value (p, der + counter, len3 + len2);
1098 counter += len3 + len2;
1105 len2 = strtol (p->value, NULL, 10);
1106 _asn1_set_value (p, NULL, 0);
1108 { /* indefinite length method */
1109 if (len - counter + 1 > 0)
1111 if ((der[counter]) || der[counter + 1])
1113 asn1_delete_structure (element);
1114 return ASN1_DER_ERROR;
1118 return ASN1_DER_ERROR;
1122 { /* definite length method */
1123 if (len2 != counter)
1125 asn1_delete_structure (element);
1126 return ASN1_DER_ERROR;
1132 { /* move==DOWN || move==RIGHT */
1134 asn1_get_length_der (der + counter, len - counter, &len2);
1136 return ASN1_DER_ERROR;
1140 _asn1_ltostr (counter + len3, temp);
1141 tlen = strlen (temp);
1143 _asn1_set_value (p, temp, tlen + 1);
1151 if (type_field (p2->type) != TYPE_TAG)
1154 asn1_delete_structure (&p2);
1163 { /* indefinite length method */
1164 _asn1_set_value (p, "-1", 3);
1169 case TYPE_SEQUENCE_OF:
1173 len2 = strtol (p->value, NULL, 10);
1175 { /* indefinite length method */
1176 if ((counter + 2) > len)
1177 return ASN1_DER_ERROR;
1178 if ((der[counter]) || der[counter + 1])
1180 _asn1_append_sequence_set (p);
1187 _asn1_set_value (p, NULL, 0);
1191 { /* definite length method */
1194 _asn1_append_sequence_set (p);
1201 _asn1_set_value (p, NULL, 0);
1202 if (len2 != counter)
1204 asn1_delete_structure (element);
1205 return ASN1_DER_ERROR;
1210 { /* move==DOWN || move==RIGHT */
1212 asn1_get_length_der (der + counter, len - counter, &len2);
1214 return ASN1_DER_ERROR;
1219 { /* definite length method */
1220 _asn1_ltostr (counter + len3, temp);
1221 tlen = strlen (temp);
1224 _asn1_set_value (p, temp, tlen + 1);
1227 { /* indefinite length method */
1228 _asn1_set_value (p, "-1", 3);
1231 while ((type_field (p2->type) == TYPE_TAG)
1232 || (type_field (p2->type) == TYPE_SIZE))
1234 if (p2->right == NULL)
1235 _asn1_append_sequence_set (p);
1242 if (asn1_get_tag_der
1243 (der + counter, len - counter, &class, &len2,
1244 &tag) != ASN1_SUCCESS)
1245 return ASN1_DER_ERROR;
1246 if (counter + len2 > len)
1247 return ASN1_DER_ERROR;
1249 asn1_get_length_der (der + counter + len2,
1250 len - counter - len2, &len3);
1252 return ASN1_DER_ERROR;
1253 if (len4 > len - counter + len2 + len3)
1254 return ASN1_DER_ERROR;
1258 _asn1_set_value_octet (p, der + counter, len2 + len3);
1259 counter += len2 + len3;
1262 { /* indefinite length */
1263 /* Check indefinite lenth method in an EXPLICIT TAG */
1264 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1269 len2 = len - counter;
1271 _asn1_get_indefinite_length_string (der + counter, &len2);
1272 if (ris != ASN1_SUCCESS)
1274 asn1_delete_structure (element);
1278 _asn1_set_value_octet (p, der + counter, len2);
1281 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1282 an indefinite length method. */
1285 if (!der[counter] && !der[counter + 1])
1291 asn1_delete_structure (element);
1292 return ASN1_DER_ERROR;
1299 move = (move == UP) ? RIGHT : DOWN;
1304 if (p == node && move != DOWN)
1314 if ((move == RIGHT) && !(p->type & CONST_SET))
1322 p = _asn1_find_up (p);
1325 _asn1_delete_not_used (*element);
1329 asn1_delete_structure (element);
1330 return ASN1_DER_ERROR;
1333 return ASN1_SUCCESS;
1337 #define SAME_BRANCH 2
1338 #define OTHER_BRANCH 3
1342 * asn1_der_decoding_element:
1343 * @structure: pointer to an ASN1 structure
1344 * @elementName: name of the element to fill
1345 * @ider: vector that contains the DER encoding of the whole structure.
1346 * @len: number of bytes of *der: der[0]..der[len-1]
1347 * @errorDescription: null-terminated string contains details when an
1350 * Fill the element named @ELEMENTNAME with values of a DER encoding
1351 * string. The structure must just be created with function
1352 * asn1_create_element(). The DER vector must contain the encoding
1353 * string of the whole @STRUCTURE. If an error occurs during the
1354 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1357 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1358 * if ELEMENT is %ASN1_TYPE_EMPTY or @elementName == NULL, and
1359 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1360 * match the structure @structure (*ELEMENT deleted).
1363 asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
1364 const void *ider, int len, char *errorDescription)
1366 ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
1367 char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
1368 int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
1369 int counter, len2, len3, len4, move, ris, tlen;
1370 unsigned char class, *temp2;
1372 int indefinite, result;
1373 const unsigned char *der = ider;
1377 if (node == ASN1_TYPE_EMPTY)
1378 return ASN1_ELEMENT_NOT_FOUND;
1380 if (elementName == NULL)
1382 asn1_delete_structure (structure);
1383 return ASN1_ELEMENT_NOT_FOUND;
1386 if (node->type & CONST_OPTION)
1388 asn1_delete_structure (structure);
1389 return ASN1_GENERIC_ERROR;
1392 if ((*structure)->name)
1393 { /* Has *structure got a name? */
1394 nameLen -= strlen ((*structure)->name);
1396 strcpy (currentName, (*structure)->name);
1399 asn1_delete_structure (structure);
1400 return ASN1_MEM_ERROR;
1402 if (!(strcmp (currentName, elementName)))
1405 nodeFound = *structure;
1407 else if (!memcmp (currentName, elementName, strlen (currentName)))
1408 state = SAME_BRANCH;
1410 state = OTHER_BRANCH;
1413 { /* *structure doesn't have a name? */
1415 if (elementName[0] == 0)
1418 nodeFound = *structure;
1422 state = SAME_BRANCH;
1436 if (p->type & CONST_SET)
1438 p2 = _asn1_find_up (p);
1439 len2 = strtol (p2->value, NULL, 10);
1440 if (counter == len2)
1446 else if (counter > len2)
1448 asn1_delete_structure (structure);
1449 return ASN1_DER_ERROR;
1454 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1456 if (type_field (p2->type) != TYPE_CHOICE)
1458 _asn1_extract_tag_der (p2, der + counter,
1459 len - counter, &len2);
1466 _asn1_extract_tag_der (p3, der + counter,
1467 len - counter, &len2);
1468 if (ris == ASN1_SUCCESS)
1473 if (ris == ASN1_SUCCESS)
1475 p2->type &= ~CONST_NOT_USED;
1484 asn1_delete_structure (structure);
1485 return ASN1_DER_ERROR;
1489 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1491 p2 = _asn1_find_up (p);
1492 len2 = strtol (p2->value, NULL, 10);
1493 if (counter == len2)
1503 if (p->type & CONST_OPTION)
1504 asn1_delete_structure (&p);
1511 if (type_field (p->type) == TYPE_CHOICE)
1517 _asn1_extract_tag_der (p->down, der + counter,
1518 len - counter, &len2);
1520 ris = ASN1_DER_ERROR;
1521 if (ris == ASN1_SUCCESS)
1523 while (p->down->right)
1525 p2 = p->down->right;
1526 asn1_delete_structure (&p2);
1530 else if (ris == ASN1_ERROR_TYPE_ANY)
1532 asn1_delete_structure (structure);
1533 return ASN1_ERROR_TYPE_ANY;
1538 asn1_delete_structure (&p2);
1542 if (p->down == NULL)
1544 if (!(p->type & CONST_OPTION))
1546 asn1_delete_structure (structure);
1547 return ASN1_DER_ERROR;
1554 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1556 p2 = _asn1_find_up (p);
1557 len2 = strtol (p2->value, NULL, 10);
1559 ris = ASN1_TAG_ERROR;
1562 if (ris == ASN1_SUCCESS)
1564 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1565 if (ris != ASN1_SUCCESS)
1567 if (p->type & CONST_OPTION)
1569 p->type |= CONST_NOT_USED;
1572 else if (p->type & CONST_DEFAULT)
1574 _asn1_set_value (p, NULL, 0);
1579 if (errorDescription != NULL)
1580 _asn1_error_description_tag_error (p, errorDescription);
1582 asn1_delete_structure (structure);
1583 return ASN1_TAG_ERROR;
1590 if (ris == ASN1_SUCCESS)
1592 switch (type_field (p->type))
1597 asn1_delete_structure (structure);
1598 return ASN1_DER_ERROR;
1608 if (der[counter++] != 1)
1610 asn1_delete_structure (structure);
1611 return ASN1_DER_ERROR;
1616 if (der[counter++] == 0)
1617 _asn1_set_value (p, "F", 1);
1619 _asn1_set_value (p, "T", 1);
1631 case TYPE_ENUMERATED:
1633 asn1_get_length_der (der + counter, len - counter, &len3);
1635 return ASN1_DER_ERROR;
1638 if (len3 + len2 > len - counter)
1639 return ASN1_DER_ERROR;
1640 _asn1_set_value (p, der + counter, len3 + len2);
1645 counter += len3 + len2;
1648 case TYPE_OBJECT_ID:
1652 _asn1_get_objectid_der (der + counter, len - counter,
1653 &len2, temp, sizeof (temp));
1654 if (result != ASN1_SUCCESS)
1659 tlen = strlen (temp);
1662 _asn1_set_value (p, temp, tlen + 1);
1670 asn1_get_length_der (der + counter, len - counter, &len3);
1672 return ASN1_DER_ERROR;
1683 _asn1_get_time_der (der + counter, len - counter, &len2,
1684 temp, sizeof (temp) - 1);
1685 if (result != ASN1_SUCCESS)
1687 asn1_delete_structure (structure);
1691 tlen = strlen (temp);
1693 _asn1_set_value (p, temp, tlen + 1);
1701 asn1_get_length_der (der + counter, len - counter, &len3);
1703 return ASN1_DER_ERROR;
1710 case TYPE_OCTET_STRING:
1711 len3 = len - counter;
1714 ris = _asn1_get_octet_string (der + counter, p, &len3);
1719 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
1721 if (ris != ASN1_SUCCESS)
1726 case TYPE_GENERALSTRING:
1728 asn1_get_length_der (der + counter, len - counter, &len3);
1730 return ASN1_DER_ERROR;
1733 if (len3 + len2 > len - counter)
1734 return ASN1_DER_ERROR;
1735 _asn1_set_value (p, der + counter, len3 + len2);
1740 counter += len3 + len2;
1743 case TYPE_BIT_STRING:
1745 asn1_get_length_der (der + counter, len - counter, &len3);
1747 return ASN1_DER_ERROR;
1750 if (len3 + len2 > len - counter)
1751 return ASN1_DER_ERROR;
1752 _asn1_set_value (p, der + counter, len3 + len2);
1757 counter += len3 + len2;
1764 len2 = strtol (p->value, NULL, 10);
1765 _asn1_set_value (p, NULL, 0);
1767 { /* indefinite length method */
1768 if ((der[counter]) || der[counter + 1])
1770 asn1_delete_structure (structure);
1771 return ASN1_DER_ERROR;
1776 { /* definite length method */
1777 if (len2 != counter)
1779 asn1_delete_structure (structure);
1780 return ASN1_DER_ERROR;
1788 { /* move==DOWN || move==RIGHT */
1789 if (state == OTHER_BRANCH)
1792 asn1_get_length_der (der + counter, len - counter,
1795 return ASN1_DER_ERROR;
1796 counter += len2 + len3;
1800 { /* state==SAME_BRANCH or state==FOUND */
1802 asn1_get_length_der (der + counter, len - counter,
1805 return ASN1_DER_ERROR;
1809 _asn1_ltostr (counter + len3, temp);
1810 tlen = strlen (temp);
1813 _asn1_set_value (p, temp, tlen + 1);
1821 if (type_field (p2->type) != TYPE_TAG)
1824 asn1_delete_structure (&p2);
1833 { /* indefinite length method */
1834 _asn1_set_value (p, "-1", 3);
1840 case TYPE_SEQUENCE_OF:
1844 len2 = strtol (p->value, NULL, 10);
1847 _asn1_append_sequence_set (p);
1854 _asn1_set_value (p, NULL, 0);
1855 if (len2 != counter)
1857 asn1_delete_structure (structure);
1858 return ASN1_DER_ERROR;
1865 { /* move==DOWN || move==RIGHT */
1866 if (state == OTHER_BRANCH)
1869 asn1_get_length_der (der + counter, len - counter,
1872 return ASN1_DER_ERROR;
1873 counter += len2 + len3;
1877 { /* state==FOUND or state==SAME_BRANCH */
1879 asn1_get_length_der (der + counter, len - counter,
1882 return ASN1_DER_ERROR;
1886 _asn1_ltostr (counter + len3, temp);
1887 tlen = strlen (temp);
1890 _asn1_set_value (p, temp, tlen + 1);
1892 while ((type_field (p2->type) == TYPE_TAG)
1893 || (type_field (p2->type) == TYPE_SIZE))
1895 if (p2->right == NULL)
1896 _asn1_append_sequence_set (p);
1905 if (asn1_get_tag_der
1906 (der + counter, len - counter, &class, &len2,
1907 &tag) != ASN1_SUCCESS)
1908 return ASN1_DER_ERROR;
1909 if (counter + len2 > len)
1910 return ASN1_DER_ERROR;
1913 asn1_get_length_der (der + counter + len2,
1914 len - counter - len2, &len3);
1916 return ASN1_DER_ERROR;
1923 _asn1_set_value_octet (p, der + counter, len2 + len3);
1929 counter += len2 + len3;
1932 { /* indefinite length */
1933 /* Check indefinite lenth method in an EXPLICIT TAG */
1934 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1939 len2 = len - counter;
1941 _asn1_get_indefinite_length_string (der + counter, &len2);
1942 if (ris != ASN1_SUCCESS)
1944 asn1_delete_structure (structure);
1950 _asn1_set_value_octet (p, der + counter, len2);
1958 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1959 an indefinite length method. */
1962 if (!der[counter] && !der[counter + 1])
1968 asn1_delete_structure (structure);
1969 return ASN1_DER_ERROR;
1977 move = (move == UP) ? RIGHT : DOWN;
1982 if ((p == node && move != DOWN) || (state == EXIT))
1993 nameLen -= strlen (p->name) + 1;
1997 strcat (currentName, ".");
1998 strcat (currentName, p->name);
2002 asn1_delete_structure (structure);
2003 return ASN1_MEM_ERROR;
2005 if (!(strcmp (currentName, elementName)))
2012 (currentName, elementName, strlen (currentName)))
2013 state = SAME_BRANCH;
2015 state = OTHER_BRANCH;
2022 if ((move == RIGHT) && !(p->type & CONST_SET))
2030 dot_p = char_p = currentName;
2031 while ((char_p = strchr (char_p, '.')))
2037 nameLen += strlen (currentName) - (dot_p - currentName);
2040 nameLen -= strlen (p->name);
2042 strcat (currentName, p->name);
2045 asn1_delete_structure (structure);
2046 return ASN1_MEM_ERROR;
2049 if (!(strcmp (currentName, elementName)))
2056 (currentName, elementName, strlen (currentName)))
2057 state = SAME_BRANCH;
2059 state = OTHER_BRANCH;
2068 p = _asn1_find_up (p);
2072 dot_p = char_p = currentName;
2073 while ((char_p = strchr (char_p, '.')))
2079 nameLen += strlen (currentName) - (dot_p - currentName);
2082 if (!(strcmp (currentName, elementName)))
2088 if (!memcmp (currentName, elementName, strlen (currentName)))
2089 state = SAME_BRANCH;
2091 state = OTHER_BRANCH;
2096 _asn1_delete_not_used (*structure);
2100 asn1_delete_structure (structure);
2101 return ASN1_DER_ERROR;
2104 return ASN1_SUCCESS;
2108 * asn1_der_decoding_startEnd:
2109 * @element: pointer to an ASN1 element
2110 * @ider: vector that contains the DER encoding.
2111 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2112 * @name_element: an element of NAME structure.
2113 * @start: the position of the first byte of NAME_ELEMENT decoding
2115 * @end: the position of the last byte of NAME_ELEMENT decoding
2118 * Find the start and end point of an element in a DER encoding
2119 * string. I mean that if you have a der encoding and you have already
2120 * used the function asn1_der_decoding() to fill a structure, it may
2121 * happen that you want to find the piece of string concerning an
2122 * element of the structure.
2124 * One example is the sequence "tbsCertificate" inside an X509
2127 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2128 * if ELEMENT is %ASN1_TYPE EMPTY or @name_element is not a valid
2129 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2130 * doesn't match the structure ELEMENT.
2133 asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
2134 const char *name_element, int *start, int *end)
2136 ASN1_TYPE node, node_to_find, p, p2, p3;
2137 int counter, len2, len3, len4, move, ris;
2138 unsigned char class;
2141 const unsigned char *der = ider;
2145 if (node == ASN1_TYPE_EMPTY)
2146 return ASN1_ELEMENT_NOT_FOUND;
2148 node_to_find = asn1_find_node (node, name_element);
2150 if (node_to_find == NULL)
2151 return ASN1_ELEMENT_NOT_FOUND;
2153 if (node_to_find == node)
2157 return ASN1_SUCCESS;
2160 if (node->type & CONST_OPTION)
2161 return ASN1_GENERIC_ERROR;
2172 if (p->type & CONST_SET)
2174 p2 = _asn1_find_up (p);
2175 len2 = strtol (p2->value, NULL, 10);
2178 if (!der[counter] && !der[counter + 1])
2186 else if (counter == len2)
2192 else if (counter > len2)
2193 return ASN1_DER_ERROR;
2197 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2199 if (type_field (p2->type) != TYPE_CHOICE)
2201 _asn1_extract_tag_der (p2, der + counter,
2202 len - counter, &len2);
2207 _asn1_extract_tag_der (p3, der + counter,
2208 len - counter, &len2);
2210 if (ris == ASN1_SUCCESS)
2212 p2->type &= ~CONST_NOT_USED;
2220 return ASN1_DER_ERROR;
2223 if (p == node_to_find)
2226 if (type_field (p->type) == TYPE_CHOICE)
2230 _asn1_extract_tag_der (p, der + counter, len - counter,
2232 if (p == node_to_find)
2236 if (ris == ASN1_SUCCESS)
2238 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2239 if (ris != ASN1_SUCCESS)
2241 if (p->type & CONST_OPTION)
2243 p->type |= CONST_NOT_USED;
2246 else if (p->type & CONST_DEFAULT)
2252 return ASN1_TAG_ERROR;
2259 if (ris == ASN1_SUCCESS)
2261 switch (type_field (p->type))
2265 return ASN1_DER_ERROR;
2270 if (der[counter++] != 1)
2271 return ASN1_DER_ERROR;
2276 case TYPE_ENUMERATED:
2278 asn1_get_length_der (der + counter, len - counter, &len3);
2280 return ASN1_DER_ERROR;
2281 counter += len3 + len2;
2284 case TYPE_OBJECT_ID:
2286 asn1_get_length_der (der + counter, len - counter, &len3);
2288 return ASN1_DER_ERROR;
2289 counter += len2 + len3;
2294 asn1_get_length_der (der + counter, len - counter, &len3);
2296 return ASN1_DER_ERROR;
2297 counter += len2 + len3;
2300 case TYPE_OCTET_STRING:
2301 len3 = len - counter;
2302 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2303 if (ris != ASN1_SUCCESS)
2308 case TYPE_GENERALSTRING:
2310 asn1_get_length_der (der + counter, len - counter, &len3);
2312 return ASN1_DER_ERROR;
2313 counter += len3 + len2;
2316 case TYPE_BIT_STRING:
2318 asn1_get_length_der (der + counter, len - counter, &len3);
2320 return ASN1_DER_ERROR;
2321 counter += len3 + len2;
2329 asn1_get_length_der (der + counter, len - counter, &len2);
2331 return ASN1_DER_ERROR;
2340 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2345 case TYPE_SEQUENCE_OF:
2350 asn1_get_length_der (der + counter, len - counter, &len2);
2352 return ASN1_DER_ERROR;
2354 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2359 while ((type_field (p2->type) == TYPE_TAG) ||
2360 (type_field (p2->type) == TYPE_SIZE))
2367 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2373 if (asn1_get_tag_der
2374 (der + counter, len - counter, &class, &len2,
2375 &tag) != ASN1_SUCCESS)
2376 return ASN1_DER_ERROR;
2377 if (counter + len2 > len)
2378 return ASN1_DER_ERROR;
2381 asn1_get_length_der (der + counter + len2,
2382 len - counter - len2, &len3);
2384 return ASN1_DER_ERROR;
2388 counter += len2 + len4 + len3;
2391 { /* indefinite length */
2392 /* Check indefinite lenth method in an EXPLICIT TAG */
2393 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2398 len2 = len - counter;
2400 _asn1_get_indefinite_length_string (der + counter, &len2);
2401 if (ris != ASN1_SUCCESS)
2405 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2406 an indefinite length method. */
2409 if (!der[counter] && !der[counter + 1])
2412 return ASN1_DER_ERROR;
2418 move = (move == UP) ? RIGHT : DOWN;
2423 if ((p == node_to_find) && (move == RIGHT))
2426 return ASN1_SUCCESS;
2429 if (p == node && move != DOWN)
2439 if ((move == RIGHT) && !(p->type & CONST_SET))
2447 p = _asn1_find_up (p);
2450 return ASN1_ELEMENT_NOT_FOUND;
2454 * asn1_expand_any_defined_by:
2455 * @definitions: ASN1 definitions
2456 * @element: pointer to an ASN1 structure
2458 * Expands every "ANY DEFINED BY" element of a structure created from
2459 * a DER decoding process (asn1_der_decoding function). The element
2460 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2461 * expand the element ANY is the first one following the definition of
2462 * the actual value of the OBJECT IDENTIFIER.
2464 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2465 * some "ANY DEFINED BY" element couldn't be expanded due to a
2466 * problem in OBJECT_ID -> TYPE association, or other error codes
2467 * depending on DER decoding.
2470 asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
2472 char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
2473 value[ASN1_MAX_NAME_SIZE];
2474 asn1_retCode retCode = ASN1_SUCCESS, result;
2475 int len, len2, len3;
2476 ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
2477 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2479 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2480 return ASN1_ELEMENT_NOT_FOUND;
2482 strcpy (definitionsName, definitions->name);
2483 strcat (definitionsName, ".");
2489 switch (type_field (p->type))
2492 if ((p->type & CONST_DEFINED_BY) && (p->value))
2494 /* search the "DEF_BY" element */
2496 while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
2501 retCode = ASN1_ERROR_TYPE_ANY;
2505 p3 = _asn1_find_up (p);
2509 retCode = ASN1_ERROR_TYPE_ANY;
2516 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2521 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2522 (p3->value == NULL))
2525 p3 = _asn1_find_up (p);
2526 p3 = _asn1_find_up (p3);
2530 retCode = ASN1_ERROR_TYPE_ANY;
2538 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2543 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2544 (p3->value == NULL))
2546 retCode = ASN1_ERROR_TYPE_ANY;
2551 /* search the OBJECT_ID into definitions */
2552 p2 = definitions->down;
2555 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2556 (p2->type & CONST_ASSIGN))
2558 strcpy (name, definitionsName);
2559 strcat (name, p2->name);
2561 len = ASN1_MAX_NAME_SIZE;
2563 asn1_read_value (definitions, name, value, &len);
2565 if ((result == ASN1_SUCCESS)
2566 && (!strcmp (p3->value, value)))
2568 p2 = p2->right; /* pointer to the structure to
2569 use for expansion */
2570 while ((p2) && (p2->type & CONST_ASSIGN))
2575 strcpy (name, definitionsName);
2576 strcat (name, p2->name);
2579 asn1_create_element (definitions, name, &aux);
2580 if (result == ASN1_SUCCESS)
2582 _asn1_set_name (aux, p->name);
2584 asn1_get_length_der (p->value,
2585 p->value_len, &len3);
2587 return ASN1_DER_ERROR;
2590 asn1_der_decoding (&aux, p->value + len3,
2593 if (result == ASN1_SUCCESS)
2596 _asn1_set_right (aux, p->right);
2597 _asn1_set_right (p, aux);
2599 result = asn1_delete_structure (&p);
2600 if (result == ASN1_SUCCESS)
2603 aux = ASN1_TYPE_EMPTY;
2607 { /* error with asn1_delete_structure */
2608 asn1_delete_structure (&aux);
2614 { /* error with asn1_der_decoding */
2620 { /* error with asn1_create_element */
2626 { /* error with the pointer to the structure to exapand */
2627 retCode = ASN1_ERROR_TYPE_ANY;
2637 retCode = ASN1_ERROR_TYPE_ANY;
2652 else if (p == *element)
2663 p = _asn1_find_up (p);
2682 * asn1_expand_octet_string:
2683 * @definitions: ASN1 definitions
2684 * @element: pointer to an ASN1 structure
2685 * @octetName: name of the OCTECT STRING field to expand.
2686 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2687 * the type for expansion.
2689 * Expands an "OCTET STRING" element of a structure created from a DER
2690 * decoding process (the asn1_der_decoding() function). The type used
2691 * for expansion is the first one following the definition of the
2692 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2694 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2695 * if @objectName or @octetName are not correct,
2696 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2697 * use for expansion, or other errors depending on DER decoding.
2700 asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
2701 const char *octetName, const char *objectName)
2703 char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
2704 asn1_retCode retCode = ASN1_SUCCESS, result;
2705 int len, len2, len3;
2706 ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
2707 ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
2708 char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
2710 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2711 return ASN1_ELEMENT_NOT_FOUND;
2713 octetNode = asn1_find_node (*element, octetName);
2714 if (octetNode == ASN1_TYPE_EMPTY)
2715 return ASN1_ELEMENT_NOT_FOUND;
2716 if (type_field (octetNode->type) != TYPE_OCTET_STRING)
2717 return ASN1_ELEMENT_NOT_FOUND;
2718 if (octetNode->value == NULL)
2719 return ASN1_VALUE_NOT_FOUND;
2721 objectNode = asn1_find_node (*element, objectName);
2722 if (objectNode == ASN1_TYPE_EMPTY)
2723 return ASN1_ELEMENT_NOT_FOUND;
2725 if (type_field (objectNode->type) != TYPE_OBJECT_ID)
2726 return ASN1_ELEMENT_NOT_FOUND;
2728 if (objectNode->value == NULL)
2729 return ASN1_VALUE_NOT_FOUND;
2732 /* search the OBJECT_ID into definitions */
2733 p2 = definitions->down;
2736 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2737 (p2->type & CONST_ASSIGN))
2739 strcpy (name, definitions->name);
2741 strcat (name, p2->name);
2743 len = sizeof (value);
2744 result = asn1_read_value (definitions, name, value, &len);
2746 if ((result == ASN1_SUCCESS)
2747 && (!strcmp (objectNode->value, value)))
2750 p2 = p2->right; /* pointer to the structure to
2751 use for expansion */
2752 while ((p2) && (p2->type & CONST_ASSIGN))
2757 strcpy (name, definitions->name);
2759 strcat (name, p2->name);
2761 result = asn1_create_element (definitions, name, &aux);
2762 if (result == ASN1_SUCCESS)
2764 _asn1_set_name (aux, octetNode->name);
2766 asn1_get_length_der (octetNode->value,
2767 octetNode->value_len, &len3);
2769 return ASN1_DER_ERROR;
2772 asn1_der_decoding (&aux, octetNode->value + len3,
2773 len2, errorDescription);
2774 if (result == ASN1_SUCCESS)
2777 _asn1_set_right (aux, octetNode->right);
2778 _asn1_set_right (octetNode, aux);
2780 result = asn1_delete_structure (&octetNode);
2781 if (result == ASN1_SUCCESS)
2783 aux = ASN1_TYPE_EMPTY;
2787 { /* error with asn1_delete_structure */
2788 asn1_delete_structure (&aux);
2794 { /* error with asn1_der_decoding */
2800 { /* error with asn1_create_element */
2806 { /* error with the pointer to the structure to exapand */
2807 retCode = ASN1_VALUE_NOT_VALID;
2818 retCode = ASN1_VALUE_NOT_VALID;