2 * Copyright (C) 2004, 2006, 2008 Free Software Foundation
3 * Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina
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
23 /*****************************************************/
25 /* Description: Functions with the read and write */
27 /*****************************************************/
32 #include "parser_aux.h"
34 #include "structure.h"
37 _asn1_hierarchical_name (node_asn
* node
, char *name
, int name_size
)
50 _asn1_str_cpy (tmp_name
, sizeof (tmp_name
), name
),
51 _asn1_str_cpy (name
, name_size
, p
->name
);
52 _asn1_str_cat (name
, name_size
, ".");
53 _asn1_str_cat (name
, name_size
, tmp_name
);
55 p
= _asn1_find_up (p
);
59 _asn1_str_cpy (name
, name_size
, "ROOT");
63 /******************************************************************/
64 /* Function : _asn1_convert_integer */
65 /* Description: converts an integer from a null terminated string */
66 /* to der decoding. The convertion from a null */
67 /* terminated string to an integer is made with */
68 /* the 'strtol' function. */
70 /* value: null terminated string to convert. */
71 /* value_out: convertion result (memory must be already */
73 /* value_out_size: number of bytes of value_out. */
74 /* len: number of significant byte of value_out. */
75 /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
76 /******************************************************************/
78 _asn1_convert_integer (const char *value
, unsigned char *value_out
,
79 int value_out_size
, int *len
)
82 unsigned char val
[SIZEOF_UNSIGNED_LONG_INT
];
86 valtmp
= strtol (value
, NULL
, 10);
88 for (k
= 0; k
< SIZEOF_UNSIGNED_LONG_INT
; k
++)
90 val
[SIZEOF_UNSIGNED_LONG_INT
- k
- 1] = (valtmp
>> (8 * k
)) & 0xFF;
98 for (k
= 0; k
< SIZEOF_UNSIGNED_LONG_INT
- 1; k
++)
100 if (negative
&& (val
[k
] != 0xFF))
102 else if (!negative
&& val
[k
])
106 if ((negative
&& !(val
[k
] & 0x80)) || (!negative
&& (val
[k
] & 0x80)))
109 *len
= SIZEOF_UNSIGNED_LONG_INT
- k
;
111 if (SIZEOF_UNSIGNED_LONG_INT
- k
> value_out_size
)
112 /* VALUE_OUT is too short to contain the value conversion */
113 return ASN1_MEM_ERROR
;
115 for (k2
= k
; k2
< SIZEOF_UNSIGNED_LONG_INT
; k2
++)
116 value_out
[k2
- k
] = val
[k2
];
119 #ifdef LIBTASN1_DEBUG_INTEGER
120 _libtasn1_log ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value
, *len
);
121 for (k
= 0; k
< SIZEOF_UNSIGNED_LONG_INT
; k
++)
122 _libtasn1_log (", vOut[%d]=%d", k
, value_out
[k
]);
123 _libtasn1_log ("\n");
132 _asn1_append_sequence_set (node_asn
* node
)
138 if (!node
|| !(node
->down
))
139 return ASN1_GENERIC_ERROR
;
142 while ((type_field (p
->type
) == TYPE_TAG
)
143 || (type_field (p
->type
) == TYPE_SIZE
))
145 p2
= _asn1_copy_structure3 (p
);
148 _asn1_set_right (p
, p2
);
151 _asn1_str_cpy (temp
, sizeof (temp
), "?1");
154 n
= strtol (p
->name
+ 1, NULL
, 0);
157 _asn1_ltostr (n
, temp
+ 1);
159 _asn1_set_name (p2
, temp
);
160 /* p2->type |= CONST_OPTION; */
167 * asn1_write_value - Set the value of one element inside a structure.
168 * @node_root: pointer to a structure
169 * @name: the name of the element inside the structure that you want to set.
170 * @ivalue: vector used to specify the value to set. If len is >0,
171 * VALUE must be a two's complement form integer. if len=0 *VALUE
172 * must be a null terminated string with an integer value.
173 * @len: number of bytes of *value to use to set the value:
174 * value[0]..value[len-1] or 0 if value is a null terminated string
176 * Set the value of one element inside a structure.
178 * If an element is OPTIONAL and you want to delete it, you must use
179 * the value=NULL and len=0. Using "pkix.asn":
181 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
184 * Description for each type:
186 * INTEGER: VALUE must contain a two's complement form integer.
188 * value[0]=0xFF , len=1 -> integer=-1.
189 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
190 * value[0]=0x01 , len=1 -> integer= 1.
191 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
192 * value="123" , len=0 -> integer= 123.
194 * ENUMERATED: As INTEGER (but only with not negative numbers).
196 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
197 * "FALSE" and LEN != 0.
199 * value="TRUE" , len=1 -> boolean=TRUE.
200 * value="FALSE" , len=1 -> boolean=FALSE.
202 * OBJECT IDENTIFIER: VALUE must be a null terminated string with
203 * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
205 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
207 * UTCTime: VALUE must be a null terminated string in one of these
208 * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
209 * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
210 * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
212 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
213 * at 12h 00m Greenwich Mean Time
215 * GeneralizedTime: VALUE must be in one of this format:
216 * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
217 * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
218 * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
219 * indicates the seconds with any precision like "10.1" or "01.02".
222 * value="2001010112001.12-0700" , len=1 -> time=Jannuary
223 * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
225 * OCTET STRING: VALUE contains the octet string and LEN is the
228 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
229 * len=3 -> three bytes octet string
231 * GeneralString: VALUE contains the generalstring and LEN is the
234 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
235 * len=3 -> three bytes generalstring
237 * BIT STRING: VALUE contains the bit string organized by bytes and
238 * LEN is the number of bits.
240 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
243 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
244 * the alternatives with a null terminated string. LEN != 0. Using
247 * result=asn1_write_value(cert,
248 * "certificate1.tbsCertificate.subject", "rdnSequence",
251 * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
253 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
254 * LEN != 0. With this instruction another element is appended in
255 * the sequence. The name of this element will be "?1" if it's the
256 * first one, "?2" for the second and so on.
260 * result=asn1_write_value(cert,
261 * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
263 * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
265 * result=asn1_write_value(cert,
266 * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
270 * ASN1_SUCCESS: Set value OK.
272 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
274 * ASN1_VALUE_NOT_VALID: VALUE has a wrong format.
278 asn1_write_value (ASN1_TYPE node_root
, const char *name
,
279 const void *ivalue
, int len
)
281 node_asn
*node
, *p
, *p2
;
282 unsigned char *temp
, *value_temp
= NULL
, *default_temp
= NULL
;
283 int len2
, k
, k2
, negative
;
284 const unsigned char *value
= ivalue
;
286 node
= asn1_find_node (node_root
, name
);
288 return ASN1_ELEMENT_NOT_FOUND
;
290 if ((node
->type
& CONST_OPTION
) && (value
== NULL
) && (len
== 0))
292 asn1_delete_structure (&node
);
296 if ((type_field (node
->type
) == TYPE_SEQUENCE_OF
) && (value
== NULL
)
300 while ((type_field (p
->type
) == TYPE_TAG
)
301 || (type_field (p
->type
) == TYPE_SIZE
))
305 asn1_delete_structure (&p
->right
);
310 switch (type_field (node
->type
))
313 if (!strcmp (value
, "TRUE"))
315 if (node
->type
& CONST_DEFAULT
)
318 while (type_field (p
->type
) != TYPE_DEFAULT
)
320 if (p
->type
& CONST_TRUE
)
321 _asn1_set_value (node
, NULL
, 0);
323 _asn1_set_value (node
, "T", 1);
326 _asn1_set_value (node
, "T", 1);
328 else if (!strcmp (value
, "FALSE"))
330 if (node
->type
& CONST_DEFAULT
)
333 while (type_field (p
->type
) != TYPE_DEFAULT
)
335 if (p
->type
& CONST_FALSE
)
336 _asn1_set_value (node
, NULL
, 0);
338 _asn1_set_value (node
, "F", 1);
341 _asn1_set_value (node
, "F", 1);
344 return ASN1_VALUE_NOT_VALID
;
347 case TYPE_ENUMERATED
:
350 if ((isdigit (value
[0])) || (value
[0] == '-'))
353 (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT
);
354 if (value_temp
== NULL
)
355 return ASN1_MEM_ALLOC_ERROR
;
357 _asn1_convert_integer (value
, value_temp
,
358 SIZEOF_UNSIGNED_LONG_INT
, &len
);
361 { /* is an identifier like v1 */
362 if (!(node
->type
& CONST_LIST
))
363 return ASN1_VALUE_NOT_VALID
;
367 if (type_field (p
->type
) == TYPE_CONSTANT
)
369 if ((p
->name
) && (!strcmp (p
->name
, value
)))
373 _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT
);
374 if (value_temp
== NULL
)
375 return ASN1_MEM_ALLOC_ERROR
;
377 _asn1_convert_integer (p
->value
,
379 SIZEOF_UNSIGNED_LONG_INT
,
387 return ASN1_VALUE_NOT_VALID
;
392 value_temp
= (unsigned char *) _asn1_malloc (len
);
393 if (value_temp
== NULL
)
394 return ASN1_MEM_ALLOC_ERROR
;
395 memcpy (value_temp
, value
, len
);
399 if (value_temp
[0] & 0x80)
404 if (negative
&& (type_field (node
->type
) == TYPE_ENUMERATED
))
406 _asn1_free (value_temp
);
407 return ASN1_VALUE_NOT_VALID
;
410 for (k
= 0; k
< len
- 1; k
++)
411 if (negative
&& (value_temp
[k
] != 0xFF))
413 else if (!negative
&& value_temp
[k
])
416 if ((negative
&& !(value_temp
[k
] & 0x80)) ||
417 (!negative
&& (value_temp
[k
] & 0x80)))
420 asn1_length_der (len
- k
, NULL
, &len2
);
421 temp
= (unsigned char *) _asn1_malloc (len
- k
+ len2
);
424 _asn1_free (value_temp
);
425 return ASN1_MEM_ALLOC_ERROR
;
428 asn1_octet_der (value_temp
+ k
, len
- k
, temp
, &len2
);
429 _asn1_set_value (node
, temp
, len2
);
434 if (node
->type
& CONST_DEFAULT
)
437 while (type_field (p
->type
) != TYPE_DEFAULT
)
439 if ((isdigit (p
->value
[0])) || (p
->value
[0] == '-'))
442 (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT
);
443 if (default_temp
== NULL
)
445 _asn1_free (value_temp
);
446 return ASN1_MEM_ALLOC_ERROR
;
449 _asn1_convert_integer (p
->value
, default_temp
,
450 SIZEOF_UNSIGNED_LONG_INT
, &len2
);
453 { /* is an identifier like v1 */
454 if (!(node
->type
& CONST_LIST
))
456 _asn1_free (value_temp
);
457 return ASN1_VALUE_NOT_VALID
;
462 if (type_field (p2
->type
) == TYPE_CONSTANT
)
464 if ((p2
->name
) && (!strcmp (p2
->name
, p
->value
)))
468 _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT
);
469 if (default_temp
== NULL
)
471 _asn1_free (value_temp
);
472 return ASN1_MEM_ALLOC_ERROR
;
475 _asn1_convert_integer (p2
->value
,
477 SIZEOF_UNSIGNED_LONG_INT
,
486 _asn1_free (value_temp
);
487 return ASN1_VALUE_NOT_VALID
;
492 if ((len
- k
) == len2
)
494 for (k2
= 0; k2
< len2
; k2
++)
495 if (value_temp
[k
+ k2
] != default_temp
[k2
])
500 _asn1_set_value (node
, NULL
, 0);
502 _asn1_free (default_temp
);
504 _asn1_free (value_temp
);
507 for (k
= 0; k
< strlen (value
); k
++)
508 if ((!isdigit (value
[k
])) && (value
[k
] != '.') && (value
[k
] != '+'))
509 return ASN1_VALUE_NOT_VALID
;
510 if (node
->type
& CONST_DEFAULT
)
513 while (type_field (p
->type
) != TYPE_DEFAULT
)
515 if (!strcmp (value
, p
->value
))
517 _asn1_set_value (node
, NULL
, 0);
521 _asn1_set_value (node
, value
, strlen (value
) + 1);
524 if (node
->type
& CONST_UTC
)
526 if (strlen (value
) < 11)
527 return ASN1_VALUE_NOT_VALID
;
528 for (k
= 0; k
< 10; k
++)
529 if (!isdigit (value
[k
]))
530 return ASN1_VALUE_NOT_VALID
;
531 switch (strlen (value
))
534 if (value
[10] != 'Z')
535 return ASN1_VALUE_NOT_VALID
;
538 if ((!isdigit (value
[10])) || (!isdigit (value
[11])) ||
540 return ASN1_VALUE_NOT_VALID
;
543 if ((value
[10] != '+') && (value
[10] != '-'))
544 return ASN1_VALUE_NOT_VALID
;
545 for (k
= 11; k
< 15; k
++)
546 if (!isdigit (value
[k
]))
547 return ASN1_VALUE_NOT_VALID
;
550 if ((!isdigit (value
[10])) || (!isdigit (value
[11])))
551 return ASN1_VALUE_NOT_VALID
;
552 if ((value
[12] != '+') && (value
[12] != '-'))
553 return ASN1_VALUE_NOT_VALID
;
554 for (k
= 13; k
< 17; k
++)
555 if (!isdigit (value
[k
]))
556 return ASN1_VALUE_NOT_VALID
;
559 return ASN1_VALUE_NOT_FOUND
;
561 _asn1_set_value (node
, value
, strlen (value
) + 1);
564 { /* GENERALIZED TIME */
566 _asn1_set_value (node
, value
, strlen (value
) + 1);
569 case TYPE_OCTET_STRING
:
571 len
= strlen (value
);
572 asn1_length_der (len
, NULL
, &len2
);
573 temp
= (unsigned char *) _asn1_malloc (len
+ len2
);
575 return ASN1_MEM_ALLOC_ERROR
;
577 asn1_octet_der (value
, len
, temp
, &len2
);
578 _asn1_set_value (node
, temp
, len2
);
581 case TYPE_GENERALSTRING
:
583 len
= strlen (value
);
584 asn1_length_der (len
, NULL
, &len2
);
585 temp
= (unsigned char *) _asn1_malloc (len
+ len2
);
587 return ASN1_MEM_ALLOC_ERROR
;
589 asn1_octet_der (value
, len
, temp
, &len2
);
590 _asn1_set_value (node
, temp
, len2
);
593 case TYPE_BIT_STRING
:
595 len
= strlen (value
);
596 asn1_length_der ((len
>> 3) + 2, NULL
, &len2
);
597 temp
= (unsigned char *) _asn1_malloc ((len
>> 3) + 2 + len2
);
599 return ASN1_MEM_ALLOC_ERROR
;
601 asn1_bit_der (value
, len
, temp
, &len2
);
602 _asn1_set_value (node
, temp
, len2
);
609 if (!strcmp (p
->name
, value
))
616 asn1_delete_structure (&p2
);
627 return ASN1_ELEMENT_NOT_FOUND
;
630 asn1_length_der (len
, NULL
, &len2
);
631 temp
= (unsigned char *) _asn1_malloc (len
+ len2
);
633 return ASN1_MEM_ALLOC_ERROR
;
635 asn1_octet_der (value
, len
, temp
, &len2
);
636 _asn1_set_value (node
, temp
, len2
);
639 case TYPE_SEQUENCE_OF
:
641 if (strcmp (value
, "NEW"))
642 return ASN1_VALUE_NOT_VALID
;
643 _asn1_append_sequence_set (node
);
646 return ASN1_ELEMENT_NOT_FOUND
;
654 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
656 if (ptr_size < data_size) { \
657 return ASN1_MEM_ERROR; \
659 memcpy( ptr, data, data_size); \
662 #define PUT_STR_VALUE( ptr, ptr_size, data) \
663 *len = strlen(data) + 1; \
664 if (ptr_size < *len) { \
665 return ASN1_MEM_ERROR; \
667 /* this strcpy is checked */ \
671 #define ADD_STR_VALUE( ptr, ptr_size, data) \
672 *len = strlen(data) + 1; \
673 if (ptr_size < strlen(ptr)+(*len)) { \
674 return ASN1_MEM_ERROR; \
676 /* this strcat is checked */ \
681 * asn1_read_value - Returns the value of one element inside a structure
682 * @root: pointer to a structure.
683 * @name: the name of the element inside a structure that you want to read.
684 * @ivalue: vector that will contain the element's content, must be a
685 * pointer to memory cells already allocated.
686 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
687 * holds the sizeof value.
689 * Returns the value of one element inside a structure.
691 * If an element is OPTIONAL and the function "read_value" returns
692 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
693 * in the der encoding that created the structure. The first element
694 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
697 * INTEGER: VALUE will contain a two's complement form integer.
699 * integer=-1 -> value[0]=0xFF , len=1.
700 * integer=1 -> value[0]=0x01 , len=1.
702 * ENUMERATED: As INTEGER (but only with not negative numbers).
704 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
705 * "FALSE" and LEN=5 or LEN=6.
707 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
708 * each number separated by a dot (i.e. "1.2.3.543.1").
710 * LEN = strlen(VALUE)+1
712 * UTCTime: VALUE will be a null terminated string in one of these
713 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
714 * LEN=strlen(VALUE)+1.
716 * GeneralizedTime: VALUE will be a null terminated string in the
717 * same format used to set the value.
719 * OCTET STRING: VALUE will contain the octet string and LEN will be
720 * the number of octets.
722 * GeneralString: VALUE will contain the generalstring and LEN will
723 * be the number of octets.
725 * BIT STRING: VALUE will contain the bit string organized by bytes
726 * and LEN will be the number of bits.
728 * CHOICE: If NAME indicates a choice type, VALUE will specify the
729 * alternative selected.
731 * ANY: If NAME indicates an any type, VALUE will indicate the DER
732 * encoding of the structure actually used.
736 * ASN1_SUCCESS: Set value OK.
738 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
740 * ASN1_VALUE_NOT_FOUND: There isn't any value for the element selected.
742 * ASN1_MEM_ERROR: The value vector isn't big enough to store the result.
743 * In this case LEN will contain the number of bytes needed.
747 asn1_read_value (ASN1_TYPE root
, const char *name
, void *ivalue
, int *len
)
749 node_asn
*node
, *p
, *p2
;
751 int value_size
= *len
;
752 unsigned char *value
= ivalue
;
754 node
= asn1_find_node (root
, name
);
756 return ASN1_ELEMENT_NOT_FOUND
;
758 if ((type_field (node
->type
) != TYPE_NULL
) &&
759 (type_field (node
->type
) != TYPE_CHOICE
) &&
760 !(node
->type
& CONST_DEFAULT
) && !(node
->type
& CONST_ASSIGN
) &&
761 (node
->value
== NULL
))
762 return ASN1_VALUE_NOT_FOUND
;
764 switch (type_field (node
->type
))
767 PUT_STR_VALUE (value
, value_size
, "NULL");
770 if ((node
->type
& CONST_DEFAULT
) && (node
->value
== NULL
))
773 while (type_field (p
->type
) != TYPE_DEFAULT
)
775 if (p
->type
& CONST_TRUE
)
777 PUT_STR_VALUE (value
, value_size
, "TRUE");
781 PUT_STR_VALUE (value
, value_size
, "FALSE");
784 else if (node
->value
[0] == 'T')
786 PUT_STR_VALUE (value
, value_size
, "TRUE");
790 PUT_STR_VALUE (value
, value_size
, "FALSE");
794 case TYPE_ENUMERATED
:
795 if ((node
->type
& CONST_DEFAULT
) && (node
->value
== NULL
))
798 while (type_field (p
->type
) != TYPE_DEFAULT
)
800 if ((isdigit (p
->value
[0])) || (p
->value
[0] == '-')
801 || (p
->value
[0] == '+'))
803 if (_asn1_convert_integer
804 (p
->value
, value
, value_size
, len
) != ASN1_SUCCESS
)
805 return ASN1_MEM_ERROR
;
808 { /* is an identifier like v1 */
812 if (type_field (p2
->type
) == TYPE_CONSTANT
)
814 if ((p2
->name
) && (!strcmp (p2
->name
, p
->value
)))
816 if (_asn1_convert_integer
817 (p2
->value
, value
, value_size
,
818 len
) != ASN1_SUCCESS
)
819 return ASN1_MEM_ERROR
;
830 if (asn1_get_octet_der
831 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
832 len
) != ASN1_SUCCESS
)
833 return ASN1_MEM_ERROR
;
837 if (node
->type
& CONST_ASSIGN
)
843 if (type_field (p
->type
) == TYPE_CONSTANT
)
845 ADD_STR_VALUE (value
, value_size
, p
->value
);
848 ADD_STR_VALUE (value
, value_size
, ".");
853 *len
= strlen (value
) + 1;
855 else if ((node
->type
& CONST_DEFAULT
) && (node
->value
== NULL
))
858 while (type_field (p
->type
) != TYPE_DEFAULT
)
860 PUT_STR_VALUE (value
, value_size
, p
->value
);
864 PUT_STR_VALUE (value
, value_size
, node
->value
);
868 PUT_STR_VALUE (value
, value_size
, node
->value
);
870 case TYPE_OCTET_STRING
:
872 if (asn1_get_octet_der
873 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
874 len
) != ASN1_SUCCESS
)
875 return ASN1_MEM_ERROR
;
877 case TYPE_GENERALSTRING
:
879 if (asn1_get_octet_der
880 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
881 len
) != ASN1_SUCCESS
)
882 return ASN1_MEM_ERROR
;
884 case TYPE_BIT_STRING
:
887 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
888 len
) != ASN1_SUCCESS
)
889 return ASN1_MEM_ERROR
;
892 PUT_STR_VALUE (value
, value_size
, node
->down
->name
);
896 len2
= asn1_get_length_der (node
->value
, node
->value_len
, &len3
);
898 return ASN1_DER_ERROR
;
899 PUT_VALUE (value
, value_size
, node
->value
+ len3
, len2
);
902 return ASN1_ELEMENT_NOT_FOUND
;
910 * asn1_read_tag - Returns the TAG of one element inside a structure
911 * @root: pointer to a structure
912 * @name: the name of the element inside a structure.
913 * @tagValue: variable that will contain the TAG value.
914 * @classValue: variable that will specify the TAG type.
916 * Returns the TAG and the CLASS of one element inside a structure.
917 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
918 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
919 * %ASN1_CLASS_CONTEXT_SPECIFIC.
923 * ASN1_SUCCESS: Set value OK.
925 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
929 asn1_read_tag (node_asn
* root
, const char *name
, int *tagValue
,
932 node_asn
*node
, *p
, *pTag
;
934 node
= asn1_find_node (root
, name
);
936 return ASN1_ELEMENT_NOT_FOUND
;
940 /* pTag will points to the IMPLICIT TAG */
942 if (node
->type
& CONST_TAG
)
946 if (type_field (p
->type
) == TYPE_TAG
)
948 if ((p
->type
& CONST_IMPLICIT
) && (pTag
== NULL
))
950 else if (p
->type
& CONST_EXPLICIT
)
959 *tagValue
= strtoul (pTag
->value
, NULL
, 10);
961 if (pTag
->type
& CONST_APPLICATION
)
962 *classValue
= ASN1_CLASS_APPLICATION
;
963 else if (pTag
->type
& CONST_UNIVERSAL
)
964 *classValue
= ASN1_CLASS_UNIVERSAL
;
965 else if (pTag
->type
& CONST_PRIVATE
)
966 *classValue
= ASN1_CLASS_PRIVATE
;
968 *classValue
= ASN1_CLASS_CONTEXT_SPECIFIC
;
972 *classValue
= ASN1_CLASS_UNIVERSAL
;
974 switch (type_field (node
->type
))
977 *tagValue
= ASN1_TAG_NULL
;
980 *tagValue
= ASN1_TAG_BOOLEAN
;
983 *tagValue
= ASN1_TAG_INTEGER
;
985 case TYPE_ENUMERATED
:
986 *tagValue
= ASN1_TAG_ENUMERATED
;
989 *tagValue
= ASN1_TAG_OBJECT_ID
;
992 if (node
->type
& CONST_UTC
)
994 *tagValue
= ASN1_TAG_UTCTime
;
997 *tagValue
= ASN1_TAG_GENERALIZEDTime
;
999 case TYPE_OCTET_STRING
:
1000 *tagValue
= ASN1_TAG_OCTET_STRING
;
1002 case TYPE_GENERALSTRING
:
1003 *tagValue
= ASN1_TAG_GENERALSTRING
;
1005 case TYPE_BIT_STRING
:
1006 *tagValue
= ASN1_TAG_BIT_STRING
;
1009 case TYPE_SEQUENCE_OF
:
1010 *tagValue
= ASN1_TAG_SEQUENCE
;
1014 *tagValue
= ASN1_TAG_SET
;
1026 return ASN1_SUCCESS
;