Line data Source code
1 : /* asn1-func2.c - More ASN.1 definitions
2 : * Copyright (C) 2000, 2001 Fabio Fiorina
3 : * Copyright (C) 2001 Free Software Foundation, Inc.
4 : * Copyright (C) 2008, 2012 g10 Code GmbH
5 : *
6 : * This file is part of KSBA.
7 : *
8 : * KSBA is free software; you can redistribute it and/or modify
9 : * it under the terms of either
10 : *
11 : * - the GNU Lesser General Public License as published by the Free
12 : * Software Foundation; either version 3 of the License, or (at
13 : * your option) any later version.
14 : *
15 : * or
16 : *
17 : * - the GNU General Public License as published by the Free
18 : * Software Foundation; either version 2 of the License, or (at
19 : * your option) any later version.
20 : *
21 : * or both in parallel, as here.
22 : *
23 : * KSBA is distributed in the hope that it will be useful, but WITHOUT
24 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25 : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
26 : * License for more details.
27 : *
28 : * You should have received a copies of the GNU General Public License
29 : * and the GNU Lesser General Public License along with this program;
30 : * if not, see <http://www.gnu.org/licenses/>.
31 : */
32 :
33 : /*
34 : This file has functions which rely on on the asn1-gentables created
35 : asn1-tables.c - we can't put this into asn1-func.c because this one
36 : is needed by asn1-gentables ;-)
37 : */
38 :
39 : #include <config.h>
40 : #include <stdio.h>
41 : #include <stdlib.h>
42 : #include <string.h>
43 : #include <ctype.h>
44 : #include <assert.h>
45 :
46 : #include "util.h"
47 : #include "ksba.h"
48 : #include "asn1-func.h"
49 :
50 :
51 : static AsnNode
52 1872 : set_right (AsnNode node, AsnNode right)
53 : {
54 1872 : if (node == NULL)
55 0 : return node;
56 :
57 1872 : node->right = right;
58 1872 : if (right)
59 1872 : right->left = node;
60 1872 : return node;
61 : }
62 :
63 :
64 : static AsnNode
65 1341 : set_down (AsnNode node, AsnNode down)
66 : {
67 1341 : if (node == NULL)
68 0 : return node;
69 :
70 1341 : node->down = down;
71 1341 : if (down)
72 1341 : down->left = node;
73 1341 : return node;
74 : }
75 :
76 :
77 : static AsnNode
78 1341 : find_up (AsnNode node)
79 : {
80 : AsnNode p;
81 :
82 1341 : if (node == NULL)
83 0 : return NULL;
84 :
85 1341 : p = node;
86 4554 : while ((p->left != NULL) && (p->left->right == p))
87 1872 : p = p->left;
88 :
89 1341 : return p->left;
90 : }
91 :
92 :
93 :
94 :
95 : /**
96 : * Creates the structures needed to manage the ASN1 definitions. ROOT is
97 : * a vector created by the asn1-gentable tool.
98 : *
99 : * Input Parameter:
100 : *
101 : * Name of the module
102 : *
103 : * Output Parameter:
104 : *
105 : * KsbaAsntree *result : return the pointer to an object to be used
106 : * with other functions.
107 : *
108 : * Return Value:
109 : * 0: structure created correctly.
110 : * GPG_ERR_GENERAL: an error occured while structure creation.
111 : * GPG_ERR_MODULE_NOT_FOUND: No such module NAME
112 : */
113 : gpg_error_t
114 9 : ksba_asn_create_tree (const char *mod_name, ksba_asn_tree_t *result)
115 : {
116 : enum { DOWN, UP, RIGHT } move;
117 : const static_asn *root;
118 : const char *strgtbl;
119 : AsnNode pointer;
120 9 : AsnNode p = NULL;
121 9 : AsnNode p_last = NULL;
122 : unsigned long k;
123 : int rc;
124 9 : AsnNode link_next = NULL;
125 :
126 9 : if (!result)
127 0 : return gpg_error (GPG_ERR_INV_VALUE);
128 9 : *result = NULL;
129 :
130 9 : if (!mod_name)
131 0 : return gpg_error (GPG_ERR_INV_VALUE);
132 9 : root = _ksba_asn_lookup_table (mod_name, &strgtbl);
133 9 : if (!root)
134 0 : return gpg_error (GPG_ERR_MODULE_NOT_FOUND);
135 :
136 9 : pointer = NULL;
137 9 : move = UP;
138 :
139 9 : k = 0;
140 3240 : while (root[k].stringvalue_off || root[k].type || root[k].name_off)
141 : {
142 3222 : p = _ksba_asn_new_node (root[k].type);
143 3222 : p->flags = root[k].flags;
144 3222 : p->flags.help_down = 0;
145 3222 : p->link_next = link_next;
146 3222 : link_next = p;
147 :
148 3222 : if (root[k].name_off)
149 2493 : _ksba_asn_set_name (p, strgtbl + root[k].name_off);
150 3222 : if (root[k].stringvalue_off)
151 : {
152 1989 : if (root[k].type == TYPE_TAG)
153 : {
154 : unsigned long val;
155 468 : val = strtoul (strgtbl+root[k].stringvalue_off, NULL, 10);
156 468 : _ksba_asn_set_value (p, VALTYPE_ULONG, &val, sizeof(val));
157 : }
158 : else
159 3042 : _ksba_asn_set_value (p, VALTYPE_CSTR,
160 1521 : strgtbl+root[k].stringvalue_off, 0);
161 : }
162 :
163 3222 : if (!pointer)
164 9 : pointer = p;
165 :
166 3222 : if (move == DOWN)
167 1341 : set_down (p_last, p);
168 1881 : else if (move == RIGHT)
169 1872 : set_right (p_last, p);
170 :
171 3222 : p_last = p;
172 :
173 3222 : if (root[k].flags.help_down)
174 1341 : move = DOWN;
175 1881 : else if (root[k].flags.help_right)
176 909 : move = RIGHT;
177 : else
178 : {
179 : while (1)
180 : {
181 1728 : if (p_last == pointer)
182 9 : break;
183 :
184 1341 : p_last = find_up (p_last);
185 :
186 1341 : if (p_last == NULL)
187 0 : break;
188 :
189 1341 : if (p_last->flags.help_right)
190 : {
191 963 : p_last->flags.help_right = 0;
192 963 : move = RIGHT;
193 963 : break;
194 : }
195 : }
196 : }
197 3222 : k++;
198 : }
199 :
200 9 : if (p_last == pointer)
201 : {
202 : ksba_asn_tree_t tree;
203 :
204 9 : _ksba_asn_change_integer_value (pointer);
205 9 : _ksba_asn_expand_object_id (pointer);
206 9 : tree = xtrymalloc (sizeof *tree + strlen (mod_name));
207 9 : if (!tree)
208 0 : rc = gpg_error (GPG_ERR_ENOMEM);
209 : else
210 : {
211 9 : tree->parse_tree = pointer;
212 9 : tree->node_list = p;
213 9 : strcpy (tree->filename, mod_name);
214 9 : *result = tree;
215 9 : rc = 0;
216 : }
217 : }
218 : else
219 0 : rc = gpg_error (GPG_ERR_GENERAL);
220 :
221 9 : if (rc)
222 0 : _ksba_asn_delete_structure (pointer);
223 :
224 9 : return rc;
225 : }
|