Coverage Report

Created: 2025-07-12 06:15

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