2 * Copyright (C) 2000-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
22 /*****************************************************/
24 /* Description: Functions with the read and write */
26 /*****************************************************/
30 #include "parser_aux.h"
32 #include "structure.h"
37 _asn1_hierarchical_name (asn1_node 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 unsigned char *value
, unsigned char *value_out
,
79 int value_out_size
, int *len
)
82 unsigned char val
[SIZEOF_UNSIGNED_LONG_INT
];
86 valtmp
= _asn1_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 printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value
, *len
);
120 for (k
= 0; k
< SIZEOF_UNSIGNED_LONG_INT
; k
++)
121 printf (", vOut[%d]=%d", k
, value_out
[k
]);
130 _asn1_append_sequence_set (asn1_node node
)
136 if (!node
|| !(node
->down
))
137 return ASN1_GENERIC_ERROR
;
140 while ((type_field (p
->type
) == ASN1_ETYPE_TAG
)
141 || (type_field (p
->type
) == ASN1_ETYPE_SIZE
))
143 p2
= _asn1_copy_structure3 (p
);
146 _asn1_set_right (p
, p2
);
149 _asn1_str_cpy (temp
, sizeof (temp
), "?1");
152 n
= strtol (p
->name
+ 1, NULL
, 0);
155 _asn1_ltostr (n
, temp
+ 1);
157 _asn1_set_name (p2
, temp
);
158 /* p2->type |= CONST_OPTION; */
166 * @node_root: pointer to a structure
167 * @name: the name of the element inside the structure that you want to set.
168 * @ivalue: vector used to specify the value to set. If len is >0,
169 * VALUE must be a two's complement form integer. if len=0 *VALUE
170 * must be a null terminated string with an integer value.
171 * @len: number of bytes of *value to use to set the value:
172 * value[0]..value[len-1] or 0 if value is a null terminated string
174 * Set the value of one element inside a structure.
176 * If an element is OPTIONAL and you want to delete it, you must use
177 * the value=NULL and len=0. Using "pkix.asn":
179 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
182 * Description for each type:
184 * INTEGER: VALUE must contain a two's complement form integer.
186 * value[0]=0xFF , len=1 -> integer=-1.
187 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
188 * value[0]=0x01 , len=1 -> integer= 1.
189 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
190 * value="123" , len=0 -> integer= 123.
192 * ENUMERATED: As INTEGER (but only with not negative numbers).
194 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
195 * "FALSE" and LEN != 0.
197 * value="TRUE" , len=1 -> boolean=TRUE.
198 * value="FALSE" , len=1 -> boolean=FALSE.
200 * OBJECT IDENTIFIER: VALUE must be a null terminated string with
201 * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
203 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
205 * UTCTime: VALUE must be a null terminated string in one of these
206 * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
207 * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
208 * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
210 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
211 * at 12h 00m Greenwich Mean Time
213 * GeneralizedTime: VALUE must be in one of this format:
214 * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
215 * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
216 * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
217 * indicates the seconds with any precision like "10.1" or "01.02".
220 * value="2001010112001.12-0700" , len=1 -> time=Jannuary
221 * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
223 * OCTET STRING: VALUE contains the octet string and LEN is the
226 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
227 * len=3 -> three bytes octet string
229 * GeneralString: VALUE contains the generalstring and LEN is the
232 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
233 * len=3 -> three bytes generalstring
235 * BIT STRING: VALUE contains the bit string organized by bytes and
236 * LEN is the number of bits.
238 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
241 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
242 * the alternatives with a null terminated string. LEN != 0. Using
245 * result=asn1_write_value(cert,
246 * "certificate1.tbsCertificate.subject", "rdnSequence",
249 * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
251 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
252 * LEN != 0. With this instruction another element is appended in
253 * the sequence. The name of this element will be "?1" if it's the
254 * first one, "?2" for the second and so on.
258 * result=asn1_write_value(cert,
259 * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
261 * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
263 * result=asn1_write_value(cert,
264 * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
266 * Returns: %ASN1_SUCCESS if the value was set,
267 * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
268 * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
271 asn1_write_value (asn1_node node_root
, const char *name
,
272 const void *ivalue
, int len
)
274 asn1_node node
, p
, p2
;
275 unsigned char *temp
, *value_temp
= NULL
, *default_temp
= NULL
;
276 int len2
, k
, k2
, negative
;
278 const unsigned char *value
= ivalue
;
281 node
= asn1_find_node (node_root
, name
);
283 return ASN1_ELEMENT_NOT_FOUND
;
285 if ((node
->type
& CONST_OPTION
) && (value
== NULL
) && (len
== 0))
287 asn1_delete_structure (&node
);
291 type
= type_field(node
->type
);
293 if ((type
== ASN1_ETYPE_SEQUENCE_OF
) && (value
== NULL
)
297 while ((type_field (p
->type
) == ASN1_ETYPE_TAG
)
298 || (type_field (p
->type
) == ASN1_ETYPE_SIZE
))
302 asn1_delete_structure (&p
->right
);
309 case ASN1_ETYPE_BOOLEAN
:
310 if (!_asn1_strcmp (value
, "TRUE"))
312 if (node
->type
& CONST_DEFAULT
)
315 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
317 if (p
->type
& CONST_TRUE
)
318 _asn1_set_value (node
, NULL
, 0);
320 _asn1_set_value (node
, "T", 1);
323 _asn1_set_value (node
, "T", 1);
325 else if (!_asn1_strcmp (value
, "FALSE"))
327 if (node
->type
& CONST_DEFAULT
)
330 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
332 if (p
->type
& CONST_FALSE
)
333 _asn1_set_value (node
, NULL
, 0);
335 _asn1_set_value (node
, "F", 1);
338 _asn1_set_value (node
, "F", 1);
341 return ASN1_VALUE_NOT_VALID
;
343 case ASN1_ETYPE_INTEGER
:
344 case ASN1_ETYPE_ENUMERATED
:
347 if ((isdigit (value
[0])) || (value
[0] == '-'))
349 value_temp
= malloc (SIZEOF_UNSIGNED_LONG_INT
);
350 if (value_temp
== NULL
)
351 return ASN1_MEM_ALLOC_ERROR
;
353 _asn1_convert_integer (value
, value_temp
,
354 SIZEOF_UNSIGNED_LONG_INT
, &len
);
357 { /* is an identifier like v1 */
358 if (!(node
->type
& CONST_LIST
))
359 return ASN1_VALUE_NOT_VALID
;
363 if (type_field (p
->type
) == ASN1_ETYPE_CONSTANT
)
365 if (!_asn1_strcmp (p
->name
, value
))
367 value_temp
= malloc (SIZEOF_UNSIGNED_LONG_INT
);
368 if (value_temp
== NULL
)
369 return ASN1_MEM_ALLOC_ERROR
;
371 _asn1_convert_integer (p
->value
,
373 SIZEOF_UNSIGNED_LONG_INT
,
381 return ASN1_VALUE_NOT_VALID
;
386 value_temp
= malloc (len
);
387 if (value_temp
== NULL
)
388 return ASN1_MEM_ALLOC_ERROR
;
389 memcpy (value_temp
, value
, len
);
392 if (value_temp
[0] & 0x80)
397 if (negative
&& (type_field (node
->type
) == ASN1_ETYPE_ENUMERATED
))
400 return ASN1_VALUE_NOT_VALID
;
403 for (k
= 0; k
< len
- 1; k
++)
404 if (negative
&& (value_temp
[k
] != 0xFF))
406 else if (!negative
&& value_temp
[k
])
409 if ((negative
&& !(value_temp
[k
] & 0x80)) ||
410 (!negative
&& (value_temp
[k
] & 0x80)))
413 _asn1_set_value_lv (node
, value_temp
+ k
, len
- k
);
415 if (node
->type
& CONST_DEFAULT
)
418 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
420 if ((isdigit (p
->value
[0])) || (p
->value
[0] == '-'))
422 default_temp
= malloc (SIZEOF_UNSIGNED_LONG_INT
);
423 if (default_temp
== NULL
)
426 return ASN1_MEM_ALLOC_ERROR
;
429 _asn1_convert_integer (p
->value
, default_temp
,
430 SIZEOF_UNSIGNED_LONG_INT
, &len2
);
433 { /* is an identifier like v1 */
434 if (!(node
->type
& CONST_LIST
))
437 return ASN1_VALUE_NOT_VALID
;
442 if (type_field (p2
->type
) == ASN1_ETYPE_CONSTANT
)
444 if (!_asn1_strcmp (p2
->name
, p
->value
))
446 default_temp
= malloc (SIZEOF_UNSIGNED_LONG_INT
);
447 if (default_temp
== NULL
)
450 return ASN1_MEM_ALLOC_ERROR
;
453 _asn1_convert_integer (p2
->value
,
455 SIZEOF_UNSIGNED_LONG_INT
,
465 return ASN1_VALUE_NOT_VALID
;
470 if ((len
- k
) == len2
)
472 for (k2
= 0; k2
< len2
; k2
++)
473 if (value_temp
[k
+ k2
] != default_temp
[k2
])
478 _asn1_set_value (node
, NULL
, 0);
484 case ASN1_ETYPE_OBJECT_ID
:
485 for (i
= 0; i
< _asn1_strlen (value
); i
++)
486 if ((!isdigit (value
[i
])) && (value
[i
] != '.') && (value
[i
] != '+'))
487 return ASN1_VALUE_NOT_VALID
;
488 if (node
->type
& CONST_DEFAULT
)
491 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
493 if (!_asn1_strcmp (value
, p
->value
))
495 _asn1_set_value (node
, NULL
, 0);
499 _asn1_set_value (node
, value
, _asn1_strlen (value
) + 1);
501 case ASN1_ETYPE_UTC_TIME
:
503 len
= _asn1_strlen(value
);
505 return ASN1_VALUE_NOT_VALID
;
506 for (k
= 0; k
< 10; k
++)
507 if (!isdigit (value
[k
]))
508 return ASN1_VALUE_NOT_VALID
;
512 if (value
[10] != 'Z')
513 return ASN1_VALUE_NOT_VALID
;
516 if ((!isdigit (value
[10])) || (!isdigit (value
[11])) ||
518 return ASN1_VALUE_NOT_VALID
;
521 if ((value
[10] != '+') && (value
[10] != '-'))
522 return ASN1_VALUE_NOT_VALID
;
523 for (k
= 11; k
< 15; k
++)
524 if (!isdigit (value
[k
]))
525 return ASN1_VALUE_NOT_VALID
;
528 if ((!isdigit (value
[10])) || (!isdigit (value
[11])))
529 return ASN1_VALUE_NOT_VALID
;
530 if ((value
[12] != '+') && (value
[12] != '-'))
531 return ASN1_VALUE_NOT_VALID
;
532 for (k
= 13; k
< 17; k
++)
533 if (!isdigit (value
[k
]))
534 return ASN1_VALUE_NOT_VALID
;
537 return ASN1_VALUE_NOT_FOUND
;
539 _asn1_set_value (node
, value
, len
);
542 case ASN1_ETYPE_GENERALIZED_TIME
:
543 len
= _asn1_strlen(value
);
544 _asn1_set_value (node
, value
, len
);
546 case ASN1_ETYPE_OCTET_STRING
:
547 case ASN1_ETYPE_GENERALSTRING
:
548 case ASN1_ETYPE_NUMERIC_STRING
:
549 case ASN1_ETYPE_IA5_STRING
:
550 case ASN1_ETYPE_TELETEX_STRING
:
551 case ASN1_ETYPE_PRINTABLE_STRING
:
552 case ASN1_ETYPE_UNIVERSAL_STRING
:
553 case ASN1_ETYPE_BMP_STRING
:
554 case ASN1_ETYPE_UTF8_STRING
:
555 case ASN1_ETYPE_VISIBLE_STRING
:
557 len
= _asn1_strlen (value
);
558 _asn1_set_value_lv (node
, value
, len
);
560 case ASN1_ETYPE_BIT_STRING
:
562 len
= _asn1_strlen (value
);
563 asn1_length_der ((len
>> 3) + 2, NULL
, &len2
);
564 temp
= malloc ((len
>> 3) + 2 + len2
);
566 return ASN1_MEM_ALLOC_ERROR
;
568 asn1_bit_der (value
, len
, temp
, &len2
);
569 _asn1_set_value_m (node
, temp
, len2
);
572 case ASN1_ETYPE_CHOICE
:
576 if (!_asn1_strcmp (p
->name
, value
))
583 asn1_delete_structure (&p2
);
594 return ASN1_ELEMENT_NOT_FOUND
;
597 _asn1_set_value_lv (node
, value
, len
);
599 case ASN1_ETYPE_SEQUENCE_OF
:
600 case ASN1_ETYPE_SET_OF
:
601 if (_asn1_strcmp (value
, "NEW"))
602 return ASN1_VALUE_NOT_VALID
;
603 _asn1_append_sequence_set (node
);
606 return ASN1_ELEMENT_NOT_FOUND
;
614 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
616 if (ptr_size < data_size) { \
617 return ASN1_MEM_ERROR; \
619 memcpy( ptr, data, data_size); \
622 #define PUT_STR_VALUE( ptr, ptr_size, data) \
623 *len = _asn1_strlen(data) + 1; \
624 if (ptr_size < *len) { \
625 return ASN1_MEM_ERROR; \
627 /* this strcpy is checked */ \
628 _asn1_strcpy(ptr, data); \
631 #define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \
632 *len = data_size + 1; \
633 if (ptr_size < *len) { \
634 return ASN1_MEM_ERROR; \
636 /* this strcpy is checked */ \
637 memcpy(ptr, data, data_size); \
638 ptr[data_size] = 0; \
641 #define ADD_STR_VALUE( ptr, ptr_size, data) \
642 *len = (int) _asn1_strlen(data) + 1; \
643 if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
644 return ASN1_MEM_ERROR; \
646 /* this strcat is checked */ \
647 _asn1_strcat(ptr, data); \
652 * @root: pointer to a structure.
653 * @name: the name of the element inside a structure that you want to read.
654 * @ivalue: vector that will contain the element's content, must be a
655 * pointer to memory cells already allocated.
656 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
657 * holds the sizeof value.
659 * Returns the value of one element inside a structure.
661 * If an element is OPTIONAL and the function "read_value" returns
662 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
663 * in the der encoding that created the structure. The first element
664 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
667 * INTEGER: VALUE will contain a two's complement form integer.
669 * integer=-1 -> value[0]=0xFF , len=1.
670 * integer=1 -> value[0]=0x01 , len=1.
672 * ENUMERATED: As INTEGER (but only with not negative numbers).
674 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
675 * "FALSE" and LEN=5 or LEN=6.
677 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
678 * each number separated by a dot (i.e. "1.2.3.543.1").
680 * LEN = strlen(VALUE)+1
682 * UTCTime: VALUE will be a null terminated string in one of these
683 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
684 * LEN=strlen(VALUE)+1.
686 * GeneralizedTime: VALUE will be a null terminated string in the
687 * same format used to set the value.
689 * OCTET STRING: VALUE will contain the octet string and LEN will be
690 * the number of octets.
692 * GeneralString: VALUE will contain the generalstring and LEN will
693 * be the number of octets.
695 * BIT STRING: VALUE will contain the bit string organized by bytes
696 * and LEN will be the number of bits.
698 * CHOICE: If NAME indicates a choice type, VALUE will specify the
699 * alternative selected.
701 * ANY: If NAME indicates an any type, VALUE will indicate the DER
702 * encoding of the structure actually used.
704 * Returns: %ASN1_SUCCESS if value is returned,
705 * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
706 * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
707 * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
708 * to store the result, and in this case @len will contain the number of
712 asn1_read_value (asn1_node root
, const char *name
, void *ivalue
, int *len
)
714 return asn1_read_value_type( root
, name
, ivalue
, len
, NULL
);
718 * asn1_read_value_type:
719 * @root: pointer to a structure.
720 * @name: the name of the element inside a structure that you want to read.
721 * @ivalue: vector that will contain the element's content, must be a
722 * pointer to memory cells already allocated.
723 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
724 * holds the sizeof value.
725 * @etype: The type of the value read (ASN1_ETYPE)
727 * Returns the value of one element inside a structure.
729 * If an element is OPTIONAL and the function "read_value" returns
730 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
731 * in the der encoding that created the structure. The first element
732 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
735 * INTEGER: VALUE will contain a two's complement form integer.
737 * integer=-1 -> value[0]=0xFF , len=1.
738 * integer=1 -> value[0]=0x01 , len=1.
740 * ENUMERATED: As INTEGER (but only with not negative numbers).
742 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
743 * "FALSE" and LEN=5 or LEN=6.
745 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
746 * each number separated by a dot (i.e. "1.2.3.543.1").
748 * LEN = strlen(VALUE)+1
750 * UTCTime: VALUE will be a null terminated string in one of these
751 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
752 * LEN=strlen(VALUE)+1.
754 * GeneralizedTime: VALUE will be a null terminated string in the
755 * same format used to set the value.
757 * OCTET STRING: VALUE will contain the octet string and LEN will be
758 * the number of octets.
760 * GeneralString: VALUE will contain the generalstring and LEN will
761 * be the number of octets.
763 * BIT STRING: VALUE will contain the bit string organized by bytes
764 * and LEN will be the number of bits.
766 * CHOICE: If NAME indicates a choice type, VALUE will specify the
767 * alternative selected.
769 * ANY: If NAME indicates an any type, VALUE will indicate the DER
770 * encoding of the structure actually used.
772 * Returns: %ASN1_SUCCESS if value is returned,
773 * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
774 * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
775 * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
776 * to store the result, and in this case @len will contain the number of
780 asn1_read_value_type (asn1_node root
, const char *name
, void *ivalue
, int *len
,
783 asn1_node node
, p
, p2
;
785 int value_size
= *len
;
786 unsigned char *value
= ivalue
;
789 node
= asn1_find_node (root
, name
);
791 return ASN1_ELEMENT_NOT_FOUND
;
793 type
= type_field (node
->type
);
795 if ((type
!= ASN1_ETYPE_NULL
) &&
796 (type
!= ASN1_ETYPE_CHOICE
) &&
797 !(node
->type
& CONST_DEFAULT
) && !(node
->type
& CONST_ASSIGN
) &&
798 (node
->value
== NULL
))
799 return ASN1_VALUE_NOT_FOUND
;
805 case ASN1_ETYPE_NULL
:
806 PUT_STR_VALUE (value
, value_size
, "NULL");
808 case ASN1_ETYPE_BOOLEAN
:
809 if ((node
->type
& CONST_DEFAULT
) && (node
->value
== NULL
))
812 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
814 if (p
->type
& CONST_TRUE
)
816 PUT_STR_VALUE (value
, value_size
, "TRUE");
820 PUT_STR_VALUE (value
, value_size
, "FALSE");
823 else if (node
->value
[0] == 'T')
825 PUT_STR_VALUE (value
, value_size
, "TRUE");
829 PUT_STR_VALUE (value
, value_size
, "FALSE");
832 case ASN1_ETYPE_INTEGER
:
833 case ASN1_ETYPE_ENUMERATED
:
834 if ((node
->type
& CONST_DEFAULT
) && (node
->value
== NULL
))
837 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
839 if ((isdigit (p
->value
[0])) || (p
->value
[0] == '-')
840 || (p
->value
[0] == '+'))
842 if (_asn1_convert_integer
843 (p
->value
, value
, value_size
, len
) != ASN1_SUCCESS
)
844 return ASN1_MEM_ERROR
;
847 { /* is an identifier like v1 */
851 if (type_field (p2
->type
) == ASN1_ETYPE_CONSTANT
)
853 if (!_asn1_strcmp (p2
->name
, p
->value
))
855 if (_asn1_convert_integer
856 (p2
->value
, value
, value_size
,
857 len
) != ASN1_SUCCESS
)
858 return ASN1_MEM_ERROR
;
869 if (asn1_get_octet_der
870 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
871 len
) != ASN1_SUCCESS
)
872 return ASN1_MEM_ERROR
;
875 case ASN1_ETYPE_OBJECT_ID
:
876 if (node
->type
& CONST_ASSIGN
)
882 if (type_field (p
->type
) == ASN1_ETYPE_CONSTANT
)
884 ADD_STR_VALUE (value
, value_size
, p
->value
);
887 ADD_STR_VALUE (value
, value_size
, ".");
892 *len
= _asn1_strlen (value
) + 1;
894 else if ((node
->type
& CONST_DEFAULT
) && (node
->value
== NULL
))
897 while (type_field (p
->type
) != ASN1_ETYPE_DEFAULT
)
899 PUT_STR_VALUE (value
, value_size
, p
->value
);
903 PUT_STR_VALUE (value
, value_size
, node
->value
);
906 case ASN1_ETYPE_GENERALIZED_TIME
:
907 case ASN1_ETYPE_UTC_TIME
:
908 PUT_AS_STR_VALUE (value
, value_size
, node
->value
, node
->value_len
);
910 case ASN1_ETYPE_OCTET_STRING
:
911 case ASN1_ETYPE_GENERALSTRING
:
912 case ASN1_ETYPE_NUMERIC_STRING
:
913 case ASN1_ETYPE_IA5_STRING
:
914 case ASN1_ETYPE_TELETEX_STRING
:
915 case ASN1_ETYPE_PRINTABLE_STRING
:
916 case ASN1_ETYPE_UNIVERSAL_STRING
:
917 case ASN1_ETYPE_BMP_STRING
:
918 case ASN1_ETYPE_UTF8_STRING
:
919 case ASN1_ETYPE_VISIBLE_STRING
:
921 if (asn1_get_octet_der
922 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
923 len
) != ASN1_SUCCESS
)
924 return ASN1_MEM_ERROR
;
926 case ASN1_ETYPE_BIT_STRING
:
929 (node
->value
, node
->value_len
, &len2
, value
, value_size
,
930 len
) != ASN1_SUCCESS
)
931 return ASN1_MEM_ERROR
;
933 case ASN1_ETYPE_CHOICE
:
934 PUT_STR_VALUE (value
, value_size
, node
->down
->name
);
938 len2
= asn1_get_length_der (node
->value
, node
->value_len
, &len3
);
940 return ASN1_DER_ERROR
;
941 PUT_VALUE (value
, value_size
, node
->value
+ len3
, len2
);
944 return ASN1_ELEMENT_NOT_FOUND
;
953 * @root: pointer to a structure
954 * @name: the name of the element inside a structure.
955 * @tagValue: variable that will contain the TAG value.
956 * @classValue: variable that will specify the TAG type.
958 * Returns the TAG and the CLASS of one element inside a structure.
959 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
960 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
961 * %ASN1_CLASS_CONTEXT_SPECIFIC.
963 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
964 * @name is not a valid element.
967 asn1_read_tag (asn1_node root
, const char *name
, int *tagValue
,
970 asn1_node node
, p
, pTag
;
972 node
= asn1_find_node (root
, name
);
974 return ASN1_ELEMENT_NOT_FOUND
;
978 /* pTag will points to the IMPLICIT TAG */
980 if (node
->type
& CONST_TAG
)
984 if (type_field (p
->type
) == ASN1_ETYPE_TAG
)
986 if ((p
->type
& CONST_IMPLICIT
) && (pTag
== NULL
))
988 else if (p
->type
& CONST_EXPLICIT
)
997 *tagValue
= _asn1_strtoul (pTag
->value
, NULL
, 10);
999 if (pTag
->type
& CONST_APPLICATION
)
1000 *classValue
= ASN1_CLASS_APPLICATION
;
1001 else if (pTag
->type
& CONST_UNIVERSAL
)
1002 *classValue
= ASN1_CLASS_UNIVERSAL
;
1003 else if (pTag
->type
& CONST_PRIVATE
)
1004 *classValue
= ASN1_CLASS_PRIVATE
;
1006 *classValue
= ASN1_CLASS_CONTEXT_SPECIFIC
;
1010 unsigned type
= type_field (node
->type
);
1011 *classValue
= ASN1_CLASS_UNIVERSAL
;
1015 CASE_HANDLED_ETYPES
:
1016 *tagValue
= _asn1_tags
[type
].tag
;
1018 case ASN1_ETYPE_TAG
:
1019 case ASN1_ETYPE_CHOICE
:
1020 case ASN1_ETYPE_ANY
:
1028 return ASN1_SUCCESS
;
1032 * asn1_read_node_value:
1033 * @node: pointer to a node.
1034 * @data: a point to a asn1_data_node_st
1036 * Returns the value a data node inside a asn1_node structure.
1037 * The data returned should be handled as constant values.
1039 * Returns: %ASN1_SUCCESS if the node exists.
1041 int asn1_read_node_value (asn1_node node
, asn1_data_node_st
* data
)
1043 data
->name
= node
->name
;
1044 data
->value
= node
->value
;
1045 data
->value_len
= node
->value_len
;
1046 data
->type
= type_field(node
->type
);
1048 return ASN1_SUCCESS
;