Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/minitasn1/parser_aux.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2000-2022 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
14.3k
{
45
14.3k
  const unsigned char *s = (unsigned char *) x;
46
14.3k
  unsigned h = 0;
47
48
179k
  while (*s)
49
165k
    h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9)));
50
51
14.3k
  return h;
52
14.3k
}
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
11.4k
{
67
11.4k
  list_type *p;
68
11.4k
  asn1_node punt;
69
70
11.4k
  punt = calloc (1, sizeof (struct asn1_node_st));
71
11.4k
  if (punt == NULL)
72
0
    return NULL;
73
74
11.4k
  p = malloc (sizeof (list_type));
75
11.4k
  if (p == NULL)
76
0
    {
77
0
      free (punt);
78
0
      return NULL;
79
0
    }
80
81
11.4k
  p->node = punt;
82
11.4k
  p->next = *e_list;
83
11.4k
  *e_list = p;
84
85
11.4k
  punt->type = type;
86
87
11.4k
  return punt;
88
11.4k
}
89
90
static int
91
_asn1_add_static_node2 (list_type ** e_list, asn1_node node)
92
0
{
93
0
  list_type *p;
94
95
0
  p = malloc (sizeof (list_type));
96
0
  if (p == NULL)
97
0
    {
98
0
      return -1;
99
0
    }
100
101
0
  p->node = node;
102
0
  p->next = *e_list;
103
0
  *e_list = p;
104
105
0
  return 0;
106
0
}
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
2.66k
{
123
2.66k
  asn1_node_const p;
124
2.66k
  char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
125
2.66k
  const char *n_start;
126
2.66k
  unsigned int nsize;
127
2.66k
  unsigned int nhash;
128
129
2.66k
  if (pointer == NULL)
130
0
    return NULL;
131
132
2.66k
  if (name == NULL)
133
0
    return NULL;
134
135
2.66k
  p = pointer;
136
2.66k
  n_start = name;
137
138
2.66k
  if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?')
139
0
    {       /* ?CURRENT */
140
0
      n_start = strchr (n_start, '.');
141
0
      if (n_start)
142
0
  n_start++;
143
0
    }
144
2.66k
  else if (p->name[0] != 0)
145
2.66k
    {       /* has *pointer got a name ? */
146
2.66k
      n_end = strchr (n_start, '.');  /* search the first dot */
147
2.66k
      if (n_end)
148
2.66k
  {
149
2.66k
    nsize = n_end - n_start;
150
2.66k
    if (nsize >= sizeof (n))
151
0
      return NULL;
152
153
2.66k
    memcpy (n, n_start, nsize);
154
2.66k
    n[nsize] = 0;
155
2.66k
    n_start = n_end;
156
2.66k
    n_start++;
157
158
2.66k
    nhash = _asn1_hash_name (n);
159
2.66k
  }
160
0
      else
161
0
  {
162
0
    _asn1_str_cpy (n, sizeof (n), n_start);
163
0
    nhash = _asn1_hash_name (n);
164
165
0
    n_start = NULL;
166
0
  }
167
168
2.66k
      while (p)
169
2.66k
  {
170
2.66k
    if (nhash == p->name_hash && (!strcmp (p->name, n)))
171
2.66k
      break;
172
0
    else
173
0
      p = p->right;
174
2.66k
  }     /* while */
175
176
2.66k
      if (p == NULL)
177
0
  return NULL;
178
2.66k
    }
179
0
  else
180
0
    {       /* *pointer doesn't have a name */
181
0
      if (n_start[0] == 0)
182
0
  return (asn1_node) p;
183
0
    }
184
185
5.32k
  while (n_start)
186
2.66k
    {       /* Has the end of NAME been reached? */
187
2.66k
      n_end = strchr (n_start, '.');  /* search the next dot */
188
2.66k
      if (n_end)
189
0
  {
190
0
    nsize = n_end - n_start;
191
0
    if (nsize >= sizeof (n))
192
0
      return NULL;
193
194
0
    memcpy (n, n_start, nsize);
195
0
    n[nsize] = 0;
196
0
    n_start = n_end;
197
0
    n_start++;
198
199
0
    nhash = _asn1_hash_name (n);
200
0
  }
201
2.66k
      else
202
2.66k
  {
203
2.66k
    _asn1_str_cpy (n, sizeof (n), n_start);
204
2.66k
    nhash = _asn1_hash_name (n);
205
2.66k
    n_start = NULL;
206
2.66k
  }
207
208
2.66k
      if (p->down == NULL)
209
0
  return NULL;
210
211
2.66k
      p = p->down;
212
2.66k
      if (p == NULL)
213
0
  return NULL;
214
215
      /* The identifier "?LAST" indicates the last element
216
         in the right chain. */
217
2.66k
      if (n[0] == '?' && n[1] == 'L')  /* ?LAST */
218
0
  {
219
0
    while (p->right)
220
0
      p = p->right;
221
0
  }
222
2.66k
      else
223
2.66k
  {     /* no "?LAST" */
224
111k
    while (p)
225
111k
      {
226
111k
        if (p->name_hash == nhash && !strcmp (p->name, n))
227
2.66k
    break;
228
108k
        else
229
108k
    p = p->right;
230
111k
      }
231
2.66k
  }
232
2.66k
      if (p == NULL)
233
0
  return NULL;
234
2.66k
    }       /* while */
235
236
2.66k
  return (asn1_node) p;
237
2.66k
}
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
4.62k
{
253
4.62k
  if (node == NULL)
254
0
    return node;
255
4.62k
  if (node->value)
256
0
    {
257
0
      if (node->value != node->small_value)
258
0
  free (node->value);
259
0
      node->value = NULL;
260
0
      node->value_len = 0;
261
0
    }
262
263
4.62k
  if (!len)
264
0
    return node;
265
266
4.62k
  if (len < sizeof (node->small_value))
267
3.14k
    {
268
3.14k
      node->value = node->small_value;
269
3.14k
    }
270
1.48k
  else
271
1.48k
    {
272
1.48k
      node->value = malloc (len);
273
1.48k
      if (node->value == NULL)
274
0
  return NULL;
275
1.48k
    }
276
4.62k
  node->value_len = len;
277
278
4.62k
  memcpy (node->value, value, len);
279
4.62k
  return node;
280
4.62k
}
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
8.98k
{
410
8.98k
  if (node == NULL)
411
0
    return node;
412
413
8.98k
  _asn1_str_cpy (node->name, sizeof (node->name), name ? name : "");
414
8.98k
  node->name_hash = _asn1_hash_name (node->name);
415
416
8.98k
  return node;
417
8.98k
}
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
7.14k
{
458
7.14k
  if (node == NULL)
459
0
    return node;
460
7.14k
  node->right = right;
461
7.14k
  if (right)
462
7.14k
    right->left = node;
463
7.14k
  return node;
464
7.14k
}
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
0
{
477
0
  asn1_node_const p;
478
479
0
  if (node == NULL)
480
0
    return NULL;
481
0
  p = node;
482
0
  while (p->right)
483
0
    p = p->right;
484
0
  return (asn1_node) p;
485
0
}
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
0
{
498
0
  if (node == NULL)
499
0
    return;
500
501
0
  if (node->value != NULL)
502
0
    {
503
0
      if (flags & ASN1_DELETE_FLAG_ZEROIZE)
504
0
  {
505
0
    safe_memset (node->value, 0, node->value_len);
506
0
  }
507
508
0
      if (node->value != node->small_value)
509
0
  free (node->value);
510
0
    }
511
0
  free (node);
512
0
}
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
21.2k
{
524
21.2k
  asn1_node_const p;
525
526
21.2k
  if (node == NULL)
527
0
    return NULL;
528
529
21.2k
  p = node;
530
531
56.9k
  while ((p->left != NULL) && (p->left->right == p))
532
35.7k
    p = p->left;
533
534
21.2k
  return p->left;
535
21.2k
}
536
537
static unsigned
538
_asn1_is_up (asn1_node_const up_cand, asn1_node_const down)
539
0
{
540
0
  asn1_node_const d, u;
541
542
0
  if (up_cand == NULL || down == NULL)
543
0
    return 0;
544
545
0
  d = down;
546
547
0
  while ((u = _asn1_find_up (d)) != NULL && u != d)
548
0
    {
549
0
      if (u == up_cand)
550
0
  return 1;
551
0
      d = u;
552
0
    }
553
554
0
  return 0;
555
0
}
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
0
{
564
0
  list_type *p = list;
565
566
0
  while (p)
567
0
    {
568
0
      if (p->node == node)
569
0
  p->node = NULL;
570
0
      p = p->next;
571
0
    }
572
0
}
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
40
{
582
40
  list_type *p;
583
584
11.4k
  while (e_list)
585
11.4k
    {
586
11.4k
      p = e_list;
587
11.4k
      e_list = e_list->next;
588
11.4k
      free (p);
589
11.4k
    }
590
40
}
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
0
{
600
0
  list_type *p;
601
602
0
  while (e_list)
603
0
    {
604
0
      p = e_list;
605
0
      e_list = e_list->next;
606
0
      _asn1_remove_node (p->node, 0);
607
0
      free (p);
608
0
    }
609
0
}
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
40
{
663
40
  asn1_node p;
664
40
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
665
40
  unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
666
40
  int len;
667
668
40
  if (node == NULL)
669
0
    return ASN1_ELEMENT_NOT_FOUND;
670
671
40
  p = node;
672
11.4k
  while (p)
673
11.4k
    {
674
11.4k
      if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
675
11.4k
    && (p->type & CONST_ASSIGN))
676
0
  {
677
0
    if (p->value)
678
0
      {
679
0
        _asn1_convert_integer (p->value, val, sizeof (val), &len);
680
0
        asn1_octet_der (val, len, val2, &len);
681
0
        _asn1_set_value (p, val2, len);
682
0
      }
683
0
  }
684
685
11.4k
      if (p->down)
686
4.24k
  {
687
4.24k
    p = p->down;
688
4.24k
  }
689
7.18k
      else
690
7.18k
  {
691
7.18k
    if (p == node)
692
0
      p = NULL;
693
7.18k
    else if (p->right)
694
3.92k
      p = p->right;
695
3.26k
    else
696
3.26k
      {
697
4.24k
        while (1)
698
4.24k
    {
699
4.24k
      p = _asn1_find_up (p);
700
4.24k
      if (p == node)
701
40
        {
702
40
          p = NULL;
703
40
          break;
704
40
        }
705
4.20k
      if (p && p->right)
706
3.22k
        {
707
3.22k
          p = p->right;
708
3.22k
          break;
709
3.22k
        }
710
4.20k
    }
711
3.26k
      }
712
7.18k
  }
713
11.4k
    }
714
715
40
  return ASN1_SUCCESS;
716
40
}
717
718
0
#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
40
{
732
40
  asn1_node p, p2, p3, p4, p5;
733
40
  char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
734
40
  int move, tlen, tries;
735
40
  unsigned max_constants;
736
737
40
  if (node == NULL)
738
0
    return ASN1_ELEMENT_NOT_FOUND;
739
740
40
  _asn1_str_cpy (name_root, sizeof (name_root), node->name);
741
742
40
  p = node;
743
40
  move = DOWN;
744
40
  tries = 0;
745
746
15.6k
  while (!((p == node) && (move == UP)))
747
15.6k
    {
748
15.6k
      if (move != UP)
749
11.4k
  {
750
11.4k
    if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
751
11.4k
        && (p->type & CONST_ASSIGN))
752
20
      {
753
20
        p2 = p->down;
754
20
        if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
755
20
    {
756
20
      if (p2->value && !c_isdigit (p2->value[0]))
757
0
        {
758
0
          _asn1_str_cpy (name2, sizeof (name2), name_root);
759
0
          _asn1_str_cat (name2, sizeof (name2), ".");
760
0
          _asn1_str_cat (name2, sizeof (name2),
761
0
             (char *) p2->value);
762
0
          p3 = asn1_find_node (node, name2);
763
0
          if (!p3 || _asn1_is_up (p2, p3) ||
764
0
        (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
765
0
        !(p3->type & CONST_ASSIGN))
766
0
      return ASN1_ELEMENT_NOT_FOUND;
767
768
0
          _asn1_set_down (p, p2->right);
769
0
          if (p2->down)
770
0
      _asn1_delete_structure (*list, &p2->down, 0);
771
0
          _asn1_delete_node_from_list (*list, p2);
772
0
          _asn1_remove_node (p2, 0);
773
0
          p2 = p;
774
0
          p4 = p3->down;
775
0
          max_constants = 0;
776
0
          while (p4)
777
0
      {
778
0
        if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
779
0
          {
780
0
            max_constants++;
781
0
            if (max_constants == MAX_CONSTANTS)
782
0
        return ASN1_RECURSION;
783
784
0
            p5 =
785
0
        _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
786
0
            _asn1_set_name (p5, p4->name);
787
0
            if (p4->value)
788
0
        {
789
0
          tlen = _asn1_strlen (p4->value);
790
0
          if (tlen > 0)
791
0
            _asn1_set_value (p5, p4->value, tlen + 1);
792
0
        }
793
0
            _asn1_add_static_node2 (list, p5);
794
795
0
            if (p2 == p)
796
0
        {
797
0
          _asn1_set_right (p5, p->down);
798
0
          _asn1_set_down (p, p5);
799
0
        }
800
0
            else
801
0
        {
802
0
          _asn1_set_right (p5, p2->right);
803
0
          _asn1_set_right (p2, p5);
804
0
        }
805
0
            p2 = p5;
806
0
          }
807
0
        p4 = p4->right;
808
0
      }
809
0
          move = DOWN;
810
811
0
          tries++;
812
0
          if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION)
813
0
      return ASN1_RECURSION;
814
815
0
          continue;
816
0
        }
817
20
    }
818
20
      }
819
11.4k
    move = DOWN;
820
11.4k
  }
821
4.20k
      else
822
4.20k
  move = RIGHT;
823
824
15.6k
      tries = 0;
825
15.6k
      if (move == DOWN)
826
11.4k
  {
827
11.4k
    if (p->down)
828
4.24k
      p = p->down;
829
7.18k
    else
830
7.18k
      move = RIGHT;
831
11.4k
  }
832
833
15.6k
      if (p == node)
834
0
  {
835
0
    move = UP;
836
0
    continue;
837
0
  }
838
839
15.6k
      if (move == RIGHT)
840
11.3k
  {
841
11.3k
    if (p && p->right)
842
7.14k
      p = p->right;
843
4.24k
    else
844
4.24k
      move = UP;
845
11.3k
  }
846
15.6k
      if (move == UP)
847
4.24k
  p = _asn1_find_up (p);
848
15.6k
    }
849
850
  /*******************************/
851
  /*       expand DEFAULT        */
852
  /*******************************/
853
40
  p = node;
854
40
  move = DOWN;
855
856
15.6k
  while (!((p == node) && (move == UP)))
857
15.6k
    {
858
15.6k
      if (move != UP)
859
11.4k
  {
860
11.4k
    if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
861
11.4k
        (p->type & CONST_DEFAULT))
862
0
      {
863
0
        p2 = p->down;
864
0
        if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
865
0
    {
866
0
      _asn1_str_cpy (name2, sizeof (name2), name_root);
867
0
      _asn1_str_cat (name2, sizeof (name2), ".");
868
0
      if (p2->value)
869
0
        _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
870
0
      p3 = asn1_find_node (node, name2);
871
0
      if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
872
0
          || !(p3->type & CONST_ASSIGN))
873
0
        return ASN1_ELEMENT_NOT_FOUND;
874
0
      p4 = p3->down;
875
0
      name2[0] = 0;
876
0
      while (p4)
877
0
        {
878
0
          if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
879
0
      {
880
0
        if (p4->value == NULL)
881
0
          return ASN1_VALUE_NOT_FOUND;
882
883
0
        if (name2[0])
884
0
          _asn1_str_cat (name2, sizeof (name2), ".");
885
0
        _asn1_str_cat (name2, sizeof (name2),
886
0
           (char *) p4->value);
887
0
      }
888
0
          p4 = p4->right;
889
0
        }
890
0
      tlen = strlen (name2);
891
0
      if (tlen > 0)
892
0
        _asn1_set_value (p2, name2, tlen + 1);
893
0
    }
894
0
      }
895
11.4k
    move = DOWN;
896
11.4k
  }
897
4.20k
      else
898
4.20k
  move = RIGHT;
899
900
15.6k
      if (move == DOWN)
901
11.4k
  {
902
11.4k
    if (p->down)
903
4.24k
      p = p->down;
904
7.18k
    else
905
7.18k
      move = RIGHT;
906
11.4k
  }
907
908
15.6k
      if (p == node)
909
0
  {
910
0
    move = UP;
911
0
    continue;
912
0
  }
913
914
15.6k
      if (move == RIGHT)
915
11.3k
  {
916
11.3k
    if (p && p->right)
917
7.14k
      p = p->right;
918
4.24k
    else
919
4.24k
      move = UP;
920
11.3k
  }
921
15.6k
      if (move == UP)
922
4.24k
  p = _asn1_find_up (p);
923
15.6k
    }
924
925
40
  return ASN1_SUCCESS;
926
40
}
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
0
{
942
0
  asn1_node p, p2;
943
0
  int move;
944
945
0
  if (node == NULL)
946
0
    return ASN1_ELEMENT_NOT_FOUND;
947
948
0
  p = node;
949
0
  move = DOWN;
950
951
0
  while (!((p == node) && (move == UP)))
952
0
    {
953
0
      if (move != UP)
954
0
  {
955
0
    if (type_field (p->type) == ASN1_ETYPE_SET)
956
0
      {
957
0
        p2 = p->down;
958
0
        while (p2)
959
0
    {
960
0
      if (type_field (p2->type) != ASN1_ETYPE_TAG)
961
0
        p2->type |= CONST_SET | CONST_NOT_USED;
962
0
      p2 = p2->right;
963
0
    }
964
0
      }
965
0
    move = DOWN;
966
0
  }
967
0
      else
968
0
  move = RIGHT;
969
970
0
      if (move == DOWN)
971
0
  {
972
0
    if (p->down)
973
0
      p = p->down;
974
0
    else
975
0
      move = RIGHT;
976
0
  }
977
978
0
      if (p == node)
979
0
  {
980
0
    move = UP;
981
0
    continue;
982
0
  }
983
984
0
      if (move == RIGHT)
985
0
  {
986
0
    if (p && p->right)
987
0
      p = p->right;
988
0
    else
989
0
      move = UP;
990
0
  }
991
0
      if (move == UP)
992
0
  p = _asn1_find_up (p);
993
0
    }
994
995
0
  return ASN1_SUCCESS;
996
0
}
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
40
{
1015
40
  asn1_node_const p, p2;
1016
40
  char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
1017
1018
40
  if (node == NULL)
1019
0
    return ASN1_ELEMENT_NOT_FOUND;
1020
1021
40
  p = node;
1022
11.4k
  while (p)
1023
11.4k
    {
1024
11.4k
      if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
1025
2.66k
  {
1026
2.66k
    _asn1_str_cpy (name2, sizeof (name2), node->name);
1027
2.66k
    _asn1_str_cat (name2, sizeof (name2), ".");
1028
2.66k
    _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
1029
2.66k
    p2 = asn1_find_node (node, name2);
1030
2.66k
    if (p2 == NULL)
1031
0
      {
1032
0
        if (p->value)
1033
0
    _asn1_str_cpy (_asn1_identifierMissing,
1034
0
             sizeof (_asn1_identifierMissing),
1035
0
             (char *) p->value);
1036
0
        else
1037
0
    _asn1_strcpy (_asn1_identifierMissing, "(null)");
1038
0
        return ASN1_IDENTIFIER_NOT_FOUND;
1039
0
      }
1040
2.66k
  }
1041
8.76k
      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1042
8.76k
         (p->type & CONST_DEFAULT))
1043
0
  {
1044
0
    p2 = p->down;
1045
0
    if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
1046
0
      {
1047
0
        _asn1_str_cpy (name2, sizeof (name2), node->name);
1048
0
        if (p2->value)
1049
0
    {
1050
0
      _asn1_str_cat (name2, sizeof (name2), ".");
1051
0
      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
1052
0
      _asn1_str_cpy (_asn1_identifierMissing,
1053
0
         sizeof (_asn1_identifierMissing),
1054
0
         (char *) p2->value);
1055
0
    }
1056
0
        else
1057
0
    _asn1_strcpy (_asn1_identifierMissing, "(null)");
1058
1059
0
        p2 = asn1_find_node (node, name2);
1060
0
        if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
1061
0
      !(p2->type & CONST_ASSIGN))
1062
0
    return ASN1_IDENTIFIER_NOT_FOUND;
1063
0
        else
1064
0
    _asn1_identifierMissing[0] = 0;
1065
0
      }
1066
0
  }
1067
8.76k
      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1068
8.76k
         (p->type & CONST_ASSIGN))
1069
20
  {
1070
20
    p2 = p->down;
1071
20
    if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
1072
20
      {
1073
20
        if (p2->value && !c_isdigit (p2->value[0]))
1074
0
    {
1075
0
      _asn1_str_cpy (name2, sizeof (name2), node->name);
1076
0
      _asn1_str_cat (name2, sizeof (name2), ".");
1077
0
      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
1078
0
      _asn1_str_cpy (_asn1_identifierMissing,
1079
0
         sizeof (_asn1_identifierMissing),
1080
0
         (char *) p2->value);
1081
1082
0
      p2 = asn1_find_node (node, name2);
1083
0
      if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID)
1084
0
          || !(p2->type & CONST_ASSIGN))
1085
0
        return ASN1_IDENTIFIER_NOT_FOUND;
1086
0
      else
1087
0
        _asn1_identifierMissing[0] = 0;
1088
0
    }
1089
20
      }
1090
20
  }
1091
1092
11.4k
      if (p->down)
1093
4.24k
  {
1094
4.24k
    p = p->down;
1095
4.24k
  }
1096
7.18k
      else if (p->right)
1097
3.92k
  p = p->right;
1098
3.26k
      else
1099
3.26k
  {
1100
4.24k
    while (p)
1101
4.24k
      {
1102
4.24k
        p = _asn1_find_up (p);
1103
4.24k
        if (p == node)
1104
40
    {
1105
40
      p = NULL;
1106
40
      break;
1107
40
    }
1108
4.20k
        if (p && p->right)
1109
3.22k
    {
1110
3.22k
      p = p->right;
1111
3.22k
      break;
1112
3.22k
    }
1113
4.20k
      }
1114
3.26k
  }
1115
11.4k
    }
1116
1117
40
  return ASN1_SUCCESS;
1118
40
}
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
0
{
1135
0
  asn1_node p;
1136
1137
0
  if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
1138
0
    return ASN1_ELEMENT_NOT_FOUND;
1139
1140
0
  p = node;
1141
0
  while (p)
1142
0
    {
1143
0
      if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
1144
0
    !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1145
0
  {
1146
0
    if (node->type & CONST_EXPLICIT)
1147
0
      p->type |= CONST_EXPLICIT;
1148
0
    else
1149
0
      p->type |= CONST_IMPLICIT;
1150
0
  }
1151
1152
0
      if (p->down)
1153
0
  {
1154
0
    p = p->down;
1155
0
  }
1156
0
      else if (p->right)
1157
0
  p = p->right;
1158
0
      else
1159
0
  {
1160
0
    while (1)
1161
0
      {
1162
0
        p = _asn1_find_up (p);
1163
0
        if (p == node)
1164
0
    {
1165
0
      p = NULL;
1166
0
      break;
1167
0
    }
1168
0
        if (p && p->right)
1169
0
    {
1170
0
      p = p->right;
1171
0
      break;
1172
0
    }
1173
0
      }
1174
0
  }
1175
0
    }
1176
1177
0
  return ASN1_SUCCESS;
1178
0
}