Add credits.
[libtasn1.git] / lib / element.c
blob703276c809d28db04a589dd2ca26eba45c072492
1 /*
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
20 * 02110-1301, USA
23 /*****************************************************/
24 /* File: element.c */
25 /* Description: Functions with the read and write */
26 /* functions. */
27 /*****************************************************/
30 #include <int.h>
31 #include <errors.h>
32 #include "parser_aux.h"
33 #include <gstr.h>
34 #include "structure.h"
36 void
37 _asn1_hierarchical_name (node_asn * node, char *name, int name_size)
39 node_asn *p;
40 char tmp_name[64];
42 p = node;
44 name[0] = 0;
46 while (p != NULL)
48 if (p->name != NULL)
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);
58 if (name[0] == 0)
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. */
69 /* Parameters: */
70 /* value: null terminated string to convert. */
71 /* value_out: convertion result (memory must be already */
72 /* allocated). */
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 /******************************************************************/
77 asn1_retCode
78 _asn1_convert_integer (const char *value, unsigned char *value_out,
79 int value_out_size, int *len)
81 char negative;
82 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
83 long valtmp;
84 int k, k2;
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;
93 if (val[0] & 0x80)
94 negative = 1;
95 else
96 negative = 0;
98 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
100 if (negative && (val[k] != 0xFF))
101 break;
102 else if (!negative && val[k])
103 break;
106 if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
107 k--;
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");
124 #endif
127 return ASN1_SUCCESS;
132 _asn1_append_sequence_set (node_asn * node)
134 node_asn *p, *p2;
135 char temp[10];
136 long n;
138 if (!node || !(node->down))
139 return ASN1_GENERIC_ERROR;
141 p = node->down;
142 while ((type_field (p->type) == TYPE_TAG)
143 || (type_field (p->type) == TYPE_SIZE))
144 p = p->right;
145 p2 = _asn1_copy_structure3 (p);
146 while (p->right)
147 p = p->right;
148 _asn1_set_right (p, p2);
150 if (p->name == NULL)
151 _asn1_str_cpy (temp, sizeof (temp), "?1");
152 else
154 n = strtol (p->name + 1, NULL, 0);
155 n++;
156 temp[0] = '?';
157 _asn1_ltostr (n, temp + 1);
159 _asn1_set_name (p2, temp);
160 /* p2->type |= CONST_OPTION; */
162 return ASN1_SUCCESS;
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",
182 * NULL, 0);
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".
220 * LEN != 0
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
226 * number of octets.
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
232 * number of octets.
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
241 * bits)
243 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
244 * the alternatives with a null terminated string. LEN != 0. Using
245 * "pkix.asn"\:
247 * result=asn1_write_value(cert,
248 * "certificate1.tbsCertificate.subject", "rdnSequence",
249 * 1);
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.
258 * Using "pkix.asn"\:
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);
268 * Returns:
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.
277 asn1_retCode
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);
287 if (node == NULL)
288 return ASN1_ELEMENT_NOT_FOUND;
290 if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
292 asn1_delete_structure (&node);
293 return ASN1_SUCCESS;
296 if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
297 && (len == 0))
299 p = node->down;
300 while ((type_field (p->type) == TYPE_TAG)
301 || (type_field (p->type) == TYPE_SIZE))
302 p = p->right;
304 while (p->right)
305 asn1_delete_structure (&p->right);
307 return ASN1_SUCCESS;
310 switch (type_field (node->type))
312 case TYPE_BOOLEAN:
313 if (!strcmp (value, "TRUE"))
315 if (node->type & CONST_DEFAULT)
317 p = node->down;
318 while (type_field (p->type) != TYPE_DEFAULT)
319 p = p->right;
320 if (p->type & CONST_TRUE)
321 _asn1_set_value (node, NULL, 0);
322 else
323 _asn1_set_value (node, "T", 1);
325 else
326 _asn1_set_value (node, "T", 1);
328 else if (!strcmp (value, "FALSE"))
330 if (node->type & CONST_DEFAULT)
332 p = node->down;
333 while (type_field (p->type) != TYPE_DEFAULT)
334 p = p->right;
335 if (p->type & CONST_FALSE)
336 _asn1_set_value (node, NULL, 0);
337 else
338 _asn1_set_value (node, "F", 1);
340 else
341 _asn1_set_value (node, "F", 1);
343 else
344 return ASN1_VALUE_NOT_VALID;
345 break;
346 case TYPE_INTEGER:
347 case TYPE_ENUMERATED:
348 if (len == 0)
350 if ((isdigit (value[0])) || (value[0] == '-'))
352 value_temp =
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);
360 else
361 { /* is an identifier like v1 */
362 if (!(node->type & CONST_LIST))
363 return ASN1_VALUE_NOT_VALID;
364 p = node->down;
365 while (p)
367 if (type_field (p->type) == TYPE_CONSTANT)
369 if ((p->name) && (!strcmp (p->name, value)))
371 value_temp =
372 (unsigned char *)
373 _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
374 if (value_temp == NULL)
375 return ASN1_MEM_ALLOC_ERROR;
377 _asn1_convert_integer (p->value,
378 value_temp,
379 SIZEOF_UNSIGNED_LONG_INT,
380 &len);
381 break;
384 p = p->right;
386 if (p == NULL)
387 return ASN1_VALUE_NOT_VALID;
390 else
391 { /* len != 0 */
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)
400 negative = 1;
401 else
402 negative = 0;
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))
412 break;
413 else if (!negative && value_temp[k])
414 break;
416 if ((negative && !(value_temp[k] & 0x80)) ||
417 (!negative && (value_temp[k] & 0x80)))
418 k--;
420 asn1_length_der (len - k, NULL, &len2);
421 temp = (unsigned char *) _asn1_malloc (len - k + len2);
422 if (temp == NULL)
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);
431 _asn1_free (temp);
434 if (node->type & CONST_DEFAULT)
436 p = node->down;
437 while (type_field (p->type) != TYPE_DEFAULT)
438 p = p->right;
439 if ((isdigit (p->value[0])) || (p->value[0] == '-'))
441 default_temp =
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);
452 else
453 { /* is an identifier like v1 */
454 if (!(node->type & CONST_LIST))
456 _asn1_free (value_temp);
457 return ASN1_VALUE_NOT_VALID;
459 p2 = node->down;
460 while (p2)
462 if (type_field (p2->type) == TYPE_CONSTANT)
464 if ((p2->name) && (!strcmp (p2->name, p->value)))
466 default_temp =
467 (unsigned char *)
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,
476 default_temp,
477 SIZEOF_UNSIGNED_LONG_INT,
478 &len2);
479 break;
482 p2 = p2->right;
484 if (p2 == NULL)
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])
497 break;
499 if (k2 == len2)
500 _asn1_set_value (node, NULL, 0);
502 _asn1_free (default_temp);
504 _asn1_free (value_temp);
505 break;
506 case TYPE_OBJECT_ID:
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)
512 p = node->down;
513 while (type_field (p->type) != TYPE_DEFAULT)
514 p = p->right;
515 if (!strcmp (value, p->value))
517 _asn1_set_value (node, NULL, 0);
518 break;
521 _asn1_set_value (node, value, strlen (value) + 1);
522 break;
523 case TYPE_TIME:
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))
533 case 11:
534 if (value[10] != 'Z')
535 return ASN1_VALUE_NOT_VALID;
536 break;
537 case 13:
538 if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
539 (value[12] != 'Z'))
540 return ASN1_VALUE_NOT_VALID;
541 break;
542 case 15:
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;
548 break;
549 case 17:
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;
557 break;
558 default:
559 return ASN1_VALUE_NOT_FOUND;
561 _asn1_set_value (node, value, strlen (value) + 1);
563 else
564 { /* GENERALIZED TIME */
565 if (value)
566 _asn1_set_value (node, value, strlen (value) + 1);
568 break;
569 case TYPE_OCTET_STRING:
570 if (len == 0)
571 len = strlen (value);
572 asn1_length_der (len, NULL, &len2);
573 temp = (unsigned char *) _asn1_malloc (len + len2);
574 if (temp == NULL)
575 return ASN1_MEM_ALLOC_ERROR;
577 asn1_octet_der (value, len, temp, &len2);
578 _asn1_set_value (node, temp, len2);
579 _asn1_free (temp);
580 break;
581 case TYPE_GENERALSTRING:
582 if (len == 0)
583 len = strlen (value);
584 asn1_length_der (len, NULL, &len2);
585 temp = (unsigned char *) _asn1_malloc (len + len2);
586 if (temp == NULL)
587 return ASN1_MEM_ALLOC_ERROR;
589 asn1_octet_der (value, len, temp, &len2);
590 _asn1_set_value (node, temp, len2);
591 _asn1_free (temp);
592 break;
593 case TYPE_BIT_STRING:
594 if (len == 0)
595 len = strlen (value);
596 asn1_length_der ((len >> 3) + 2, NULL, &len2);
597 temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
598 if (temp == NULL)
599 return ASN1_MEM_ALLOC_ERROR;
601 asn1_bit_der (value, len, temp, &len2);
602 _asn1_set_value (node, temp, len2);
603 _asn1_free (temp);
604 break;
605 case TYPE_CHOICE:
606 p = node->down;
607 while (p)
609 if (!strcmp (p->name, value))
611 p2 = node->down;
612 while (p2)
614 if (p2 != p)
616 asn1_delete_structure (&p2);
617 p2 = node->down;
619 else
620 p2 = p2->right;
622 break;
624 p = p->right;
626 if (!p)
627 return ASN1_ELEMENT_NOT_FOUND;
628 break;
629 case TYPE_ANY:
630 asn1_length_der (len, NULL, &len2);
631 temp = (unsigned char *) _asn1_malloc (len + len2);
632 if (temp == NULL)
633 return ASN1_MEM_ALLOC_ERROR;
635 asn1_octet_der (value, len, temp, &len2);
636 _asn1_set_value (node, temp, len2);
637 _asn1_free (temp);
638 break;
639 case TYPE_SEQUENCE_OF:
640 case TYPE_SET_OF:
641 if (strcmp (value, "NEW"))
642 return ASN1_VALUE_NOT_VALID;
643 _asn1_append_sequence_set (node);
644 break;
645 default:
646 return ASN1_ELEMENT_NOT_FOUND;
647 break;
650 return ASN1_SUCCESS;
654 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
655 *len = data_size; \
656 if (ptr_size < data_size) { \
657 return ASN1_MEM_ERROR; \
658 } else { \
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; \
666 } else { \
667 /* this strcpy is checked */ \
668 strcpy(ptr, data); \
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; \
675 } else { \
676 /* this strcat is checked */ \
677 strcat(ptr, data); \
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
695 * so on.
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.
734 * Returns:
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.
746 asn1_retCode
747 asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
749 node_asn *node, *p, *p2;
750 int len2, len3;
751 int value_size = *len;
752 unsigned char *value = ivalue;
754 node = asn1_find_node (root, name);
755 if (node == NULL)
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))
766 case TYPE_NULL:
767 PUT_STR_VALUE (value, value_size, "NULL");
768 break;
769 case TYPE_BOOLEAN:
770 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
772 p = node->down;
773 while (type_field (p->type) != TYPE_DEFAULT)
774 p = p->right;
775 if (p->type & CONST_TRUE)
777 PUT_STR_VALUE (value, value_size, "TRUE");
779 else
781 PUT_STR_VALUE (value, value_size, "FALSE");
784 else if (node->value[0] == 'T')
786 PUT_STR_VALUE (value, value_size, "TRUE");
788 else
790 PUT_STR_VALUE (value, value_size, "FALSE");
792 break;
793 case TYPE_INTEGER:
794 case TYPE_ENUMERATED:
795 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
797 p = node->down;
798 while (type_field (p->type) != TYPE_DEFAULT)
799 p = p->right;
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;
807 else
808 { /* is an identifier like v1 */
809 p2 = node->down;
810 while (p2)
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;
820 break;
823 p2 = p2->right;
827 else
829 len2 = -1;
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;
835 break;
836 case TYPE_OBJECT_ID:
837 if (node->type & CONST_ASSIGN)
839 value[0] = 0;
840 p = node->down;
841 while (p)
843 if (type_field (p->type) == TYPE_CONSTANT)
845 ADD_STR_VALUE (value, value_size, p->value);
846 if (p->right)
848 ADD_STR_VALUE (value, value_size, ".");
851 p = p->right;
853 *len = strlen (value) + 1;
855 else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
857 p = node->down;
858 while (type_field (p->type) != TYPE_DEFAULT)
859 p = p->right;
860 PUT_STR_VALUE (value, value_size, p->value);
862 else
864 PUT_STR_VALUE (value, value_size, node->value);
866 break;
867 case TYPE_TIME:
868 PUT_STR_VALUE (value, value_size, node->value);
869 break;
870 case TYPE_OCTET_STRING:
871 len2 = -1;
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;
876 break;
877 case TYPE_GENERALSTRING:
878 len2 = -1;
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;
883 break;
884 case TYPE_BIT_STRING:
885 len2 = -1;
886 if (asn1_get_bit_der
887 (node->value, node->value_len, &len2, value, value_size,
888 len) != ASN1_SUCCESS)
889 return ASN1_MEM_ERROR;
890 break;
891 case TYPE_CHOICE:
892 PUT_STR_VALUE (value, value_size, node->down->name);
893 break;
894 case TYPE_ANY:
895 len3 = -1;
896 len2 = asn1_get_length_der (node->value, node->value_len, &len3);
897 if (len2 < 0)
898 return ASN1_DER_ERROR;
899 PUT_VALUE (value, value_size, node->value + len3, len2);
900 break;
901 default:
902 return ASN1_ELEMENT_NOT_FOUND;
903 break;
905 return ASN1_SUCCESS;
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.
921 * Returns:
923 * ASN1_SUCCESS: Set value OK.
925 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
928 asn1_retCode
929 asn1_read_tag (node_asn * root, const char *name, int *tagValue,
930 int *classValue)
932 node_asn *node, *p, *pTag;
934 node = asn1_find_node (root, name);
935 if (node == NULL)
936 return ASN1_ELEMENT_NOT_FOUND;
938 p = node->down;
940 /* pTag will points to the IMPLICIT TAG */
941 pTag = NULL;
942 if (node->type & CONST_TAG)
944 while (p)
946 if (type_field (p->type) == TYPE_TAG)
948 if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
949 pTag = p;
950 else if (p->type & CONST_EXPLICIT)
951 pTag = NULL;
953 p = p->right;
957 if (pTag)
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;
967 else
968 *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
970 else
972 *classValue = ASN1_CLASS_UNIVERSAL;
974 switch (type_field (node->type))
976 case TYPE_NULL:
977 *tagValue = ASN1_TAG_NULL;
978 break;
979 case TYPE_BOOLEAN:
980 *tagValue = ASN1_TAG_BOOLEAN;
981 break;
982 case TYPE_INTEGER:
983 *tagValue = ASN1_TAG_INTEGER;
984 break;
985 case TYPE_ENUMERATED:
986 *tagValue = ASN1_TAG_ENUMERATED;
987 break;
988 case TYPE_OBJECT_ID:
989 *tagValue = ASN1_TAG_OBJECT_ID;
990 break;
991 case TYPE_TIME:
992 if (node->type & CONST_UTC)
994 *tagValue = ASN1_TAG_UTCTime;
996 else
997 *tagValue = ASN1_TAG_GENERALIZEDTime;
998 break;
999 case TYPE_OCTET_STRING:
1000 *tagValue = ASN1_TAG_OCTET_STRING;
1001 break;
1002 case TYPE_GENERALSTRING:
1003 *tagValue = ASN1_TAG_GENERALSTRING;
1004 break;
1005 case TYPE_BIT_STRING:
1006 *tagValue = ASN1_TAG_BIT_STRING;
1007 break;
1008 case TYPE_SEQUENCE:
1009 case TYPE_SEQUENCE_OF:
1010 *tagValue = ASN1_TAG_SEQUENCE;
1011 break;
1012 case TYPE_SET:
1013 case TYPE_SET_OF:
1014 *tagValue = ASN1_TAG_SET;
1015 break;
1016 case TYPE_TAG:
1017 case TYPE_CHOICE:
1018 case TYPE_ANY:
1019 break;
1020 default:
1021 break;
1026 return ASN1_SUCCESS;