2 * Copyright (C) 2000-2016 Free Software Foundation, Inc.
4 * This file is part of LIBTASN1.
6 * The LIBTASN1 library is free software; you can redistribute it
7 * and/or modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 #include <hash-pjw-bare.h>
24 #include "parser_aux.h"
26 #include "structure.h"
29 char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
31 /***********************************************/
33 /* Description: type used in the list during */
34 /* the structure creation. */
35 /***********************************************/
36 typedef struct list_struct
39 struct list_struct *next;
43 /* Pointer to the first element of the list */
44 list_type *firstElement = NULL;
46 /******************************************************/
47 /* Function : _asn1_add_static_node */
48 /* Description: creates a new NODE_ASN element and */
49 /* puts it in the list pointed by firstElement. */
51 /* type: type of the new element (see ASN1_ETYPE_ */
52 /* and CONST_ constants). */
53 /* Return: pointer to the new element. */
54 /******************************************************/
56 _asn1_add_static_node (unsigned int type)
58 list_type *listElement;
61 punt = calloc (1, sizeof (struct asn1_node_st));
65 listElement = malloc (sizeof (list_type));
66 if (listElement == NULL)
72 listElement->node = punt;
73 listElement->next = firstElement;
74 firstElement = listElement;
83 * @pointer: NODE_ASN element pointer.
84 * @name: null terminated string with the element's name to find.
86 * Searches for an element called @name starting from @pointer. The
87 * name is composed by differents identifiers separated by dots. When
88 * *@pointer has a name, the first identifier must be the name of
89 * *@pointer, otherwise it must be the name of one child of *@pointer.
91 * Returns: the search result, or %NULL if not found.
94 asn1_find_node (asn1_node pointer, const char *name)
97 char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
111 if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?')
113 n_start = strchr(n_start, '.');
117 else if (p->name[0] != 0)
118 { /* has *pointer got a name ? */
119 n_end = strchr (n_start, '.'); /* search the first dot */
122 nsize = n_end - n_start;
123 memcpy (n, n_start, nsize);
128 nhash = hash_pjw_bare (n, nsize);
132 nsize = _asn1_str_cpy (n, sizeof (n), n_start);
133 nhash = hash_pjw_bare (n, nsize);
140 if (nhash == p->name_hash && (!strcmp (p->name, n)))
150 { /* *pointer doesn't have a name */
156 { /* Has the end of NAME been reached? */
157 n_end = strchr (n_start, '.'); /* search the next dot */
160 nsize = n_end - n_start;
161 memcpy (n, n_start, nsize);
166 nhash = hash_pjw_bare (n, nsize);
170 nsize = _asn1_str_cpy (n, sizeof (n), n_start);
171 nhash = hash_pjw_bare (n, nsize);
182 /* The identifier "?LAST" indicates the last element
183 in the right chain. */
184 if (n[0] == '?' && n[1] == 'L') /* ?LAST */
193 if (p->name_hash == nhash && !strcmp (p->name, n))
207 /******************************************************************/
208 /* Function : _asn1_set_value */
209 /* Description: sets the field VALUE in a NODE_ASN element. The */
210 /* previous value (if exist) will be lost */
212 /* node: element pointer. */
213 /* value: pointer to the value that you want to set. */
214 /* len: character number of value. */
215 /* Return: pointer to the NODE_ASN element. */
216 /******************************************************************/
218 _asn1_set_value (asn1_node node, const void *value, unsigned int len)
224 if (node->value != node->small_value)
233 if (len < sizeof (node->small_value))
235 node->value = node->small_value;
239 node->value = malloc (len);
240 if (node->value == NULL)
243 node->value_len = len;
245 memcpy (node->value, value, len);
249 /******************************************************************/
250 /* Function : _asn1_set_value_lv */
251 /* Description: sets the field VALUE in a NODE_ASN element. The */
252 /* previous value (if exist) will be lost. The value */
253 /* given is stored as an length-value format (LV */
255 /* node: element pointer. */
256 /* value: pointer to the value that you want to set. */
257 /* len: character number of value. */
258 /* Return: pointer to the NODE_ASN element. */
259 /******************************************************************/
261 _asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
269 asn1_length_der (len, NULL, &len2);
270 temp = malloc (len + len2);
274 asn1_octet_der (value, len, temp, &len2);
275 return _asn1_set_value_m (node, temp, len2);
278 /* the same as _asn1_set_value except that it sets an already malloc'ed
282 _asn1_set_value_m (asn1_node node, void *value, unsigned int len)
289 if (node->value != node->small_value)
299 node->value_len = len;
304 /******************************************************************/
305 /* Function : _asn1_append_value */
306 /* Description: appends to the field VALUE in a NODE_ASN element. */
309 /* node: element pointer. */
310 /* value: pointer to the value that you want to be appended. */
311 /* len: character number of value. */
312 /* Return: pointer to the NODE_ASN element. */
313 /******************************************************************/
315 _asn1_append_value (asn1_node node, const void *value, unsigned int len)
320 if (node->value == NULL)
321 return _asn1_set_value (node, value, len);
326 if (node->value == node->small_value)
328 /* value is in node */
329 int prev_len = node->value_len;
330 node->value_len += len;
331 node->value = malloc (node->value_len);
332 if (node->value == NULL)
339 memcpy (node->value, node->small_value, prev_len);
341 memcpy (&node->value[prev_len], value, len);
345 else /* if (node->value != NULL && node->value != node->small_value) */
347 /* value is allocated */
348 int prev_len = node->value_len;
349 node->value_len += len;
351 node->value = _asn1_realloc (node->value, node->value_len);
352 if (node->value == NULL)
358 memcpy (&node->value[prev_len], value, len);
364 /******************************************************************/
365 /* Function : _asn1_set_name */
366 /* Description: sets the field NAME in a NODE_ASN element. The */
367 /* previous value (if exist) will be lost */
369 /* node: element pointer. */
370 /* name: a null terminated string with the name that you want */
372 /* Return: pointer to the NODE_ASN element. */
373 /******************************************************************/
375 _asn1_set_name (asn1_node node, const char *name)
385 node->name_hash = hash_pjw_bare (node->name, 0);
389 nsize = _asn1_str_cpy (node->name, sizeof (node->name), name);
390 node->name_hash = hash_pjw_bare (node->name, nsize);
395 /******************************************************************/
396 /* Function : _asn1_cpy_name */
397 /* Description: copies the field NAME in a NODE_ASN element. */
399 /* dst: a dest element pointer. */
400 /* src: a source element pointer. */
401 /* Return: pointer to the NODE_ASN element. */
402 /******************************************************************/
404 _asn1_cpy_name (asn1_node dst, asn1_node src)
412 dst->name_hash = hash_pjw_bare (dst->name, 0);
416 _asn1_str_cpy (dst->name, sizeof (dst->name), src->name);
417 dst->name_hash = src->name_hash;
422 /******************************************************************/
423 /* Function : _asn1_set_right */
424 /* Description: sets the field RIGHT in a NODE_ASN element. */
426 /* node: element pointer. */
427 /* right: pointer to a NODE_ASN element that you want be pointed*/
429 /* Return: pointer to *NODE. */
430 /******************************************************************/
432 _asn1_set_right (asn1_node node, asn1_node right)
443 /******************************************************************/
444 /* Function : _asn1_get_last_right */
445 /* Description: return the last element along the right chain. */
447 /* node: starting element pointer. */
448 /* Return: pointer to the last element along the right chain. */
449 /******************************************************************/
451 _asn1_get_last_right (asn1_node node)
463 /******************************************************************/
464 /* Function : _asn1_remove_node */
465 /* Description: gets free the memory allocated for an NODE_ASN */
466 /* element (not the elements pointed by it). */
468 /* node: NODE_ASN element pointer. */
469 /* flags: ASN1_DELETE_FLAG_* */
470 /******************************************************************/
472 _asn1_remove_node (asn1_node node, unsigned int flags)
477 if (node->value != NULL)
479 if (flags & ASN1_DELETE_FLAG_ZEROIZE)
481 safe_memset(node->value, 0, node->value_len);
484 if (node->value != node->small_value)
490 /******************************************************************/
491 /* Function : _asn1_find_up */
492 /* Description: return the father of the NODE_ASN element. */
494 /* node: NODE_ASN element pointer. */
495 /* Return: Null if not found. */
496 /******************************************************************/
498 _asn1_find_up (asn1_node node)
507 while ((p->left != NULL) && (p->left->right == p))
513 /******************************************************************/
514 /* Function : _asn1_delete_list */
515 /* Description: deletes the list elements (not the elements */
516 /* pointed by them). */
517 /******************************************************************/
519 _asn1_delete_list (void)
521 list_type *listElement;
525 listElement = firstElement;
526 firstElement = firstElement->next;
531 /******************************************************************/
532 /* Function : _asn1_delete_list_and nodes */
533 /* Description: deletes the list elements and the elements */
534 /* pointed by them. */
535 /******************************************************************/
537 _asn1_delete_list_and_nodes (void)
539 list_type *listElement;
543 listElement = firstElement;
544 firstElement = firstElement->next;
545 _asn1_remove_node (listElement->node, 0);
552 _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
555 char temp[LTOSTR_MAX_SIZE];
572 temp[start + count] = '0' + (char) r;
576 while (v && ((start+count) < LTOSTR_MAX_SIZE-1));
578 for (k = 0; k < count; k++)
579 str[k + start] = temp[start + count - k - 1];
580 str[count + start] = 0;
585 /******************************************************************/
586 /* Function : _asn1_change_integer_value */
587 /* Description: converts into DER coding the value assign to an */
588 /* INTEGER constant. */
590 /* node: root of an ASN1element. */
592 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
593 /* otherwise ASN1_SUCCESS */
594 /******************************************************************/
596 _asn1_change_integer_value (asn1_node node)
599 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
600 unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
604 return ASN1_ELEMENT_NOT_FOUND;
609 if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
610 && (p->type & CONST_ASSIGN))
614 _asn1_convert_integer (p->value, val, sizeof (val), &len);
615 asn1_octet_der (val, len, val2, &len);
616 _asn1_set_value (p, val2, len);
634 p = _asn1_find_up (p);
654 /******************************************************************/
655 /* Function : _asn1_expand_object_id */
656 /* Description: expand the IDs of an OBJECT IDENTIFIER constant. */
658 /* node: root of an ASN1 element. */
660 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
661 /* otherwise ASN1_SUCCESS */
662 /******************************************************************/
664 _asn1_expand_object_id (asn1_node node)
666 asn1_node p, p2, p3, p4, p5;
667 char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
671 return ASN1_ELEMENT_NOT_FOUND;
673 _asn1_str_cpy (name_root, sizeof (name_root), node->name);
678 while (!((p == node) && (move == UP)))
682 if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
683 && (p->type & CONST_ASSIGN))
686 if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
688 if (p2->value && !isdigit (p2->value[0]))
690 _asn1_str_cpy (name2, sizeof (name2), name_root);
691 _asn1_str_cat (name2, sizeof (name2), ".");
692 _asn1_str_cat (name2, sizeof (name2),
694 p3 = asn1_find_node (node, name2);
696 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
697 || !(p3->type & CONST_ASSIGN))
698 return ASN1_ELEMENT_NOT_FOUND;
699 _asn1_set_down (p, p2->right);
700 _asn1_remove_node (p2, 0);
705 if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
708 _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
709 _asn1_set_name (p5, p4->name);
712 tlen = _asn1_strlen (p4->value);
714 _asn1_set_value (p5, p4->value, tlen + 1);
718 _asn1_set_right (p5, p->down);
719 _asn1_set_down (p, p5);
723 _asn1_set_right (p5, p2->right);
724 _asn1_set_right (p2, p5);
762 p = _asn1_find_up (p);
766 /*******************************/
768 /*******************************/
772 while (!((p == node) && (move == UP)))
776 if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
777 (p->type & CONST_DEFAULT))
780 if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
782 _asn1_str_cpy (name2, sizeof (name2), name_root);
783 _asn1_str_cat (name2, sizeof (name2), ".");
784 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
785 p3 = asn1_find_node (node, name2);
786 if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
787 || !(p3->type & CONST_ASSIGN))
788 return ASN1_ELEMENT_NOT_FOUND;
793 if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
795 if (p4->value == NULL)
796 return ASN1_VALUE_NOT_FOUND;
799 _asn1_str_cat (name2, sizeof (name2), ".");
800 _asn1_str_cat (name2, sizeof (name2),
805 tlen = strlen (name2);
807 _asn1_set_value (p2, name2, tlen + 1);
837 p = _asn1_find_up (p);
844 /******************************************************************/
845 /* Function : _asn1_type_set_config */
846 /* Description: sets the CONST_SET and CONST_NOT_USED properties */
847 /* in the fields of the SET elements. */
849 /* node: root of an ASN1 element. */
851 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
852 /* otherwise ASN1_SUCCESS */
853 /******************************************************************/
855 _asn1_type_set_config (asn1_node node)
861 return ASN1_ELEMENT_NOT_FOUND;
866 while (!((p == node) && (move == UP)))
870 if (type_field (p->type) == ASN1_ETYPE_SET)
875 if (type_field (p2->type) != ASN1_ETYPE_TAG)
876 p2->type |= CONST_SET | CONST_NOT_USED;
907 p = _asn1_find_up (p);
914 /******************************************************************/
915 /* Function : _asn1_check_identifier */
916 /* Description: checks the definitions of all the identifiers */
917 /* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */
918 /* The _asn1_identifierMissing global variable is filled if */
921 /* node: root of an ASN1 element. */
923 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
924 /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
925 /* otherwise ASN1_SUCCESS */
926 /******************************************************************/
928 _asn1_check_identifier (asn1_node node)
931 char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
934 return ASN1_ELEMENT_NOT_FOUND;
939 if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
941 _asn1_str_cpy (name2, sizeof (name2), node->name);
942 _asn1_str_cat (name2, sizeof (name2), ".");
943 _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
944 p2 = asn1_find_node (node, name2);
948 _asn1_strcpy (_asn1_identifierMissing, p->value);
950 _asn1_strcpy (_asn1_identifierMissing, "(null)");
951 return ASN1_IDENTIFIER_NOT_FOUND;
954 else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
955 (p->type & CONST_DEFAULT))
958 if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
960 _asn1_str_cpy (name2, sizeof (name2), node->name);
961 _asn1_str_cat (name2, sizeof (name2), ".");
962 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
963 _asn1_strcpy (_asn1_identifierMissing, p2->value);
964 p2 = asn1_find_node (node, name2);
965 if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
966 !(p2->type & CONST_ASSIGN))
967 return ASN1_IDENTIFIER_NOT_FOUND;
969 _asn1_identifierMissing[0] = 0;
972 else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
973 (p->type & CONST_ASSIGN))
976 if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
978 if (p2->value && !isdigit (p2->value[0]))
980 _asn1_str_cpy (name2, sizeof (name2), node->name);
981 _asn1_str_cat (name2, sizeof (name2), ".");
982 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
983 _asn1_strcpy (_asn1_identifierMissing, p2->value);
984 p2 = asn1_find_node (node, name2);
985 if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID)
986 || !(p2->type & CONST_ASSIGN))
987 return ASN1_IDENTIFIER_NOT_FOUND;
989 _asn1_identifierMissing[0] = 0;
1004 p = _asn1_find_up (p);
1019 return ASN1_SUCCESS;
1023 /******************************************************************/
1024 /* Function : _asn1_set_default_tag */
1025 /* Description: sets the default IMPLICIT or EXPLICIT property in */
1026 /* the tagged elements that don't have this declaration. */
1028 /* node: pointer to a DEFINITIONS element. */
1030 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */
1031 /* a DEFINITIONS element, */
1032 /* otherwise ASN1_SUCCESS */
1033 /******************************************************************/
1035 _asn1_set_default_tag (asn1_node node)
1039 if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
1040 return ASN1_ELEMENT_NOT_FOUND;
1045 if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
1046 !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1048 if (node->type & CONST_EXPLICIT)
1049 p->type |= CONST_EXPLICIT;
1051 p->type |= CONST_IMPLICIT;
1064 p = _asn1_find_up (p);
1079 return ASN1_SUCCESS;