Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2000-2012 Free Software Foundation, Inc.
3 : : *
4 : : * This file is part of LIBTASN1.
5 : : *
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.
10 : : *
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.
15 : : *
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
20 : : */
21 : :
22 : : #include <int.h>
23 : : #include "parser_aux.h"
24 : : #include "gstr.h"
25 : : #include "structure.h"
26 : : #include "element.h"
27 : :
28 : : char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
29 : :
30 : : /***********************************************/
31 : : /* Type: list_type */
32 : : /* Description: type used in the list during */
33 : : /* the structure creation. */
34 : : /***********************************************/
35 : : typedef struct list_struct
36 : : {
37 : : ASN1_TYPE node;
38 : : struct list_struct *next;
39 : : } list_type;
40 : :
41 : :
42 : : /* Pointer to the first element of the list */
43 : : list_type *firstElement = NULL;
44 : :
45 : : /******************************************************/
46 : : /* Function : _asn1_add_node */
47 : : /* Description: creates a new NODE_ASN element and */
48 : : /* puts it in the list pointed by firstElement. */
49 : : /* Parameters: */
50 : : /* type: type of the new element (see TYPE_ */
51 : : /* and CONST_ constants). */
52 : : /* Return: pointer to the new element. */
53 : : /******************************************************/
54 : : ASN1_TYPE
55 : 2813 : _asn1_add_node (unsigned int type)
56 : : {
57 : : list_type *listElement;
58 : : ASN1_TYPE punt;
59 : :
60 : 2813 : punt = (ASN1_TYPE) _asn1_calloc (1, sizeof (struct node_asn_struct));
61 [ - + ]: 2813 : if (punt == NULL)
62 : 0 : return NULL;
63 : :
64 : 2813 : listElement = (list_type *) _asn1_malloc (sizeof (list_type));
65 [ - + ]: 2813 : if (listElement == NULL)
66 : : {
67 : 0 : _asn1_free (punt);
68 : 0 : return NULL;
69 : : }
70 : :
71 : 2813 : listElement->node = punt;
72 : 2813 : listElement->next = firstElement;
73 : 2813 : firstElement = listElement;
74 : :
75 : 2813 : punt->type = type;
76 : :
77 : 2813 : return punt;
78 : : }
79 : :
80 : : /**
81 : : * asn1_find_node:
82 : : * @pointer: NODE_ASN element pointer.
83 : : * @name: null terminated string with the element's name to find.
84 : : *
85 : : * Searches for an element called @name starting from @pointer. The
86 : : * name is composed by differents identifiers separated by dots. When
87 : : * *@pointer has a name, the first identifier must be the name of
88 : : * *@pointer, otherwise it must be the name of one child of *@pointer.
89 : : *
90 : : * Returns: the search result, or %NULL if not found.
91 : : **/
92 : : ASN1_TYPE
93 : 1173 : asn1_find_node (ASN1_TYPE pointer, const char *name)
94 : : {
95 : : ASN1_TYPE p;
96 : : char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
97 : : const char *n_start;
98 : :
99 [ - + ]: 1173 : if (pointer == NULL)
100 : 0 : return NULL;
101 : :
102 [ - + ]: 1173 : if (name == NULL)
103 : 0 : return NULL;
104 : :
105 : 1173 : p = pointer;
106 : 1173 : n_start = name;
107 : :
108 [ + + ]: 1173 : if (p->name != NULL)
109 : : { /* has *pointer got a name ? */
110 : 954 : n_end = strchr (n_start, '.'); /* search the first dot */
111 [ + - ]: 954 : if (n_end)
112 : : {
113 : 954 : memcpy (n, n_start, n_end - n_start);
114 : 954 : n[n_end - n_start] = 0;
115 : 954 : n_start = n_end;
116 : 954 : n_start++;
117 : : }
118 : : else
119 : : {
120 : 0 : _asn1_str_cpy (n, sizeof (n), n_start);
121 : 0 : n_start = NULL;
122 : : }
123 : :
124 [ + - ]: 954 : while (p)
125 : : {
126 [ + - ][ - + ]: 954 : if ((p->name) && (!strcmp (p->name, n)))
127 : : break;
128 : : else
129 : 0 : p = p->right;
130 : : } /* while */
131 : :
132 [ - + ]: 954 : if (p == NULL)
133 : 0 : return NULL;
134 : : }
135 : : else
136 : : { /* *pointer doesn't have a name */
137 [ + + ]: 219 : if (n_start[0] == 0)
138 : 74 : return p;
139 : : }
140 : :
141 [ + + ]: 2261 : while (n_start)
142 : : { /* Has the end of NAME been reached? */
143 : 1170 : n_end = strchr (n_start, '.'); /* search the next dot */
144 [ + + ]: 1170 : if (n_end)
145 : : {
146 : 71 : memcpy (n, n_start, n_end - n_start);
147 : 71 : n[n_end - n_start] = 0;
148 : 71 : n_start = n_end;
149 : 71 : n_start++;
150 : : }
151 : : else
152 : : {
153 : 1099 : _asn1_str_cpy (n, sizeof (n), n_start);
154 : 1099 : n_start = NULL;
155 : : }
156 : :
157 [ - + ]: 1170 : if (p->down == NULL)
158 : 0 : return NULL;
159 : :
160 : 1170 : p = p->down;
161 : :
162 : : /* The identifier "?LAST" indicates the last element
163 : : in the right chain. */
164 [ + + ]: 1170 : if (!strcmp (n, "?LAST"))
165 : : {
166 [ - + ]: 21 : if (p == NULL)
167 : 0 : return NULL;
168 [ + + ]: 115 : while (p->right)
169 : 94 : p = p->right;
170 : : }
171 : : else
172 : : { /* no "?LAST" */
173 [ + + ]: 92632 : while (p)
174 : : {
175 [ + + ][ + + ]: 92624 : if ((p->name) && (!strcmp (p->name, n)))
176 : : break;
177 : : else
178 : 91483 : p = p->right;
179 : : }
180 [ + + ]: 1149 : if (p == NULL)
181 : 8 : return NULL;
182 : : }
183 : : } /* while */
184 : :
185 : 1173 : return p;
186 : : }
187 : :
188 : :
189 : : /******************************************************************/
190 : : /* Function : _asn1_set_value */
191 : : /* Description: sets the field VALUE in a NODE_ASN element. The */
192 : : /* previous value (if exist) will be lost */
193 : : /* Parameters: */
194 : : /* node: element pointer. */
195 : : /* value: pointer to the value that you want to set. */
196 : : /* len: character number of value. */
197 : : /* Return: pointer to the NODE_ASN element. */
198 : : /******************************************************************/
199 : : ASN1_TYPE
200 : 3630 : _asn1_set_value (ASN1_TYPE node, const void *value, unsigned int len)
201 : : {
202 [ - + ]: 3630 : if (node == NULL)
203 : 0 : return node;
204 [ + + ]: 3630 : if (node->value)
205 : : {
206 [ + + ]: 274 : if (node->value != node->small_value)
207 : 4 : _asn1_free (node->value);
208 : 274 : node->value = NULL;
209 : 274 : node->value_len = 0;
210 : : }
211 : :
212 [ + + ]: 3630 : if (!len)
213 : 139 : return node;
214 : :
215 [ + + ]: 3491 : if (len < sizeof (node->small_value))
216 : : {
217 : 3199 : node->value = node->small_value;
218 : : }
219 : : else
220 : : {
221 : 292 : node->value = _asn1_malloc (len);
222 [ - + ]: 292 : if (node->value == NULL)
223 : 0 : return NULL;
224 : : }
225 : 3491 : node->value_len = len;
226 : :
227 : 3491 : memcpy (node->value, value, len);
228 : 3630 : return node;
229 : : }
230 : :
231 : : /******************************************************************/
232 : : /* Function : _asn1_set_value_octet */
233 : : /* Description: sets the field VALUE in a NODE_ASN element. The */
234 : : /* previous value (if exist) will be lost. The value */
235 : : /* given is stored as an octet string. */
236 : : /* Parameters: */
237 : : /* node: element pointer. */
238 : : /* value: pointer to the value that you want to set. */
239 : : /* len: character number of value. */
240 : : /* Return: pointer to the NODE_ASN element. */
241 : : /******************************************************************/
242 : : ASN1_TYPE
243 : 62 : _asn1_set_value_octet (ASN1_TYPE node, const void *value, unsigned int len)
244 : : {
245 : : int len2;
246 : : void *temp;
247 : :
248 [ - + ]: 62 : if (node == NULL)
249 : 0 : return node;
250 : :
251 : 62 : asn1_length_der (len, NULL, &len2);
252 : 62 : temp = (unsigned char *) _asn1_malloc (len + len2);
253 [ - + ]: 62 : if (temp == NULL)
254 : 0 : return NULL;
255 : :
256 : 62 : asn1_octet_der (value, len, temp, &len2);
257 : 62 : return _asn1_set_value_m (node, temp, len2);
258 : : }
259 : :
260 : : /* the same as _asn1_set_value except that it sets an already malloc'ed
261 : : * value.
262 : : */
263 : : ASN1_TYPE
264 : 63 : _asn1_set_value_m (ASN1_TYPE node, void *value, unsigned int len)
265 : : {
266 [ - + ]: 63 : if (node == NULL)
267 : 0 : return node;
268 : :
269 [ + + ]: 63 : if (node->value)
270 : : {
271 [ + - ]: 7 : if (node->value != node->small_value)
272 : 7 : _asn1_free (node->value);
273 : 7 : node->value = NULL;
274 : 7 : node->value_len = 0;
275 : : }
276 : :
277 [ - + ]: 63 : if (!len)
278 : 0 : return node;
279 : :
280 : 63 : node->value = value;
281 : 63 : node->value_len = len;
282 : :
283 : 63 : return node;
284 : : }
285 : :
286 : : /******************************************************************/
287 : : /* Function : _asn1_append_value */
288 : : /* Description: appends to the field VALUE in a NODE_ASN element. */
289 : : /* */
290 : : /* Parameters: */
291 : : /* node: element pointer. */
292 : : /* value: pointer to the value that you want to be appended. */
293 : : /* len: character number of value. */
294 : : /* Return: pointer to the NODE_ASN element. */
295 : : /******************************************************************/
296 : : ASN1_TYPE
297 : 0 : _asn1_append_value (ASN1_TYPE node, const void *value, unsigned int len)
298 : : {
299 [ # # ]: 0 : if (node == NULL)
300 : 0 : return node;
301 [ # # ][ # # ]: 0 : if (node->value != NULL && node->value != node->small_value)
302 : : {
303 : : /* value is allocated */
304 : 0 : int prev_len = node->value_len;
305 : 0 : node->value_len += len;
306 : 0 : node->value = _asn1_realloc (node->value, node->value_len);
307 [ # # ]: 0 : if (node->value == NULL)
308 : : {
309 : 0 : node->value_len = 0;
310 : 0 : return NULL;
311 : : }
312 : 0 : memcpy (&node->value[prev_len], value, len);
313 : :
314 : 0 : return node;
315 : : }
316 [ # # ]: 0 : else if (node->value == node->small_value)
317 : : {
318 : : /* value is in node */
319 : 0 : int prev_len = node->value_len;
320 : 0 : node->value_len += len;
321 : 0 : node->value = _asn1_malloc (node->value_len);
322 [ # # ]: 0 : if (node->value == NULL)
323 : : {
324 : 0 : node->value_len = 0;
325 : 0 : return NULL;
326 : : }
327 : 0 : memcpy (node->value, node->small_value, prev_len);
328 : 0 : memcpy (&node->value[prev_len], value, len);
329 : :
330 : 0 : return node;
331 : : }
332 : : else /* node->value == NULL */
333 : 0 : return _asn1_set_value (node, value, len);
334 : : }
335 : :
336 : : /******************************************************************/
337 : : /* Function : _asn1_set_name */
338 : : /* Description: sets the field NAME in a NODE_ASN element. The */
339 : : /* previous value (if exist) will be lost */
340 : : /* Parameters: */
341 : : /* node: element pointer. */
342 : : /* name: a null terminated string with the name that you want */
343 : : /* to set. */
344 : : /* Return: pointer to the NODE_ASN element. */
345 : : /******************************************************************/
346 : : ASN1_TYPE
347 : 3573 : _asn1_set_name (ASN1_TYPE node, const char *name)
348 : : {
349 [ - + ]: 3573 : if (node == NULL)
350 : 0 : return node;
351 : :
352 [ + + ]: 3573 : if (node->name)
353 : : {
354 : 132 : _asn1_free (node->name);
355 : 132 : node->name = NULL;
356 : : }
357 : :
358 [ + + ]: 3573 : if (name == NULL)
359 : 186 : return node;
360 : :
361 [ + + ]: 3387 : if (strlen (name))
362 : : {
363 : 3328 : node->name = (char *) _asn1_strdup (name);
364 [ - + ]: 3328 : if (node->name == NULL)
365 : 0 : return NULL;
366 : : }
367 : : else
368 : 59 : node->name = NULL;
369 : 3573 : return node;
370 : : }
371 : :
372 : : /******************************************************************/
373 : : /* Function : _asn1_set_right */
374 : : /* Description: sets the field RIGHT in a NODE_ASN element. */
375 : : /* Parameters: */
376 : : /* node: element pointer. */
377 : : /* right: pointer to a NODE_ASN element that you want be pointed*/
378 : : /* by NODE. */
379 : : /* Return: pointer to *NODE. */
380 : : /******************************************************************/
381 : : ASN1_TYPE
382 : 3946 : _asn1_set_right (ASN1_TYPE node, ASN1_TYPE right)
383 : : {
384 [ - + ]: 3946 : if (node == NULL)
385 : 0 : return node;
386 : 3946 : node->right = right;
387 [ + + ]: 3946 : if (right)
388 : 3749 : right->left = node;
389 : 3946 : return node;
390 : : }
391 : :
392 : : /******************************************************************/
393 : : /* Function : _asn1_get_right */
394 : : /* Description: returns the element pointed by the RIGHT field of */
395 : : /* a NODE_ASN element. */
396 : : /* Parameters: */
397 : : /* node: NODE_ASN element pointer. */
398 : : /* Return: field RIGHT of NODE. */
399 : : /******************************************************************/
400 : : ASN1_TYPE
401 : 0 : _asn1_get_right (ASN1_TYPE node)
402 : : {
403 [ # # ]: 0 : if (node == NULL)
404 : 0 : return NULL;
405 : 0 : return node->right;
406 : : }
407 : :
408 : : /******************************************************************/
409 : : /* Function : _asn1_get_last_right */
410 : : /* Description: return the last element along the right chain. */
411 : : /* Parameters: */
412 : : /* node: starting element pointer. */
413 : : /* Return: pointer to the last element along the right chain. */
414 : : /******************************************************************/
415 : : ASN1_TYPE
416 : 1709 : _asn1_get_last_right (ASN1_TYPE node)
417 : : {
418 : : ASN1_TYPE p;
419 : :
420 [ - + ]: 1709 : if (node == NULL)
421 : 0 : return NULL;
422 : 1709 : p = node;
423 [ + + ]: 103714 : while (p->right)
424 : 102005 : p = p->right;
425 : 1709 : return p;
426 : : }
427 : :
428 : : /******************************************************************/
429 : : /* Function : _asn1_set_down */
430 : : /* Description: sets the field DOWN in a NODE_ASN element. */
431 : : /* Parameters: */
432 : : /* node: element pointer. */
433 : : /* down: pointer to a NODE_ASN element that you want be pointed */
434 : : /* by NODE. */
435 : : /* Return: pointer to *NODE. */
436 : : /******************************************************************/
437 : : ASN1_TYPE
438 : 5467 : _asn1_set_down (ASN1_TYPE node, ASN1_TYPE down)
439 : : {
440 [ - + ]: 5467 : if (node == NULL)
441 : 0 : return node;
442 : 5467 : node->down = down;
443 [ + + ]: 5467 : if (down)
444 : 4337 : down->left = node;
445 : 5467 : return node;
446 : : }
447 : :
448 : : /******************************************************************/
449 : : /* Function : _asn1_get_down */
450 : : /* Description: returns the element pointed by the DOWN field of */
451 : : /* a NODE_ASN element. */
452 : : /* Parameters: */
453 : : /* node: NODE_ASN element pointer. */
454 : : /* Return: field DOWN of NODE. */
455 : : /******************************************************************/
456 : : ASN1_TYPE
457 : 274 : _asn1_get_down (ASN1_TYPE node)
458 : : {
459 [ - + ]: 274 : if (node == NULL)
460 : 0 : return NULL;
461 : 274 : return node->down;
462 : : }
463 : :
464 : : /******************************************************************/
465 : : /* Function : _asn1_get_name */
466 : : /* Description: returns the name of a NODE_ASN element. */
467 : : /* Parameters: */
468 : : /* node: NODE_ASN element pointer. */
469 : : /* Return: a null terminated string. */
470 : : /******************************************************************/
471 : : char *
472 : 26 : _asn1_get_name (ASN1_TYPE node)
473 : : {
474 [ - + ]: 26 : if (node == NULL)
475 : 0 : return NULL;
476 : 26 : return node->name;
477 : : }
478 : :
479 : : /******************************************************************/
480 : : /* Function : _asn1_mod_type */
481 : : /* Description: change the field TYPE of an NODE_ASN element. */
482 : : /* The new value is the old one | (bitwise or) the */
483 : : /* paramener VALUE. */
484 : : /* Parameters: */
485 : : /* node: NODE_ASN element pointer. */
486 : : /* value: the integer value that must be or-ed with the current */
487 : : /* value of field TYPE. */
488 : : /* Return: NODE pointer. */
489 : : /******************************************************************/
490 : : ASN1_TYPE
491 : 467 : _asn1_mod_type (ASN1_TYPE node, unsigned int value)
492 : : {
493 [ - + ]: 467 : if (node == NULL)
494 : 0 : return node;
495 : 467 : node->type |= value;
496 : 467 : return node;
497 : : }
498 : :
499 : :
500 : : /******************************************************************/
501 : : /* Function : _asn1_remove_node */
502 : : /* Description: gets free the memory allocated for an NODE_ASN */
503 : : /* element (not the elements pointed by it). */
504 : : /* Parameters: */
505 : : /* node: NODE_ASN element pointer. */
506 : : /******************************************************************/
507 : : void
508 : 4400 : _asn1_remove_node (ASN1_TYPE node)
509 : : {
510 [ - + ]: 4400 : if (node == NULL)
511 : 4400 : return;
512 : :
513 [ + + ]: 4400 : if (node->name != NULL)
514 : 3169 : _asn1_free (node->name);
515 [ + + ][ + + ]: 4400 : if (node->value != NULL && node->value != node->small_value)
516 : 339 : _asn1_free (node->value);
517 : 4400 : _asn1_free (node);
518 : : }
519 : :
520 : : /******************************************************************/
521 : : /* Function : _asn1_find_up */
522 : : /* Description: return the father of the NODE_ASN element. */
523 : : /* Parameters: */
524 : : /* node: NODE_ASN element pointer. */
525 : : /* Return: Null if not found. */
526 : : /******************************************************************/
527 : : ASN1_TYPE
528 : 10412 : _asn1_find_up (ASN1_TYPE node)
529 : : {
530 : : ASN1_TYPE p;
531 : :
532 [ - + ]: 10412 : if (node == NULL)
533 : 0 : return NULL;
534 : :
535 : 10412 : p = node;
536 : :
537 [ + + ][ + + ]: 23936 : while ((p->left != NULL) && (p->left->right == p))
538 : 13524 : p = p->left;
539 : :
540 : 10412 : return p->left;
541 : : }
542 : :
543 : : /******************************************************************/
544 : : /* Function : _asn1_delete_list */
545 : : /* Description: deletes the list elements (not the elements */
546 : : /* pointed by them). */
547 : : /******************************************************************/
548 : : void
549 : 20 : _asn1_delete_list (void)
550 : : {
551 : : list_type *listElement;
552 : :
553 [ + + ]: 2630 : while (firstElement)
554 : : {
555 : 2610 : listElement = firstElement;
556 : 2610 : firstElement = firstElement->next;
557 : 2610 : _asn1_free (listElement);
558 : : }
559 : 20 : }
560 : :
561 : : /******************************************************************/
562 : : /* Function : _asn1_delete_list_and nodes */
563 : : /* Description: deletes the list elements and the elements */
564 : : /* pointed by them. */
565 : : /******************************************************************/
566 : : void
567 : 11 : _asn1_delete_list_and_nodes (void)
568 : : {
569 : : list_type *listElement;
570 : :
571 [ + + ]: 214 : while (firstElement)
572 : : {
573 : 203 : listElement = firstElement;
574 : 203 : firstElement = firstElement->next;
575 : 203 : _asn1_remove_node (listElement->node);
576 : 203 : _asn1_free (listElement);
577 : : }
578 : 11 : }
579 : :
580 : :
581 : : char *
582 : 288 : _asn1_ltostr (long v, char *str)
583 : : {
584 : : long d, r;
585 : : char temp[20];
586 : : int count, k, start;
587 : :
588 [ - + ]: 288 : if (v < 0)
589 : : {
590 : 0 : str[0] = '-';
591 : 0 : start = 1;
592 : 0 : v = -v;
593 : : }
594 : : else
595 : 288 : start = 0;
596 : :
597 : 288 : count = 0;
598 : : do
599 : : {
600 : 433 : d = v / 10;
601 : 433 : r = v - d * 10;
602 : 433 : temp[start + count] = '0' + (char) r;
603 : 433 : count++;
604 : 433 : v = d;
605 : : }
606 [ + + ]: 433 : while (v);
607 : :
608 [ + + ]: 721 : for (k = 0; k < count; k++)
609 : 433 : str[k + start] = temp[start + count - k - 1];
610 : 288 : str[count + start] = 0;
611 : 288 : return str;
612 : : }
613 : :
614 : :
615 : : /******************************************************************/
616 : : /* Function : _asn1_change_integer_value */
617 : : /* Description: converts into DER coding the value assign to an */
618 : : /* INTEGER constant. */
619 : : /* Parameters: */
620 : : /* node: root of an ASN1element. */
621 : : /* Return: */
622 : : /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
623 : : /* otherwise ASN1_SUCCESS */
624 : : /******************************************************************/
625 : : asn1_retCode
626 : 20 : _asn1_change_integer_value (ASN1_TYPE node)
627 : : {
628 : : ASN1_TYPE p;
629 : : unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
630 : : unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
631 : : int len;
632 : :
633 [ - + ]: 20 : if (node == NULL)
634 : 0 : return ASN1_ELEMENT_NOT_FOUND;
635 : :
636 : 20 : p = node;
637 [ + + ]: 2569 : while (p)
638 : : {
639 [ + + ][ + + ]: 2549 : if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
640 : : {
641 [ + - ]: 119 : if (p->value)
642 : : {
643 : 119 : _asn1_convert_integer (p->value, val, sizeof (val), &len);
644 : 119 : asn1_octet_der (val, len, val2, &len);
645 : 119 : _asn1_set_value (p, val2, len);
646 : : }
647 : : }
648 : :
649 [ + + ]: 2549 : if (p->down)
650 : : {
651 : 839 : p = p->down;
652 : : }
653 : : else
654 : : {
655 [ - + ]: 1710 : if (p == node)
656 : 0 : p = NULL;
657 [ + + ]: 1710 : else if (p->right)
658 : 995 : p = p->right;
659 : : else
660 : : {
661 : : while (1)
662 : : {
663 : 839 : p = _asn1_find_up (p);
664 [ + + ]: 839 : if (p == node)
665 : : {
666 : 20 : p = NULL;
667 : 20 : break;
668 : : }
669 [ + + ]: 819 : if (p->right)
670 : : {
671 : 695 : p = p->right;
672 : 695 : break;
673 : : }
674 : 124 : }
675 : : }
676 : : }
677 : : }
678 : :
679 : 20 : return ASN1_SUCCESS;
680 : : }
681 : :
682 : :
683 : : /******************************************************************/
684 : : /* Function : _asn1_expand_object_id */
685 : : /* Description: expand the IDs of an OBJECT IDENTIFIER constant. */
686 : : /* Parameters: */
687 : : /* node: root of an ASN1 element. */
688 : : /* Return: */
689 : : /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
690 : : /* otherwise ASN1_SUCCESS */
691 : : /******************************************************************/
692 : : asn1_retCode
693 : 20 : _asn1_expand_object_id (ASN1_TYPE node)
694 : : {
695 : : ASN1_TYPE p, p2, p3, p4, p5;
696 : : char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
697 : : int move, tlen;
698 : :
699 [ - + ]: 20 : if (node == NULL)
700 : 0 : return ASN1_ELEMENT_NOT_FOUND;
701 : :
702 : 20 : _asn1_str_cpy (name_root, sizeof (name_root), node->name);
703 : :
704 : 20 : p = node;
705 : 20 : move = DOWN;
706 : :
707 [ + + ][ + + ]: 4183 : while (!((p == node) && (move == UP)))
708 : : {
709 [ + + ]: 4163 : if (move != UP)
710 : : {
711 [ + + ]: 3344 : if ((type_field (p->type) == TYPE_OBJECT_ID)
712 [ + + ]: 442 : && (p->type & CONST_ASSIGN))
713 : : {
714 : 374 : p2 = p->down;
715 [ + - ][ + - ]: 374 : if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
716 : : {
717 [ + - ][ + + ]: 374 : if (p2->value && !isdigit (p2->value[0]))
718 : : {
719 : 175 : _asn1_str_cpy (name2, sizeof (name2), name_root);
720 : 175 : _asn1_str_cat (name2, sizeof (name2), ".");
721 : 175 : _asn1_str_cat (name2, sizeof (name2),
722 : 175 : (char *) p2->value);
723 : 175 : p3 = asn1_find_node (node, name2);
724 [ + - ][ + - ]: 175 : if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
[ - + ]
725 : 175 : !(p3->type & CONST_ASSIGN))
726 : 0 : return ASN1_ELEMENT_NOT_FOUND;
727 : 175 : _asn1_set_down (p, p2->right);
728 : 175 : _asn1_remove_node (p2);
729 : 175 : p2 = p;
730 : 175 : p4 = p3->down;
731 [ + + ]: 970 : while (p4)
732 : : {
733 [ + - ]: 795 : if (type_field (p4->type) == TYPE_CONSTANT)
734 : : {
735 : 795 : p5 = _asn1_add_node_only (TYPE_CONSTANT);
736 : 795 : _asn1_set_name (p5, p4->name);
737 : 795 : tlen = _asn1_strlen (p4->value);
738 [ + - ]: 795 : if (tlen > 0)
739 : 795 : _asn1_set_value (p5, p4->value, tlen + 1);
740 [ + + ]: 795 : if (p2 == p)
741 : : {
742 : 175 : _asn1_set_right (p5, p->down);
743 : 175 : _asn1_set_down (p, p5);
744 : : }
745 : : else
746 : : {
747 : 620 : _asn1_set_right (p5, p2->right);
748 : 620 : _asn1_set_right (p2, p5);
749 : : }
750 : 795 : p2 = p5;
751 : : }
752 : 795 : p4 = p4->right;
753 : : }
754 : 175 : move = DOWN;
755 : 175 : continue;
756 : : }
757 : : }
758 : : }
759 : 3169 : move = DOWN;
760 : : }
761 : : else
762 : 819 : move = RIGHT;
763 : :
764 [ + + ]: 3988 : if (move == DOWN)
765 : : {
766 [ + + ]: 3169 : if (p->down)
767 : 839 : p = p->down;
768 : : else
769 : 2330 : move = RIGHT;
770 : : }
771 : :
772 [ - + ]: 3988 : if (p == node)
773 : : {
774 : 0 : move = UP;
775 : 0 : continue;
776 : : }
777 : :
778 [ + + ]: 3988 : if (move == RIGHT)
779 : : {
780 [ + + ]: 3149 : if (p->right)
781 : 2310 : p = p->right;
782 : : else
783 : 839 : move = UP;
784 : : }
785 [ + + ]: 3988 : if (move == UP)
786 : 839 : p = _asn1_find_up (p);
787 : : }
788 : :
789 : :
790 : : /*******************************/
791 : : /* expand DEFAULT */
792 : : /*******************************/
793 : 20 : p = node;
794 : 20 : move = DOWN;
795 : :
796 [ + + ][ + + ]: 4008 : while (!((p == node) && (move == UP)))
797 : : {
798 [ + + ]: 3988 : if (move != UP)
799 : : {
800 [ + + ][ + + ]: 3169 : if ((type_field (p->type) == TYPE_OBJECT_ID) &&
801 : 267 : (p->type & CONST_DEFAULT))
802 : : {
803 : 19 : p2 = p->down;
804 [ + - ][ + - ]: 19 : if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
805 : : {
806 : 19 : _asn1_str_cpy (name2, sizeof (name2), name_root);
807 : 19 : _asn1_str_cat (name2, sizeof (name2), ".");
808 : 19 : _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
809 : 19 : p3 = asn1_find_node (node, name2);
810 [ + - ][ + - ]: 19 : if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
[ - + ]
811 : 19 : !(p3->type & CONST_ASSIGN))
812 : 0 : return ASN1_ELEMENT_NOT_FOUND;
813 : 19 : p4 = p3->down;
814 : 19 : name2[0] = 0;
815 [ + + ]: 95 : while (p4)
816 : : {
817 [ + - ]: 76 : if (type_field (p4->type) == TYPE_CONSTANT)
818 : : {
819 [ + + ]: 76 : if (name2[0])
820 : 57 : _asn1_str_cat (name2, sizeof (name2), ".");
821 : 76 : _asn1_str_cat (name2, sizeof (name2),
822 : 76 : (char *) p4->value);
823 : : }
824 : 76 : p4 = p4->right;
825 : : }
826 : 19 : tlen = strlen (name2);
827 [ + - ]: 19 : if (tlen > 0)
828 : 19 : _asn1_set_value (p2, name2, tlen + 1);
829 : : }
830 : : }
831 : 3169 : move = DOWN;
832 : : }
833 : : else
834 : 819 : move = RIGHT;
835 : :
836 [ + + ]: 3988 : if (move == DOWN)
837 : : {
838 [ + + ]: 3169 : if (p->down)
839 : 839 : p = p->down;
840 : : else
841 : 2330 : move = RIGHT;
842 : : }
843 : :
844 [ - + ]: 3988 : if (p == node)
845 : : {
846 : 0 : move = UP;
847 : 0 : continue;
848 : : }
849 : :
850 [ + + ]: 3988 : if (move == RIGHT)
851 : : {
852 [ + + ]: 3149 : if (p->right)
853 : 2310 : p = p->right;
854 : : else
855 : 839 : move = UP;
856 : : }
857 [ + + ]: 3988 : if (move == UP)
858 : 839 : p = _asn1_find_up (p);
859 : : }
860 : :
861 : 20 : return ASN1_SUCCESS;
862 : : }
863 : :
864 : :
865 : : /******************************************************************/
866 : : /* Function : _asn1_type_set_config */
867 : : /* Description: sets the CONST_SET and CONST_NOT_USED properties */
868 : : /* in the fields of the SET elements. */
869 : : /* Parameters: */
870 : : /* node: root of an ASN1 element. */
871 : : /* Return: */
872 : : /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
873 : : /* otherwise ASN1_SUCCESS */
874 : : /******************************************************************/
875 : : asn1_retCode
876 : 25 : _asn1_type_set_config (ASN1_TYPE node)
877 : : {
878 : : ASN1_TYPE p, p2;
879 : : int move;
880 : :
881 [ - + ]: 25 : if (node == NULL)
882 : 0 : return ASN1_ELEMENT_NOT_FOUND;
883 : :
884 : 25 : p = node;
885 : 25 : move = DOWN;
886 : :
887 [ + + ][ + + ]: 3545 : while (!((p == node) && (move == UP)))
888 : : {
889 [ + + ]: 3520 : if (move != UP)
890 : : {
891 [ + + ]: 2675 : if (type_field (p->type) == TYPE_SET)
892 : : {
893 : 8 : p2 = p->down;
894 [ + + ]: 32 : while (p2)
895 : : {
896 [ + - ]: 24 : if (type_field (p2->type) != TYPE_TAG)
897 : 24 : p2->type |= CONST_SET | CONST_NOT_USED;
898 : 24 : p2 = p2->right;
899 : : }
900 : : }
901 : 2675 : move = DOWN;
902 : : }
903 : : else
904 : 845 : move = RIGHT;
905 : :
906 [ + + ]: 3520 : if (move == DOWN)
907 : : {
908 [ + + ]: 2675 : if (p->down)
909 : 870 : p = p->down;
910 : : else
911 : 1805 : move = RIGHT;
912 : : }
913 : :
914 [ - + ]: 3520 : if (p == node)
915 : : {
916 : 0 : move = UP;
917 : 0 : continue;
918 : : }
919 : :
920 [ + + ]: 3520 : if (move == RIGHT)
921 : : {
922 [ + + ]: 2650 : if (p->right)
923 : 1780 : p = p->right;
924 : : else
925 : 870 : move = UP;
926 : : }
927 [ + + ]: 3520 : if (move == UP)
928 : 870 : p = _asn1_find_up (p);
929 : : }
930 : :
931 : 25 : return ASN1_SUCCESS;
932 : : }
933 : :
934 : :
935 : : /******************************************************************/
936 : : /* Function : _asn1_check_identifier */
937 : : /* Description: checks the definitions of all the identifiers */
938 : : /* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */
939 : : /* The _asn1_identifierMissing global variable is filled if */
940 : : /* necessary. */
941 : : /* Parameters: */
942 : : /* node: root of an ASN1 element. */
943 : : /* Return: */
944 : : /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
945 : : /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
946 : : /* otherwise ASN1_SUCCESS */
947 : : /******************************************************************/
948 : : asn1_retCode
949 : 25 : _asn1_check_identifier (ASN1_TYPE node)
950 : : {
951 : : ASN1_TYPE p, p2;
952 : : char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
953 : :
954 [ - + ]: 25 : if (node == NULL)
955 : 0 : return ASN1_ELEMENT_NOT_FOUND;
956 : :
957 : 25 : p = node;
958 [ + + ]: 2642 : while (p)
959 : : {
960 [ + + ]: 2622 : if (type_field (p->type) == TYPE_IDENTIFIER)
961 : : {
962 : 460 : _asn1_str_cpy (name2, sizeof (name2), node->name);
963 : 460 : _asn1_str_cat (name2, sizeof (name2), ".");
964 : 460 : _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
965 : 460 : p2 = asn1_find_node (node, name2);
966 [ + + ]: 460 : if (p2 == NULL)
967 : : {
968 : 2 : _asn1_strcpy (_asn1_identifierMissing, p->value);
969 : 2 : return ASN1_IDENTIFIER_NOT_FOUND;
970 : : }
971 : : }
972 [ + + ][ + + ]: 2162 : else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
973 : 275 : (p->type & CONST_DEFAULT))
974 : : {
975 : 21 : p2 = p->down;
976 [ + - ][ + - ]: 40 : if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
977 : : {
978 : 21 : _asn1_str_cpy (name2, sizeof (name2), node->name);
979 : 21 : _asn1_str_cat (name2, sizeof (name2), ".");
980 : 21 : _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
981 : 21 : _asn1_strcpy (_asn1_identifierMissing, p2->value);
982 : 21 : p2 = asn1_find_node (node, name2);
983 [ + + ][ + - ]: 21 : if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
[ - + ]
984 : 19 : !(p2->type & CONST_ASSIGN))
985 : 2 : return ASN1_IDENTIFIER_NOT_FOUND;
986 : : else
987 : 19 : _asn1_identifierMissing[0] = 0;
988 : : }
989 : : }
990 [ + + ][ + + ]: 2141 : else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
991 : 254 : (p->type & CONST_ASSIGN))
992 : : {
993 : 200 : p2 = p->down;
994 [ + - ][ + - ]: 200 : if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
995 : : {
996 [ + - ][ + + ]: 200 : if (p2->value && !isdigit (p2->value[0]))
997 : : {
998 : 158 : _asn1_str_cpy (name2, sizeof (name2), node->name);
999 : 158 : _asn1_str_cat (name2, sizeof (name2), ".");
1000 : 158 : _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
1001 : 158 : _asn1_strcpy (_asn1_identifierMissing, p2->value);
1002 : 158 : p2 = asn1_find_node (node, name2);
1003 [ + + ][ + - ]: 158 : if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
[ - + ]
1004 : 157 : !(p2->type & CONST_ASSIGN))
1005 : 1 : return ASN1_IDENTIFIER_NOT_FOUND;
1006 : : else
1007 : 157 : _asn1_identifierMissing[0] = 0;
1008 : : }
1009 : : }
1010 : : }
1011 : :
1012 [ + + ]: 2617 : if (p->down)
1013 : : {
1014 : 854 : p = p->down;
1015 : : }
1016 [ + + ]: 1763 : else if (p->right)
1017 : 1041 : p = p->right;
1018 : : else
1019 : : {
1020 : : while (1)
1021 : : {
1022 : 846 : p = _asn1_find_up (p);
1023 [ + + ]: 846 : if (p == node)
1024 : : {
1025 : 20 : p = NULL;
1026 : 20 : break;
1027 : : }
1028 [ + + ]: 826 : if (p->right)
1029 : : {
1030 : 702 : p = p->right;
1031 : 702 : break;
1032 : : }
1033 : 124 : }
1034 : : }
1035 : : }
1036 : :
1037 : 25 : return ASN1_SUCCESS;
1038 : : }
1039 : :
1040 : :
1041 : : /******************************************************************/
1042 : : /* Function : _asn1_set_default_tag */
1043 : : /* Description: sets the default IMPLICIT or EXPLICIT property in */
1044 : : /* the tagged elements that don't have this declaration. */
1045 : : /* Parameters: */
1046 : : /* node: pointer to a DEFINITIONS element. */
1047 : : /* Return: */
1048 : : /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */
1049 : : /* a DEFINITIONS element, */
1050 : : /* otherwise ASN1_SUCCESS */
1051 : : /******************************************************************/
1052 : : asn1_retCode
1053 : 25 : _asn1_set_default_tag (ASN1_TYPE node)
1054 : : {
1055 : : ASN1_TYPE p;
1056 : :
1057 [ + - ][ - + ]: 25 : if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
1058 : 0 : return ASN1_ELEMENT_NOT_FOUND;
1059 : :
1060 : 25 : p = node;
1061 [ + + ]: 2700 : while (p)
1062 : : {
1063 [ + + ][ + + ]: 2675 : if ((type_field (p->type) == TYPE_TAG) &&
1064 [ + + ]: 123 : !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1065 : : {
1066 [ - + ]: 86 : if (node->type & CONST_EXPLICIT)
1067 : 0 : p->type |= CONST_EXPLICIT;
1068 : : else
1069 : 86 : p->type |= CONST_IMPLICIT;
1070 : : }
1071 : :
1072 [ + + ]: 2675 : if (p->down)
1073 : : {
1074 : 870 : p = p->down;
1075 : : }
1076 [ + + ]: 1805 : else if (p->right)
1077 : 1064 : p = p->right;
1078 : : else
1079 : : {
1080 : : while (1)
1081 : : {
1082 : 870 : p = _asn1_find_up (p);
1083 [ + + ]: 870 : if (p == node)
1084 : : {
1085 : 25 : p = NULL;
1086 : 25 : break;
1087 : : }
1088 [ + + ]: 845 : if (p->right)
1089 : : {
1090 : 716 : p = p->right;
1091 : 716 : break;
1092 : : }
1093 : 129 : }
1094 : : }
1095 : : }
1096 : :
1097 : 25 : return ASN1_SUCCESS;
1098 : : }
|