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
23 /*****************************************************/
24 /* File: decoding.c */
25 /* Description: Functions to manage DER decoding */
26 /*****************************************************/
29 #include "parser_aux.h"
31 #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 to fit in a int, or -4
59 * when the decoded length value plus @len would exceed @der_len.
62 asn1_get_length_der (const unsigned char *der
, int der_len
, int *len
)
64 unsigned int ans
, sum
, last
;
83 { /* definite length method */
85 while (punt
<= k
&& punt
< der_len
)
89 ans
= (ans
*256) + der
[punt
++];
91 /* we wrapped around, no bignum support... */
96 { /* indefinite length method */
106 /* check for overflow as well INT_MAX as a maximum upper
107 * limit for length */
108 if (sum
>= INT_MAX
|| sum
< ans
)
111 if (((int) sum
) > der_len
)
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
)
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)
152 while (punt
<= der_len
&& der
[punt
] & 128)
156 ris
= (ris
* 128) + (der
[punt
++] & 0x7F);
158 /* wrapped around, and no bignums... */
159 return ASN1_DER_ERROR
;
163 return ASN1_DER_ERROR
;
167 ris
= (ris
* 128) + (der
[punt
++] & 0x7F);
169 return ASN1_DER_ERROR
;
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.
194 asn1_get_length_ber (const unsigned char *ber
, int ber_len
, int *len
)
199 ret
= asn1_get_length_der (ber
, ber_len
, len
);
201 { /* indefinite length method */
203 err
= _asn1_get_indefinite_length_string (ber
+ 1, &ret
);
204 if (err
!= ASN1_SUCCESS
)
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
,
232 return ASN1_GENERIC_ERROR
;
234 /* if(str==NULL) return ASN1_SUCCESS; */
235 *str_len
= asn1_get_length_der (der
, der_len
, &len_len
);
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
);
245 return ASN1_MEM_ERROR
;
251 /* Returns ASN1_SUCCESS on success or an error code on error.
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
);
266 *ret_len
= str_len
+ len_len
;
272 _asn1_get_objectid_der (const unsigned char *der
, int der_len
, int *ret_len
,
273 char *str
, int str_size
)
278 unsigned long val
, val1
, prev_val
;
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
));
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
;
309 /* check for wrap around */
311 val
|= der
[len_len
+ k
] & 0x7F;
314 return ASN1_DER_ERROR
;
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
));
327 *ret_len
= len
+ len_len
;
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
,
350 int len_len
, len_byte
;
353 return ASN1_GENERIC_ERROR
;
354 len_byte
= asn1_get_length_der (der
, der_len
, &len_len
) - 1;
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
);
365 return ASN1_MEM_ERROR
;
372 _asn1_extract_tag_der (ASN1_TYPE node
, const unsigned char *der
, int der_len
,
376 int counter
, len2
, len3
, is_tag_implicit
;
377 unsigned long tag
, tag_implicit
= 0;
378 unsigned char class, class2
, class_implicit
= 0;
381 return ASN1_GENERIC_ERROR
;
383 counter
= is_tag_implicit
= 0;
385 if (node
->type
& CONST_TAG
)
390 if (type_field (p
->type
) == TYPE_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
;
399 class2
= ASN1_CLASS_CONTEXT_SPECIFIC
;
401 if (p
->type
& CONST_EXPLICIT
)
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
;
413 asn1_get_length_ber (der
+ counter
, der_len
- counter
,
416 return ASN1_DER_ERROR
;
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
;
429 { /* ASN1_TAG_IMPLICIT */
430 if ((class != class_implicit
) || (tag
!= tag_implicit
))
431 return ASN1_TAG_ERROR
;
436 { /* ASN1_TAG_IMPLICIT */
437 if (!is_tag_implicit
)
439 if ((type_field (node
->type
) == TYPE_SEQUENCE
) ||
440 (type_field (node
->type
) == TYPE_SEQUENCE_OF
) ||
441 (type_field (node
->type
) == TYPE_SET
) ||
442 (type_field (node
->type
) == TYPE_SET_OF
))
443 class2
|= ASN1_CLASS_STRUCTURED
;
444 class_implicit
= class2
;
445 tag_implicit
= strtoul ((char *) p
->value
, NULL
, 10);
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
) == TYPE_OCTET_STRING
)
467 class_implicit
|= ASN1_CLASS_STRUCTURED
;
468 if ((class != class_implicit
) || (tag
!= tag_implicit
))
469 return ASN1_TAG_ERROR
;
472 return ASN1_TAG_ERROR
;
477 if (type_field (node
->type
) == TYPE_TAG
)
485 (der
+ counter
, der_len
- counter
, &class, &len2
,
486 &tag
) != ASN1_SUCCESS
)
487 return ASN1_DER_ERROR
;
489 if (counter
+ len2
> der_len
)
490 return ASN1_DER_ERROR
;
492 switch (type_field (node
->type
))
495 if ((class != ASN1_CLASS_UNIVERSAL
) || (tag
!= ASN1_TAG_NULL
))
496 return ASN1_DER_ERROR
;
499 if ((class != ASN1_CLASS_UNIVERSAL
) || (tag
!= ASN1_TAG_BOOLEAN
))
500 return ASN1_DER_ERROR
;
503 if ((class != ASN1_CLASS_UNIVERSAL
) || (tag
!= ASN1_TAG_INTEGER
))
504 return ASN1_DER_ERROR
;
506 case TYPE_ENUMERATED
:
507 if ((class != ASN1_CLASS_UNIVERSAL
) || (tag
!= ASN1_TAG_ENUMERATED
))
508 return ASN1_DER_ERROR
;
511 if ((class != ASN1_CLASS_UNIVERSAL
) || (tag
!= ASN1_TAG_OBJECT_ID
))
512 return ASN1_DER_ERROR
;
515 if (node
->type
& CONST_UTC
)
517 if ((class != ASN1_CLASS_UNIVERSAL
)
518 || (tag
!= ASN1_TAG_UTCTime
))
519 return ASN1_DER_ERROR
;
523 if ((class != ASN1_CLASS_UNIVERSAL
)
524 || (tag
!= ASN1_TAG_GENERALIZEDTime
))
525 return ASN1_DER_ERROR
;
528 case TYPE_OCTET_STRING
:
529 if (((class != ASN1_CLASS_UNIVERSAL
)
530 && (class != (ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
)))
531 || (tag
!= ASN1_TAG_OCTET_STRING
))
532 return ASN1_DER_ERROR
;
534 case TYPE_GENERALSTRING
:
535 if ((class != ASN1_CLASS_UNIVERSAL
)
536 || (tag
!= ASN1_TAG_GENERALSTRING
))
537 return ASN1_DER_ERROR
;
539 case TYPE_BIT_STRING
:
540 if ((class != ASN1_CLASS_UNIVERSAL
) || (tag
!= ASN1_TAG_BIT_STRING
))
541 return ASN1_DER_ERROR
;
544 case TYPE_SEQUENCE_OF
:
545 if ((class != (ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
))
546 || (tag
!= ASN1_TAG_SEQUENCE
))
547 return ASN1_DER_ERROR
;
551 if ((class != (ASN1_CLASS_UNIVERSAL
| ASN1_CLASS_STRUCTURED
))
552 || (tag
!= ASN1_TAG_SET
))
553 return ASN1_DER_ERROR
;
559 return ASN1_DER_ERROR
;
570 _asn1_delete_not_used (ASN1_TYPE node
)
575 return ASN1_ELEMENT_NOT_FOUND
;
580 if (p
->type
& CONST_NOT_USED
)
585 p2
= _asn1_find_left (p
);
587 p2
= _asn1_find_up (p
);
589 asn1_delete_structure (&p
);
594 break; /* reach node */
610 p
= _asn1_find_up (p
);
629 _asn1_extract_der_octet (ASN1_TYPE node
, const unsigned char *der
,
633 int counter2
, counter_end
;
635 len2
= asn1_get_length_der (der
, der_len
, &len3
);
637 return ASN1_DER_ERROR
;
642 counter_end
= der_len
- 2;
644 counter_end
= der_len
;
646 while (counter2
< counter_end
)
648 len2
= asn1_get_length_der (der
+ counter2
, der_len
- counter2
, &len3
);
651 return ASN1_DER_ERROR
;
655 _asn1_append_value (node
, der
+ counter2
+ len3
, len2
);
661 _asn1_extract_der_octet (node
, der
+ counter2
+ len3
,
662 der_len
- counter2
- len3
);
667 counter2
+= len2
+ len3
+ 1;
674 _asn1_get_octet_string (const unsigned char *der
, ASN1_TYPE node
, int *len
)
676 int len2
, len3
, counter
, tot_len
, indefinite
;
680 if (*(der
- 1) & ASN1_CLASS_STRUCTURED
)
683 indefinite
= asn1_get_length_der (der
, *len
, &len3
);
685 return ASN1_DER_ERROR
;
693 if (counter
> (*len
))
694 return ASN1_DER_ERROR
;
696 if (indefinite
== -1)
698 if ((der
[counter
] == 0) && (der
[counter
+ 1] == 0))
704 else if (counter
>= indefinite
)
707 if (der
[counter
] != ASN1_TAG_OCTET_STRING
)
708 return ASN1_DER_ERROR
;
712 len2
= asn1_get_length_der (der
+ counter
, *len
- counter
, &len3
);
714 return ASN1_DER_ERROR
;
716 counter
+= len3
+ len2
;
723 unsigned char temp
[DER_LEN
];
726 len2
= sizeof (temp
);
728 asn1_length_der (tot_len
, temp
, &len2
);
729 _asn1_set_value (node
, temp
, len2
);
733 ret
= _asn1_extract_der_octet (node
, der
, *len
);
734 if (ret
!= ASN1_SUCCESS
)
740 { /* NOT STRUCTURED */
741 len2
= asn1_get_length_der (der
, *len
, &len3
);
743 return ASN1_DER_ERROR
;
745 _asn1_set_value (node
, der
, len3
+ len2
);
746 counter
= len3
+ len2
;
755 _asn1_get_indefinite_length_string (const unsigned char *der
, int *len
)
757 int len2
, len3
, counter
, indefinite
;
761 counter
= indefinite
= 0;
765 if ((*len
) < counter
)
766 return ASN1_DER_ERROR
;
768 if ((der
[counter
] == 0) && (der
[counter
+ 1] == 0))
779 (der
+ counter
, *len
- counter
, &class, &len2
,
780 &tag
) != ASN1_SUCCESS
)
781 return ASN1_DER_ERROR
;
782 if (counter
+ len2
> *len
)
783 return ASN1_DER_ERROR
;
785 len2
= asn1_get_length_der (der
+ counter
, *len
- counter
, &len3
);
787 return ASN1_DER_ERROR
;
795 counter
+= len2
+ len3
;
806 * @element: pointer to an ASN1 structure.
807 * @ider: vector that contains the DER encoding.
808 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
809 * @errorDescription: null-terminated string contains details when an
812 * Fill the structure *@ELEMENT with values of a DER encoding
813 * string. The structure must just be created with function
814 * asn1_create_element(). If an error occurs during the decoding
815 * procedure, the *@ELEMENT is deleted and set equal to
818 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
819 * if @ELEMENT is %ASN1_TYPE_EMPTY, and %ASN1_TAG_ERROR or
820 * %ASN1_DER_ERROR if the der encoding doesn't match the structure
821 * name (*@ELEMENT deleted).
824 asn1_der_decoding (ASN1_TYPE
* element
, const void *ider
, int len
,
825 char *errorDescription
)
827 ASN1_TYPE node
, p
, p2
, p3
;
829 int counter
, len2
, len3
, len4
, move
, ris
, tlen
;
832 int indefinite
, result
;
833 const unsigned char *der
= ider
;
837 if (node
== ASN1_TYPE_EMPTY
)
838 return ASN1_ELEMENT_NOT_FOUND
;
840 if (node
->type
& CONST_OPTION
)
842 result
= ASN1_GENERIC_ERROR
;
854 if (p
->type
& CONST_SET
)
856 p2
= _asn1_find_up (p
);
857 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
860 if (!der
[counter
] && !der
[counter
+ 1])
868 else if (counter
== len2
)
874 else if (counter
> len2
)
876 result
= ASN1_DER_ERROR
;
882 if ((p2
->type
& CONST_SET
) && (p2
->type
& CONST_NOT_USED
))
884 if (type_field (p2
->type
) != TYPE_CHOICE
)
886 _asn1_extract_tag_der (p2
, der
+ counter
,
887 len
- counter
, &len2
);
894 _asn1_extract_tag_der (p3
, der
+ counter
,
895 len
- counter
, &len2
);
896 if (ris
== ASN1_SUCCESS
)
901 if (ris
== ASN1_SUCCESS
)
903 p2
->type
&= ~CONST_NOT_USED
;
912 result
= ASN1_DER_ERROR
;
917 if ((p
->type
& CONST_OPTION
) || (p
->type
& CONST_DEFAULT
))
919 p2
= _asn1_find_up (p
);
920 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
931 if (p
->type
& CONST_OPTION
)
932 asn1_delete_structure (&p
);
939 if (type_field (p
->type
) == TYPE_CHOICE
)
945 _asn1_extract_tag_der (p
->down
, der
+ counter
,
946 len
- counter
, &len2
);
948 ris
= ASN1_DER_ERROR
;
949 if (ris
== ASN1_SUCCESS
)
951 while (p
->down
->right
)
954 asn1_delete_structure (&p2
);
958 else if (ris
== ASN1_ERROR_TYPE_ANY
)
960 result
= ASN1_ERROR_TYPE_ANY
;
966 asn1_delete_structure (&p2
);
972 if (!(p
->type
& CONST_OPTION
))
974 result
= ASN1_DER_ERROR
;
982 if ((p
->type
& CONST_OPTION
) || (p
->type
& CONST_DEFAULT
))
984 p2
= _asn1_find_up (p
);
985 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
986 if ((len2
!= -1) && (counter
> len2
))
987 ris
= ASN1_TAG_ERROR
;
990 if (ris
== ASN1_SUCCESS
)
992 _asn1_extract_tag_der (p
, der
+ counter
, len
- counter
, &len2
);
993 if (ris
!= ASN1_SUCCESS
)
995 if (p
->type
& CONST_OPTION
)
997 p
->type
|= CONST_NOT_USED
;
1000 else if (p
->type
& CONST_DEFAULT
)
1002 _asn1_set_value (p
, NULL
, 0);
1007 if (errorDescription
!= NULL
)
1008 _asn1_error_description_tag_error (p
, errorDescription
);
1010 result
= ASN1_TAG_ERROR
;
1018 if (ris
== ASN1_SUCCESS
)
1020 switch (type_field (p
->type
))
1025 result
= ASN1_DER_ERROR
;
1032 if (der
[counter
++] != 1)
1034 result
= ASN1_DER_ERROR
;
1037 if (der
[counter
++] == 0)
1038 _asn1_set_value (p
, "F", 1);
1040 _asn1_set_value (p
, "T", 1);
1044 case TYPE_ENUMERATED
:
1046 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1049 result
= ASN1_DER_ERROR
;
1053 _asn1_set_value (p
, der
+ counter
, len3
+ len2
);
1054 counter
+= len3
+ len2
;
1057 case TYPE_OBJECT_ID
:
1059 _asn1_get_objectid_der (der
+ counter
, len
- counter
, &len2
,
1060 temp
, sizeof (temp
));
1061 if (result
!= ASN1_SUCCESS
)
1064 tlen
= strlen (temp
);
1066 _asn1_set_value (p
, temp
, tlen
+ 1);
1072 _asn1_get_time_der (der
+ counter
, len
- counter
, &len2
, temp
,
1074 if (result
!= ASN1_SUCCESS
)
1077 tlen
= strlen (temp
);
1079 _asn1_set_value (p
, temp
, tlen
+ 1);
1083 case TYPE_OCTET_STRING
:
1084 len3
= len
- counter
;
1085 result
= _asn1_get_octet_string (der
+ counter
, p
, &len3
);
1086 if (result
!= ASN1_SUCCESS
)
1092 case TYPE_GENERALSTRING
:
1094 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1097 result
= ASN1_DER_ERROR
;
1101 _asn1_set_value (p
, der
+ counter
, len3
+ len2
);
1102 counter
+= len3
+ len2
;
1105 case TYPE_BIT_STRING
:
1107 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1110 result
= ASN1_DER_ERROR
;
1114 _asn1_set_value (p
, der
+ counter
, len3
+ len2
);
1115 counter
+= len3
+ len2
;
1122 len2
= _asn1_strtol (p
->value
, NULL
, 10);
1123 _asn1_set_value (p
, NULL
, 0);
1125 { /* indefinite length method */
1126 if (len
- counter
+ 1 > 0)
1128 if ((der
[counter
]) || der
[counter
+ 1])
1130 result
= ASN1_DER_ERROR
;
1136 result
= ASN1_DER_ERROR
;
1142 { /* definite length method */
1143 if (len2
!= counter
)
1145 result
= ASN1_DER_ERROR
;
1152 { /* move==DOWN || move==RIGHT */
1154 asn1_get_length_der (der
+ counter
, len
- counter
, &len2
);
1157 result
= ASN1_DER_ERROR
;
1163 _asn1_ltostr (counter
+ len3
, temp
);
1164 tlen
= strlen (temp
);
1166 _asn1_set_value (p
, temp
, tlen
+ 1);
1174 if (type_field (p2
->type
) != TYPE_TAG
)
1177 asn1_delete_structure (&p2
);
1186 { /* indefinite length method */
1187 _asn1_set_value (p
, "-1", 3);
1192 case TYPE_SEQUENCE_OF
:
1196 len2
= _asn1_strtol (p
->value
, NULL
, 10);
1198 { /* indefinite length method */
1199 if ((counter
+ 2) > len
)
1201 result
= ASN1_DER_ERROR
;
1205 if ((der
[counter
]) || der
[counter
+ 1])
1207 _asn1_append_sequence_set (p
);
1214 _asn1_set_value (p
, NULL
, 0);
1218 { /* definite length method */
1221 _asn1_append_sequence_set (p
);
1228 _asn1_set_value (p
, NULL
, 0);
1229 if (len2
!= counter
)
1231 result
= ASN1_DER_ERROR
;
1237 { /* move==DOWN || move==RIGHT */
1239 asn1_get_length_der (der
+ counter
, len
- counter
, &len2
);
1242 result
= ASN1_DER_ERROR
;
1249 { /* definite length method */
1250 _asn1_ltostr (counter
+ len3
, temp
);
1251 tlen
= strlen (temp
);
1254 _asn1_set_value (p
, temp
, tlen
+ 1);
1257 { /* indefinite length method */
1258 _asn1_set_value (p
, "-1", 3);
1261 while ((type_field (p2
->type
) == TYPE_TAG
)
1262 || (type_field (p2
->type
) == TYPE_SIZE
))
1264 if (p2
->right
== NULL
)
1265 _asn1_append_sequence_set (p
);
1272 if (asn1_get_tag_der
1273 (der
+ counter
, len
- counter
, &class, &len2
,
1274 &tag
) != ASN1_SUCCESS
)
1276 result
= ASN1_DER_ERROR
;
1280 if (counter
+ len2
> len
)
1282 result
= ASN1_DER_ERROR
;
1286 asn1_get_length_der (der
+ counter
+ len2
,
1287 len
- counter
- len2
, &len3
);
1290 result
= ASN1_DER_ERROR
;
1296 _asn1_set_value_octet (p
, der
+ counter
, len2
+ len3
);
1297 counter
+= len2
+ len3
;
1300 { /* indefinite length */
1301 /* Check indefinite lenth method in an EXPLICIT TAG */
1302 if ((p
->type
& CONST_TAG
) && (der
[counter
- 1] == 0x80))
1307 len2
= len
- counter
;
1309 _asn1_get_indefinite_length_string (der
+ counter
, &len2
);
1310 if (result
!= ASN1_SUCCESS
)
1313 _asn1_set_value_octet (p
, der
+ counter
, len2
);
1316 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1317 an indefinite length method. */
1320 if (!der
[counter
] && !der
[counter
+ 1])
1326 result
= ASN1_DER_ERROR
;
1334 move
= (move
== UP
) ? RIGHT
: DOWN
;
1339 if (p
== node
&& move
!= DOWN
)
1349 if ((move
== RIGHT
) && !(p
->type
& CONST_SET
))
1357 p
= _asn1_find_up (p
);
1360 _asn1_delete_not_used (*element
);
1364 result
= ASN1_DER_ERROR
;
1368 return ASN1_SUCCESS
;
1371 asn1_delete_structure (element
);
1376 #define SAME_BRANCH 2
1377 #define OTHER_BRANCH 3
1381 * asn1_der_decoding_element:
1382 * @structure: pointer to an ASN1 structure
1383 * @elementName: name of the element to fill
1384 * @ider: vector that contains the DER encoding of the whole structure.
1385 * @len: number of bytes of *der: der[0]..der[len-1]
1386 * @errorDescription: null-terminated string contains details when an
1389 * Fill the element named @ELEMENTNAME with values of a DER encoding
1390 * string. The structure must just be created with function
1391 * asn1_create_element(). The DER vector must contain the encoding
1392 * string of the whole @STRUCTURE. If an error occurs during the
1393 * decoding procedure, the *@STRUCTURE is deleted and set equal to
1396 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
1397 * if ELEMENT is %ASN1_TYPE_EMPTY or @elementName == NULL, and
1398 * %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
1399 * match the structure @structure (*ELEMENT deleted).
1402 asn1_der_decoding_element (ASN1_TYPE
* structure
, const char *elementName
,
1403 const void *ider
, int len
, char *errorDescription
)
1405 ASN1_TYPE node
, p
, p2
, p3
, nodeFound
= ASN1_TYPE_EMPTY
;
1406 char temp
[128], currentName
[ASN1_MAX_NAME_SIZE
* 10], *dot_p
, *char_p
;
1407 int nameLen
= ASN1_MAX_NAME_SIZE
* 10 - 1, state
;
1408 int counter
, len2
, len3
, len4
, move
, ris
, tlen
;
1409 unsigned char class;
1411 int indefinite
, result
;
1412 const unsigned char *der
= ider
;
1416 if (node
== ASN1_TYPE_EMPTY
)
1417 return ASN1_ELEMENT_NOT_FOUND
;
1419 if (elementName
== NULL
)
1421 result
= ASN1_ELEMENT_NOT_FOUND
;
1425 if (node
->type
& CONST_OPTION
)
1427 result
= ASN1_GENERIC_ERROR
;
1431 if ((*structure
)->name
)
1432 { /* Has *structure got a name? */
1433 nameLen
-= strlen ((*structure
)->name
);
1435 strcpy (currentName
, (*structure
)->name
);
1438 result
= ASN1_MEM_ERROR
;
1441 if (!(strcmp (currentName
, elementName
)))
1444 nodeFound
= *structure
;
1446 else if (!memcmp (currentName
, elementName
, strlen (currentName
)))
1447 state
= SAME_BRANCH
;
1449 state
= OTHER_BRANCH
;
1452 { /* *structure doesn't have a name? */
1454 if (elementName
[0] == 0)
1457 nodeFound
= *structure
;
1461 state
= SAME_BRANCH
;
1475 if (p
->type
& CONST_SET
)
1477 p2
= _asn1_find_up (p
);
1478 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
1479 if (counter
== len2
)
1485 else if (counter
> len2
)
1487 result
= ASN1_DER_ERROR
;
1493 if ((p2
->type
& CONST_SET
) && (p2
->type
& CONST_NOT_USED
))
1495 if (type_field (p2
->type
) != TYPE_CHOICE
)
1497 _asn1_extract_tag_der (p2
, der
+ counter
,
1498 len
- counter
, &len2
);
1505 _asn1_extract_tag_der (p3
, der
+ counter
,
1506 len
- counter
, &len2
);
1507 if (ris
== ASN1_SUCCESS
)
1512 if (ris
== ASN1_SUCCESS
)
1514 p2
->type
&= ~CONST_NOT_USED
;
1523 result
= ASN1_DER_ERROR
;
1528 if ((p
->type
& CONST_OPTION
) || (p
->type
& CONST_DEFAULT
))
1530 p2
= _asn1_find_up (p
);
1531 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
1532 if (counter
== len2
)
1542 if (p
->type
& CONST_OPTION
)
1543 asn1_delete_structure (&p
);
1550 if (type_field (p
->type
) == TYPE_CHOICE
)
1556 _asn1_extract_tag_der (p
->down
, der
+ counter
,
1557 len
- counter
, &len2
);
1559 ris
= ASN1_DER_ERROR
;
1560 if (ris
== ASN1_SUCCESS
)
1562 while (p
->down
->right
)
1564 p2
= p
->down
->right
;
1565 asn1_delete_structure (&p2
);
1569 else if (ris
== ASN1_ERROR_TYPE_ANY
)
1571 result
= ASN1_ERROR_TYPE_ANY
;
1577 asn1_delete_structure (&p2
);
1581 if (p
->down
== NULL
)
1583 if (!(p
->type
& CONST_OPTION
))
1585 result
= ASN1_DER_ERROR
;
1593 if ((p
->type
& CONST_OPTION
) || (p
->type
& CONST_DEFAULT
))
1595 p2
= _asn1_find_up (p
);
1596 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
1598 ris
= ASN1_TAG_ERROR
;
1601 if (ris
== ASN1_SUCCESS
)
1603 _asn1_extract_tag_der (p
, der
+ counter
, len
- counter
, &len2
);
1604 if (ris
!= ASN1_SUCCESS
)
1606 if (p
->type
& CONST_OPTION
)
1608 p
->type
|= CONST_NOT_USED
;
1611 else if (p
->type
& CONST_DEFAULT
)
1613 _asn1_set_value (p
, NULL
, 0);
1618 if (errorDescription
!= NULL
)
1619 _asn1_error_description_tag_error (p
, errorDescription
);
1621 result
= ASN1_TAG_ERROR
;
1629 if (ris
== ASN1_SUCCESS
)
1631 switch (type_field (p
->type
))
1636 result
= ASN1_DER_ERROR
;
1647 if (der
[counter
++] != 1)
1649 result
= ASN1_DER_ERROR
;
1655 if (der
[counter
++] == 0)
1656 _asn1_set_value (p
, "F", 1);
1658 _asn1_set_value (p
, "T", 1);
1670 case TYPE_ENUMERATED
:
1672 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1675 result
= ASN1_DER_ERROR
;
1681 if (len3
+ len2
> len
- counter
)
1683 result
= ASN1_DER_ERROR
;
1686 _asn1_set_value (p
, der
+ counter
, len3
+ len2
);
1691 counter
+= len3
+ len2
;
1694 case TYPE_OBJECT_ID
:
1698 _asn1_get_objectid_der (der
+ counter
, len
- counter
,
1699 &len2
, temp
, sizeof (temp
));
1700 if (result
!= ASN1_SUCCESS
)
1703 tlen
= strlen (temp
);
1706 _asn1_set_value (p
, temp
, tlen
+ 1);
1714 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1717 result
= ASN1_DER_ERROR
;
1730 _asn1_get_time_der (der
+ counter
, len
- counter
, &len2
,
1731 temp
, sizeof (temp
) - 1);
1732 if (result
!= ASN1_SUCCESS
)
1735 tlen
= strlen (temp
);
1737 _asn1_set_value (p
, temp
, tlen
+ 1);
1745 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1748 result
= ASN1_DER_ERROR
;
1757 case TYPE_OCTET_STRING
:
1758 len3
= len
- counter
;
1761 result
= _asn1_get_octet_string (der
+ counter
, p
, &len3
);
1766 result
= _asn1_get_octet_string (der
+ counter
, NULL
, &len3
);
1768 if (result
!= ASN1_SUCCESS
)
1774 case TYPE_GENERALSTRING
:
1776 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1779 result
= ASN1_DER_ERROR
;
1785 if (len3
+ len2
> len
- counter
)
1787 result
= ASN1_DER_ERROR
;
1790 _asn1_set_value (p
, der
+ counter
, len3
+ len2
);
1795 counter
+= len3
+ len2
;
1798 case TYPE_BIT_STRING
:
1800 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
1803 result
= ASN1_DER_ERROR
;
1808 if (len3
+ len2
> len
- counter
)
1810 result
= ASN1_DER_ERROR
;
1813 _asn1_set_value (p
, der
+ counter
, len3
+ len2
);
1818 counter
+= len3
+ len2
;
1825 len2
= _asn1_strtol (p
->value
, NULL
, 10);
1826 _asn1_set_value (p
, NULL
, 0);
1828 { /* indefinite length method */
1829 if ((der
[counter
]) || der
[counter
+ 1])
1831 result
= ASN1_DER_ERROR
;
1837 { /* definite length method */
1838 if (len2
!= counter
)
1840 result
= ASN1_DER_ERROR
;
1849 { /* move==DOWN || move==RIGHT */
1850 if (state
== OTHER_BRANCH
)
1853 asn1_get_length_der (der
+ counter
, len
- counter
,
1857 result
= ASN1_DER_ERROR
;
1860 counter
+= len2
+ len3
;
1864 { /* state==SAME_BRANCH or state==FOUND */
1866 asn1_get_length_der (der
+ counter
, len
- counter
,
1870 result
= ASN1_DER_ERROR
;
1876 _asn1_ltostr (counter
+ len3
, temp
);
1877 tlen
= strlen (temp
);
1880 _asn1_set_value (p
, temp
, tlen
+ 1);
1888 if (type_field (p2
->type
) != TYPE_TAG
)
1891 asn1_delete_structure (&p2
);
1900 { /* indefinite length method */
1901 _asn1_set_value (p
, "-1", 3);
1907 case TYPE_SEQUENCE_OF
:
1911 len2
= _asn1_strtol (p
->value
, NULL
, 10);
1914 _asn1_append_sequence_set (p
);
1921 _asn1_set_value (p
, NULL
, 0);
1922 if (len2
!= counter
)
1924 result
= ASN1_DER_ERROR
;
1932 { /* move==DOWN || move==RIGHT */
1933 if (state
== OTHER_BRANCH
)
1936 asn1_get_length_der (der
+ counter
, len
- counter
,
1940 result
= ASN1_DER_ERROR
;
1943 counter
+= len2
+ len3
;
1947 { /* state==FOUND or state==SAME_BRANCH */
1949 asn1_get_length_der (der
+ counter
, len
- counter
,
1953 result
= ASN1_DER_ERROR
;
1959 _asn1_ltostr (counter
+ len3
, temp
);
1960 tlen
= strlen (temp
);
1963 _asn1_set_value (p
, temp
, tlen
+ 1);
1965 while ((type_field (p2
->type
) == TYPE_TAG
)
1966 || (type_field (p2
->type
) == TYPE_SIZE
))
1968 if (p2
->right
== NULL
)
1969 _asn1_append_sequence_set (p
);
1978 if (asn1_get_tag_der
1979 (der
+ counter
, len
- counter
, &class, &len2
,
1980 &tag
) != ASN1_SUCCESS
)
1982 result
= ASN1_DER_ERROR
;
1986 if (counter
+ len2
> len
)
1988 result
= ASN1_DER_ERROR
;
1993 asn1_get_length_der (der
+ counter
+ len2
,
1994 len
- counter
- len2
, &len3
);
1997 result
= ASN1_DER_ERROR
;
2006 _asn1_set_value_octet (p
, der
+ counter
, len2
+ len3
);
2011 counter
+= len2
+ len3
;
2014 { /* indefinite length */
2015 /* Check indefinite lenth method in an EXPLICIT TAG */
2016 if ((p
->type
& CONST_TAG
) && (der
[counter
- 1] == 0x80))
2021 len2
= len
- counter
;
2023 _asn1_get_indefinite_length_string (der
+ counter
, &len2
);
2024 if (result
!= ASN1_SUCCESS
)
2029 _asn1_set_value_octet (p
, der
+ counter
, len2
);
2037 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2038 an indefinite length method. */
2041 if (!der
[counter
] && !der
[counter
+ 1])
2047 result
= ASN1_DER_ERROR
;
2056 move
= (move
== UP
) ? RIGHT
: DOWN
;
2061 if ((p
== node
&& move
!= DOWN
) || (state
== EXIT
))
2072 nameLen
-= strlen (p
->name
) + 1;
2076 strcat (currentName
, ".");
2077 strcat (currentName
, p
->name
);
2081 result
= ASN1_MEM_ERROR
;
2084 if (!(strcmp (currentName
, elementName
)))
2091 (currentName
, elementName
, strlen (currentName
)))
2092 state
= SAME_BRANCH
;
2094 state
= OTHER_BRANCH
;
2101 if ((move
== RIGHT
) && !(p
->type
& CONST_SET
))
2109 dot_p
= char_p
= currentName
;
2110 while ((char_p
= strchr (char_p
, '.')))
2116 nameLen
+= strlen (currentName
) - (dot_p
- currentName
);
2119 nameLen
-= strlen (p
->name
);
2121 strcat (currentName
, p
->name
);
2124 result
= ASN1_MEM_ERROR
;
2128 if (!(strcmp (currentName
, elementName
)))
2135 (currentName
, elementName
, strlen (currentName
)))
2136 state
= SAME_BRANCH
;
2138 state
= OTHER_BRANCH
;
2147 p
= _asn1_find_up (p
);
2151 dot_p
= char_p
= currentName
;
2152 while ((char_p
= strchr (char_p
, '.')))
2158 nameLen
+= strlen (currentName
) - (dot_p
- currentName
);
2161 if (!(strcmp (currentName
, elementName
)))
2167 if (!memcmp (currentName
, elementName
, strlen (currentName
)))
2168 state
= SAME_BRANCH
;
2170 state
= OTHER_BRANCH
;
2175 _asn1_delete_not_used (*structure
);
2179 result
= ASN1_DER_ERROR
;
2183 return ASN1_SUCCESS
;
2186 asn1_delete_structure (structure
);
2191 * asn1_der_decoding_startEnd:
2192 * @element: pointer to an ASN1 element
2193 * @ider: vector that contains the DER encoding.
2194 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2195 * @name_element: an element of NAME structure.
2196 * @start: the position of the first byte of NAME_ELEMENT decoding
2198 * @end: the position of the last byte of NAME_ELEMENT decoding
2201 * Find the start and end point of an element in a DER encoding
2202 * string. I mean that if you have a der encoding and you have already
2203 * used the function asn1_der_decoding() to fill a structure, it may
2204 * happen that you want to find the piece of string concerning an
2205 * element of the structure.
2207 * One example is the sequence "tbsCertificate" inside an X509
2210 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
2211 * if ELEMENT is %ASN1_TYPE EMPTY or @name_element is not a valid
2212 * element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
2213 * doesn't match the structure ELEMENT.
2216 asn1_der_decoding_startEnd (ASN1_TYPE element
, const void *ider
, int len
,
2217 const char *name_element
, int *start
, int *end
)
2219 ASN1_TYPE node
, node_to_find
, p
, p2
, p3
;
2220 int counter
, len2
, len3
, len4
, move
, ris
;
2221 unsigned char class;
2224 const unsigned char *der
= ider
;
2228 if (node
== ASN1_TYPE_EMPTY
)
2229 return ASN1_ELEMENT_NOT_FOUND
;
2231 node_to_find
= asn1_find_node (node
, name_element
);
2233 if (node_to_find
== NULL
)
2234 return ASN1_ELEMENT_NOT_FOUND
;
2236 if (node_to_find
== node
)
2240 return ASN1_SUCCESS
;
2243 if (node
->type
& CONST_OPTION
)
2244 return ASN1_GENERIC_ERROR
;
2255 if (p
->type
& CONST_SET
)
2257 p2
= _asn1_find_up (p
);
2258 len2
= _asn1_strtol (p2
->value
, NULL
, 10);
2261 if (!der
[counter
] && !der
[counter
+ 1])
2269 else if (counter
== len2
)
2275 else if (counter
> len2
)
2276 return ASN1_DER_ERROR
;
2280 if ((p2
->type
& CONST_SET
) && (p2
->type
& CONST_NOT_USED
))
2282 if (type_field (p2
->type
) != TYPE_CHOICE
)
2284 _asn1_extract_tag_der (p2
, der
+ counter
,
2285 len
- counter
, &len2
);
2290 _asn1_extract_tag_der (p3
, der
+ counter
,
2291 len
- counter
, &len2
);
2293 if (ris
== ASN1_SUCCESS
)
2295 p2
->type
&= ~CONST_NOT_USED
;
2303 return ASN1_DER_ERROR
;
2306 if (p
== node_to_find
)
2309 if (type_field (p
->type
) == TYPE_CHOICE
)
2313 _asn1_extract_tag_der (p
, der
+ counter
, len
- counter
,
2315 if (p
== node_to_find
)
2319 if (ris
== ASN1_SUCCESS
)
2321 _asn1_extract_tag_der (p
, der
+ counter
, len
- counter
, &len2
);
2322 if (ris
!= ASN1_SUCCESS
)
2324 if (p
->type
& CONST_OPTION
)
2326 p
->type
|= CONST_NOT_USED
;
2329 else if (p
->type
& CONST_DEFAULT
)
2335 return ASN1_TAG_ERROR
;
2342 if (ris
== ASN1_SUCCESS
)
2344 switch (type_field (p
->type
))
2348 return ASN1_DER_ERROR
;
2353 if (der
[counter
++] != 1)
2354 return ASN1_DER_ERROR
;
2359 case TYPE_ENUMERATED
:
2361 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
2363 return ASN1_DER_ERROR
;
2364 counter
+= len3
+ len2
;
2367 case TYPE_OBJECT_ID
:
2369 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
2371 return ASN1_DER_ERROR
;
2372 counter
+= len2
+ len3
;
2377 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
2379 return ASN1_DER_ERROR
;
2380 counter
+= len2
+ len3
;
2383 case TYPE_OCTET_STRING
:
2384 len3
= len
- counter
;
2385 ris
= _asn1_get_octet_string (der
+ counter
, NULL
, &len3
);
2386 if (ris
!= ASN1_SUCCESS
)
2391 case TYPE_GENERALSTRING
:
2393 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
2395 return ASN1_DER_ERROR
;
2396 counter
+= len3
+ len2
;
2399 case TYPE_BIT_STRING
:
2401 asn1_get_length_der (der
+ counter
, len
- counter
, &len3
);
2403 return ASN1_DER_ERROR
;
2404 counter
+= len3
+ len2
;
2412 asn1_get_length_der (der
+ counter
, len
- counter
, &len2
);
2414 return ASN1_DER_ERROR
;
2423 if (!der
[counter
] && !der
[counter
+ 1]) /* indefinite length method */
2428 case TYPE_SEQUENCE_OF
:
2433 asn1_get_length_der (der
+ counter
, len
- counter
, &len2
);
2435 return ASN1_DER_ERROR
;
2437 if ((len3
== -1) && !der
[counter
] && !der
[counter
+ 1])
2442 while ((type_field (p2
->type
) == TYPE_TAG
) ||
2443 (type_field (p2
->type
) == TYPE_SIZE
))
2450 if (!der
[counter
] && !der
[counter
+ 1]) /* indefinite length method */
2456 if (asn1_get_tag_der
2457 (der
+ counter
, len
- counter
, &class, &len2
,
2458 &tag
) != ASN1_SUCCESS
)
2459 return ASN1_DER_ERROR
;
2460 if (counter
+ len2
> len
)
2461 return ASN1_DER_ERROR
;
2464 asn1_get_length_der (der
+ counter
+ len2
,
2465 len
- counter
- len2
, &len3
);
2467 return ASN1_DER_ERROR
;
2471 counter
+= len2
+ len4
+ len3
;
2474 { /* indefinite length */
2475 /* Check indefinite lenth method in an EXPLICIT TAG */
2476 if ((p
->type
& CONST_TAG
) && (der
[counter
- 1] == 0x80))
2481 len2
= len
- counter
;
2483 _asn1_get_indefinite_length_string (der
+ counter
, &len2
);
2484 if (ris
!= ASN1_SUCCESS
)
2488 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2489 an indefinite length method. */
2492 if (!der
[counter
] && !der
[counter
+ 1])
2495 return ASN1_DER_ERROR
;
2501 move
= (move
== UP
) ? RIGHT
: DOWN
;
2506 if ((p
== node_to_find
) && (move
== RIGHT
))
2509 return ASN1_SUCCESS
;
2512 if (p
== node
&& move
!= DOWN
)
2522 if ((move
== RIGHT
) && !(p
->type
& CONST_SET
))
2530 p
= _asn1_find_up (p
);
2533 return ASN1_ELEMENT_NOT_FOUND
;
2537 * asn1_expand_any_defined_by:
2538 * @definitions: ASN1 definitions
2539 * @element: pointer to an ASN1 structure
2541 * Expands every "ANY DEFINED BY" element of a structure created from
2542 * a DER decoding process (asn1_der_decoding function). The element
2543 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
2544 * expand the element ANY is the first one following the definition of
2545 * the actual value of the OBJECT IDENTIFIER.
2547 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
2548 * some "ANY DEFINED BY" element couldn't be expanded due to a
2549 * problem in OBJECT_ID -> TYPE association, or other error codes
2550 * depending on DER decoding.
2553 asn1_expand_any_defined_by (ASN1_TYPE definitions
, ASN1_TYPE
* element
)
2555 char definitionsName
[ASN1_MAX_NAME_SIZE
], name
[2 * ASN1_MAX_NAME_SIZE
+ 1],
2556 value
[ASN1_MAX_NAME_SIZE
];
2557 asn1_retCode retCode
= ASN1_SUCCESS
, result
;
2558 int len
, len2
, len3
;
2559 ASN1_TYPE p
, p2
, p3
, aux
= ASN1_TYPE_EMPTY
;
2560 char errorDescription
[ASN1_MAX_ERROR_DESCRIPTION_SIZE
];
2562 if ((definitions
== ASN1_TYPE_EMPTY
) || (*element
== ASN1_TYPE_EMPTY
))
2563 return ASN1_ELEMENT_NOT_FOUND
;
2565 strcpy (definitionsName
, definitions
->name
);
2566 strcat (definitionsName
, ".");
2572 switch (type_field (p
->type
))
2575 if ((p
->type
& CONST_DEFINED_BY
) && (p
->value
))
2577 /* search the "DEF_BY" element */
2579 while ((p2
) && (type_field (p2
->type
) != TYPE_CONSTANT
))
2584 retCode
= ASN1_ERROR_TYPE_ANY
;
2588 p3
= _asn1_find_up (p
);
2592 retCode
= ASN1_ERROR_TYPE_ANY
;
2599 if ((p3
->name
) && !(strcmp (p3
->name
, p2
->name
)))
2604 if ((!p3
) || (type_field (p3
->type
) != TYPE_OBJECT_ID
) ||
2605 (p3
->value
== NULL
))
2608 p3
= _asn1_find_up (p
);
2609 p3
= _asn1_find_up (p3
);
2613 retCode
= ASN1_ERROR_TYPE_ANY
;
2621 if ((p3
->name
) && !(strcmp (p3
->name
, p2
->name
)))
2626 if ((!p3
) || (type_field (p3
->type
) != TYPE_OBJECT_ID
) ||
2627 (p3
->value
== NULL
))
2629 retCode
= ASN1_ERROR_TYPE_ANY
;
2634 /* search the OBJECT_ID into definitions */
2635 p2
= definitions
->down
;
2638 if ((type_field (p2
->type
) == TYPE_OBJECT_ID
) &&
2639 (p2
->type
& CONST_ASSIGN
))
2641 strcpy (name
, definitionsName
);
2642 strcat (name
, p2
->name
);
2644 len
= ASN1_MAX_NAME_SIZE
;
2646 asn1_read_value (definitions
, name
, value
, &len
);
2648 if ((result
== ASN1_SUCCESS
)
2649 && (!_asn1_strcmp (p3
->value
, value
)))
2651 p2
= p2
->right
; /* pointer to the structure to
2652 use for expansion */
2653 while ((p2
) && (p2
->type
& CONST_ASSIGN
))
2658 strcpy (name
, definitionsName
);
2659 strcat (name
, p2
->name
);
2662 asn1_create_element (definitions
, name
, &aux
);
2663 if (result
== ASN1_SUCCESS
)
2665 _asn1_set_name (aux
, p
->name
);
2667 asn1_get_length_der (p
->value
,
2668 p
->value_len
, &len3
);
2670 return ASN1_DER_ERROR
;
2673 asn1_der_decoding (&aux
, p
->value
+ len3
,
2676 if (result
== ASN1_SUCCESS
)
2679 _asn1_set_right (aux
, p
->right
);
2680 _asn1_set_right (p
, aux
);
2682 result
= asn1_delete_structure (&p
);
2683 if (result
== ASN1_SUCCESS
)
2686 aux
= ASN1_TYPE_EMPTY
;
2690 { /* error with asn1_delete_structure */
2691 asn1_delete_structure (&aux
);
2697 { /* error with asn1_der_decoding */
2703 { /* error with asn1_create_element */
2709 { /* error with the pointer to the structure to exapand */
2710 retCode
= ASN1_ERROR_TYPE_ANY
;
2720 retCode
= ASN1_ERROR_TYPE_ANY
;
2735 else if (p
== *element
)
2746 p
= _asn1_find_up (p
);
2765 * asn1_expand_octet_string:
2766 * @definitions: ASN1 definitions
2767 * @element: pointer to an ASN1 structure
2768 * @octetName: name of the OCTECT STRING field to expand.
2769 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2770 * the type for expansion.
2772 * Expands an "OCTET STRING" element of a structure created from a DER
2773 * decoding process (the asn1_der_decoding() function). The type used
2774 * for expansion is the first one following the definition of the
2775 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2777 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
2778 * if @objectName or @octetName are not correct,
2779 * %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
2780 * use for expansion, or other errors depending on DER decoding.
2783 asn1_expand_octet_string (ASN1_TYPE definitions
, ASN1_TYPE
* element
,
2784 const char *octetName
, const char *objectName
)
2786 char name
[2 * ASN1_MAX_NAME_SIZE
+ 1], value
[ASN1_MAX_NAME_SIZE
];
2787 asn1_retCode retCode
= ASN1_SUCCESS
, result
;
2788 int len
, len2
, len3
;
2789 ASN1_TYPE p2
, aux
= ASN1_TYPE_EMPTY
;
2790 ASN1_TYPE octetNode
= ASN1_TYPE_EMPTY
, objectNode
= ASN1_TYPE_EMPTY
;
2791 char errorDescription
[ASN1_MAX_ERROR_DESCRIPTION_SIZE
];
2793 if ((definitions
== ASN1_TYPE_EMPTY
) || (*element
== ASN1_TYPE_EMPTY
))
2794 return ASN1_ELEMENT_NOT_FOUND
;
2796 octetNode
= asn1_find_node (*element
, octetName
);
2797 if (octetNode
== ASN1_TYPE_EMPTY
)
2798 return ASN1_ELEMENT_NOT_FOUND
;
2799 if (type_field (octetNode
->type
) != TYPE_OCTET_STRING
)
2800 return ASN1_ELEMENT_NOT_FOUND
;
2801 if (octetNode
->value
== NULL
)
2802 return ASN1_VALUE_NOT_FOUND
;
2804 objectNode
= asn1_find_node (*element
, objectName
);
2805 if (objectNode
== ASN1_TYPE_EMPTY
)
2806 return ASN1_ELEMENT_NOT_FOUND
;
2808 if (type_field (objectNode
->type
) != TYPE_OBJECT_ID
)
2809 return ASN1_ELEMENT_NOT_FOUND
;
2811 if (objectNode
->value
== NULL
)
2812 return ASN1_VALUE_NOT_FOUND
;
2815 /* search the OBJECT_ID into definitions */
2816 p2
= definitions
->down
;
2819 if ((type_field (p2
->type
) == TYPE_OBJECT_ID
) &&
2820 (p2
->type
& CONST_ASSIGN
))
2822 strcpy (name
, definitions
->name
);
2824 strcat (name
, p2
->name
);
2826 len
= sizeof (value
);
2827 result
= asn1_read_value (definitions
, name
, value
, &len
);
2829 if ((result
== ASN1_SUCCESS
)
2830 && (!_asn1_strcmp (objectNode
->value
, value
)))
2833 p2
= p2
->right
; /* pointer to the structure to
2834 use for expansion */
2835 while ((p2
) && (p2
->type
& CONST_ASSIGN
))
2840 strcpy (name
, definitions
->name
);
2842 strcat (name
, p2
->name
);
2844 result
= asn1_create_element (definitions
, name
, &aux
);
2845 if (result
== ASN1_SUCCESS
)
2847 _asn1_set_name (aux
, octetNode
->name
);
2849 asn1_get_length_der (octetNode
->value
,
2850 octetNode
->value_len
, &len3
);
2852 return ASN1_DER_ERROR
;
2855 asn1_der_decoding (&aux
, octetNode
->value
+ len3
,
2856 len2
, errorDescription
);
2857 if (result
== ASN1_SUCCESS
)
2860 _asn1_set_right (aux
, octetNode
->right
);
2861 _asn1_set_right (octetNode
, aux
);
2863 result
= asn1_delete_structure (&octetNode
);
2864 if (result
== ASN1_SUCCESS
)
2866 aux
= ASN1_TYPE_EMPTY
;
2870 { /* error with asn1_delete_structure */
2871 asn1_delete_structure (&aux
);
2877 { /* error with asn1_der_decoding */
2883 { /* error with asn1_create_element */
2889 { /* error with the pointer to the structure to exapand */
2890 retCode
= ASN1_VALUE_NOT_VALID
;
2901 retCode
= ASN1_VALUE_NOT_VALID
;