Coverage Report

Created: 2023-06-07 06:11

/src/libtasn1/lib/parser_aux.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2000-2023 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 <limits.h>   /* WORD_BIT */
23
24
#include "int.h"
25
#include "parser_aux.h"
26
#include "gstr.h"
27
#include "structure.h"
28
#include "element.h"
29
#include "c-ctype.h"
30
31
char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
32
33
/* Return a hash of the N bytes of X using the method described by
34
   Bruno Haible in https://www.haible.de/bruno/hashfunc.html.
35
   Note that while many hash functions reduce their result via modulo
36
   to a 0..table_size-1 range, this function does not do that.
37
38
   This implementation has been changed from size_t -> unsigned int. */
39
40
#ifdef __clang__
41
__attribute__((no_sanitize ("integer")))
42
#endif
43
     _GL_ATTRIBUTE_PURE static unsigned int _asn1_hash_name (const char *x)
44
83.1k
{
45
83.1k
  const unsigned char *s = (unsigned char *) x;
46
83.1k
  unsigned h = 0;
47
48
156k
  while (*s)
49
73.3k
    h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9)));
50
51
83.1k
  return h;
52
83.1k
}
53
54
/******************************************************/
55
/* Function : _asn1_add_static_node                   */
56
/* Description: creates a new NODE_ASN element and    */
57
/* puts it in the list pointed by e_list.       */
58
/* Parameters:                                        */
59
/*   e_list: of type list_type; must be NULL initially */
60
/*   type: type of the new element (see ASN1_ETYPE_   */
61
/*         and CONST_ constants).                     */
62
/* Return: pointer to the new element.                */
63
/******************************************************/
64
asn1_node
65
_asn1_add_static_node (list_type ** e_list, unsigned int type)
66
44.9k
{
67
44.9k
  list_type *p;
68
44.9k
  asn1_node punt;
69
70
44.9k
  punt = calloc (1, sizeof (struct asn1_node_st));
71
44.9k
  if (punt == NULL)
72
0
    return NULL;
73
74
44.9k
  p = malloc (sizeof (list_type));
75
44.9k
  if (p == NULL)
76
0
    {
77
0
      free (punt);
78
0
      return NULL;
79
0
    }
80
81
44.9k
  p->node = punt;
82
44.9k
  p->next = *e_list;
83
44.9k
  *e_list = p;
84
85
44.9k
  punt->type = type;
86
87
44.9k
  return punt;
88
44.9k
}
89
90
static int
91
_asn1_add_static_node2 (list_type ** e_list, asn1_node node)
92
37.1k
{
93
37.1k
  list_type *p;
94
95
37.1k
  p = malloc (sizeof (list_type));
96
37.1k
  if (p == NULL)
97
0
    {
98
0
      return -1;
99
0
    }
100
101
37.1k
  p->node = node;
102
37.1k
  p->next = *e_list;
103
37.1k
  *e_list = p;
104
105
37.1k
  return 0;
106
37.1k
}
107
108
/**
109
 * asn1_find_node:
110
 * @pointer: NODE_ASN element pointer.
111
 * @name: null terminated string with the element's name to find.
112
 *
113
 * Searches for an element called @name starting from @pointer.  The
114
 * name is composed by different identifiers separated by dots.  When
115
 * *@pointer has a name, the first identifier must be the name of
116
 * *@pointer, otherwise it must be the name of one child of *@pointer.
117
 *
118
 * Returns: the search result, or %NULL if not found.
119
 **/
120
asn1_node
121
asn1_find_node (asn1_node_const pointer, const char *name)
122
9.24k
{
123
9.24k
  asn1_node_const p;
124
9.24k
  char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
125
9.24k
  const char *n_start;
126
9.24k
  unsigned int nsize;
127
9.24k
  unsigned int nhash;
128
129
9.24k
  if (pointer == NULL)
130
0
    return NULL;
131
132
9.24k
  if (name == NULL)
133
0
    return NULL;
134
135
9.24k
  p = pointer;
136
9.24k
  n_start = name;
137
138
9.24k
  if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?')
139
202
    {       /* ?CURRENT */
140
202
      n_start = strchr (n_start, '.');
141
202
      if (n_start)
142
201
  n_start++;
143
202
    }
144
9.04k
  else if (p->name[0] != 0)
145
8.48k
    {       /* has *pointer got a name ? */
146
8.48k
      n_end = strchr (n_start, '.');  /* search the first dot */
147
8.48k
      if (n_end)
148
8.46k
  {
149
8.46k
    nsize = n_end - n_start;
150
8.46k
    if (nsize >= sizeof (n))
151
0
      return NULL;
152
153
8.46k
    memcpy (n, n_start, nsize);
154
8.46k
    n[nsize] = 0;
155
8.46k
    n_start = n_end;
156
8.46k
    n_start++;
157
158
8.46k
    nhash = _asn1_hash_name (n);
159
8.46k
  }
160
13
      else
161
13
  {
162
13
    _asn1_str_cpy (n, sizeof (n), n_start);
163
13
    nhash = _asn1_hash_name (n);
164
165
13
    n_start = NULL;
166
13
  }
167
168
8.53k
      while (p)
169
8.48k
  {
170
8.48k
    if (nhash == p->name_hash && (!strcmp (p->name, n)))
171
8.42k
      break;
172
54
    else
173
54
      p = p->right;
174
8.48k
  }     /* while */
175
176
8.48k
      if (p == NULL)
177
54
  return NULL;
178
8.48k
    }
179
562
  else
180
562
    {       /* *pointer doesn't have a name */
181
562
      if (n_start[0] == 0)
182
1
  return (asn1_node) p;
183
562
    }
184
185
18.6k
  while (n_start)
186
9.73k
    {       /* Has the end of NAME been reached? */
187
9.73k
      n_end = strchr (n_start, '.');  /* search the next dot */
188
9.73k
      if (n_end)
189
561
  {
190
561
    nsize = n_end - n_start;
191
561
    if (nsize >= sizeof (n))
192
0
      return NULL;
193
194
561
    memcpy (n, n_start, nsize);
195
561
    n[nsize] = 0;
196
561
    n_start = n_end;
197
561
    n_start++;
198
199
561
    nhash = _asn1_hash_name (n);
200
561
  }
201
9.17k
      else
202
9.17k
  {
203
9.17k
    _asn1_str_cpy (n, sizeof (n), n_start);
204
9.17k
    nhash = _asn1_hash_name (n);
205
9.17k
    n_start = NULL;
206
9.17k
  }
207
208
9.73k
      if (p->down == NULL)
209
3
  return NULL;
210
211
9.73k
      p = p->down;
212
9.73k
      if (p == NULL)
213
0
  return NULL;
214
215
      /* The identifier "?LAST" indicates the last element
216
         in the right chain. */
217
9.73k
      if (n[0] == '?' && n[1] == 'L')  /* ?LAST */
218
1.07k
  {
219
15.5k
    while (p->right)
220
14.4k
      p = p->right;
221
1.07k
  }
222
8.65k
      else
223
8.65k
  {     /* no "?LAST" */
224
49.5k
    while (p)
225
49.1k
      {
226
49.1k
        if (p->name_hash == nhash && !strcmp (p->name, n))
227
8.33k
    break;
228
40.8k
        else
229
40.8k
    p = p->right;
230
49.1k
      }
231
8.65k
  }
232
9.73k
      if (p == NULL)
233
320
  return NULL;
234
9.73k
    }        /* while */
235
236
8.86k
  return (asn1_node) p;
237
9.18k
}
238
239
240
/******************************************************************/
241
/* Function : _asn1_set_value                                     */
242
/* Description: sets the field VALUE in a NODE_ASN element. The   */
243
/*              previous value (if exist) will be lost            */
244
/* Parameters:                                                    */
245
/*   node: element pointer.                                       */
246
/*   value: pointer to the value that you want to set.            */
247
/*   len: character number of value.                              */
248
/* Return: pointer to the NODE_ASN element.                       */
249
/******************************************************************/
250
asn1_node
251
_asn1_set_value (asn1_node node, const void *value, unsigned int len)
252
67.4k
{
253
67.4k
  if (node == NULL)
254
0
    return node;
255
67.4k
  if (node->value)
256
2.46k
    {
257
2.46k
      if (node->value != node->small_value)
258
420
  free (node->value);
259
2.46k
      node->value = NULL;
260
2.46k
      node->value_len = 0;
261
2.46k
    }
262
263
67.4k
  if (!len)
264
0
    return node;
265
266
67.4k
  if (len < sizeof (node->small_value))
267
62.3k
    {
268
62.3k
      node->value = node->small_value;
269
62.3k
    }
270
5.07k
  else
271
5.07k
    {
272
5.07k
      node->value = malloc (len);
273
5.07k
      if (node->value == NULL)
274
0
  return NULL;
275
5.07k
    }
276
67.4k
  node->value_len = len;
277
278
67.4k
  memcpy (node->value, value, len);
279
67.4k
  return node;
280
67.4k
}
281
282
/******************************************************************/
283
/* Function : _asn1_set_value_lv                                  */
284
/* Description: sets the field VALUE in a NODE_ASN element. The   */
285
/*              previous value (if exist) will be lost. The value */
286
/*    given is stored as an length-value format (LV     */
287
/* Parameters:                                                    */
288
/*   node: element pointer.                                       */
289
/*   value: pointer to the value that you want to set.            */
290
/*   len: character number of value.                              */
291
/* Return: pointer to the NODE_ASN element.                       */
292
/******************************************************************/
293
asn1_node
294
_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
295
0
{
296
0
  int len2;
297
0
  void *temp;
298
299
0
  if (node == NULL)
300
0
    return node;
301
302
0
  asn1_length_der (len, NULL, &len2);
303
0
  temp = malloc (len + len2);
304
0
  if (temp == NULL)
305
0
    return NULL;
306
307
0
  asn1_octet_der (value, len, temp, &len2);
308
0
  return _asn1_set_value_m (node, temp, len2);
309
0
}
310
311
/* the same as _asn1_set_value except that it sets an already malloc'ed
312
 * value.
313
 */
314
asn1_node
315
_asn1_set_value_m (asn1_node node, void *value, unsigned int len)
316
0
{
317
0
  if (node == NULL)
318
0
    return node;
319
320
0
  if (node->value)
321
0
    {
322
0
      if (node->value != node->small_value)
323
0
  free (node->value);
324
0
      node->value = NULL;
325
0
      node->value_len = 0;
326
0
    }
327
328
0
  if (!len)
329
0
    return node;
330
331
0
  node->value = value;
332
0
  node->value_len = len;
333
334
0
  return node;
335
0
}
336
337
/******************************************************************/
338
/* Function : _asn1_append_value                                  */
339
/* Description: appends to the field VALUE in a NODE_ASN element. */
340
/*                        */
341
/* Parameters:                                                    */
342
/*   node: element pointer.                                       */
343
/*   value: pointer to the value that you want to be appended.    */
344
/*   len: character number of value.                              */
345
/* Return: pointer to the NODE_ASN element.                       */
346
/******************************************************************/
347
asn1_node
348
_asn1_append_value (asn1_node node, const void *value, unsigned int len)
349
0
{
350
0
  if (node == NULL)
351
0
    return node;
352
353
0
  if (node->value == NULL)
354
0
    return _asn1_set_value (node, value, len);
355
356
0
  if (len == 0)
357
0
    return node;
358
359
0
  if (node->value == node->small_value)
360
0
    {
361
      /* value is in node */
362
0
      int prev_len = node->value_len;
363
0
      node->value_len += len;
364
0
      node->value = malloc (node->value_len);
365
0
      if (node->value == NULL)
366
0
  {
367
0
    node->value_len = 0;
368
0
    return NULL;
369
0
  }
370
371
0
      if (prev_len > 0)
372
0
  memcpy (node->value, node->small_value, prev_len);
373
374
0
      memcpy (&node->value[prev_len], value, len);
375
376
0
      return node;
377
0
    }
378
0
  else        /* if (node->value != NULL && node->value != node->small_value) */
379
0
    {
380
      /* value is allocated */
381
0
      int prev_len = node->value_len;
382
0
      node->value_len += len;
383
384
0
      node->value = _asn1_realloc (node->value, node->value_len);
385
0
      if (node->value == NULL)
386
0
  {
387
0
    node->value_len = 0;
388
0
    return NULL;
389
0
  }
390
391
0
      memcpy (&node->value[prev_len], value, len);
392
393
0
      return node;
394
0
    }
395
0
}
396
397
/******************************************************************/
398
/* Function : _asn1_set_name                                      */
399
/* Description: sets the field NAME in a NODE_ASN element. The    */
400
/*              previous value (if exist) will be lost            */
401
/* Parameters:                                                    */
402
/*   node: element pointer.                                       */
403
/*   name: a null terminated string with the name that you want   */
404
/*         to set.                                                */
405
/* Return: pointer to the NODE_ASN element.                       */
406
/******************************************************************/
407
asn1_node
408
_asn1_set_name (asn1_node node, const char *name)
409
64.9k
{
410
64.9k
  if (node == NULL)
411
0
    return node;
412
413
64.9k
  _asn1_str_cpy (node->name, sizeof (node->name), name ? name : "");
414
64.9k
  node->name_hash = _asn1_hash_name (node->name);
415
416
64.9k
  return node;
417
64.9k
}
418
419
/******************************************************************/
420
/* Function : _asn1_cpy_name                                      */
421
/* Description: copies the field NAME in a NODE_ASN element.      */
422
/* Parameters:                                                    */
423
/*   dst: a dest element pointer.                                 */
424
/*   src: a source element pointer.                               */
425
/* Return: pointer to the NODE_ASN element.                       */
426
/******************************************************************/
427
asn1_node
428
_asn1_cpy_name (asn1_node dst, asn1_node_const src)
429
0
{
430
0
  if (dst == NULL)
431
0
    return dst;
432
433
0
  if (src == NULL)
434
0
    {
435
0
      dst->name[0] = 0;
436
0
      dst->name_hash = _asn1_hash_name (dst->name);
437
0
      return dst;
438
0
    }
439
440
0
  _asn1_str_cpy (dst->name, sizeof (dst->name), src->name);
441
0
  dst->name_hash = src->name_hash;
442
443
0
  return dst;
444
0
}
445
446
/******************************************************************/
447
/* Function : _asn1_set_right                                     */
448
/* Description: sets the field RIGHT in a NODE_ASN element.       */
449
/* Parameters:                                                    */
450
/*   node: element pointer.                                       */
451
/*   right: pointer to a NODE_ASN element that you want be pointed*/
452
/*          by NODE.                                              */
453
/* Return: pointer to *NODE.                                      */
454
/******************************************************************/
455
asn1_node
456
_asn1_set_right (asn1_node node, asn1_node right)
457
102k
{
458
102k
  if (node == NULL)
459
0
    return node;
460
102k
  node->right = right;
461
102k
  if (right)
462
93.8k
    right->left = node;
463
102k
  return node;
464
102k
}
465
466
467
/******************************************************************/
468
/* Function : _asn1_get_last_right                                */
469
/* Description: return the last element along the right chain.    */
470
/* Parameters:                                                    */
471
/*   node: starting element pointer.                              */
472
/* Return: pointer to the last element along the right chain.     */
473
/******************************************************************/
474
asn1_node
475
_asn1_get_last_right (asn1_node_const node)
476
24.1k
{
477
24.1k
  asn1_node_const p;
478
479
24.1k
  if (node == NULL)
480
0
    return NULL;
481
24.1k
  p = node;
482
1.11M
  while (p->right)
483
1.08M
    p = p->right;
484
24.1k
  return (asn1_node) p;
485
24.1k
}
486
487
/******************************************************************/
488
/* Function : _asn1_remove_node                                   */
489
/* Description: gets free the memory allocated for an NODE_ASN    */
490
/*              element (not the elements pointed by it).         */
491
/* Parameters:                                                    */
492
/*   node: NODE_ASN element pointer.                              */
493
/*   flags: ASN1_DELETE_FLAG_*                                    */
494
/******************************************************************/
495
void
496
_asn1_remove_node (asn1_node node, unsigned int flags)
497
83.4k
{
498
83.4k
  if (node == NULL)
499
1.32k
    return;
500
501
82.1k
  if (node->value != NULL)
502
64.9k
    {
503
64.9k
      if (flags & ASN1_DELETE_FLAG_ZEROIZE)
504
0
  {
505
0
    safe_memset (node->value, 0, node->value_len);
506
0
  }
507
508
64.9k
      if (node->value != node->small_value)
509
4.65k
  free (node->value);
510
64.9k
    }
511
82.1k
  free (node);
512
82.1k
}
513
514
/******************************************************************/
515
/* Function : _asn1_find_up                                       */
516
/* Description: return the father of the NODE_ASN element.        */
517
/* Parameters:                                                    */
518
/*   node: NODE_ASN element pointer.                              */
519
/* Return: Null if not found.                                     */
520
/******************************************************************/
521
asn1_node
522
_asn1_find_up (asn1_node_const node)
523
55.6k
{
524
55.6k
  asn1_node_const p;
525
526
55.6k
  if (node == NULL)
527
0
    return NULL;
528
529
55.6k
  p = node;
530
531
166k
  while ((p->left != NULL) && (p->left->right == p))
532
110k
    p = p->left;
533
534
55.6k
  return p->left;
535
55.6k
}
536
537
static unsigned
538
_asn1_is_up (asn1_node_const up_cand, asn1_node_const down)
539
5.00k
{
540
5.00k
  asn1_node_const d, u;
541
542
5.00k
  if (up_cand == NULL || down == NULL)
543
0
    return 0;
544
545
5.00k
  d = down;
546
547
10.0k
  while ((u = _asn1_find_up (d)) != NULL && u != d)
548
5.00k
    {
549
5.00k
      if (u == up_cand)
550
0
  return 1;
551
5.00k
      d = u;
552
5.00k
    }
553
554
5.00k
  return 0;
555
5.00k
}
556
557
/******************************************************************/
558
/* Function : _asn1_delete_node_from_list                         */
559
/* Description: deletes the list element given                    */
560
/******************************************************************/
561
void
562
_asn1_delete_node_from_list (list_type * list, asn1_node node)
563
4.99k
{
564
4.99k
  list_type *p = list;
565
566
708k
  while (p)
567
703k
    {
568
703k
      if (p->node == node)
569
4.99k
  p->node = NULL;
570
703k
      p = p->next;
571
703k
    }
572
4.99k
}
573
574
/******************************************************************/
575
/* Function : _asn1_delete_list                                   */
576
/* Description: deletes the list elements (not the elements       */
577
/*  pointed by them).                                             */
578
/******************************************************************/
579
void
580
_asn1_delete_list (list_type * e_list)
581
440
{
582
440
  list_type *p;
583
584
23.6k
  while (e_list)
585
23.2k
    {
586
23.2k
      p = e_list;
587
23.2k
      e_list = e_list->next;
588
23.2k
      free (p);
589
23.2k
    }
590
440
}
591
592
/******************************************************************/
593
/* Function : _asn1_delete_list_and nodes                         */
594
/* Description: deletes the list elements and the elements        */
595
/*  pointed by them.                                              */
596
/******************************************************************/
597
void
598
_asn1_delete_list_and_nodes (list_type * e_list)
599
1.88k
{
600
1.88k
  list_type *p;
601
602
60.7k
  while (e_list)
603
58.8k
    {
604
58.8k
      p = e_list;
605
58.8k
      e_list = e_list->next;
606
58.8k
      _asn1_remove_node (p->node, 0);
607
58.8k
      free (p);
608
58.8k
    }
609
1.88k
}
610
611
612
char *
613
_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE])
614
0
{
615
0
  uint64_t d, r;
616
0
  char temp[LTOSTR_MAX_SIZE];
617
0
  int count, k, start;
618
0
  uint64_t val;
619
620
0
  if (v < 0)
621
0
    {
622
0
      str[0] = '-';
623
0
      start = 1;
624
0
      val = -((uint64_t) v);
625
0
    }
626
0
  else
627
0
    {
628
0
      val = v;
629
0
      start = 0;
630
0
    }
631
632
0
  count = 0;
633
0
  do
634
0
    {
635
0
      d = val / 10;
636
0
      r = val - d * 10;
637
0
      temp[start + count] = '0' + (char) r;
638
0
      count++;
639
0
      val = d;
640
0
    }
641
0
  while (val && ((start + count) < LTOSTR_MAX_SIZE - 1));
642
643
0
  for (k = 0; k < count; k++)
644
0
    str[k + start] = temp[start + count - k - 1];
645
0
  str[count + start] = 0;
646
0
  return str;
647
0
}
648
649
650
/******************************************************************/
651
/* Function : _asn1_change_integer_value                          */
652
/* Description: converts into DER coding the value assign to an   */
653
/*   INTEGER constant.                                            */
654
/* Parameters:                                                    */
655
/*   node: root of an ASN1element.                                */
656
/* Return:                                                        */
657
/*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
658
/*   otherwise ASN1_SUCCESS                                             */
659
/******************************************************************/
660
int
661
_asn1_change_integer_value (asn1_node node)
662
589
{
663
589
  asn1_node p;
664
589
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
665
589
  unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
666
589
  int len;
667
668
589
  if (node == NULL)
669
0
    return ASN1_ELEMENT_NOT_FOUND;
670
671
589
  p = node;
672
13.2k
  while (p)
673
12.7k
    {
674
12.7k
      if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
675
12.7k
    && (p->type & CONST_ASSIGN))
676
1.84k
  {
677
1.84k
    if (p->value)
678
1.84k
      {
679
1.84k
        _asn1_convert_integer (p->value, val, sizeof (val), &len);
680
1.84k
        asn1_octet_der (val, len, val2, &len);
681
1.84k
        _asn1_set_value (p, val2, len);
682
1.84k
      }
683
1.84k
  }
684
685
12.7k
      if (p->down)
686
4.24k
  {
687
4.24k
    p = p->down;
688
4.24k
  }
689
8.46k
      else
690
8.46k
  {
691
8.46k
    if (p == node)
692
0
      p = NULL;
693
8.46k
    else if (p->right)
694
5.28k
      p = p->right;
695
3.17k
    else
696
3.17k
      {
697
4.24k
        while (1)
698
4.24k
    {
699
4.24k
      p = _asn1_find_up (p);
700
4.24k
      if (p == node)
701
589
        {
702
589
          p = NULL;
703
589
          break;
704
589
        }
705
3.65k
      if (p && p->right)
706
2.58k
        {
707
2.58k
          p = p->right;
708
2.58k
          break;
709
2.58k
        }
710
3.65k
    }
711
3.17k
      }
712
8.46k
  }
713
12.7k
    }
714
715
589
  return ASN1_SUCCESS;
716
589
}
717
718
37.1k
#define MAX_CONSTANTS 1024
719
/******************************************************************/
720
/* Function : _asn1_expand_object_id                              */
721
/* Description: expand the IDs of an OBJECT IDENTIFIER constant.  */
722
/* Parameters:                                                    */
723
/*   list: root of an object list                                 */
724
/*   node: root of an ASN1 element.                               */
725
/* Return:                                                        */
726
/*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                      */
727
/*   otherwise ASN1_SUCCESS                                       */
728
/******************************************************************/
729
int
730
_asn1_expand_object_id (list_type ** list, asn1_node node)
731
589
{
732
589
  asn1_node p, p2, p3, p4, p5;
733
589
  char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
734
589
  int move, tlen, tries;
735
589
  unsigned max_constants;
736
737
589
  if (node == NULL)
738
0
    return ASN1_ELEMENT_NOT_FOUND;
739
740
589
  _asn1_str_cpy (name_root, sizeof (name_root), node->name);
741
742
589
  p = node;
743
589
  move = DOWN;
744
589
  tries = 0;
745
746
29.5k
  while (!((p == node) && (move == UP)))
747
29.0k
    {
748
29.0k
      if (move != UP)
749
26.2k
  {
750
26.2k
    if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
751
26.2k
        && (p->type & CONST_ASSIGN))
752
6.49k
      {
753
6.49k
        p2 = p->down;
754
6.49k
        if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
755
5.89k
    {
756
5.89k
      if (p2->value && !c_isdigit (p2->value[0]))
757
5.08k
        {
758
5.08k
          _asn1_str_cpy (name2, sizeof (name2), name_root);
759
5.08k
          _asn1_str_cat (name2, sizeof (name2), ".");
760
5.08k
          _asn1_str_cat (name2, sizeof (name2),
761
5.08k
             (char *) p2->value);
762
5.08k
          p3 = asn1_find_node (node, name2);
763
5.08k
          if (!p3 || _asn1_is_up (p2, p3) ||
764
5.08k
        (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
765
5.08k
        !(p3->type & CONST_ASSIGN))
766
95
      return ASN1_ELEMENT_NOT_FOUND;
767
768
4.99k
          _asn1_set_down (p, p2->right);
769
4.99k
          if (p2->down)
770
0
      _asn1_delete_structure (*list, &p2->down, 0);
771
4.99k
          _asn1_delete_node_from_list (*list, p2);
772
4.99k
          _asn1_remove_node (p2, 0);
773
4.99k
          p2 = p;
774
4.99k
          p4 = p3->down;
775
4.99k
          max_constants = 0;
776
42.1k
          while (p4)
777
37.1k
      {
778
37.1k
        if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
779
37.1k
          {
780
37.1k
            max_constants++;
781
37.1k
            if (max_constants == MAX_CONSTANTS)
782
9
        return ASN1_RECURSION;
783
784
37.1k
            p5 =
785
37.1k
        _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
786
37.1k
            _asn1_set_name (p5, p4->name);
787
37.1k
            if (p4->value)
788
35.0k
        {
789
35.0k
          tlen = _asn1_strlen (p4->value);
790
35.0k
          if (tlen > 0)
791
34.5k
            _asn1_set_value (p5, p4->value, tlen + 1);
792
35.0k
        }
793
37.1k
            _asn1_add_static_node2 (list, p5);
794
795
37.1k
            if (p2 == p)
796
3.02k
        {
797
3.02k
          _asn1_set_right (p5, p->down);
798
3.02k
          _asn1_set_down (p, p5);
799
3.02k
        }
800
34.1k
            else
801
34.1k
        {
802
34.1k
          _asn1_set_right (p5, p2->right);
803
34.1k
          _asn1_set_right (p2, p5);
804
34.1k
        }
805
37.1k
            p2 = p5;
806
37.1k
          }
807
37.1k
        p4 = p4->right;
808
37.1k
      }
809
4.98k
          move = DOWN;
810
811
4.98k
          tries++;
812
4.98k
          if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION)
813
43
      return ASN1_RECURSION;
814
815
4.94k
          continue;
816
4.98k
        }
817
5.89k
    }
818
6.49k
      }
819
21.1k
    move = DOWN;
820
21.1k
  }
821
2.88k
      else
822
2.88k
  move = RIGHT;
823
824
24.0k
      tries = 0;
825
24.0k
      if (move == DOWN)
826
21.1k
  {
827
21.1k
    if (p->down)
828
3.47k
      p = p->down;
829
17.6k
    else
830
17.6k
      move = RIGHT;
831
21.1k
  }
832
833
24.0k
      if (p == node)
834
0
  {
835
0
    move = UP;
836
0
    continue;
837
0
  }
838
839
24.0k
      if (move == RIGHT)
840
20.5k
  {
841
20.5k
    if (p && p->right)
842
17.2k
      p = p->right;
843
3.32k
    else
844
3.32k
      move = UP;
845
20.5k
  }
846
24.0k
      if (move == UP)
847
3.32k
  p = _asn1_find_up (p);
848
24.0k
    }
849
850
  /*******************************/
851
  /*       expand DEFAULT        */
852
  /*******************************/
853
442
  p = node;
854
442
  move = DOWN;
855
856
22.8k
  while (!((p == node) && (move == UP)))
857
22.4k
    {
858
22.4k
      if (move != UP)
859
19.5k
  {
860
19.5k
    if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
861
19.5k
        (p->type & CONST_DEFAULT))
862
817
      {
863
817
        p2 = p->down;
864
817
        if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
865
817
    {
866
817
      _asn1_str_cpy (name2, sizeof (name2), name_root);
867
817
      _asn1_str_cat (name2, sizeof (name2), ".");
868
817
      if (p2->value)
869
817
        _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
870
817
      p3 = asn1_find_node (node, name2);
871
817
      if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
872
817
          || !(p3->type & CONST_ASSIGN))
873
1
        return ASN1_ELEMENT_NOT_FOUND;
874
816
      p4 = p3->down;
875
816
      name2[0] = 0;
876
3.48k
      while (p4)
877
2.66k
        {
878
2.66k
          if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
879
2.66k
      {
880
2.66k
        if (p4->value == NULL)
881
1
          return ASN1_VALUE_NOT_FOUND;
882
883
2.66k
        if (name2[0])
884
2.04k
          _asn1_str_cat (name2, sizeof (name2), ".");
885
2.66k
        _asn1_str_cat (name2, sizeof (name2),
886
2.66k
           (char *) p4->value);
887
2.66k
      }
888
2.66k
          p4 = p4->right;
889
2.66k
        }
890
815
      tlen = strlen (name2);
891
815
      if (tlen > 0)
892
621
        _asn1_set_value (p2, name2, tlen + 1);
893
815
    }
894
817
      }
895
19.5k
    move = DOWN;
896
19.5k
  }
897
2.83k
      else
898
2.83k
  move = RIGHT;
899
900
22.4k
      if (move == DOWN)
901
19.5k
  {
902
19.5k
    if (p->down)
903
3.27k
      p = p->down;
904
16.3k
    else
905
16.3k
      move = RIGHT;
906
19.5k
  }
907
908
22.4k
      if (p == node)
909
0
  {
910
0
    move = UP;
911
0
    continue;
912
0
  }
913
914
22.4k
      if (move == RIGHT)
915
19.1k
  {
916
19.1k
    if (p && p->right)
917
15.8k
      p = p->right;
918
3.27k
    else
919
3.27k
      move = UP;
920
19.1k
  }
921
22.4k
      if (move == UP)
922
3.27k
  p = _asn1_find_up (p);
923
22.4k
    }
924
925
440
  return ASN1_SUCCESS;
926
442
}
927
928
929
/******************************************************************/
930
/* Function : _asn1_type_set_config                               */
931
/* Description: sets the CONST_SET and CONST_NOT_USED properties  */
932
/*   in the fields of the SET elements.                           */
933
/* Parameters:                                                    */
934
/*   node: root of an ASN1 element.                               */
935
/* Return:                                                        */
936
/*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
937
/*   otherwise ASN1_SUCCESS                                             */
938
/******************************************************************/
939
int
940
_asn1_type_set_config (asn1_node node)
941
905
{
942
905
  asn1_node p, p2;
943
905
  int move;
944
945
905
  if (node == NULL)
946
0
    return ASN1_ELEMENT_NOT_FOUND;
947
948
905
  p = node;
949
905
  move = DOWN;
950
951
21.1k
  while (!((p == node) && (move == UP)))
952
20.2k
    {
953
20.2k
      if (move != UP)
954
15.6k
  {
955
15.6k
    if (type_field (p->type) == ASN1_ETYPE_SET)
956
575
      {
957
575
        p2 = p->down;
958
4.65k
        while (p2)
959
4.07k
    {
960
4.07k
      if (type_field (p2->type) != ASN1_ETYPE_TAG)
961
3.84k
        p2->type |= CONST_SET | CONST_NOT_USED;
962
4.07k
      p2 = p2->right;
963
4.07k
    }
964
575
      }
965
15.6k
    move = DOWN;
966
15.6k
  }
967
4.58k
      else
968
4.58k
  move = RIGHT;
969
970
20.2k
      if (move == DOWN)
971
15.6k
  {
972
15.6k
    if (p->down)
973
5.49k
      p = p->down;
974
10.1k
    else
975
10.1k
      move = RIGHT;
976
15.6k
  }
977
978
20.2k
      if (p == node)
979
0
  {
980
0
    move = UP;
981
0
    continue;
982
0
  }
983
984
20.2k
      if (move == RIGHT)
985
14.7k
  {
986
14.7k
    if (p && p->right)
987
9.24k
      p = p->right;
988
5.49k
    else
989
5.49k
      move = UP;
990
14.7k
  }
991
20.2k
      if (move == UP)
992
5.49k
  p = _asn1_find_up (p);
993
20.2k
    }
994
995
905
  return ASN1_SUCCESS;
996
905
}
997
998
999
/******************************************************************/
1000
/* Function : _asn1_check_identifier                              */
1001
/* Description: checks the definitions of all the identifiers     */
1002
/*   and the first element of an OBJECT_ID (e.g. {pkix 0 4}).     */
1003
/*   The _asn1_identifierMissing global variable is filled if     */
1004
/*   necessary.                                                   */
1005
/* Parameters:                                                    */
1006
/*   node: root of an ASN1 element.                               */
1007
/* Return:                                                        */
1008
/*   ASN1_ELEMENT_NOT_FOUND      if NODE is NULL,                 */
1009
/*   ASN1_IDENTIFIER_NOT_FOUND   if an identifier is not defined, */
1010
/*   otherwise ASN1_SUCCESS                                       */
1011
/******************************************************************/
1012
int
1013
_asn1_check_identifier (asn1_node_const node)
1014
905
{
1015
905
  asn1_node_const p, p2;
1016
905
  char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
1017
1018
905
  if (node == NULL)
1019
0
    return ASN1_ELEMENT_NOT_FOUND;
1020
1021
905
  p = node;
1022
14.4k
  while (p)
1023
13.8k
    {
1024
13.8k
      if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
1025
1.32k
  {
1026
1.32k
    _asn1_str_cpy (name2, sizeof (name2), node->name);
1027
1.32k
    _asn1_str_cat (name2, sizeof (name2), ".");
1028
1.32k
    _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
1029
1.32k
    p2 = asn1_find_node (node, name2);
1030
1.32k
    if (p2 == NULL)
1031
278
      {
1032
278
        if (p->value)
1033
278
    _asn1_str_cpy (_asn1_identifierMissing,
1034
278
             sizeof (_asn1_identifierMissing),
1035
278
             (char *) p->value);
1036
0
        else
1037
0
    _asn1_strcpy (_asn1_identifierMissing, "(null)");
1038
278
        return ASN1_IDENTIFIER_NOT_FOUND;
1039
278
      }
1040
1.32k
  }
1041
12.5k
      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1042
12.5k
         (p->type & CONST_DEFAULT))
1043
835
  {
1044
835
    p2 = p->down;
1045
835
    if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
1046
835
      {
1047
835
        _asn1_str_cpy (name2, sizeof (name2), node->name);
1048
835
        if (p2->value)
1049
820
    {
1050
820
      _asn1_str_cat (name2, sizeof (name2), ".");
1051
820
      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
1052
820
      _asn1_str_cpy (_asn1_identifierMissing,
1053
820
         sizeof (_asn1_identifierMissing),
1054
820
         (char *) p2->value);
1055
820
    }
1056
15
        else
1057
15
    _asn1_strcpy (_asn1_identifierMissing, "(null)");
1058
1059
835
        p2 = asn1_find_node (node, name2);
1060
835
        if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
1061
835
      !(p2->type & CONST_ASSIGN))
1062
18
    return ASN1_IDENTIFIER_NOT_FOUND;
1063
817
        else
1064
817
    _asn1_identifierMissing[0] = 0;
1065
835
      }
1066
835
  }
1067
11.7k
      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1068
11.7k
         (p->type & CONST_ASSIGN))
1069
1.59k
  {
1070
1.59k
    p2 = p->down;
1071
1.59k
    if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
1072
1.59k
      {
1073
1.59k
        if (p2->value && !c_isdigit (p2->value[0]))
1074
1.18k
    {
1075
1.18k
      _asn1_str_cpy (name2, sizeof (name2), node->name);
1076
1.18k
      _asn1_str_cat (name2, sizeof (name2), ".");
1077
1.18k
      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
1078
1.18k
      _asn1_str_cpy (_asn1_identifierMissing,
1079
1.18k
         sizeof (_asn1_identifierMissing),
1080
1.18k
         (char *) p2->value);
1081
1082
1.18k
      p2 = asn1_find_node (node, name2);
1083
1.18k
      if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID)
1084
1.18k
          || !(p2->type & CONST_ASSIGN))
1085
20
        return ASN1_IDENTIFIER_NOT_FOUND;
1086
1.16k
      else
1087
1.16k
        _asn1_identifierMissing[0] = 0;
1088
1.18k
    }
1089
1.59k
      }
1090
1.59k
  }
1091
1092
13.5k
      if (p->down)
1093
4.68k
  {
1094
4.68k
    p = p->down;
1095
4.68k
  }
1096
8.87k
      else if (p->right)
1097
5.65k
  p = p->right;
1098
3.22k
      else
1099
3.22k
  {
1100
4.28k
    while (p)
1101
4.28k
      {
1102
4.28k
        p = _asn1_find_up (p);
1103
4.28k
        if (p == node)
1104
589
    {
1105
589
      p = NULL;
1106
589
      break;
1107
589
    }
1108
3.70k
        if (p && p->right)
1109
2.63k
    {
1110
2.63k
      p = p->right;
1111
2.63k
      break;
1112
2.63k
    }
1113
3.70k
      }
1114
3.22k
  }
1115
13.5k
    }
1116
1117
589
  return ASN1_SUCCESS;
1118
905
}
1119
1120
1121
/******************************************************************/
1122
/* Function : _asn1_set_default_tag                               */
1123
/* Description: sets the default IMPLICIT or EXPLICIT property in */
1124
/*   the tagged elements that don't have this declaration.        */
1125
/* Parameters:                                                    */
1126
/*   node: pointer to a DEFINITIONS element.                      */
1127
/* Return:                                                        */
1128
/*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to   */
1129
/*     a DEFINITIONS element,                                     */
1130
/*   otherwise ASN1_SUCCESS                                       */
1131
/******************************************************************/
1132
int
1133
_asn1_set_default_tag (asn1_node node)
1134
905
{
1135
905
  asn1_node p;
1136
1137
905
  if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
1138
0
    return ASN1_ELEMENT_NOT_FOUND;
1139
1140
905
  p = node;
1141
16.5k
  while (p)
1142
15.6k
    {
1143
15.6k
      if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
1144
15.6k
    !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1145
1.19k
  {
1146
1.19k
    if (node->type & CONST_EXPLICIT)
1147
403
      p->type |= CONST_EXPLICIT;
1148
795
    else
1149
795
      p->type |= CONST_IMPLICIT;
1150
1.19k
  }
1151
1152
15.6k
      if (p->down)
1153
5.49k
  {
1154
5.49k
    p = p->down;
1155
5.49k
  }
1156
10.1k
      else if (p->right)
1157
5.87k
  p = p->right;
1158
4.27k
      else
1159
4.27k
  {
1160
5.49k
    while (1)
1161
5.49k
      {
1162
5.49k
        p = _asn1_find_up (p);
1163
5.49k
        if (p == node)
1164
905
    {
1165
905
      p = NULL;
1166
905
      break;
1167
905
    }
1168
4.58k
        if (p && p->right)
1169
3.37k
    {
1170
3.37k
      p = p->right;
1171
3.37k
      break;
1172
3.37k
    }
1173
4.58k
      }
1174
4.27k
  }
1175
15.6k
    }
1176
1177
905
  return ASN1_SUCCESS;
1178
905
}