check for either iconv or libiconv.
[gnutls.git] / lib / minitasn1 / element.c
blob4c871a1b3117805e1f5f6deb624c0f3c07e62ff0
1 /*
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
19 * 02110-1301, USA
22 /*****************************************************/
23 /* File: element.c */
24 /* Description: Functions with the read and write */
25 /* functions. */
26 /*****************************************************/
29 #include <int.h>
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "structure.h"
34 #include "element.h"
36 void
37 _asn1_hierarchical_name (asn1_node node, char *name, int name_size)
39 asn1_node p;
40 char tmp_name[64];
42 p = node;
44 name[0] = 0;
46 while (p != NULL)
48 if (p->name[0] != 0)
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 int
78 _asn1_convert_integer (const unsigned 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 = _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;
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];
118 #if 0
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]);
122 printf ("\n");
123 #endif
125 return ASN1_SUCCESS;
130 _asn1_append_sequence_set (asn1_node node)
132 asn1_node p, p2;
133 char temp[10];
134 long n;
136 if (!node || !(node->down))
137 return ASN1_GENERIC_ERROR;
139 p = node->down;
140 while ((type_field (p->type) == TYPE_TAG)
141 || (type_field (p->type) == TYPE_SIZE))
142 p = p->right;
143 p2 = _asn1_copy_structure3 (p);
144 while (p->right)
145 p = p->right;
146 _asn1_set_right (p, p2);
148 if (p->name[0] == 0)
149 _asn1_str_cpy (temp, sizeof (temp), "?1");
150 else
152 n = strtol (p->name + 1, NULL, 0);
153 n++;
154 temp[0] = '?';
155 _asn1_ltostr (n, temp + 1);
157 _asn1_set_name (p2, temp);
158 /* p2->type |= CONST_OPTION; */
160 return ASN1_SUCCESS;
165 * asn1_write_value:
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",
180 * NULL, 0);
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".
218 * LEN != 0
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
224 * number of octets.
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
230 * number of octets.
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
239 * bits)
241 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
242 * the alternatives with a null terminated string. LEN != 0. Using
243 * "pkix.asn"\:
245 * result=asn1_write_value(cert,
246 * "certificate1.tbsCertificate.subject", "rdnSequence",
247 * 1);
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.
256 * Using "pkix.asn"\:
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;
277 size_t i;
278 const unsigned char *value = ivalue;
280 node = asn1_find_node (node_root, name);
281 if (node == NULL)
282 return ASN1_ELEMENT_NOT_FOUND;
284 if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
286 asn1_delete_structure (&node);
287 return ASN1_SUCCESS;
290 if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
291 && (len == 0))
293 p = node->down;
294 while ((type_field (p->type) == TYPE_TAG)
295 || (type_field (p->type) == TYPE_SIZE))
296 p = p->right;
298 while (p->right)
299 asn1_delete_structure (&p->right);
301 return ASN1_SUCCESS;
304 switch (type_field (node->type))
306 case TYPE_BOOLEAN:
307 if (!_asn1_strcmp (value, "TRUE"))
309 if (node->type & CONST_DEFAULT)
311 p = node->down;
312 while (type_field (p->type) != TYPE_DEFAULT)
313 p = p->right;
314 if (p->type & CONST_TRUE)
315 _asn1_set_value (node, NULL, 0);
316 else
317 _asn1_set_value (node, "T", 1);
319 else
320 _asn1_set_value (node, "T", 1);
322 else if (!_asn1_strcmp (value, "FALSE"))
324 if (node->type & CONST_DEFAULT)
326 p = node->down;
327 while (type_field (p->type) != TYPE_DEFAULT)
328 p = p->right;
329 if (p->type & CONST_FALSE)
330 _asn1_set_value (node, NULL, 0);
331 else
332 _asn1_set_value (node, "F", 1);
334 else
335 _asn1_set_value (node, "F", 1);
337 else
338 return ASN1_VALUE_NOT_VALID;
339 break;
340 case TYPE_INTEGER:
341 case TYPE_ENUMERATED:
342 if (len == 0)
344 if ((isdigit (value[0])) || (value[0] == '-'))
346 value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
347 if (value_temp == NULL)
348 return ASN1_MEM_ALLOC_ERROR;
350 _asn1_convert_integer (value, value_temp,
351 SIZEOF_UNSIGNED_LONG_INT, &len);
353 else
354 { /* is an identifier like v1 */
355 if (!(node->type & CONST_LIST))
356 return ASN1_VALUE_NOT_VALID;
357 p = node->down;
358 while (p)
360 if (type_field (p->type) == TYPE_CONSTANT)
362 if (!_asn1_strcmp (p->name, value))
364 value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
365 if (value_temp == NULL)
366 return ASN1_MEM_ALLOC_ERROR;
368 _asn1_convert_integer (p->value,
369 value_temp,
370 SIZEOF_UNSIGNED_LONG_INT,
371 &len);
372 break;
375 p = p->right;
377 if (p == NULL)
378 return ASN1_VALUE_NOT_VALID;
381 else
382 { /* len != 0 */
383 value_temp = malloc (len);
384 if (value_temp == NULL)
385 return ASN1_MEM_ALLOC_ERROR;
386 memcpy (value_temp, value, len);
390 if (value_temp[0] & 0x80)
391 negative = 1;
392 else
393 negative = 0;
395 if (negative && (type_field (node->type) == TYPE_ENUMERATED))
397 free (value_temp);
398 return ASN1_VALUE_NOT_VALID;
401 for (k = 0; k < len - 1; k++)
402 if (negative && (value_temp[k] != 0xFF))
403 break;
404 else if (!negative && value_temp[k])
405 break;
407 if ((negative && !(value_temp[k] & 0x80)) ||
408 (!negative && (value_temp[k] & 0x80)))
409 k--;
411 _asn1_set_value_octet (node, value_temp + k, len - k);
413 if (node->type & CONST_DEFAULT)
415 p = node->down;
416 while (type_field (p->type) != TYPE_DEFAULT)
417 p = p->right;
418 if ((isdigit (p->value[0])) || (p->value[0] == '-'))
420 default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
421 if (default_temp == NULL)
423 free (value_temp);
424 return ASN1_MEM_ALLOC_ERROR;
427 _asn1_convert_integer (p->value, default_temp,
428 SIZEOF_UNSIGNED_LONG_INT, &len2);
430 else
431 { /* is an identifier like v1 */
432 if (!(node->type & CONST_LIST))
434 free (value_temp);
435 return ASN1_VALUE_NOT_VALID;
437 p2 = node->down;
438 while (p2)
440 if (type_field (p2->type) == TYPE_CONSTANT)
442 if (!_asn1_strcmp (p2->name, p->value))
444 default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
445 if (default_temp == NULL)
447 free (value_temp);
448 return ASN1_MEM_ALLOC_ERROR;
451 _asn1_convert_integer (p2->value,
452 default_temp,
453 SIZEOF_UNSIGNED_LONG_INT,
454 &len2);
455 break;
458 p2 = p2->right;
460 if (p2 == NULL)
462 free (value_temp);
463 return ASN1_VALUE_NOT_VALID;
468 if ((len - k) == len2)
470 for (k2 = 0; k2 < len2; k2++)
471 if (value_temp[k + k2] != default_temp[k2])
473 break;
475 if (k2 == len2)
476 _asn1_set_value (node, NULL, 0);
478 free (default_temp);
480 free (value_temp);
481 break;
482 case TYPE_OBJECT_ID:
483 for (i = 0; i < _asn1_strlen (value); i++)
484 if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
485 return ASN1_VALUE_NOT_VALID;
486 if (node->type & CONST_DEFAULT)
488 p = node->down;
489 while (type_field (p->type) != TYPE_DEFAULT)
490 p = p->right;
491 if (!_asn1_strcmp (value, p->value))
493 _asn1_set_value (node, NULL, 0);
494 break;
497 _asn1_set_value (node, value, _asn1_strlen (value) + 1);
498 break;
499 case TYPE_TIME:
500 if (node->type & CONST_UTC)
502 if (_asn1_strlen (value) < 11)
503 return ASN1_VALUE_NOT_VALID;
504 for (k = 0; k < 10; k++)
505 if (!isdigit (value[k]))
506 return ASN1_VALUE_NOT_VALID;
507 switch (_asn1_strlen (value))
509 case 11:
510 if (value[10] != 'Z')
511 return ASN1_VALUE_NOT_VALID;
512 break;
513 case 13:
514 if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
515 (value[12] != 'Z'))
516 return ASN1_VALUE_NOT_VALID;
517 break;
518 case 15:
519 if ((value[10] != '+') && (value[10] != '-'))
520 return ASN1_VALUE_NOT_VALID;
521 for (k = 11; k < 15; k++)
522 if (!isdigit (value[k]))
523 return ASN1_VALUE_NOT_VALID;
524 break;
525 case 17:
526 if ((!isdigit (value[10])) || (!isdigit (value[11])))
527 return ASN1_VALUE_NOT_VALID;
528 if ((value[12] != '+') && (value[12] != '-'))
529 return ASN1_VALUE_NOT_VALID;
530 for (k = 13; k < 17; k++)
531 if (!isdigit (value[k]))
532 return ASN1_VALUE_NOT_VALID;
533 break;
534 default:
535 return ASN1_VALUE_NOT_FOUND;
537 _asn1_set_value (node, value, _asn1_strlen (value) + 1);
539 else
540 { /* GENERALIZED TIME */
541 if (value)
542 _asn1_set_value (node, value, _asn1_strlen (value) + 1);
544 break;
545 case TYPE_OCTET_STRING:
546 if (len == 0)
547 len = _asn1_strlen (value);
548 _asn1_set_value_octet (node, value, len);
549 break;
550 case TYPE_GENERALSTRING:
551 if (len == 0)
552 len = _asn1_strlen (value);
553 _asn1_set_value_octet (node, value, len);
554 break;
555 case TYPE_BIT_STRING:
556 if (len == 0)
557 len = _asn1_strlen (value);
558 asn1_length_der ((len >> 3) + 2, NULL, &len2);
559 temp = malloc ((len >> 3) + 2 + len2);
560 if (temp == NULL)
561 return ASN1_MEM_ALLOC_ERROR;
563 asn1_bit_der (value, len, temp, &len2);
564 _asn1_set_value_m (node, temp, len2);
565 temp = NULL;
566 break;
567 case TYPE_CHOICE:
568 p = node->down;
569 while (p)
571 if (!_asn1_strcmp (p->name, value))
573 p2 = node->down;
574 while (p2)
576 if (p2 != p)
578 asn1_delete_structure (&p2);
579 p2 = node->down;
581 else
582 p2 = p2->right;
584 break;
586 p = p->right;
588 if (!p)
589 return ASN1_ELEMENT_NOT_FOUND;
590 break;
591 case TYPE_ANY:
592 _asn1_set_value_octet (node, value, len);
593 break;
594 case TYPE_SEQUENCE_OF:
595 case TYPE_SET_OF:
596 if (_asn1_strcmp (value, "NEW"))
597 return ASN1_VALUE_NOT_VALID;
598 _asn1_append_sequence_set (node);
599 break;
600 default:
601 return ASN1_ELEMENT_NOT_FOUND;
602 break;
605 return ASN1_SUCCESS;
609 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
610 *len = data_size; \
611 if (ptr_size < data_size) { \
612 return ASN1_MEM_ERROR; \
613 } else { \
614 memcpy( ptr, data, data_size); \
617 #define PUT_STR_VALUE( ptr, ptr_size, data) \
618 *len = _asn1_strlen(data) + 1; \
619 if (ptr_size < *len) { \
620 return ASN1_MEM_ERROR; \
621 } else { \
622 /* this strcpy is checked */ \
623 _asn1_strcpy(ptr, data); \
626 #define ADD_STR_VALUE( ptr, ptr_size, data) \
627 *len = (int) _asn1_strlen(data) + 1; \
628 if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
629 return ASN1_MEM_ERROR; \
630 } else { \
631 /* this strcat is checked */ \
632 _asn1_strcat(ptr, data); \
636 * asn1_read_value:
637 * @root: pointer to a structure.
638 * @name: the name of the element inside a structure that you want to read.
639 * @ivalue: vector that will contain the element's content, must be a
640 * pointer to memory cells already allocated.
641 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
642 * holds the sizeof value.
644 * Returns the value of one element inside a structure.
646 * If an element is OPTIONAL and the function "read_value" returns
647 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
648 * in the der encoding that created the structure. The first element
649 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
650 * so on.
652 * INTEGER: VALUE will contain a two's complement form integer.
654 * integer=-1 -> value[0]=0xFF , len=1.
655 * integer=1 -> value[0]=0x01 , len=1.
657 * ENUMERATED: As INTEGER (but only with not negative numbers).
659 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
660 * "FALSE" and LEN=5 or LEN=6.
662 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
663 * each number separated by a dot (i.e. "1.2.3.543.1").
665 * LEN = strlen(VALUE)+1
667 * UTCTime: VALUE will be a null terminated string in one of these
668 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
669 * LEN=strlen(VALUE)+1.
671 * GeneralizedTime: VALUE will be a null terminated string in the
672 * same format used to set the value.
674 * OCTET STRING: VALUE will contain the octet string and LEN will be
675 * the number of octets.
677 * GeneralString: VALUE will contain the generalstring and LEN will
678 * be the number of octets.
680 * BIT STRING: VALUE will contain the bit string organized by bytes
681 * and LEN will be the number of bits.
683 * CHOICE: If NAME indicates a choice type, VALUE will specify the
684 * alternative selected.
686 * ANY: If NAME indicates an any type, VALUE will indicate the DER
687 * encoding of the structure actually used.
689 * Returns: %ASN1_SUCCESS if value is returned,
690 * %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
691 * %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
692 * selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
693 * to store the result, and in this case @len will contain the number of
694 * bytes needed.
697 asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len)
699 asn1_node node, p, p2;
700 int len2, len3;
701 int value_size = *len;
702 unsigned char *value = ivalue;
704 node = asn1_find_node (root, name);
705 if (node == NULL)
706 return ASN1_ELEMENT_NOT_FOUND;
708 if ((type_field (node->type) != TYPE_NULL) &&
709 (type_field (node->type) != TYPE_CHOICE) &&
710 !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
711 (node->value == NULL))
712 return ASN1_VALUE_NOT_FOUND;
714 switch (type_field (node->type))
716 case TYPE_NULL:
717 PUT_STR_VALUE (value, value_size, "NULL");
718 break;
719 case TYPE_BOOLEAN:
720 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
722 p = node->down;
723 while (type_field (p->type) != TYPE_DEFAULT)
724 p = p->right;
725 if (p->type & CONST_TRUE)
727 PUT_STR_VALUE (value, value_size, "TRUE");
729 else
731 PUT_STR_VALUE (value, value_size, "FALSE");
734 else if (node->value[0] == 'T')
736 PUT_STR_VALUE (value, value_size, "TRUE");
738 else
740 PUT_STR_VALUE (value, value_size, "FALSE");
742 break;
743 case TYPE_INTEGER:
744 case TYPE_ENUMERATED:
745 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
747 p = node->down;
748 while (type_field (p->type) != TYPE_DEFAULT)
749 p = p->right;
750 if ((isdigit (p->value[0])) || (p->value[0] == '-')
751 || (p->value[0] == '+'))
753 if (_asn1_convert_integer
754 (p->value, value, value_size, len) != ASN1_SUCCESS)
755 return ASN1_MEM_ERROR;
757 else
758 { /* is an identifier like v1 */
759 p2 = node->down;
760 while (p2)
762 if (type_field (p2->type) == TYPE_CONSTANT)
764 if (!_asn1_strcmp (p2->name, p->value))
766 if (_asn1_convert_integer
767 (p2->value, value, value_size,
768 len) != ASN1_SUCCESS)
769 return ASN1_MEM_ERROR;
770 break;
773 p2 = p2->right;
777 else
779 len2 = -1;
780 if (asn1_get_octet_der
781 (node->value, node->value_len, &len2, value, value_size,
782 len) != ASN1_SUCCESS)
783 return ASN1_MEM_ERROR;
785 break;
786 case TYPE_OBJECT_ID:
787 if (node->type & CONST_ASSIGN)
789 value[0] = 0;
790 p = node->down;
791 while (p)
793 if (type_field (p->type) == TYPE_CONSTANT)
795 ADD_STR_VALUE (value, value_size, p->value);
796 if (p->right)
798 ADD_STR_VALUE (value, value_size, ".");
801 p = p->right;
803 *len = _asn1_strlen (value) + 1;
805 else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
807 p = node->down;
808 while (type_field (p->type) != TYPE_DEFAULT)
809 p = p->right;
810 PUT_STR_VALUE (value, value_size, p->value);
812 else
814 PUT_STR_VALUE (value, value_size, node->value);
816 break;
817 case TYPE_TIME:
818 PUT_STR_VALUE (value, value_size, node->value);
819 break;
820 case TYPE_OCTET_STRING:
821 len2 = -1;
822 if (asn1_get_octet_der
823 (node->value, node->value_len, &len2, value, value_size,
824 len) != ASN1_SUCCESS)
825 return ASN1_MEM_ERROR;
826 break;
827 case TYPE_GENERALSTRING:
828 len2 = -1;
829 if (asn1_get_octet_der
830 (node->value, node->value_len, &len2, value, value_size,
831 len) != ASN1_SUCCESS)
832 return ASN1_MEM_ERROR;
833 break;
834 case TYPE_BIT_STRING:
835 len2 = -1;
836 if (asn1_get_bit_der
837 (node->value, node->value_len, &len2, value, value_size,
838 len) != ASN1_SUCCESS)
839 return ASN1_MEM_ERROR;
840 break;
841 case TYPE_CHOICE:
842 PUT_STR_VALUE (value, value_size, node->down->name);
843 break;
844 case TYPE_ANY:
845 len3 = -1;
846 len2 = asn1_get_length_der (node->value, node->value_len, &len3);
847 if (len2 < 0)
848 return ASN1_DER_ERROR;
849 PUT_VALUE (value, value_size, node->value + len3, len2);
850 break;
851 default:
852 return ASN1_ELEMENT_NOT_FOUND;
853 break;
855 return ASN1_SUCCESS;
860 * asn1_read_tag:
861 * @root: pointer to a structure
862 * @name: the name of the element inside a structure.
863 * @tagValue: variable that will contain the TAG value.
864 * @classValue: variable that will specify the TAG type.
866 * Returns the TAG and the CLASS of one element inside a structure.
867 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
868 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
869 * %ASN1_CLASS_CONTEXT_SPECIFIC.
871 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
872 * @name is not a valid element.
875 asn1_read_tag (asn1_node root, const char *name, int *tagValue,
876 int *classValue)
878 asn1_node node, p, pTag;
880 node = asn1_find_node (root, name);
881 if (node == NULL)
882 return ASN1_ELEMENT_NOT_FOUND;
884 p = node->down;
886 /* pTag will points to the IMPLICIT TAG */
887 pTag = NULL;
888 if (node->type & CONST_TAG)
890 while (p)
892 if (type_field (p->type) == TYPE_TAG)
894 if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
895 pTag = p;
896 else if (p->type & CONST_EXPLICIT)
897 pTag = NULL;
899 p = p->right;
903 if (pTag)
905 *tagValue = _asn1_strtoul (pTag->value, NULL, 10);
907 if (pTag->type & CONST_APPLICATION)
908 *classValue = ASN1_CLASS_APPLICATION;
909 else if (pTag->type & CONST_UNIVERSAL)
910 *classValue = ASN1_CLASS_UNIVERSAL;
911 else if (pTag->type & CONST_PRIVATE)
912 *classValue = ASN1_CLASS_PRIVATE;
913 else
914 *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
916 else
918 *classValue = ASN1_CLASS_UNIVERSAL;
920 switch (type_field (node->type))
922 case TYPE_NULL:
923 *tagValue = ASN1_TAG_NULL;
924 break;
925 case TYPE_BOOLEAN:
926 *tagValue = ASN1_TAG_BOOLEAN;
927 break;
928 case TYPE_INTEGER:
929 *tagValue = ASN1_TAG_INTEGER;
930 break;
931 case TYPE_ENUMERATED:
932 *tagValue = ASN1_TAG_ENUMERATED;
933 break;
934 case TYPE_OBJECT_ID:
935 *tagValue = ASN1_TAG_OBJECT_ID;
936 break;
937 case TYPE_TIME:
938 if (node->type & CONST_UTC)
940 *tagValue = ASN1_TAG_UTCTime;
942 else
943 *tagValue = ASN1_TAG_GENERALIZEDTime;
944 break;
945 case TYPE_OCTET_STRING:
946 *tagValue = ASN1_TAG_OCTET_STRING;
947 break;
948 case TYPE_GENERALSTRING:
949 *tagValue = ASN1_TAG_GENERALSTRING;
950 break;
951 case TYPE_BIT_STRING:
952 *tagValue = ASN1_TAG_BIT_STRING;
953 break;
954 case TYPE_SEQUENCE:
955 case TYPE_SEQUENCE_OF:
956 *tagValue = ASN1_TAG_SEQUENCE;
957 break;
958 case TYPE_SET:
959 case TYPE_SET_OF:
960 *tagValue = ASN1_TAG_SET;
961 break;
962 case TYPE_TAG:
963 case TYPE_CHOICE:
964 case TYPE_ANY:
965 break;
966 default:
967 break;
971 return ASN1_SUCCESS;
975 * asn1_read_node_value:
976 * @node: pointer to a node.
977 * @data: a point to a asn1_data_node_st
979 * Returns the value a data node inside a asn1_node structure.
980 * The data returned should be handled as constant values.
982 * Returns: %ASN1_SUCCESS if the node exists.
984 int asn1_read_node_value (asn1_node node, asn1_data_node_st* data)
986 data->name = node->name;
987 data->value = node->value;
988 data->value_len = node->value_len;
989 data->type = type_field(node->type);
991 return ASN1_SUCCESS;