Coverage Report

Created: 2024-06-20 06:28

/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
1.43k
{
45
1.43k
  const unsigned char *s = (unsigned char *) x;
46
1.43k
  unsigned h = 0;
47
48
17.9k
  while (*s)
49
16.5k
    h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9)));
50
51
1.43k
  return h;
52
1.43k
}
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
1.14k
{
67
1.14k
  list_type *p;
68
1.14k
  asn1_node punt;
69
70
1.14k
  punt = calloc (1, sizeof (struct asn1_node_st));
71
1.14k
  if (punt == NULL)
72
0
    return NULL;
73
74
1.14k
  p = malloc (sizeof (list_type));
75
1.14k
  if (p == NULL)
76
0
    {
77
0
      free (punt);
78
0
      return NULL;
79
0
    }
80
81
1.14k
  p->node = punt;
82
1.14k
  p->next = *e_list;
83
1.14k
  *e_list = p;
84
85
1.14k
  punt->type = type;
86
87
1.14k
  return punt;
88
1.14k
}
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
266
{
123
266
  asn1_node_const p;
124
266
  char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
125
266
  const char *n_start;
126
266
  unsigned int nsize;
127
266
  unsigned int nhash;
128
129
266
  if (pointer == NULL)
130
0
    return NULL;
131
132
266
  if (name == NULL)
133
0
    return NULL;
134
135
266
  p = pointer;
136
266
  n_start = name;
137
138
266
  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
266
  else if (p->name[0] != 0)
145
266
    {       /* has *pointer got a name ? */
146
266
      n_end = strchr (n_start, '.');  /* search the first dot */
147
266
      if (n_end)
148
266
  {
149
266
    nsize = n_end - n_start;
150
266
    if (nsize >= sizeof (n))
151
0
      return NULL;
152
153
266
    memcpy (n, n_start, nsize);
154
266
    n[nsize] = 0;
155
266
    n_start = n_end;
156
266
    n_start++;
157
158
266
    nhash = _asn1_hash_name (n);
159
266
  }
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
266
      while (p)
169
266
  {
170
266
    if (nhash == p->name_hash && (!strcmp (p->name, n)))
171
266
      break;
172
0
    else
173
0
      p = p->right;
174
266
  }     /* while */
175
176
266
      if (p == NULL)
177
0
  return NULL;
178
266
    }
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
532
  while (n_start)
186
266
    {       /* Has the end of NAME been reached? */
187
266
      n_end = strchr (n_start, '.');  /* search the next dot */
188
266
      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
266
      else
202
266
  {
203
266
    _asn1_str_cpy (n, sizeof (n), n_start);
204
266
    nhash = _asn1_hash_name (n);
205
266
    n_start = NULL;
206
266
  }
207
208
266
      if (p->down == NULL)
209
0
  return NULL;
210
211
266
      p = p->down;
212
266
      if (p == NULL)
213
0
  return NULL;
214
215
      /* The identifier "?LAST" indicates the last element
216
         in the right chain. */
217
266
      if (n[0] == '?' && n[1] == 'L')  /* ?LAST */
218
0
  {
219
0
    while (p->right)
220
0
      p = p->right;
221
0
  }
222
266
      else
223
266
  {     /* no "?LAST" */
224
11.1k
    while (p)
225
11.1k
      {
226
11.1k
        if (p->name_hash == nhash && !strcmp (p->name, n))
227
266
    break;
228
10.8k
        else
229
10.8k
    p = p->right;
230
11.1k
      }
231
266
  }
232
266
      if (p == NULL)
233
0
  return NULL;
234
266
    }       /* while */
235
236
266
  return (asn1_node) p;
237
266
}
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
462
{
253
462
  if (node == NULL)
254
0
    return node;
255
462
  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
462
  if (!len)
264
0
    return node;
265
266
462
  if (len < sizeof (node->small_value))
267
314
    {
268
314
      node->value = node->small_value;
269
314
    }
270
148
  else
271
148
    {
272
148
      node->value = malloc (len);
273
148
      if (node->value == NULL)
274
0
  return NULL;
275
148
    }
276
462
  node->value_len = len;
277
278
462
  memcpy (node->value, value, len);
279
462
  return node;
280
462
}
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
898
{
410
898
  if (node == NULL)
411
0
    return node;
412
413
898
  _asn1_str_cpy (node->name, sizeof (node->name), name ? name : "");
414
898
  node->name_hash = _asn1_hash_name (node->name);
415
416
898
  return node;
417
898
}
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
714
{
458
714
  if (node == NULL)
459
0
    return node;
460
714
  node->right = right;
461
714
  if (right)
462
714
    right->left = node;
463
714
  return node;
464
714
}
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
2.12k
{
524
2.12k
  asn1_node_const p;
525
526
2.12k
  if (node == NULL)
527
0
    return NULL;
528
529
2.12k
  p = node;
530
531
5.69k
  while ((p->left != NULL) && (p->left->right == p))
532
3.57k
    p = p->left;
533
534
2.12k
  return p->left;
535
2.12k
}
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
4
{
582
4
  list_type *p;
583
584
1.14k
  while (e_list)
585
1.14k
    {
586
1.14k
      p = e_list;
587
1.14k
      e_list = e_list->next;
588
1.14k
      free (p);
589
1.14k
    }
590
4
}
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
4
{
663
4
  asn1_node p;
664
4
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
665
4
  unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
666
4
  int len;
667
668
4
  if (node == NULL)
669
0
    return ASN1_ELEMENT_NOT_FOUND;
670
671
4
  p = node;
672
1.14k
  while (p)
673
1.14k
    {
674
1.14k
      if ((type_field (p->type) == ASN1_ETYPE_INTEGER)
675
1.14k
    && (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
1.14k
      if (p->down)
686
424
  {
687
424
    p = p->down;
688
424
  }
689
718
      else
690
718
  {
691
718
    if (p == node)
692
0
      p = NULL;
693
718
    else if (p->right)
694
392
      p = p->right;
695
326
    else
696
326
      {
697
424
        while (1)
698
424
    {
699
424
      p = _asn1_find_up (p);
700
424
      if (p == node)
701
4
        {
702
4
          p = NULL;
703
4
          break;
704
4
        }
705
420
      if (p && p->right)
706
322
        {
707
322
          p = p->right;
708
322
          break;
709
322
        }
710
420
    }
711
326
      }
712
718
  }
713
1.14k
    }
714
715
4
  return ASN1_SUCCESS;
716
4
}
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
4
{
732
4
  asn1_node p, p2, p3, p4, p5;
733
4
  char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
734
4
  int move, tlen, tries;
735
4
  unsigned max_constants;
736
737
4
  if (node == NULL)
738
0
    return ASN1_ELEMENT_NOT_FOUND;
739
740
4
  _asn1_str_cpy (name_root, sizeof (name_root), node->name);
741
742
4
  p = node;
743
4
  move = DOWN;
744
4
  tries = 0;
745
746
1.56k
  while (!((p == node) && (move == UP)))
747
1.56k
    {
748
1.56k
      if (move != UP)
749
1.14k
  {
750
1.14k
    if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
751
1.14k
        && (p->type & CONST_ASSIGN))
752
2
      {
753
2
        p2 = p->down;
754
2
        if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
755
2
    {
756
2
      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
2
    }
818
2
      }
819
1.14k
    move = DOWN;
820
1.14k
  }
821
420
      else
822
420
  move = RIGHT;
823
824
1.56k
      tries = 0;
825
1.56k
      if (move == DOWN)
826
1.14k
  {
827
1.14k
    if (p->down)
828
424
      p = p->down;
829
718
    else
830
718
      move = RIGHT;
831
1.14k
  }
832
833
1.56k
      if (p == node)
834
0
  {
835
0
    move = UP;
836
0
    continue;
837
0
  }
838
839
1.56k
      if (move == RIGHT)
840
1.13k
  {
841
1.13k
    if (p && p->right)
842
714
      p = p->right;
843
424
    else
844
424
      move = UP;
845
1.13k
  }
846
1.56k
      if (move == UP)
847
424
  p = _asn1_find_up (p);
848
1.56k
    }
849
850
  /*******************************/
851
  /*       expand DEFAULT        */
852
  /*******************************/
853
4
  p = node;
854
4
  move = DOWN;
855
856
1.56k
  while (!((p == node) && (move == UP)))
857
1.56k
    {
858
1.56k
      if (move != UP)
859
1.14k
  {
860
1.14k
    if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
861
1.14k
        (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
1.14k
    move = DOWN;
896
1.14k
  }
897
420
      else
898
420
  move = RIGHT;
899
900
1.56k
      if (move == DOWN)
901
1.14k
  {
902
1.14k
    if (p->down)
903
424
      p = p->down;
904
718
    else
905
718
      move = RIGHT;
906
1.14k
  }
907
908
1.56k
      if (p == node)
909
0
  {
910
0
    move = UP;
911
0
    continue;
912
0
  }
913
914
1.56k
      if (move == RIGHT)
915
1.13k
  {
916
1.13k
    if (p && p->right)
917
714
      p = p->right;
918
424
    else
919
424
      move = UP;
920
1.13k
  }
921
1.56k
      if (move == UP)
922
424
  p = _asn1_find_up (p);
923
1.56k
    }
924
925
4
  return ASN1_SUCCESS;
926
4
}
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
4
{
1015
4
  asn1_node_const p, p2;
1016
4
  char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
1017
1018
4
  if (node == NULL)
1019
0
    return ASN1_ELEMENT_NOT_FOUND;
1020
1021
4
  p = node;
1022
1.14k
  while (p)
1023
1.14k
    {
1024
1.14k
      if (p->value && type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
1025
266
  {
1026
266
    _asn1_str_cpy (name2, sizeof (name2), node->name);
1027
266
    _asn1_str_cat (name2, sizeof (name2), ".");
1028
266
    _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
1029
266
    p2 = asn1_find_node (node, name2);
1030
266
    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
266
  }
1041
876
      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1042
876
         (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
876
      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
1068
876
         (p->type & CONST_ASSIGN))
1069
2
  {
1070
2
    p2 = p->down;
1071
2
    if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
1072
2
      {
1073
2
        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
2
      }
1090
2
  }
1091
1092
1.14k
      if (p->down)
1093
424
  {
1094
424
    p = p->down;
1095
424
  }
1096
718
      else if (p->right)
1097
392
  p = p->right;
1098
326
      else
1099
326
  {
1100
424
    while (p)
1101
424
      {
1102
424
        p = _asn1_find_up (p);
1103
424
        if (p == node)
1104
4
    {
1105
4
      p = NULL;
1106
4
      break;
1107
4
    }
1108
420
        if (p && p->right)
1109
322
    {
1110
322
      p = p->right;
1111
322
      break;
1112
322
    }
1113
420
      }
1114
326
  }
1115
1.14k
    }
1116
1117
4
  return ASN1_SUCCESS;
1118
4
}
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
}