~ubuntu-branches/ubuntu/lucid/libtasn1-3/lucid-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2015-2806.patch/lib/decoding.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-04-02 11:27:53 UTC
  • Revision ID: package-import@ubuntu.com-20150402112753-ek5d5e0lzmg7r3mr
Tags: 2.4-1ubuntu0.3
* SECURITY UPDATE: denial of service and possible code execution via
  overflow in _asn1_ltostr
  - debian/patches/CVE-2015-2806.patch: introduce LTOSTR_MAX_SIZE and use
    in lib/coding.c, lib/decoding.c, lib/element.c, lib/parser_aux.c,
    lib/parser_aux.h.
  - CVE-2015-2806

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software
 
3
 * Foundation, Inc.
 
4
 *
 
5
 * This file is part of LIBTASN1.
 
6
 *
 
7
 * The LIBTASN1 library is free software; you can redistribute it
 
8
 * and/or modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
20
 * 02110-1301, USA
 
21
 */
 
22
 
 
23
 
 
24
/*****************************************************/
 
25
/* File: decoding.c                                  */
 
26
/* Description: Functions to manage DER decoding     */
 
27
/*****************************************************/
 
28
 
 
29
#include <int.h>
 
30
#include "parser_aux.h"
 
31
#include <gstr.h>
 
32
#include "structure.h"
 
33
#include "element.h"
 
34
 
 
35
#ifdef DEBUG
 
36
# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
 
37
#else
 
38
# define warn()
 
39
#endif
 
40
 
 
41
#define HAVE_TWO(x) (x>=2?1:0)
 
42
 
 
43
#define DECR_LEN(l, s) do { \
 
44
          l -= s; \
 
45
          if (l < 0) { \
 
46
            warn(); \
 
47
            result = ASN1_DER_ERROR; \
 
48
            goto cleanup; \
 
49
          } \
 
50
        } while (0)
 
51
 
 
52
static asn1_retCode
 
53
_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len);
 
54
 
 
55
static void
 
56
_asn1_error_description_tag_error (ASN1_TYPE node, char *ErrorDescription)
 
57
{
 
58
 
 
59
  Estrcpy (ErrorDescription, ":: tag error near element '");
 
60
  _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
 
61
                           ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
 
62
  Estrcat (ErrorDescription, "'");
 
63
 
 
64
}
 
65
 
 
66
/**
 
67
 * asn1_get_length_der:
 
68
 * @der: DER data to decode.
 
69
 * @der_len: Length of DER data to decode.
 
70
 * @len: Output variable containing the length of the DER length field.
 
71
 *
 
72
 * Extract a length field from DER data.
 
73
 *
 
74
 * Return value: Return the decoded length value, or -1 on indefinite
 
75
 *   length, or -2 when the value was too big to fit in a int, or -4
 
76
 *   when the decoded length value plus @len would exceed @der_len.
 
77
 **/
 
78
signed long
 
79
asn1_get_length_der (const unsigned char *der, int der_len, int *len)
 
80
{
 
81
  int ans;
 
82
  int k, punt;
 
83
 
 
84
  *len = 0;
 
85
  if (der_len <= 0)
 
86
    return 0;
 
87
 
 
88
  if (!(der[0] & 128))
 
89
    {
 
90
      /* short form */
 
91
      *len = 1;
 
92
      return der[0];
 
93
    }
 
94
  else
 
95
    {
 
96
      /* Long form */
 
97
      k = der[0] & 0x7F;
 
98
      punt = 1;
 
99
      if (k)
 
100
        {                       /* definite length method */
 
101
          ans = 0;
 
102
          while (punt <= k && punt < der_len)
 
103
            {
 
104
              int last = ans;
 
105
 
 
106
              ans = ans * 256 + der[punt++];
 
107
              if (ans < last)
 
108
                /* we wrapped around, no bignum support... */
 
109
                return -2;
 
110
            }
 
111
        }
 
112
      else
 
113
        {                       /* indefinite length method */
 
114
          *len = punt;
 
115
          return -1;
 
116
        }
 
117
 
 
118
      *len = punt;
 
119
      if (ans + *len < ans || ans + *len > der_len)
 
120
        return -4;
 
121
      return ans;
 
122
    }
 
123
}
 
124
 
 
125
 
 
126
/**
 
127
 * asn1_get_tag_der:
 
128
 * @der: DER data to decode.
 
129
 * @der_len: Length of DER data to decode.
 
130
 * @cls: Output variable containing decoded class.
 
131
 * @len: Output variable containing the length of the DER TAG data.
 
132
 * @tag: Output variable containing the decoded tag.
 
133
 *
 
134
 * Decode the class and TAG from DER code.
 
135
 *
 
136
 * Return value: Returns ASN1_SUCCESS on success, or an error.
 
137
 **/
 
138
int
 
139
asn1_get_tag_der (const unsigned char *der, int der_len,
 
140
                  unsigned char *cls, int *len, unsigned long *tag)
 
141
{
 
142
  int punt, ris;
 
143
 
 
144
  if (der == NULL || der_len < 2 || len == NULL)
 
145
    return ASN1_DER_ERROR;
 
146
 
 
147
  *cls = der[0] & 0xE0;
 
148
  if ((der[0] & 0x1F) != 0x1F)
 
149
    {
 
150
      /* short form */
 
151
      *len = 1;
 
152
      ris = der[0] & 0x1F;
 
153
    }
 
154
  else
 
155
    {
 
156
      /* Long form */
 
157
      punt = 1;
 
158
      ris = 0;
 
159
      while (punt < der_len && der[punt] & 128)
 
160
        {
 
161
          int last = ris;
 
162
          ris = ris * 128 + (der[punt++] & 0x7F);
 
163
          if (ris < last)
 
164
            /* wrapper around, and no bignums... */
 
165
            return ASN1_DER_ERROR;
 
166
        }
 
167
      if (punt >= der_len)
 
168
        return ASN1_DER_ERROR;
 
169
      {
 
170
        int last = ris;
 
171
        ris = ris * 128 + (der[punt++] & 0x7F);
 
172
        if (ris < last)
 
173
          /* wrapper around, and no bignums... */
 
174
          return ASN1_DER_ERROR;
 
175
      }
 
176
      *len = punt;
 
177
    }
 
178
  if (tag)
 
179
    *tag = ris;
 
180
  return ASN1_SUCCESS;
 
181
}
 
182
 
 
183
/**
 
184
 * asn1_get_length_ber:
 
185
 * @ber: BER data to decode.
 
186
 * @ber_len: Length of BER data to decode.
 
187
 * @len: Output variable containing the length of the BER length field.
 
188
 *
 
189
 * Extract a length field from BER data.  The difference to
 
190
 * asn1_get_length_der() is that this function will return a length
 
191
 * even if the value has indefinite encoding.
 
192
 *
 
193
 * Return value: Return the decoded length value, or negative value
 
194
 *   when the value was too big.
 
195
 *
 
196
 * Since: 2.0
 
197
 **/
 
198
signed long
 
199
asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
 
200
{
 
201
  int ret;
 
202
  long err;
 
203
 
 
204
  ret = asn1_get_length_der (ber, ber_len, len);
 
205
  if (ret == -1)
 
206
    {                           /* indefinite length method */
 
207
      err = _asn1_get_indefinite_length_string (ber + 1, ber_len, &ret);
 
208
      if (err != ASN1_SUCCESS)
 
209
        return -3;
 
210
    }
 
211
 
 
212
  return ret;
 
213
}
 
214
 
 
215
/**
 
216
 * asn1_get_octet_der:
 
217
 * @der: DER data to decode containing the OCTET SEQUENCE.
 
218
 * @der_len: Length of DER data to decode.
 
219
 * @ret_len: Output variable containing the length of the DER data.
 
220
 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
 
221
 * @str_size: Length of pre-allocated output buffer.
 
222
 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
 
223
 *
 
224
 * Extract an OCTET SEQUENCE from DER data.
 
225
 *
 
226
 * Return value: Returns ASN1_SUCCESS on success, or an error.
 
227
 **/
 
228
int
 
229
asn1_get_octet_der (const unsigned char *der, int der_len,
 
230
                    int *ret_len, unsigned char *str, int str_size,
 
231
                    int *str_len)
 
232
{
 
233
  int len_len = 0;
 
234
 
 
235
  if (der_len <= 0)
 
236
    return ASN1_GENERIC_ERROR;
 
237
 
 
238
  *str_len = asn1_get_length_der (der, der_len, &len_len);
 
239
 
 
240
  if (*str_len < 0)
 
241
    return ASN1_DER_ERROR;
 
242
 
 
243
  *ret_len = *str_len + len_len;
 
244
  if (str_size >= *str_len)
 
245
    {
 
246
      if (*str_len > 0 && str != NULL)
 
247
        memcpy (str, der + len_len, *str_len);
 
248
    }
 
249
  else
 
250
    {
 
251
      return ASN1_MEM_ERROR;
 
252
    }
 
253
 
 
254
  return ASN1_SUCCESS;
 
255
}
 
256
 
 
257
 
 
258
 
 
259
/* Returns ASN1_SUCCESS on success or an error code on error.
 
260
 */
 
261
static int
 
262
_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
 
263
                    char *str, int str_size)
 
264
{
 
265
  int len_len, str_len;
 
266
 
 
267
  if (der_len <= 0 || str == NULL)
 
268
    return ASN1_DER_ERROR;
 
269
 
 
270
  str_len = asn1_get_length_der (der, der_len, &len_len);
 
271
  if (str_len <= 0 || str_size < str_len)
 
272
    return ASN1_DER_ERROR;
 
273
 
 
274
  memcpy (str, der + len_len, str_len);
 
275
  str[str_len] = 0;
 
276
  *ret_len = str_len + len_len;
 
277
 
 
278
  return ASN1_SUCCESS;
 
279
}
 
280
 
 
281
 
 
282
 
 
283
static int
 
284
_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
 
285
                        char *str, int str_size)
 
286
{
 
287
  int len_len, len, k;
 
288
  int leading;
 
289
  char temp[20];
 
290
  unsigned long val, val1, prev_val;
 
291
 
 
292
  *ret_len = 0;
 
293
  if (str && str_size > 0)
 
294
    str[0] = 0;                 /* no oid */
 
295
 
 
296
  if (str == NULL || der_len <= 0)
 
297
    return ASN1_GENERIC_ERROR;
 
298
  len = asn1_get_length_der (der, der_len, &len_len);
 
299
 
 
300
  if (len <= 0 || len + len_len > der_len)
 
301
    return ASN1_DER_ERROR;
 
302
 
 
303
  val1 = der[len_len] / 40;
 
304
  val = der[len_len] - val1 * 40;
 
305
 
 
306
  _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
 
307
  _asn1_str_cat (str, str_size, ".");
 
308
  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
 
309
 
 
310
  prev_val = 0;
 
311
  val = 0;
 
312
  leading = 1;
 
313
  for (k = 1; k < len; k++)
 
314
    {
 
315
      
 
316
 
 
317
      /* X.690 mandates that the leading byte must never be 0x80
 
318
       */
 
319
      if (leading != 0 && der[len_len + k] == 0x80) return ASN1_DER_ERROR;
 
320
      leading = 0;
 
321
 
 
322
      /* check for wrap around */
 
323
      val = val << 7;
 
324
      val |= der[len_len + k] & 0x7F;
 
325
 
 
326
      if (val < prev_val) return ASN1_DER_ERROR;
 
327
 
 
328
      prev_val = val;
 
329
 
 
330
      if (!(der[len_len + k] & 0x80))
 
331
        {
 
332
          _asn1_str_cat (str, str_size, ".");
 
333
          _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
 
334
          val = 0;
 
335
          prev_val = 0;
 
336
          leading = 1;
 
337
        }
 
338
    }
 
339
  *ret_len = len + len_len;
 
340
  
 
341
  return ASN1_SUCCESS;
 
342
}
 
343
 
 
344
/**
 
345
 * asn1_get_bit_der:
 
346
 * @der: DER data to decode containing the BIT SEQUENCE.
 
347
 * @der_len: Length of DER data to decode.
 
348
 * @ret_len: Output variable containing the length of the DER data.
 
349
 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
 
350
 * @str_size: Length of pre-allocated output buffer.
 
351
 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
 
352
 *
 
353
 * Extract a BIT SEQUENCE from DER data.
 
354
 *
 
355
 * Return value: Return ASN1_SUCCESS on success, or an error.
 
356
 **/
 
357
int
 
358
asn1_get_bit_der (const unsigned char *der, int der_len,
 
359
                  int *ret_len, unsigned char *str, int str_size,
 
360
                  int *bit_len)
 
361
{
 
362
  int len_len = 0, len_byte;
 
363
 
 
364
  if (der_len <= 0)
 
365
    return ASN1_GENERIC_ERROR;
 
366
 
 
367
  len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
 
368
  if (len_byte < 0)
 
369
    return ASN1_DER_ERROR;
 
370
 
 
371
  *ret_len = len_byte + len_len + 1;
 
372
  *bit_len = len_byte * 8 - der[len_len];
 
373
  
 
374
  if (*bit_len < 0)
 
375
     return ASN1_DER_ERROR;
 
376
 
 
377
  if (str_size >= len_byte)
 
378
    {
 
379
      if (len_byte > 0 && str)
 
380
        memcpy (str, der + len_len + 1, len_byte);
 
381
    }
 
382
  else
 
383
    {
 
384
      return ASN1_MEM_ERROR;
 
385
    }
 
386
 
 
387
  return ASN1_SUCCESS;
 
388
}
 
389
 
 
390
 
 
391
 
 
392
 
 
393
static int
 
394
_asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
 
395
                       int *ret_len)
 
396
{
 
397
  ASN1_TYPE p;
 
398
  int counter, len2, len3, is_tag_implicit;
 
399
  int result;
 
400
  unsigned long tag, tag_implicit = 0;
 
401
  unsigned char class, class2, class_implicit = 0;
 
402
 
 
403
  if (der_len <= 0)
 
404
    return ASN1_GENERIC_ERROR;
 
405
 
 
406
  counter = is_tag_implicit = 0;
 
407
 
 
408
  if (node->type & CONST_TAG)
 
409
    {
 
410
      p = node->down;
 
411
      while (p)
 
412
        {
 
413
          if (type_field (p->type) == TYPE_TAG)
 
414
            {
 
415
              if (p->type & CONST_APPLICATION)
 
416
                class2 = ASN1_CLASS_APPLICATION;
 
417
              else if (p->type & CONST_UNIVERSAL)
 
418
                class2 = ASN1_CLASS_UNIVERSAL;
 
419
              else if (p->type & CONST_PRIVATE)
 
420
                class2 = ASN1_CLASS_PRIVATE;
 
421
              else
 
422
                class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
 
423
 
 
424
              if (p->type & CONST_EXPLICIT)
 
425
                {
 
426
                  if (asn1_get_tag_der
 
427
                      (der + counter, der_len, &class, &len2,
 
428
                       &tag) != ASN1_SUCCESS)
 
429
                    return ASN1_DER_ERROR;
 
430
 
 
431
                  DECR_LEN(der_len, len2);
 
432
                  counter += len2;
 
433
 
 
434
                  len3 =
 
435
                    asn1_get_length_ber (der + counter, der_len,
 
436
                                         &len2);
 
437
                  if (len3 < 0)
 
438
                    return ASN1_DER_ERROR;
 
439
 
 
440
                  DECR_LEN(der_len, len2);
 
441
                  counter += len2;
 
442
 
 
443
                  if (!is_tag_implicit)
 
444
                    {
 
445
                      if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
 
446
                          (tag != strtoul ((char *) p->value, NULL, 10)))
 
447
                        return ASN1_TAG_ERROR;
 
448
                    }
 
449
                  else
 
450
                    {           /* ASN1_TAG_IMPLICIT */
 
451
                      if ((class != class_implicit) || (tag != tag_implicit))
 
452
                        return ASN1_TAG_ERROR;
 
453
                    }
 
454
                  is_tag_implicit = 0;
 
455
                }
 
456
              else
 
457
                {               /* ASN1_TAG_IMPLICIT */
 
458
                  if (!is_tag_implicit)
 
459
                    {
 
460
                      if ((type_field (node->type) == TYPE_SEQUENCE) ||
 
461
                          (type_field (node->type) == TYPE_SEQUENCE_OF) ||
 
462
                          (type_field (node->type) == TYPE_SET) ||
 
463
                          (type_field (node->type) == TYPE_SET_OF))
 
464
                        class2 |= ASN1_CLASS_STRUCTURED;
 
465
                      class_implicit = class2;
 
466
                      tag_implicit = strtoul ((char *) p->value, NULL, 10);
 
467
                      is_tag_implicit = 1;
 
468
                    }
 
469
                }
 
470
            }
 
471
          p = p->right;
 
472
        }
 
473
    }
 
474
 
 
475
  if (is_tag_implicit)
 
476
    {
 
477
      if (asn1_get_tag_der
 
478
          (der + counter, der_len, &class, &len2,
 
479
           &tag) != ASN1_SUCCESS)
 
480
        return ASN1_DER_ERROR;
 
481
 
 
482
      DECR_LEN(der_len, len2);
 
483
 
 
484
      if ((class != class_implicit) || (tag != tag_implicit))
 
485
        {
 
486
          if (type_field (node->type) == TYPE_OCTET_STRING)
 
487
            {
 
488
              class_implicit |= ASN1_CLASS_STRUCTURED;
 
489
              if ((class != class_implicit) || (tag != tag_implicit))
 
490
                return ASN1_TAG_ERROR;
 
491
            }
 
492
          else
 
493
            return ASN1_TAG_ERROR;
 
494
        }
 
495
    }
 
496
  else
 
497
    {
 
498
      if (type_field (node->type) == TYPE_TAG)
 
499
        {
 
500
          *ret_len = 0;
 
501
          return ASN1_SUCCESS;
 
502
        }
 
503
 
 
504
      if (asn1_get_tag_der
 
505
          (der + counter, der_len, &class, &len2,
 
506
           &tag) != ASN1_SUCCESS)
 
507
        return ASN1_DER_ERROR;
 
508
 
 
509
      DECR_LEN(der_len, len2);
 
510
 
 
511
      switch (type_field (node->type))
 
512
        {
 
513
        case TYPE_NULL:
 
514
          if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
 
515
            return ASN1_DER_ERROR;
 
516
          break;
 
517
        case TYPE_BOOLEAN:
 
518
          if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
 
519
            return ASN1_DER_ERROR;
 
520
          break;
 
521
        case TYPE_INTEGER:
 
522
          if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
 
523
            return ASN1_DER_ERROR;
 
524
          break;
 
525
        case TYPE_ENUMERATED:
 
526
          if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
 
527
            return ASN1_DER_ERROR;
 
528
          break;
 
529
        case TYPE_OBJECT_ID:
 
530
          if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
 
531
            return ASN1_DER_ERROR;
 
532
          break;
 
533
        case TYPE_TIME:
 
534
          if (node->type & CONST_UTC)
 
535
            {
 
536
              if ((class != ASN1_CLASS_UNIVERSAL)
 
537
                  || (tag != ASN1_TAG_UTCTime))
 
538
                return ASN1_DER_ERROR;
 
539
            }
 
540
          else
 
541
            {
 
542
              if ((class != ASN1_CLASS_UNIVERSAL)
 
543
                  || (tag != ASN1_TAG_GENERALIZEDTime))
 
544
                return ASN1_DER_ERROR;
 
545
            }
 
546
          break;
 
547
        case TYPE_OCTET_STRING:
 
548
          if (((class != ASN1_CLASS_UNIVERSAL)
 
549
               && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
 
550
              || (tag != ASN1_TAG_OCTET_STRING))
 
551
            return ASN1_DER_ERROR;
 
552
          break;
 
553
        case TYPE_GENERALSTRING:
 
554
          if ((class != ASN1_CLASS_UNIVERSAL)
 
555
              || (tag != ASN1_TAG_GENERALSTRING))
 
556
            return ASN1_DER_ERROR;
 
557
          break;
 
558
        case TYPE_BIT_STRING:
 
559
          if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
 
560
            return ASN1_DER_ERROR;
 
561
          break;
 
562
        case TYPE_SEQUENCE:
 
563
        case TYPE_SEQUENCE_OF:
 
564
          if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
 
565
              || (tag != ASN1_TAG_SEQUENCE))
 
566
            return ASN1_DER_ERROR;
 
567
          break;
 
568
        case TYPE_SET:
 
569
        case TYPE_SET_OF:
 
570
          if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
 
571
              || (tag != ASN1_TAG_SET))
 
572
            return ASN1_DER_ERROR;
 
573
          break;
 
574
        case TYPE_ANY:
 
575
          counter -= len2;
 
576
          break;
 
577
        default:
 
578
          return ASN1_DER_ERROR;
 
579
          break;
 
580
        }
 
581
    }
 
582
 
 
583
  counter += len2;
 
584
  *ret_len = counter;
 
585
  return ASN1_SUCCESS;
 
586
 
 
587
cleanup:
 
588
  return result;
 
589
}
 
590
 
 
591
 
 
592
static int
 
593
_asn1_delete_not_used (ASN1_TYPE node)
 
594
{
 
595
  ASN1_TYPE p, p2;
 
596
 
 
597
  if (node == NULL)
 
598
    return ASN1_ELEMENT_NOT_FOUND;
 
599
 
 
600
  p = node;
 
601
  while (p)
 
602
    {
 
603
      if (p->type & CONST_NOT_USED)
 
604
        {
 
605
          p2 = NULL;
 
606
          if (p != node)
 
607
            {
 
608
              p2 = _asn1_find_left (p);
 
609
              if (!p2)
 
610
                p2 = _asn1_find_up (p);
 
611
            }
 
612
          asn1_delete_structure (&p);
 
613
          p = p2;
 
614
        }
 
615
 
 
616
      if (!p)
 
617
        break;                  /* reach node */
 
618
 
 
619
      if (p->down)
 
620
        {
 
621
          p = p->down;
 
622
        }
 
623
      else
 
624
        {
 
625
          if (p == node)
 
626
            p = NULL;
 
627
          else if (p->right)
 
628
            p = p->right;
 
629
          else
 
630
            {
 
631
              while (1)
 
632
                {
 
633
                  p = _asn1_find_up (p);
 
634
                  if (p == node)
 
635
                    {
 
636
                      p = NULL;
 
637
                      break;
 
638
                    }
 
639
                  if (p->right)
 
640
                    {
 
641
                      p = p->right;
 
642
                      break;
 
643
                    }
 
644
                }
 
645
            }
 
646
        }
 
647
    }
 
648
  return ASN1_SUCCESS;
 
649
}
 
650
 
 
651
static asn1_retCode
 
652
_asn1_extract_der_octet (ASN1_TYPE node, const unsigned char *der,
 
653
                         int der_len)
 
654
{
 
655
  int len2, len3;
 
656
  int counter, counter_end;
 
657
  int result;
 
658
 
 
659
  len2 = asn1_get_length_der (der, der_len, &len3);
 
660
  if (len2 < -1)
 
661
    return ASN1_DER_ERROR;
 
662
 
 
663
  counter = len3 + 1;
 
664
 
 
665
  if (len2 == -1)
 
666
    counter_end = der_len - 2;
 
667
  else
 
668
    counter_end = der_len;
 
669
 
 
670
  while (counter < counter_end)
 
671
    {
 
672
      len2 = asn1_get_length_der (der + counter, der_len, &len3);
 
673
 
 
674
      if (len2 < -1)
 
675
        return ASN1_DER_ERROR;
 
676
 
 
677
      if (len2 >= 0)
 
678
        {
 
679
          DECR_LEN(der_len, len2+len3);
 
680
          _asn1_append_value (node, der + counter + len3, len2);
 
681
        }
 
682
      else
 
683
        {                       /* indefinite */
 
684
 
 
685
          DECR_LEN(der_len, len3);
 
686
          result =
 
687
            _asn1_extract_der_octet (node, der + counter + len3,
 
688
                                     der_len);
 
689
          if (result != ASN1_SUCCESS)
 
690
            return result;
 
691
          len2 = 0;
 
692
        }
 
693
 
 
694
      DECR_LEN(der_len, 1);
 
695
      counter += len2 + len3 + 1;
 
696
    }
 
697
 
 
698
  return ASN1_SUCCESS;
 
699
 
 
700
cleanup:
 
701
  return result;
 
702
}
 
703
 
 
704
 
 
705
static asn1_retCode
 
706
_asn1_get_octet_string (ASN1_TYPE node, const unsigned char *der, int der_len, int *len)
 
707
{
 
708
  int len2, len3, counter, tot_len, indefinite;
 
709
  int result;
 
710
 
 
711
  counter = 0;
 
712
 
 
713
  if (*(der - 1) & ASN1_CLASS_STRUCTURED)
 
714
    {
 
715
      tot_len = 0;
 
716
      indefinite = asn1_get_length_der (der, der_len, &len3);
 
717
      if (indefinite < -1)
 
718
        return ASN1_DER_ERROR;
 
719
 
 
720
      counter += len3;
 
721
      DECR_LEN(der_len, len3);
 
722
 
 
723
      if (indefinite >= 0)
 
724
        indefinite += len3;
 
725
 
 
726
      while (1)
 
727
        {
 
728
          if (indefinite == -1)
 
729
            {
 
730
              if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
 
731
                {
 
732
                  counter += 2;
 
733
                  DECR_LEN(der_len, 2);
 
734
                  break;
 
735
                }
 
736
            }
 
737
          else if (counter >= indefinite)
 
738
            break;
 
739
 
 
740
          DECR_LEN(der_len, 1);
 
741
          if (der[counter] != ASN1_TAG_OCTET_STRING)
 
742
            return ASN1_DER_ERROR;
 
743
 
 
744
          counter++;
 
745
 
 
746
          len2 = asn1_get_length_der (der + counter, der_len, &len3);
 
747
          if (len2 <= 0)
 
748
            return ASN1_DER_ERROR;
 
749
 
 
750
          DECR_LEN(der_len, len3 + len2);
 
751
          counter += len3 + len2;
 
752
 
 
753
          tot_len += len2;
 
754
        }
 
755
 
 
756
      /* copy */
 
757
      if (node)
 
758
        {
 
759
          unsigned char temp[DER_LEN];
 
760
          int ret;
 
761
 
 
762
          len2 = sizeof (temp);
 
763
 
 
764
          asn1_length_der (tot_len, temp, &len2);
 
765
          _asn1_set_value (node, temp, len2);
 
766
 
 
767
          ret = _asn1_extract_der_octet (node, der, der_len);
 
768
          if (ret != ASN1_SUCCESS)
 
769
            return ret;
 
770
 
 
771
        }
 
772
    }
 
773
  else
 
774
    {                           /* NOT STRUCTURED */
 
775
      len2 = asn1_get_length_der (der, der_len, &len3);
 
776
      if (len2 < 0)
 
777
        return ASN1_DER_ERROR;
 
778
 
 
779
      DECR_LEN(der_len, len3+len2);
 
780
      counter = len3 + len2;
 
781
      if (node)
 
782
        _asn1_set_value (node, der, counter);
 
783
    }
 
784
 
 
785
  *len = counter;
 
786
  return ASN1_SUCCESS;
 
787
 
 
788
cleanup:
 
789
  return result;
 
790
}
 
791
 
 
792
static asn1_retCode
 
793
_asn1_get_indefinite_length_string (const unsigned char *der,
 
794
                                    int der_len, int *len)
 
795
{
 
796
  int len2, len3, counter, indefinite;
 
797
  int result;
 
798
  unsigned long tag;
 
799
  unsigned char class;
 
800
 
 
801
  counter = indefinite = 0;
 
802
 
 
803
  while (1)
 
804
    {
 
805
      if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0))
 
806
        {
 
807
          counter += 2;
 
808
          DECR_LEN(der_len, 2);
 
809
 
 
810
          indefinite--;
 
811
          if (indefinite <= 0)
 
812
            break;
 
813
          else
 
814
            continue;
 
815
        }
 
816
 
 
817
      if (asn1_get_tag_der
 
818
          (der + counter, der_len, &class, &len2,
 
819
           &tag) != ASN1_SUCCESS)
 
820
        return ASN1_DER_ERROR;
 
821
 
 
822
      DECR_LEN(der_len, len2);
 
823
      counter += len2;
 
824
 
 
825
      len2 = asn1_get_length_der (der + counter, der_len, &len3);
 
826
      if (len2 < -1)
 
827
        return ASN1_DER_ERROR;
 
828
 
 
829
      if (len2 == -1)
 
830
        {
 
831
          indefinite++;
 
832
          counter += 1;
 
833
          DECR_LEN(der_len, 1);
 
834
        }
 
835
      else
 
836
        {
 
837
          counter += len2 + len3;
 
838
          DECR_LEN(der_len, len2+len3);
 
839
        }
 
840
    }
 
841
 
 
842
  *len = counter;
 
843
  return ASN1_SUCCESS;
 
844
 
 
845
cleanup:
 
846
  return result;
 
847
}
 
848
 
 
849
 
 
850
 
 
851
/**
 
852
  * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
 
853
  * @element: pointer to an ASN1 structure.
 
854
  * @ider: vector that contains the DER encoding.
 
855
  * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1].
 
856
  * @errorDescription: null-terminated string contains details when an
 
857
  *   error occurred.
 
858
  *
 
859
  * Fill the structure *ELEMENT with values of a DER encoding
 
860
  * string. The structure must just be created with function
 
861
  * 'asn1_create_element'.  If an error occurs during the decoding
 
862
  * procedure, the *ELEMENT is deleted and set equal to
 
863
  * %ASN1_TYPE_EMPTY.
 
864
  *
 
865
  * Returns:
 
866
  *
 
867
  *   ASN1_SUCCESS: DER encoding OK.
 
868
  *
 
869
  *   ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
 
870
  *
 
871
  *   ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
 
872
  *     the structure NAME. *ELEMENT deleted.
 
873
  **/
 
874
 
 
875
asn1_retCode
 
876
asn1_der_decoding (ASN1_TYPE * element, const void *ider, int ider_len,
 
877
                   char *errorDescription)
 
878
{
 
879
  ASN1_TYPE node, p, p2, p3;
 
880
  char temp[128];
 
881
  int counter, len2, len3, len4, move, ris, tlen;
 
882
  unsigned char class;
 
883
  unsigned long tag;
 
884
  int indefinite, result;
 
885
  const unsigned char *der = ider;
 
886
 
 
887
  node = *element;
 
888
 
 
889
  if (node == ASN1_TYPE_EMPTY)
 
890
    return ASN1_ELEMENT_NOT_FOUND;
 
891
 
 
892
  if (node->type & CONST_OPTION)
 
893
    {
 
894
      warn();
 
895
      asn1_delete_structure (element);
 
896
      return ASN1_GENERIC_ERROR;
 
897
    }
 
898
 
 
899
  counter = 0;
 
900
  move = DOWN;
 
901
  p = node;
 
902
  while (1)
 
903
    {
 
904
      ris = ASN1_SUCCESS;
 
905
      if (move != UP)
 
906
        {
 
907
          if (p->type & CONST_SET)
 
908
            {
 
909
              p2 = _asn1_find_up (p);
 
910
              len2 = strtol (p2->value, NULL, 10);
 
911
              if (len2 == -1)
 
912
                {
 
913
                  if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1])
 
914
                    {
 
915
                      p = p2;
 
916
                      move = UP;
 
917
                      counter += 2;
 
918
                      DECR_LEN(ider_len, 2);
 
919
                      continue;
 
920
                    }
 
921
                }
 
922
              else if (counter == len2)
 
923
                {
 
924
                  p = p2;
 
925
                  move = UP;
 
926
                  continue;
 
927
                }
 
928
              else if (counter > len2)
 
929
                {
 
930
                  warn();
 
931
                  asn1_delete_structure (element);
 
932
                  return ASN1_DER_ERROR;
 
933
                }
 
934
              p2 = p2->down;
 
935
              while (p2)
 
936
                {
 
937
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
 
938
                    {
 
939
                      if (type_field (p2->type) != TYPE_CHOICE)
 
940
                        ris =
 
941
                          _asn1_extract_tag_der (p2, der + counter,
 
942
                                                 ider_len, &len2);
 
943
                      else
 
944
                        {
 
945
                          p3 = p2->down;
 
946
                          while (p3)
 
947
                            {
 
948
                              ris =
 
949
                                _asn1_extract_tag_der (p3, der + counter,
 
950
                                                       ider_len, &len2);
 
951
                              if (ris == ASN1_SUCCESS)
 
952
                                break;
 
953
                              p3 = p3->right;
 
954
                            }
 
955
                        }
 
956
                      if (ris == ASN1_SUCCESS)
 
957
                        {
 
958
                          p2->type &= ~CONST_NOT_USED;
 
959
                          p = p2;
 
960
                          break;
 
961
                        }
 
962
                    }
 
963
                  p2 = p2->right;
 
964
                }
 
965
              if (p2 == NULL)
 
966
                {
 
967
                  warn();
 
968
                  asn1_delete_structure (element);
 
969
                  return ASN1_DER_ERROR;
 
970
                }
 
971
            }
 
972
 
 
973
          if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
 
974
            {
 
975
              p2 = _asn1_find_up (p);
 
976
              len2 = strtol (p2->value, NULL, 10);
 
977
              if (counter == len2)
 
978
                {
 
979
                  if (p->right)
 
980
                    {
 
981
                      p2 = p->right;
 
982
                      move = RIGHT;
 
983
                    }
 
984
                  else
 
985
                    move = UP;
 
986
 
 
987
                  if (p->type & CONST_OPTION)
 
988
                    asn1_delete_structure (&p);
 
989
 
 
990
                  p = p2;
 
991
                  continue;
 
992
                }
 
993
            }
 
994
 
 
995
          if (type_field (p->type) == TYPE_CHOICE)
 
996
            {
 
997
              while (p->down)
 
998
                {
 
999
                  ris =
 
1000
                      _asn1_extract_tag_der (p->down, der + counter,
 
1001
                                             ider_len, &len2);
 
1002
 
 
1003
                  if (ris == ASN1_SUCCESS)
 
1004
                    {
 
1005
                      while (p->down->right)
 
1006
                        {
 
1007
                          p2 = p->down->right;
 
1008
                          asn1_delete_structure (&p2);
 
1009
                        }
 
1010
                      break;
 
1011
                    }
 
1012
                  else if (ris == ASN1_ERROR_TYPE_ANY)
 
1013
                    {
 
1014
                      warn();
 
1015
                      asn1_delete_structure (element);
 
1016
                      return ASN1_ERROR_TYPE_ANY;
 
1017
                    }
 
1018
                  else
 
1019
                    {
 
1020
                      p2 = p->down;
 
1021
                      asn1_delete_structure (&p2);
 
1022
                    }
 
1023
                }
 
1024
 
 
1025
              if (p->down == NULL)
 
1026
                {
 
1027
                  if (!(p->type & CONST_OPTION))
 
1028
                    {
 
1029
                      warn();
 
1030
                      asn1_delete_structure (element);
 
1031
                      return ASN1_DER_ERROR;
 
1032
                    }
 
1033
                }
 
1034
              else
 
1035
                p = p->down;
 
1036
            }
 
1037
 
 
1038
          if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
 
1039
            {
 
1040
              p2 = _asn1_find_up (p);
 
1041
              len2 = strtol (p2->value, NULL, 10);
 
1042
 
 
1043
              if ((len2 != -1) && (counter > len2))
 
1044
                ris = ASN1_TAG_ERROR;
 
1045
            }
 
1046
 
 
1047
          if (ris == ASN1_SUCCESS)
 
1048
            ris =
 
1049
              _asn1_extract_tag_der (p, der + counter, ider_len, &len2);
 
1050
 
 
1051
          if (ris != ASN1_SUCCESS)
 
1052
            {
 
1053
              if (p->type & CONST_OPTION)
 
1054
                {
 
1055
                  p->type |= CONST_NOT_USED;
 
1056
                  move = RIGHT;
 
1057
                }
 
1058
              else if (p->type & CONST_DEFAULT)
 
1059
                {
 
1060
                  _asn1_set_value (p, NULL, 0);
 
1061
                  move = RIGHT;
 
1062
                }
 
1063
              else
 
1064
                {
 
1065
                  if (errorDescription != NULL)
 
1066
                    _asn1_error_description_tag_error (p, errorDescription);
 
1067
 
 
1068
                  warn();
 
1069
                  asn1_delete_structure (element);
 
1070
                  return ASN1_TAG_ERROR;
 
1071
                }
 
1072
            }
 
1073
          else
 
1074
            {
 
1075
              DECR_LEN(ider_len, len2);
 
1076
              counter += len2;
 
1077
            }
 
1078
        }
 
1079
 
 
1080
      if (ris == ASN1_SUCCESS)
 
1081
        {
 
1082
          switch (type_field (p->type))
 
1083
            {
 
1084
            case TYPE_NULL:
 
1085
              DECR_LEN(ider_len, 1);
 
1086
              if (der[counter])
 
1087
                {
 
1088
                  warn();
 
1089
                  asn1_delete_structure (element);
 
1090
                  return ASN1_DER_ERROR;
 
1091
                }
 
1092
              counter++;
 
1093
              move = RIGHT;
 
1094
              break;
 
1095
            case TYPE_BOOLEAN:
 
1096
              DECR_LEN(ider_len, 2);
 
1097
 
 
1098
              if (der[counter++] != 1)
 
1099
                {
 
1100
                  warn();
 
1101
                  asn1_delete_structure (element);
 
1102
                  return ASN1_DER_ERROR;
 
1103
                }
 
1104
              if (der[counter++] == 0)
 
1105
                _asn1_set_value (p, "F", 1);
 
1106
              else
 
1107
                _asn1_set_value (p, "T", 1);
 
1108
              move = RIGHT;
 
1109
              break;
 
1110
            case TYPE_INTEGER:
 
1111
            case TYPE_ENUMERATED:
 
1112
              len2 =
 
1113
                asn1_get_length_der (der + counter, ider_len, &len3);
 
1114
              if (len2 < 0)
 
1115
                {
 
1116
                  warn();
 
1117
                  return ASN1_DER_ERROR;
 
1118
                }
 
1119
              DECR_LEN(ider_len, len3+len2);
 
1120
 
 
1121
              _asn1_set_value (p, der + counter, len3 + len2);
 
1122
              counter += len3 + len2;
 
1123
              move = RIGHT;
 
1124
              break;
 
1125
            case TYPE_OBJECT_ID:
 
1126
              result = _asn1_get_objectid_der (der + counter, ider_len, &len2,
 
1127
                                      temp, sizeof (temp));
 
1128
              if (result != ASN1_SUCCESS)
 
1129
                {
 
1130
                  warn();
 
1131
                  asn1_delete_structure (element);
 
1132
                  return result;
 
1133
                }
 
1134
 
 
1135
              DECR_LEN(ider_len, len2);
 
1136
 
 
1137
              tlen = strlen (temp);
 
1138
              if (tlen > 0)
 
1139
                _asn1_set_value (p, temp, tlen + 1);
 
1140
 
 
1141
              counter += len2;
 
1142
              move = RIGHT;
 
1143
              break;
 
1144
            case TYPE_TIME:
 
1145
              result =
 
1146
                _asn1_get_time_der (der + counter, ider_len, &len2, temp,
 
1147
                                    sizeof (temp) - 1);
 
1148
              if (result != ASN1_SUCCESS)
 
1149
                {
 
1150
                  warn();
 
1151
                  asn1_delete_structure (element);
 
1152
                  return result;
 
1153
                }
 
1154
 
 
1155
              DECR_LEN(ider_len, len2);
 
1156
 
 
1157
              tlen = strlen (temp);
 
1158
              if (tlen > 0)
 
1159
                _asn1_set_value (p, temp, tlen + 1);
 
1160
 
 
1161
              counter += len2;
 
1162
              move = RIGHT;
 
1163
              break;
 
1164
            case TYPE_OCTET_STRING:
 
1165
              ris = _asn1_get_octet_string (p, der + counter, ider_len, &len3);
 
1166
              if (ris != ASN1_SUCCESS)
 
1167
                {
 
1168
                  warn();
 
1169
                  return ris;
 
1170
                }
 
1171
 
 
1172
              DECR_LEN(ider_len, len3);
 
1173
              counter += len3;
 
1174
              move = RIGHT;
 
1175
              break;
 
1176
            case TYPE_GENERALSTRING:
 
1177
              len2 =
 
1178
                asn1_get_length_der (der + counter, ider_len, &len3);
 
1179
              if (len2 < 0)
 
1180
                {
 
1181
                  warn();
 
1182
                  return ASN1_DER_ERROR;
 
1183
                }
 
1184
 
 
1185
              _asn1_set_value (p, der + counter, len3 + len2);
 
1186
 
 
1187
              DECR_LEN(ider_len, len3 + len2);
 
1188
              counter += len3 + len2;
 
1189
              move = RIGHT;
 
1190
              break;
 
1191
            case TYPE_BIT_STRING:
 
1192
              len2 =
 
1193
                asn1_get_length_der (der + counter, ider_len, &len3);
 
1194
              if (len2 < 0)
 
1195
                {
 
1196
                  warn();
 
1197
                  return ASN1_DER_ERROR;
 
1198
                }
 
1199
 
 
1200
              _asn1_set_value (p, der + counter, len3 + len2);
 
1201
 
 
1202
 
 
1203
              DECR_LEN(ider_len, len3 + len2);
 
1204
              counter += len3 + len2;
 
1205
              move = RIGHT;
 
1206
              break;
 
1207
            case TYPE_SEQUENCE:
 
1208
            case TYPE_SET:
 
1209
              if (move == UP)
 
1210
                {
 
1211
                  len2 = strtol (p->value, NULL, 10);
 
1212
                  _asn1_set_value (p, NULL, 0);
 
1213
                  if (len2 == -1)
 
1214
                    {           /* indefinite length method */
 
1215
                      DECR_LEN(ider_len, 2);
 
1216
                      if ((der[counter]) || der[counter + 1])
 
1217
                        {
 
1218
                          warn();
 
1219
                          asn1_delete_structure (element);
 
1220
                          return ASN1_DER_ERROR;
 
1221
                        }
 
1222
                      counter += 2;
 
1223
                    }
 
1224
                  else
 
1225
                    {           /* definite length method */
 
1226
                      if (len2 != counter)
 
1227
                        {
 
1228
                          warn();
 
1229
                          asn1_delete_structure (element);
 
1230
                          return ASN1_DER_ERROR;
 
1231
                        }
 
1232
                    }
 
1233
                  move = RIGHT;
 
1234
                }
 
1235
              else
 
1236
                {               /* move==DOWN || move==RIGHT */
 
1237
                  len3 =
 
1238
                    asn1_get_length_der (der + counter, ider_len, &len2);
 
1239
                  if (len3 < -1)
 
1240
                    {
 
1241
                      warn();
 
1242
                      return ASN1_DER_ERROR;
 
1243
                    }
 
1244
 
 
1245
                  DECR_LEN(ider_len, len2);
 
1246
                  counter += len2;
 
1247
                  if (len3 > 0)
 
1248
                    {
 
1249
                      _asn1_ltostr (counter + len3, temp);
 
1250
                      tlen = strlen (temp);
 
1251
                      if (tlen > 0)
 
1252
                        _asn1_set_value (p, temp, tlen + 1);
 
1253
                      move = DOWN;
 
1254
                    }
 
1255
                  else if (len3 == 0)
 
1256
                    {
 
1257
                      p2 = p->down;
 
1258
                      while (p2)
 
1259
                        {
 
1260
                          if (type_field (p2->type) != TYPE_TAG)
 
1261
                            {
 
1262
                              p3 = p2->right;
 
1263
                              asn1_delete_structure (&p2);
 
1264
                              p2 = p3;
 
1265
                            }
 
1266
                          else
 
1267
                            p2 = p2->right;
 
1268
                        }
 
1269
                      move = RIGHT;
 
1270
                    }
 
1271
                  else
 
1272
                    {           /* indefinite length method */
 
1273
                      _asn1_set_value (p, "-1", 3);
 
1274
                      move = DOWN;
 
1275
                    }
 
1276
                }
 
1277
              break;
 
1278
            case TYPE_SEQUENCE_OF:
 
1279
            case TYPE_SET_OF:
 
1280
              if (move == UP)
 
1281
                {
 
1282
                  len2 = strtol (p->value, NULL, 10);
 
1283
                  if (len2 == -1)
 
1284
                    {           /* indefinite length method */
 
1285
                      if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1]))
 
1286
                        {
 
1287
                          _asn1_append_sequence_set (p);
 
1288
                          p = p->down;
 
1289
                          while (p->right)
 
1290
                            p = p->right;
 
1291
                          move = RIGHT;
 
1292
                          continue;
 
1293
                        }
 
1294
 
 
1295
                      _asn1_set_value (p, NULL, 0);
 
1296
                      DECR_LEN(ider_len, 2);
 
1297
                      counter += 2;
 
1298
                    }
 
1299
                  else
 
1300
                    {           /* definite length method */
 
1301
                      if (len2 > counter)
 
1302
                        {
 
1303
                          _asn1_append_sequence_set (p);
 
1304
                          p = p->down;
 
1305
                          while (p->right)
 
1306
                            p = p->right;
 
1307
                          move = RIGHT;
 
1308
                          continue;
 
1309
                        }
 
1310
 
 
1311
                      _asn1_set_value (p, NULL, 0);
 
1312
                      if (len2 != counter)
 
1313
                        {
 
1314
                          warn();
 
1315
                          asn1_delete_structure (element);
 
1316
                          return ASN1_DER_ERROR;
 
1317
                        }
 
1318
                    }
 
1319
                }
 
1320
              else
 
1321
                {               /* move==DOWN || move==RIGHT */
 
1322
                  len3 =
 
1323
                    asn1_get_length_der (der + counter, ider_len, &len2);
 
1324
                  if (len3 < -1)
 
1325
                    {
 
1326
                      warn();
 
1327
                      return ASN1_DER_ERROR;
 
1328
                    }
 
1329
 
 
1330
                  DECR_LEN(ider_len, len2);
 
1331
                  counter += len2;
 
1332
                  if (len3)
 
1333
                    {
 
1334
                      if (len3 > 0)
 
1335
                        {       /* definite length method */
 
1336
                          _asn1_ltostr (counter + len3, temp);
 
1337
                          tlen = strlen (temp);
 
1338
 
 
1339
                          if (tlen > 0)
 
1340
                            _asn1_set_value (p, temp, tlen + 1);
 
1341
                        }
 
1342
                      else
 
1343
                        {       /* indefinite length method */
 
1344
                          _asn1_set_value (p, "-1", 3);
 
1345
                        }
 
1346
                      p2 = p->down;
 
1347
                      while ((type_field (p2->type) == TYPE_TAG)
 
1348
                             || (type_field (p2->type) == TYPE_SIZE))
 
1349
                        p2 = p2->right;
 
1350
                      if (p2->right == NULL)
 
1351
                        _asn1_append_sequence_set (p);
 
1352
                      p = p2;
 
1353
                    }
 
1354
                }
 
1355
              move = RIGHT;
 
1356
              break;
 
1357
            case TYPE_ANY:
 
1358
              if (asn1_get_tag_der
 
1359
                  (der + counter, ider_len, &class, &len2,
 
1360
                   &tag) != ASN1_SUCCESS)
 
1361
                {
 
1362
                  warn();
 
1363
                  return ASN1_DER_ERROR;
 
1364
                }
 
1365
 
 
1366
              DECR_LEN(ider_len, len2);
 
1367
 
 
1368
              len4 =
 
1369
                asn1_get_length_der (der + counter + len2,
 
1370
                                     ider_len, &len3);
 
1371
              if (len4 < -1)
 
1372
                {
 
1373
                  warn();
 
1374
                  return ASN1_DER_ERROR;
 
1375
                }
 
1376
              if (len4 != -1) /* definite */
 
1377
                {
 
1378
                  len2 += len4;
 
1379
 
 
1380
                  DECR_LEN(ider_len, len4+len3);
 
1381
                  _asn1_set_value_octet (p, der + counter, len2 + len3);
 
1382
                  counter += len2 + len3;
 
1383
                }
 
1384
              else /* == -1 */
 
1385
                {               /* indefinite length */
 
1386
                  ider_len += len2; /* undo DECR_LEN */
 
1387
 
 
1388
                  if (counter == 0)
 
1389
                    {
 
1390
                      warn();
 
1391
                      return ASN1_DER_ERROR;
 
1392
                    }
 
1393
 
 
1394
                  /* Check indefinite lenth method in an EXPLICIT TAG */
 
1395
                  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
 
1396
                    indefinite = 1;
 
1397
                  else
 
1398
                    indefinite = 0;
 
1399
 
 
1400
                  ris =
 
1401
                    _asn1_get_indefinite_length_string (der + counter, ider_len, &len2);
 
1402
                  if (ris != ASN1_SUCCESS)
 
1403
                    {
 
1404
                      warn();
 
1405
                      asn1_delete_structure (element);
 
1406
                      return ris;
 
1407
                    }
 
1408
 
 
1409
                  DECR_LEN(ider_len, len2);
 
1410
                  _asn1_set_value_octet (p, der + counter, len2);
 
1411
                  counter += len2;
 
1412
 
 
1413
                  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
 
1414
                     an indefinite length method. */
 
1415
                  if (indefinite)
 
1416
                    {
 
1417
                      DECR_LEN(ider_len, 2);
 
1418
                      if (!der[counter] && !der[counter + 1])
 
1419
                        {
 
1420
                          counter += 2;
 
1421
                        }
 
1422
                      else
 
1423
                        {
 
1424
                          warn();
 
1425
                          asn1_delete_structure (element);
 
1426
                          return ASN1_DER_ERROR;
 
1427
                        }
 
1428
                    }
 
1429
                }
 
1430
              move = RIGHT;
 
1431
              break;
 
1432
            default:
 
1433
              move = (move == UP) ? RIGHT : DOWN;
 
1434
              break;
 
1435
            }
 
1436
        }
 
1437
 
 
1438
      if (p == node && move != DOWN)
 
1439
        break;
 
1440
 
 
1441
      if (move == DOWN)
 
1442
        {
 
1443
          if (p->down)
 
1444
            p = p->down;
 
1445
          else
 
1446
            move = RIGHT;
 
1447
        }
 
1448
      if ((move == RIGHT) && !(p->type & CONST_SET))
 
1449
        {
 
1450
          if (p->right)
 
1451
            p = p->right;
 
1452
          else
 
1453
            move = UP;
 
1454
        }
 
1455
      if (move == UP)
 
1456
        p = _asn1_find_up (p);
 
1457
    }
 
1458
 
 
1459
  _asn1_delete_not_used (*element);
 
1460
 
 
1461
  if (ider_len != 0)
 
1462
    {
 
1463
      warn();
 
1464
      asn1_delete_structure (element);
 
1465
      return ASN1_DER_ERROR;
 
1466
    }
 
1467
 
 
1468
  return ASN1_SUCCESS;
 
1469
 
 
1470
cleanup:
 
1471
  return result;
 
1472
}
 
1473
 
 
1474
 
 
1475
#define FOUND        1
 
1476
#define SAME_BRANCH  2
 
1477
#define OTHER_BRANCH 3
 
1478
#define EXIT         4
 
1479
 
 
1480
/**
 
1481
  * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
 
1482
  * @structure: pointer to an ASN1 structure
 
1483
  * @elementName: name of the element to fill
 
1484
  * @ider: vector that contains the DER encoding of the whole structure.
 
1485
  * @len: number of bytes of *der: der[0]..der[len-1]
 
1486
  * @errorDescription: null-terminated string contains details when an
 
1487
  *   error occurred.
 
1488
  *
 
1489
  * Fill the element named ELEMENTNAME with values of a DER encoding
 
1490
  * string.  The structure must just be created with function
 
1491
  * 'asn1_create_element'.  The DER vector must contain the encoding
 
1492
  * string of the whole STRUCTURE.  If an error occurs during the
 
1493
  * decoding procedure, the *STRUCTURE is deleted and set equal to
 
1494
  * %ASN1_TYPE_EMPTY.
 
1495
  *
 
1496
  * This function is deprecated and may just be an alias to asn1_der_decoding
 
1497
  * in future versions. Use asn1_der_decoding() instead.
 
1498
  *
 
1499
  * Returns:
 
1500
  *
 
1501
  *   ASN1_SUCCESS: DER encoding OK.
 
1502
  *
 
1503
  *   ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
 
1504
  *     elementName == NULL.
 
1505
  *
 
1506
  *   ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
 
1507
  *   the structure STRUCTURE. *ELEMENT deleted.
 
1508
  *
 
1509
  **/
 
1510
asn1_retCode
 
1511
asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
 
1512
                           const void *ider, int len, char *errorDescription)
 
1513
{
 
1514
  ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
 
1515
  char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
 
1516
  int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
 
1517
  int counter, len2, len3, len4, move, ris, tlen;
 
1518
  unsigned char class, *temp2;
 
1519
  unsigned long tag;
 
1520
  int indefinite, result;
 
1521
  const unsigned char *der = ider;
 
1522
 
 
1523
  node = *structure;
 
1524
 
 
1525
  if (node == ASN1_TYPE_EMPTY)
 
1526
    return ASN1_ELEMENT_NOT_FOUND;
 
1527
 
 
1528
  if (elementName == NULL)
 
1529
    {
 
1530
      asn1_delete_structure (structure);
 
1531
      return ASN1_ELEMENT_NOT_FOUND;
 
1532
    }
 
1533
 
 
1534
  if (node->type & CONST_OPTION)
 
1535
    {
 
1536
      asn1_delete_structure (structure);
 
1537
      return ASN1_GENERIC_ERROR;
 
1538
    }
 
1539
 
 
1540
  if ((*structure)->name)
 
1541
    {                           /* Has *structure got a name? */
 
1542
      nameLen -= strlen ((*structure)->name);
 
1543
      if (nameLen > 0)
 
1544
        strcpy (currentName, (*structure)->name);
 
1545
      else
 
1546
        {
 
1547
          asn1_delete_structure (structure);
 
1548
          return ASN1_MEM_ERROR;
 
1549
        }
 
1550
      if (!(strcmp (currentName, elementName)))
 
1551
        {
 
1552
          state = FOUND;
 
1553
          nodeFound = *structure;
 
1554
        }
 
1555
      else if (!memcmp (currentName, elementName, strlen (currentName)))
 
1556
        state = SAME_BRANCH;
 
1557
      else
 
1558
        state = OTHER_BRANCH;
 
1559
    }
 
1560
  else
 
1561
    {                           /* *structure doesn't have a name? */
 
1562
      currentName[0] = 0;
 
1563
      if (elementName[0] == 0)
 
1564
        {
 
1565
          state = FOUND;
 
1566
          nodeFound = *structure;
 
1567
        }
 
1568
      else
 
1569
        {
 
1570
          state = SAME_BRANCH;
 
1571
        }
 
1572
    }
 
1573
 
 
1574
  counter = 0;
 
1575
  move = DOWN;
 
1576
  p = node;
 
1577
  while (1)
 
1578
    {
 
1579
 
 
1580
      ris = ASN1_SUCCESS;
 
1581
 
 
1582
      if (move != UP)
 
1583
        {
 
1584
          if (p->type & CONST_SET)
 
1585
            {
 
1586
              p2 = _asn1_find_up (p);
 
1587
              len2 = strtol (p2->value, NULL, 10);
 
1588
              if (counter == len2)
 
1589
                {
 
1590
                  p = p2;
 
1591
                  move = UP;
 
1592
                  continue;
 
1593
                }
 
1594
              else if (counter > len2)
 
1595
                {
 
1596
                  asn1_delete_structure (structure);
 
1597
                  return ASN1_DER_ERROR;
 
1598
                }
 
1599
              p2 = p2->down;
 
1600
              while (p2)
 
1601
                {
 
1602
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
 
1603
                    {
 
1604
                      if (type_field (p2->type) != TYPE_CHOICE)
 
1605
                        ris =
 
1606
                          _asn1_extract_tag_der (p2, der + counter,
 
1607
                                                 len - counter, &len2);
 
1608
                      else
 
1609
                        {
 
1610
                          p3 = p2->down;
 
1611
                          while (p3)
 
1612
                            {
 
1613
                              ris =
 
1614
                                _asn1_extract_tag_der (p3, der + counter,
 
1615
                                                       len - counter, &len2);
 
1616
                              if (ris == ASN1_SUCCESS)
 
1617
                                break;
 
1618
                              p3 = p3->right;
 
1619
                            }
 
1620
                        }
 
1621
                      if (ris == ASN1_SUCCESS)
 
1622
                        {
 
1623
                          p2->type &= ~CONST_NOT_USED;
 
1624
                          p = p2;
 
1625
                          break;
 
1626
                        }
 
1627
                    }
 
1628
                  p2 = p2->right;
 
1629
                }
 
1630
              if (p2 == NULL)
 
1631
                {
 
1632
                  asn1_delete_structure (structure);
 
1633
                  return ASN1_DER_ERROR;
 
1634
                }
 
1635
            }
 
1636
 
 
1637
          if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
 
1638
            {
 
1639
              p2 = _asn1_find_up (p);
 
1640
              len2 = strtol (p2->value, NULL, 10);
 
1641
              if (counter == len2)
 
1642
                {
 
1643
                  if (p->right)
 
1644
                    {
 
1645
                      p2 = p->right;
 
1646
                      move = RIGHT;
 
1647
                    }
 
1648
                  else
 
1649
                    move = UP;
 
1650
 
 
1651
                  if (p->type & CONST_OPTION)
 
1652
                    asn1_delete_structure (&p);
 
1653
 
 
1654
                  p = p2;
 
1655
                  continue;
 
1656
                }
 
1657
            }
 
1658
 
 
1659
          if (type_field (p->type) == TYPE_CHOICE)
 
1660
            {
 
1661
              while (p->down)
 
1662
                {
 
1663
                  if (counter < len)
 
1664
                    ris =
 
1665
                      _asn1_extract_tag_der (p->down, der + counter,
 
1666
                                             len - counter, &len2);
 
1667
                  else
 
1668
                    ris = ASN1_DER_ERROR;
 
1669
                  if (ris == ASN1_SUCCESS)
 
1670
                    {
 
1671
                      while (p->down->right)
 
1672
                        {
 
1673
                          p2 = p->down->right;
 
1674
                          asn1_delete_structure (&p2);
 
1675
                        }
 
1676
                      break;
 
1677
                    }
 
1678
                  else if (ris == ASN1_ERROR_TYPE_ANY)
 
1679
                    {
 
1680
                      asn1_delete_structure (structure);
 
1681
                      return ASN1_ERROR_TYPE_ANY;
 
1682
                    }
 
1683
                  else
 
1684
                    {
 
1685
                      p2 = p->down;
 
1686
                      asn1_delete_structure (&p2);
 
1687
                    }
 
1688
                }
 
1689
 
 
1690
              if (p->down == NULL)
 
1691
                {
 
1692
                  if (!(p->type & CONST_OPTION))
 
1693
                    {
 
1694
                      asn1_delete_structure (structure);
 
1695
                      return ASN1_DER_ERROR;
 
1696
                    }
 
1697
                }
 
1698
              else
 
1699
                p = p->down;
 
1700
            }
 
1701
 
 
1702
          if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
 
1703
            {
 
1704
              p2 = _asn1_find_up (p);
 
1705
              len2 = strtol (p2->value, NULL, 10);
 
1706
              if (counter > len2)
 
1707
                ris = ASN1_TAG_ERROR;
 
1708
            }
 
1709
 
 
1710
          if (ris == ASN1_SUCCESS)
 
1711
            ris =
 
1712
              _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
 
1713
          if (ris != ASN1_SUCCESS)
 
1714
            {
 
1715
              if (p->type & CONST_OPTION)
 
1716
                {
 
1717
                  p->type |= CONST_NOT_USED;
 
1718
                  move = RIGHT;
 
1719
                }
 
1720
              else if (p->type & CONST_DEFAULT)
 
1721
                {
 
1722
                  _asn1_set_value (p, NULL, 0);
 
1723
                  move = RIGHT;
 
1724
                }
 
1725
              else
 
1726
                {
 
1727
                  if (errorDescription != NULL)
 
1728
                    _asn1_error_description_tag_error (p, errorDescription);
 
1729
 
 
1730
                  asn1_delete_structure (structure);
 
1731
                  return ASN1_TAG_ERROR;
 
1732
                }
 
1733
            }
 
1734
          else
 
1735
            counter += len2;
 
1736
        }
 
1737
 
 
1738
      if (ris == ASN1_SUCCESS)
 
1739
        {
 
1740
          switch (type_field (p->type))
 
1741
            {
 
1742
            case TYPE_NULL:
 
1743
              if (der[counter])
 
1744
                {
 
1745
                  asn1_delete_structure (structure);
 
1746
                  return ASN1_DER_ERROR;
 
1747
                }
 
1748
 
 
1749
              if (p == nodeFound)
 
1750
                state = EXIT;
 
1751
 
 
1752
              counter++;
 
1753
              move = RIGHT;
 
1754
              break;
 
1755
            case TYPE_BOOLEAN:
 
1756
              if (der[counter++] != 1)
 
1757
                {
 
1758
                  asn1_delete_structure (structure);
 
1759
                  return ASN1_DER_ERROR;
 
1760
                }
 
1761
 
 
1762
              if (state == FOUND)
 
1763
                {
 
1764
                  if (der[counter++] == 0)
 
1765
                    _asn1_set_value (p, "F", 1);
 
1766
                  else
 
1767
                    _asn1_set_value (p, "T", 1);
 
1768
 
 
1769
                  if (p == nodeFound)
 
1770
                    state = EXIT;
 
1771
 
 
1772
                }
 
1773
              else
 
1774
                counter++;
 
1775
 
 
1776
              move = RIGHT;
 
1777
              break;
 
1778
            case TYPE_INTEGER:
 
1779
            case TYPE_ENUMERATED:
 
1780
              len2 =
 
1781
                asn1_get_length_der (der + counter, len - counter, &len3);
 
1782
              if (len2 < 0)
 
1783
                return ASN1_DER_ERROR;
 
1784
              if (state == FOUND)
 
1785
                {
 
1786
                  if (len3 + len2 > len - counter)
 
1787
                    return ASN1_DER_ERROR;
 
1788
                  _asn1_set_value (p, der + counter, len3 + len2);
 
1789
 
 
1790
                  if (p == nodeFound)
 
1791
                    state = EXIT;
 
1792
                }
 
1793
              counter += len3 + len2;
 
1794
              move = RIGHT;
 
1795
              break;
 
1796
            case TYPE_OBJECT_ID:
 
1797
              if (state == FOUND)
 
1798
                {
 
1799
                  result = _asn1_get_objectid_der (der + counter, len - counter, &len2,
 
1800
                                          temp, sizeof (temp));
 
1801
                  if (result != ASN1_SUCCESS)
 
1802
                  {
 
1803
                    return result;
 
1804
                  }
 
1805
 
 
1806
                  tlen = strlen (temp);
 
1807
 
 
1808
                  if (tlen > 0)
 
1809
                    _asn1_set_value (p, temp, tlen + 1);
 
1810
 
 
1811
                  if (p == nodeFound)
 
1812
                    state = EXIT;
 
1813
                }
 
1814
              else
 
1815
                {
 
1816
                  len2 =
 
1817
                    asn1_get_length_der (der + counter, len - counter, &len3);
 
1818
                  if (len2 < 0)
 
1819
                    return ASN1_DER_ERROR;
 
1820
                  len2 += len3;
 
1821
                }
 
1822
 
 
1823
              counter += len2;
 
1824
              move = RIGHT;
 
1825
              break;
 
1826
            case TYPE_TIME:
 
1827
              if (state == FOUND)
 
1828
                {
 
1829
                  result =
 
1830
                    _asn1_get_time_der (der + counter, len - counter, &len2,
 
1831
                                        temp, sizeof (temp) - 1);
 
1832
                  if (result != ASN1_SUCCESS)
 
1833
                    {
 
1834
                      asn1_delete_structure (structure);
 
1835
                      return result;
 
1836
                    }
 
1837
 
 
1838
                  tlen = strlen (temp);
 
1839
                  if (tlen > 0)
 
1840
                    _asn1_set_value (p, temp, tlen + 1);
 
1841
 
 
1842
                  if (p == nodeFound)
 
1843
                    state = EXIT;
 
1844
                }
 
1845
              else
 
1846
                {
 
1847
                  len2 =
 
1848
                    asn1_get_length_der (der + counter, len - counter, &len3);
 
1849
                  if (len2 < 0)
 
1850
                    return ASN1_DER_ERROR;
 
1851
                  len2 += len3;
 
1852
                }
 
1853
 
 
1854
              counter += len2;
 
1855
              move = RIGHT;
 
1856
              break;
 
1857
            case TYPE_OCTET_STRING:
 
1858
              if (state == FOUND)
 
1859
                {
 
1860
                  ris = _asn1_get_octet_string (p, der + counter, len-counter, &len3);
 
1861
                  if (p == nodeFound)
 
1862
                    state = EXIT;
 
1863
                }
 
1864
              else
 
1865
                ris = _asn1_get_octet_string (NULL, der + counter, len-counter, &len3);
 
1866
 
 
1867
              if (ris != ASN1_SUCCESS)
 
1868
                return ris;
 
1869
              counter += len3;
 
1870
              move = RIGHT;
 
1871
              break;
 
1872
            case TYPE_GENERALSTRING:
 
1873
              len2 =
 
1874
                asn1_get_length_der (der + counter, len - counter, &len3);
 
1875
              if (len2 < 0)
 
1876
                return ASN1_DER_ERROR;
 
1877
              if (state == FOUND)
 
1878
                {
 
1879
                  if (len3 + len2 > len - counter)
 
1880
                    return ASN1_DER_ERROR;
 
1881
                  _asn1_set_value (p, der + counter, len3 + len2);
 
1882
 
 
1883
                  if (p == nodeFound)
 
1884
                    state = EXIT;
 
1885
                }
 
1886
              counter += len3 + len2;
 
1887
              move = RIGHT;
 
1888
              break;
 
1889
            case TYPE_BIT_STRING:
 
1890
              len2 =
 
1891
                asn1_get_length_der (der + counter, len - counter, &len3);
 
1892
              if (len2 < 0)
 
1893
                return ASN1_DER_ERROR;
 
1894
              if (state == FOUND)
 
1895
                {
 
1896
                  if (len3 + len2 > len - counter)
 
1897
                    return ASN1_DER_ERROR;
 
1898
                  _asn1_set_value (p, der + counter, len3 + len2);
 
1899
 
 
1900
                  if (p == nodeFound)
 
1901
                    state = EXIT;
 
1902
                }
 
1903
              counter += len3 + len2;
 
1904
              move = RIGHT;
 
1905
              break;
 
1906
            case TYPE_SEQUENCE:
 
1907
            case TYPE_SET:
 
1908
              if (move == UP)
 
1909
                {
 
1910
                  len2 = strtol (p->value, NULL, 10);
 
1911
                  _asn1_set_value (p, NULL, 0);
 
1912
                  if (len2 == -1)
 
1913
                    {           /* indefinite length method */
 
1914
                      if ((der[counter]) || der[counter + 1])
 
1915
                        {
 
1916
                          asn1_delete_structure (structure);
 
1917
                          return ASN1_DER_ERROR;
 
1918
                        }
 
1919
                      counter += 2;
 
1920
                    }
 
1921
                  else
 
1922
                    {           /* definite length method */
 
1923
                      if (len2 != counter)
 
1924
                        {
 
1925
                          asn1_delete_structure (structure);
 
1926
                          return ASN1_DER_ERROR;
 
1927
                        }
 
1928
                    }
 
1929
                  if (p == nodeFound)
 
1930
                    state = EXIT;
 
1931
                  move = RIGHT;
 
1932
                }
 
1933
              else
 
1934
                {               /* move==DOWN || move==RIGHT */
 
1935
                  if (state == OTHER_BRANCH)
 
1936
                    {
 
1937
                      len3 =
 
1938
                        asn1_get_length_der (der + counter, len - counter,
 
1939
                                             &len2);
 
1940
                      if (len3 < 0)
 
1941
                        return ASN1_DER_ERROR;
 
1942
                      counter += len2 + len3;
 
1943
                      move = RIGHT;
 
1944
                    }
 
1945
                  else
 
1946
                    {           /*  state==SAME_BRANCH or state==FOUND */
 
1947
                      len3 =
 
1948
                        asn1_get_length_der (der + counter, len - counter,
 
1949
                                             &len2);
 
1950
                      if (len3 < 0)
 
1951
                        return ASN1_DER_ERROR;
 
1952
                      counter += len2;
 
1953
                      if (len3 > 0)
 
1954
                        {
 
1955
                          _asn1_ltostr (counter + len3, temp);
 
1956
                          tlen = strlen (temp);
 
1957
 
 
1958
                          if (tlen > 0)
 
1959
                            _asn1_set_value (p, temp, tlen + 1);
 
1960
                          move = DOWN;
 
1961
                        }
 
1962
                      else if (len3 == 0)
 
1963
                        {
 
1964
                          p2 = p->down;
 
1965
                          while (p2)
 
1966
                            {
 
1967
                              if (type_field (p2->type) != TYPE_TAG)
 
1968
                                {
 
1969
                                  p3 = p2->right;
 
1970
                                  asn1_delete_structure (&p2);
 
1971
                                  p2 = p3;
 
1972
                                }
 
1973
                              else
 
1974
                                p2 = p2->right;
 
1975
                            }
 
1976
                          move = RIGHT;
 
1977
                        }
 
1978
                      else
 
1979
                        {       /* indefinite length method */
 
1980
                          _asn1_set_value (p, "-1", 3);
 
1981
                          move = DOWN;
 
1982
                        }
 
1983
                    }
 
1984
                }
 
1985
              break;
 
1986
            case TYPE_SEQUENCE_OF:
 
1987
            case TYPE_SET_OF:
 
1988
              if (move == UP)
 
1989
                {
 
1990
                  len2 = strtol (p->value, NULL, 10);
 
1991
                  if (len2 > counter)
 
1992
                    {
 
1993
                      _asn1_append_sequence_set (p);
 
1994
                      p = p->down;
 
1995
                      while (p->right)
 
1996
                        p = p->right;
 
1997
                      move = RIGHT;
 
1998
                      continue;
 
1999
                    }
 
2000
                  _asn1_set_value (p, NULL, 0);
 
2001
                  if (len2 != counter)
 
2002
                    {
 
2003
                      asn1_delete_structure (structure);
 
2004
                      return ASN1_DER_ERROR;
 
2005
                    }
 
2006
 
 
2007
                  if (p == nodeFound)
 
2008
                    state = EXIT;
 
2009
                }
 
2010
              else
 
2011
                {               /* move==DOWN || move==RIGHT */
 
2012
                  if (state == OTHER_BRANCH)
 
2013
                    {
 
2014
                      len3 =
 
2015
                        asn1_get_length_der (der + counter, len - counter,
 
2016
                                             &len2);
 
2017
                      if (len3 < 0)
 
2018
                        return ASN1_DER_ERROR;
 
2019
                      counter += len2 + len3;
 
2020
                      move = RIGHT;
 
2021
                    }
 
2022
                  else
 
2023
                    {           /* state==FOUND or state==SAME_BRANCH */
 
2024
                      len3 =
 
2025
                        asn1_get_length_der (der + counter, len - counter,
 
2026
                                             &len2);
 
2027
                      if (len3 < 0)
 
2028
                        return ASN1_DER_ERROR;
 
2029
                      counter += len2;
 
2030
                      if (len3)
 
2031
                        {
 
2032
                          _asn1_ltostr (counter + len3, temp);
 
2033
                          tlen = strlen (temp);
 
2034
 
 
2035
                          if (tlen > 0)
 
2036
                            _asn1_set_value (p, temp, tlen + 1);
 
2037
                          p2 = p->down;
 
2038
                          while ((type_field (p2->type) == TYPE_TAG)
 
2039
                                 || (type_field (p2->type) == TYPE_SIZE))
 
2040
                            p2 = p2->right;
 
2041
                          if (p2->right == NULL)
 
2042
                            _asn1_append_sequence_set (p);
 
2043
                          p = p2;
 
2044
                          state = FOUND;
 
2045
                        }
 
2046
                    }
 
2047
                }
 
2048
 
 
2049
              break;
 
2050
            case TYPE_ANY:
 
2051
              if (asn1_get_tag_der
 
2052
                  (der + counter, len - counter, &class, &len2,
 
2053
                   &tag) != ASN1_SUCCESS)
 
2054
                return ASN1_DER_ERROR;
 
2055
              if (counter + len2 > len)
 
2056
                return ASN1_DER_ERROR;
 
2057
 
 
2058
              len4 =
 
2059
                asn1_get_length_der (der + counter + len2,
 
2060
                                     len - counter - len2, &len3);
 
2061
              if (len4 < -1)
 
2062
                return ASN1_DER_ERROR;
 
2063
 
 
2064
              if (len4 != -1)
 
2065
                {
 
2066
                  len2 += len4;
 
2067
                  if (state == FOUND)
 
2068
                    {
 
2069
                      _asn1_set_value_octet (p, der + counter, len2 + len3);
 
2070
                      temp2 = NULL;
 
2071
 
 
2072
                      if (p == nodeFound)
 
2073
                        state = EXIT;
 
2074
                    }
 
2075
                  counter += len2 + len3;
 
2076
                }
 
2077
              else
 
2078
                {               /* indefinite length */
 
2079
                  /* Check indefinite lenth method in an EXPLICIT TAG */
 
2080
                  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
 
2081
                    indefinite = 1;
 
2082
                  else
 
2083
                    indefinite = 0;
 
2084
 
 
2085
                  ris =
 
2086
                    _asn1_get_indefinite_length_string (der + counter, len-counter, &len2);
 
2087
                  if (ris != ASN1_SUCCESS)
 
2088
                    {
 
2089
                      asn1_delete_structure (structure);
 
2090
                      return ris;
 
2091
                    }
 
2092
 
 
2093
                  if (state == FOUND)
 
2094
                    {
 
2095
                      _asn1_set_value_octet (p, der + counter, len2);
 
2096
 
 
2097
                      if (p == nodeFound)
 
2098
                        state = EXIT;
 
2099
                    }
 
2100
 
 
2101
                  counter += len2;
 
2102
 
 
2103
                  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
 
2104
                     an indefinite length method. */
 
2105
                  if (indefinite)
 
2106
                    {
 
2107
                      if (!der[counter] && !der[counter + 1])
 
2108
                        {
 
2109
                          counter += 2;
 
2110
                        }
 
2111
                      else
 
2112
                        {
 
2113
                          asn1_delete_structure (structure);
 
2114
                          return ASN1_DER_ERROR;
 
2115
                        }
 
2116
                    }
 
2117
                }
 
2118
              move = RIGHT;
 
2119
              break;
 
2120
 
 
2121
            default:
 
2122
              move = (move == UP) ? RIGHT : DOWN;
 
2123
              break;
 
2124
            }
 
2125
        }
 
2126
 
 
2127
      if ((p == node && move != DOWN) || (state == EXIT))
 
2128
        break;
 
2129
 
 
2130
      if (move == DOWN)
 
2131
        {
 
2132
          if (p->down)
 
2133
            {
 
2134
              p = p->down;
 
2135
 
 
2136
              if (state != FOUND)
 
2137
                {
 
2138
                  nameLen -= strlen (p->name) + 1;
 
2139
                  if (nameLen > 0)
 
2140
                    {
 
2141
                      if (currentName[0])
 
2142
                        strcat (currentName, ".");
 
2143
                      strcat (currentName, p->name);
 
2144
                    }
 
2145
                  else
 
2146
                    {
 
2147
                      asn1_delete_structure (structure);
 
2148
                      return ASN1_MEM_ERROR;
 
2149
                    }
 
2150
                  if (!(strcmp (currentName, elementName)))
 
2151
                    {
 
2152
                      state = FOUND;
 
2153
                      nodeFound = p;
 
2154
                    }
 
2155
                  else
 
2156
                    if (!memcmp
 
2157
                        (currentName, elementName, strlen (currentName)))
 
2158
                    state = SAME_BRANCH;
 
2159
                  else
 
2160
                    state = OTHER_BRANCH;
 
2161
                }
 
2162
            }
 
2163
          else
 
2164
            move = RIGHT;
 
2165
        }
 
2166
 
 
2167
      if ((move == RIGHT) && !(p->type & CONST_SET))
 
2168
        {
 
2169
          if (p->right)
 
2170
            {
 
2171
              p = p->right;
 
2172
 
 
2173
              if (state != FOUND)
 
2174
                {
 
2175
                  dot_p = char_p = currentName;
 
2176
                  while ((char_p = strchr (char_p, '.')))
 
2177
                    {
 
2178
                      dot_p = char_p++;
 
2179
                      dot_p++;
 
2180
                    }
 
2181
 
 
2182
                  nameLen += strlen (currentName) - (dot_p - currentName);
 
2183
                  *dot_p = 0;
 
2184
 
 
2185
                  nameLen -= strlen (p->name);
 
2186
                  if (nameLen > 0)
 
2187
                    strcat (currentName, p->name);
 
2188
                  else
 
2189
                    {
 
2190
                      asn1_delete_structure (structure);
 
2191
                      return ASN1_MEM_ERROR;
 
2192
                    }
 
2193
 
 
2194
                  if (!(strcmp (currentName, elementName)))
 
2195
                    {
 
2196
                      state = FOUND;
 
2197
                      nodeFound = p;
 
2198
                    }
 
2199
                  else
 
2200
                    if (!memcmp
 
2201
                        (currentName, elementName, strlen (currentName)))
 
2202
                    state = SAME_BRANCH;
 
2203
                  else
 
2204
                    state = OTHER_BRANCH;
 
2205
                }
 
2206
            }
 
2207
          else
 
2208
            move = UP;
 
2209
        }
 
2210
 
 
2211
      if (move == UP)
 
2212
        {
 
2213
          p = _asn1_find_up (p);
 
2214
 
 
2215
          if (state != FOUND)
 
2216
            {
 
2217
              dot_p = char_p = currentName;
 
2218
              while ((char_p = strchr (char_p, '.')))
 
2219
                {
 
2220
                  dot_p = char_p++;
 
2221
                  dot_p++;
 
2222
                }
 
2223
 
 
2224
              nameLen += strlen (currentName) - (dot_p - currentName);
 
2225
              *dot_p = 0;
 
2226
 
 
2227
              if (!(strcmp (currentName, elementName)))
 
2228
                {
 
2229
                  state = FOUND;
 
2230
                  nodeFound = p;
 
2231
                }
 
2232
              else
 
2233
                if (!memcmp (currentName, elementName, strlen (currentName)))
 
2234
                state = SAME_BRANCH;
 
2235
              else
 
2236
                state = OTHER_BRANCH;
 
2237
            }
 
2238
        }
 
2239
    }
 
2240
 
 
2241
  _asn1_delete_not_used (*structure);
 
2242
 
 
2243
  if (counter > len)
 
2244
    {
 
2245
      asn1_delete_structure (structure);
 
2246
      return ASN1_DER_ERROR;
 
2247
    }
 
2248
 
 
2249
  return ASN1_SUCCESS;
 
2250
}
 
2251
 
 
2252
 
 
2253
 
 
2254
/**
 
2255
  * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
 
2256
  * @element: pointer to an ASN1 element
 
2257
  * @ider: vector that contains the DER encoding.
 
2258
  * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]
 
2259
  * @name_element: an element of NAME structure.
 
2260
  * @start: the position of the first byte of NAME_ELEMENT decoding
 
2261
  *   (@ider[*start])
 
2262
  * @end: the position of the last byte of NAME_ELEMENT decoding
 
2263
  *  (@ider[*end])
 
2264
  *
 
2265
  * Find the start and end point of an element in a DER encoding
 
2266
  * string. I mean that if you have a der encoding and you have
 
2267
  * already used the function "asn1_der_decoding" to fill a structure,
 
2268
  * it may happen that you want to find the piece of string concerning
 
2269
  * an element of the structure.
 
2270
  *
 
2271
  * Example: the sequence "tbsCertificate" inside an X509 certificate.
 
2272
  *
 
2273
  * Returns:
 
2274
  *
 
2275
  *   ASN1_SUCCESS: DER encoding OK.
 
2276
  *
 
2277
  *   ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
 
2278
  *   NAME_ELEMENT is not a valid element.
 
2279
  *
 
2280
  *   ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
 
2281
  *   the structure ELEMENT.
 
2282
  *
 
2283
  **/
 
2284
asn1_retCode
 
2285
asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int ider_len,
 
2286
                            const char *name_element, int *start, int *end)
 
2287
{
 
2288
  ASN1_TYPE node, node_to_find, p, p2, p3;
 
2289
  int counter, len2, len3, len4, move, ris;
 
2290
  unsigned char class;
 
2291
  unsigned long tag;
 
2292
  int indefinite, result = ASN1_DER_ERROR;
 
2293
  const unsigned char *der = ider;
 
2294
 
 
2295
  node = element;
 
2296
 
 
2297
  if (node == ASN1_TYPE_EMPTY)
 
2298
    return ASN1_ELEMENT_NOT_FOUND;
 
2299
 
 
2300
  node_to_find = asn1_find_node (node, name_element);
 
2301
 
 
2302
  if (node_to_find == NULL)
 
2303
    return ASN1_ELEMENT_NOT_FOUND;
 
2304
 
 
2305
  if (node_to_find == node)
 
2306
    {
 
2307
      *start = 0;
 
2308
      *end = ider_len - 1;
 
2309
      return ASN1_SUCCESS;
 
2310
    }
 
2311
 
 
2312
  if (node->type & CONST_OPTION)
 
2313
    return ASN1_GENERIC_ERROR;
 
2314
 
 
2315
  counter = 0;
 
2316
  move = DOWN;
 
2317
  p = node;
 
2318
  while (1)
 
2319
    {
 
2320
      ris = ASN1_SUCCESS;
 
2321
 
 
2322
      if (move != UP)
 
2323
        {
 
2324
          if (p->type & CONST_SET)
 
2325
            {
 
2326
              p2 = _asn1_find_up (p);
 
2327
              len2 = strtol (p2->value, NULL, 10);
 
2328
              if (len2 == -1)
 
2329
                {
 
2330
                  if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1])
 
2331
                    {
 
2332
                      p = p2;
 
2333
                      move = UP;
 
2334
                      counter += 2;
 
2335
                      DECR_LEN(ider_len, 2);
 
2336
                      continue;
 
2337
                    }
 
2338
                }
 
2339
              else if (counter == len2)
 
2340
                {
 
2341
                  p = p2;
 
2342
                  move = UP;
 
2343
                  continue;
 
2344
                }
 
2345
              else if (counter > len2)
 
2346
                {
 
2347
                  warn();
 
2348
                  return ASN1_DER_ERROR;
 
2349
                }
 
2350
              p2 = p2->down;
 
2351
              while (p2)
 
2352
                {
 
2353
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
 
2354
                    {           /* CONTROLLARE */
 
2355
                      if (type_field (p2->type) != TYPE_CHOICE)
 
2356
                        ris =
 
2357
                          _asn1_extract_tag_der (p2, der + counter,
 
2358
                                                 ider_len, &len2);
 
2359
                      else
 
2360
                        {
 
2361
                          p3 = p2->down;
 
2362
                          ris =
 
2363
                            _asn1_extract_tag_der (p3, der + counter,
 
2364
                                                   ider_len, &len2);
 
2365
                        }
 
2366
                      if (ris == ASN1_SUCCESS)
 
2367
                        {
 
2368
                          p2->type &= ~CONST_NOT_USED;
 
2369
                          p = p2;
 
2370
                          break;
 
2371
                        }
 
2372
                    }
 
2373
                  p2 = p2->right;
 
2374
                }
 
2375
              if (p2 == NULL)
 
2376
                {
 
2377
                  warn();
 
2378
                  return ASN1_DER_ERROR;
 
2379
                }
 
2380
            }
 
2381
 
 
2382
          if (p == node_to_find)
 
2383
            *start = counter;
 
2384
 
 
2385
          if (type_field (p->type) == TYPE_CHOICE)
 
2386
            {
 
2387
              p = p->down;
 
2388
              ris =
 
2389
                _asn1_extract_tag_der (p, der + counter, ider_len,
 
2390
                                       &len2);
 
2391
              if (p == node_to_find)
 
2392
                *start = counter;
 
2393
            }
 
2394
 
 
2395
          if (ris == ASN1_SUCCESS)
 
2396
            ris =
 
2397
              _asn1_extract_tag_der (p, der + counter, ider_len, &len2);
 
2398
          if (ris != ASN1_SUCCESS)
 
2399
            {
 
2400
              if (p->type & CONST_OPTION)
 
2401
                {
 
2402
                  p->type |= CONST_NOT_USED;
 
2403
                  move = RIGHT;
 
2404
                }
 
2405
              else if (p->type & CONST_DEFAULT)
 
2406
                {
 
2407
                  move = RIGHT;
 
2408
                }
 
2409
              else
 
2410
                {
 
2411
                  warn();
 
2412
                  return ASN1_TAG_ERROR;
 
2413
                }
 
2414
            }
 
2415
          else
 
2416
            {
 
2417
              DECR_LEN(ider_len, len2);
 
2418
              counter += len2;
 
2419
            }
 
2420
        }
 
2421
 
 
2422
      if (ris == ASN1_SUCCESS)
 
2423
        {
 
2424
          switch (type_field (p->type))
 
2425
            {
 
2426
            case TYPE_NULL:
 
2427
              DECR_LEN(ider_len, 1);
 
2428
 
 
2429
              if (der[counter])
 
2430
                {
 
2431
                  warn();
 
2432
                  return ASN1_DER_ERROR;
 
2433
                }
 
2434
              counter++;
 
2435
              move = RIGHT;
 
2436
              break;
 
2437
            case TYPE_BOOLEAN:
 
2438
              DECR_LEN(ider_len, 2);
 
2439
 
 
2440
              if (der[counter] != 1)
 
2441
                {
 
2442
                  warn();
 
2443
                  return ASN1_DER_ERROR;
 
2444
                }
 
2445
 
 
2446
              counter += 2;
 
2447
              move = RIGHT;
 
2448
              break;
 
2449
            case TYPE_INTEGER:
 
2450
            case TYPE_ENUMERATED:
 
2451
              len2 =
 
2452
                asn1_get_length_der (der + counter, ider_len, &len3);
 
2453
              if (len2 < 0)
 
2454
                {
 
2455
                  warn();
 
2456
                  return ASN1_DER_ERROR;
 
2457
                }
 
2458
              DECR_LEN(ider_len, len3 + len2);
 
2459
              counter += len3 + len2;
 
2460
              move = RIGHT;
 
2461
              break;
 
2462
            case TYPE_OBJECT_ID:
 
2463
              len2 =
 
2464
                asn1_get_length_der (der + counter, ider_len, &len3);
 
2465
              if (len2 < 0)
 
2466
                {
 
2467
                  warn();
 
2468
                  return ASN1_DER_ERROR;
 
2469
                }
 
2470
              DECR_LEN(ider_len, len2 + len3);
 
2471
              counter += len2 + len3;
 
2472
              move = RIGHT;
 
2473
              break;
 
2474
            case TYPE_TIME:
 
2475
              len2 =
 
2476
                asn1_get_length_der (der + counter, ider_len, &len3);
 
2477
              if (len2 < 0)
 
2478
                {
 
2479
                  warn();
 
2480
                  return ASN1_DER_ERROR;
 
2481
                }
 
2482
              DECR_LEN(ider_len, len2 + len3);
 
2483
              counter += len2 + len3;
 
2484
              move = RIGHT;
 
2485
              break;
 
2486
            case TYPE_OCTET_STRING:
 
2487
              ris = _asn1_get_octet_string (NULL, der + counter, ider_len, &len3);
 
2488
              if (ris != ASN1_SUCCESS)
 
2489
                {
 
2490
                  warn();
 
2491
                  return ris;
 
2492
                }
 
2493
              DECR_LEN(ider_len, len3);
 
2494
              counter += len3;
 
2495
              move = RIGHT;
 
2496
              break;
 
2497
            case TYPE_GENERALSTRING:
 
2498
              len2 =
 
2499
                asn1_get_length_der (der + counter, ider_len, &len3);
 
2500
              if (len2 < 0)
 
2501
                {
 
2502
                  warn();
 
2503
                  return ASN1_DER_ERROR;
 
2504
                }
 
2505
 
 
2506
              DECR_LEN(ider_len, len3 + len2);
 
2507
              counter += len3 + len2;
 
2508
              move = RIGHT;
 
2509
              break;
 
2510
            case TYPE_BIT_STRING:
 
2511
              len2 =
 
2512
                asn1_get_length_der (der + counter, ider_len, &len3);
 
2513
              if (len2 < 0)
 
2514
                {
 
2515
                  warn();
 
2516
                  return ASN1_DER_ERROR;
 
2517
                }
 
2518
              DECR_LEN(ider_len, len3 + len2);
 
2519
              counter += len3 + len2;
 
2520
              move = RIGHT;
 
2521
              break;
 
2522
            case TYPE_SEQUENCE:
 
2523
            case TYPE_SET:
 
2524
              if (move != UP)
 
2525
                {
 
2526
                  len3 =
 
2527
                    asn1_get_length_der (der + counter, ider_len, &len2);
 
2528
                  if (len3 < -1)
 
2529
                    {
 
2530
                      warn();
 
2531
                      return ASN1_DER_ERROR;
 
2532
                    }
 
2533
 
 
2534
                  DECR_LEN(ider_len, len2);
 
2535
                  counter += len2;
 
2536
 
 
2537
                  if (len3 == 0)
 
2538
                    move = RIGHT;
 
2539
                  else
 
2540
                    move = DOWN;
 
2541
                }
 
2542
              else
 
2543
                {
 
2544
                  if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1]) /* indefinite length method */
 
2545
                    {
 
2546
                      counter += 2;
 
2547
                      DECR_LEN(ider_len, 2);
 
2548
                    }
 
2549
                  move = RIGHT;
 
2550
                }
 
2551
              break;
 
2552
            case TYPE_SEQUENCE_OF:
 
2553
            case TYPE_SET_OF:
 
2554
              if (move != UP)
 
2555
                {
 
2556
                  len3 =
 
2557
                    asn1_get_length_der (der + counter, ider_len, &len2);
 
2558
                  if (len3 < -1)
 
2559
                    {
 
2560
                      warn();
 
2561
                      return ASN1_DER_ERROR;
 
2562
                    }
 
2563
 
 
2564
                  DECR_LEN(ider_len, len2);
 
2565
                  counter += len2;
 
2566
 
 
2567
                  if (len3 == -1)
 
2568
                    {
 
2569
                       if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1])
 
2570
                         {
 
2571
                           DECR_LEN(ider_len, 2);
 
2572
                           counter += 2;
 
2573
                         }
 
2574
                    }
 
2575
 
 
2576
                  if (len3)
 
2577
                    {
 
2578
                      p2 = p->down;
 
2579
                      while ((type_field (p2->type) == TYPE_TAG) ||
 
2580
                             (type_field (p2->type) == TYPE_SIZE))
 
2581
                        p2 = p2->right;
 
2582
                      p = p2;
 
2583
                    }
 
2584
                }
 
2585
              else
 
2586
                {
 
2587
                  if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1]) /* indefinite length method */
 
2588
                    {
 
2589
                      DECR_LEN(ider_len, 2);
 
2590
                      counter += 2;
 
2591
                    }
 
2592
                }
 
2593
              move = RIGHT;
 
2594
              break;
 
2595
            case TYPE_ANY:
 
2596
              if (asn1_get_tag_der
 
2597
                  (der + counter, ider_len, &class, &len2,
 
2598
                   &tag) != ASN1_SUCCESS)
 
2599
                 {
 
2600
                    warn();
 
2601
                    return ASN1_DER_ERROR;
 
2602
                 }
 
2603
 
 
2604
              DECR_LEN(ider_len, len2);
 
2605
 
 
2606
              len4 =
 
2607
                asn1_get_length_der (der + counter + len2,
 
2608
                                     ider_len, &len3);
 
2609
              if (len4 < -1)
 
2610
                {
 
2611
                  warn();
 
2612
                  return ASN1_DER_ERROR;
 
2613
                }
 
2614
 
 
2615
              if (len4 != -1)
 
2616
                {
 
2617
                  DECR_LEN(ider_len, len3 + len4);
 
2618
                  counter += len2 + len3 + len4;
 
2619
                }
 
2620
              else
 
2621
                {               /* indefinite length */
 
2622
                  /* Check indefinite lenth method in an EXPLICIT TAG */
 
2623
                  ider_len += len2; /* undo DECR_LEN */
 
2624
 
 
2625
                  if (counter == 0)
 
2626
                    {
 
2627
                      warn();
 
2628
                      return ASN1_DER_ERROR;
 
2629
                    }
 
2630
 
 
2631
                  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
 
2632
                    indefinite = 1;
 
2633
                  else
 
2634
                    indefinite = 0;
 
2635
 
 
2636
                  ris =
 
2637
                    _asn1_get_indefinite_length_string (der + counter, ider_len, &len2);
 
2638
                  if (ris != ASN1_SUCCESS)
 
2639
                    {
 
2640
                      warn();
 
2641
                      return ris;
 
2642
                    }
 
2643
                  counter += len2;
 
2644
                  DECR_LEN(ider_len, len2);
 
2645
 
 
2646
                  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
 
2647
                     an indefinite length method. */
 
2648
                  if (indefinite)
 
2649
                    {
 
2650
                      DECR_LEN(ider_len, 2);
 
2651
 
 
2652
                      if (!der[counter] && !der[counter + 1])
 
2653
                        counter += 2;
 
2654
                      else
 
2655
                        {
 
2656
                          warn();
 
2657
                          return ASN1_DER_ERROR;
 
2658
                        }
 
2659
                    }
 
2660
                }
 
2661
              move = RIGHT;
 
2662
              break;
 
2663
            default:
 
2664
              move = (move == UP) ? RIGHT : DOWN;
 
2665
              break;
 
2666
            }
 
2667
        }
 
2668
 
 
2669
      if ((p == node_to_find) && (move == RIGHT))
 
2670
        {
 
2671
          *end = counter - 1;
 
2672
          return ASN1_SUCCESS;
 
2673
        }
 
2674
 
 
2675
      if (p == node && move != DOWN)
 
2676
        break;
 
2677
 
 
2678
      if (move == DOWN)
 
2679
        {
 
2680
          if (p->down)
 
2681
            p = p->down;
 
2682
          else
 
2683
            move = RIGHT;
 
2684
        }
 
2685
      if ((move == RIGHT) && !(p->type & CONST_SET))
 
2686
        {
 
2687
          if (p->right)
 
2688
            p = p->right;
 
2689
          else
 
2690
            move = UP;
 
2691
        }
 
2692
      if (move == UP)
 
2693
        p = _asn1_find_up (p);
 
2694
    }
 
2695
 
 
2696
  warn();
 
2697
  return ASN1_ELEMENT_NOT_FOUND;
 
2698
 
 
2699
cleanup:
 
2700
  return result;
 
2701
}
 
2702
 
 
2703
 
 
2704
/**
 
2705
  * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
 
2706
  * @definitions: ASN1 definitions
 
2707
  * @element: pointer to an ASN1 structure
 
2708
  *
 
2709
  * Expands every "ANY DEFINED BY" element of a structure created from
 
2710
  * a DER decoding process (asn1_der_decoding function). The element ANY
 
2711
  * must be defined by an OBJECT IDENTIFIER. The type used to expand
 
2712
  * the element ANY is the first one following the definition of
 
2713
  * the actual value of the OBJECT IDENTIFIER.
 
2714
  *
 
2715
  *
 
2716
  * Returns:
 
2717
  *
 
2718
  *   ASN1_SUCCESS: Substitution OK.
 
2719
  *
 
2720
  *   ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
 
2721
  *   expanded due to a problem in OBJECT_ID -> TYPE association.
 
2722
  *
 
2723
  *   other errors: Result of der decoding process.
 
2724
  **/
 
2725
 
 
2726
asn1_retCode
 
2727
asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
 
2728
{
 
2729
  char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
 
2730
    value[ASN1_MAX_NAME_SIZE];
 
2731
  asn1_retCode retCode = ASN1_SUCCESS, result;
 
2732
  int len, len2, len3;
 
2733
  ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
 
2734
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
 
2735
 
 
2736
  if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
 
2737
    return ASN1_ELEMENT_NOT_FOUND;
 
2738
 
 
2739
  strcpy (definitionsName, definitions->name);
 
2740
  strcat (definitionsName, ".");
 
2741
 
 
2742
  p = *element;
 
2743
  while (p)
 
2744
    {
 
2745
 
 
2746
      switch (type_field (p->type))
 
2747
        {
 
2748
        case TYPE_ANY:
 
2749
          if ((p->type & CONST_DEFINED_BY) && (p->value))
 
2750
            {
 
2751
              /* search the "DEF_BY" element */
 
2752
              p2 = p->down;
 
2753
              while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
 
2754
                p2 = p2->right;
 
2755
 
 
2756
              if (!p2)
 
2757
                {
 
2758
                  retCode = ASN1_ERROR_TYPE_ANY;
 
2759
                  break;
 
2760
                }
 
2761
 
 
2762
              p3 = _asn1_find_up (p);
 
2763
 
 
2764
              if (!p3)
 
2765
                {
 
2766
                  retCode = ASN1_ERROR_TYPE_ANY;
 
2767
                  break;
 
2768
                }
 
2769
 
 
2770
              p3 = p3->down;
 
2771
              while (p3)
 
2772
                {
 
2773
                  if ((p3->name) && !(strcmp (p3->name, p2->name)))
 
2774
                    break;
 
2775
                  p3 = p3->right;
 
2776
                }
 
2777
 
 
2778
              if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
 
2779
                  (p3->value == NULL))
 
2780
                {
 
2781
 
 
2782
                  p3 = _asn1_find_up (p);
 
2783
                  p3 = _asn1_find_up (p3);
 
2784
 
 
2785
                  if (!p3)
 
2786
                    {
 
2787
                      retCode = ASN1_ERROR_TYPE_ANY;
 
2788
                      break;
 
2789
                    }
 
2790
 
 
2791
                  p3 = p3->down;
 
2792
 
 
2793
                  while (p3)
 
2794
                    {
 
2795
                      if ((p3->name) && !(strcmp (p3->name, p2->name)))
 
2796
                        break;
 
2797
                      p3 = p3->right;
 
2798
                    }
 
2799
 
 
2800
                  if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
 
2801
                      (p3->value == NULL))
 
2802
                    {
 
2803
                      retCode = ASN1_ERROR_TYPE_ANY;
 
2804
                      break;
 
2805
                    }
 
2806
                }
 
2807
 
 
2808
              /* search the OBJECT_ID into definitions */
 
2809
              p2 = definitions->down;
 
2810
              while (p2)
 
2811
                {
 
2812
                  if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
 
2813
                      (p2->type & CONST_ASSIGN))
 
2814
                    {
 
2815
                      strcpy (name, definitionsName);
 
2816
                      strcat (name, p2->name);
 
2817
 
 
2818
                      len = ASN1_MAX_NAME_SIZE;
 
2819
                      result =
 
2820
                        asn1_read_value (definitions, name, value, &len);
 
2821
 
 
2822
                      if ((result == ASN1_SUCCESS)
 
2823
                          && (!strcmp (p3->value, value)))
 
2824
                        {
 
2825
                          p2 = p2->right;       /* pointer to the structure to 
 
2826
                                                   use for expansion */
 
2827
                          while ((p2) && (p2->type & CONST_ASSIGN))
 
2828
                            p2 = p2->right;
 
2829
 
 
2830
                          if (p2)
 
2831
                            {
 
2832
                              strcpy (name, definitionsName);
 
2833
                              strcat (name, p2->name);
 
2834
 
 
2835
                              result =
 
2836
                                asn1_create_element (definitions, name, &aux);
 
2837
                              if (result == ASN1_SUCCESS)
 
2838
                                {
 
2839
                                  _asn1_set_name (aux, p->name);
 
2840
                                  len2 =
 
2841
                                    asn1_get_length_der (p->value,
 
2842
                                                         p->value_len, &len3);
 
2843
                                  if (len2 < 0)
 
2844
                                    return ASN1_DER_ERROR;
 
2845
 
 
2846
                                  result =
 
2847
                                    asn1_der_decoding (&aux, p->value + len3,
 
2848
                                                       len2,
 
2849
                                                       errorDescription);
 
2850
                                  if (result == ASN1_SUCCESS)
 
2851
                                    {
 
2852
 
 
2853
                                      _asn1_set_right (aux, p->right);
 
2854
                                      _asn1_set_right (p, aux);
 
2855
 
 
2856
                                      result = asn1_delete_structure (&p);
 
2857
                                      if (result == ASN1_SUCCESS)
 
2858
                                        {
 
2859
                                          p = aux;
 
2860
                                          aux = ASN1_TYPE_EMPTY;
 
2861
                                          break;
 
2862
                                        }
 
2863
                                      else
 
2864
                                        {       /* error with asn1_delete_structure */
 
2865
                                          asn1_delete_structure (&aux);
 
2866
                                          retCode = result;
 
2867
                                          break;
 
2868
                                        }
 
2869
                                    }
 
2870
                                  else
 
2871
                                    {   /* error with asn1_der_decoding */
 
2872
                                      retCode = result;
 
2873
                                      break;
 
2874
                                    }
 
2875
                                }
 
2876
                              else
 
2877
                                {       /* error with asn1_create_element */
 
2878
                                  retCode = result;
 
2879
                                  break;
 
2880
                                }
 
2881
                            }
 
2882
                          else
 
2883
                            {   /* error with the pointer to the structure to exapand */
 
2884
                              retCode = ASN1_ERROR_TYPE_ANY;
 
2885
                              break;
 
2886
                            }
 
2887
                        }
 
2888
                    }
 
2889
                  p2 = p2->right;
 
2890
                }               /* end while */
 
2891
 
 
2892
              if (!p2)
 
2893
                {
 
2894
                  retCode = ASN1_ERROR_TYPE_ANY;
 
2895
                  break;
 
2896
                }
 
2897
 
 
2898
            }
 
2899
          break;
 
2900
        default:
 
2901
          break;
 
2902
        }
 
2903
 
 
2904
 
 
2905
      if (p->down)
 
2906
        {
 
2907
          p = p->down;
 
2908
        }
 
2909
      else if (p == *element)
 
2910
        {
 
2911
          p = NULL;
 
2912
          break;
 
2913
        }
 
2914
      else if (p->right)
 
2915
        p = p->right;
 
2916
      else
 
2917
        {
 
2918
          while (1)
 
2919
            {
 
2920
              p = _asn1_find_up (p);
 
2921
              if (p == *element)
 
2922
                {
 
2923
                  p = NULL;
 
2924
                  break;
 
2925
                }
 
2926
              if (p->right)
 
2927
                {
 
2928
                  p = p->right;
 
2929
                  break;
 
2930
                }
 
2931
            }
 
2932
        }
 
2933
    }
 
2934
 
 
2935
  return retCode;
 
2936
}
 
2937
 
 
2938
 
 
2939
 
 
2940
/**
 
2941
  * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
 
2942
  * @definitions: ASN1 definitions
 
2943
  * @element: pointer to an ASN1 structure
 
2944
  * @octetName: name of the OCTECT STRING field to expand.
 
2945
  * @objectName: name of the OBJECT IDENTIFIER field to use to define
 
2946
  *    the type for expansion.
 
2947
  *
 
2948
  * Expands an "OCTET STRING" element of a structure created from a
 
2949
  * DER decoding process (asn1_der_decoding function). The type used
 
2950
  * for expansion is the first one following the definition of the
 
2951
  * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
 
2952
  *
 
2953
  * Returns:
 
2954
  *
 
2955
  *   ASN1_SUCCESS: Substitution OK.
 
2956
  *
 
2957
  *   ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
 
2958
  *
 
2959
  *   ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
 
2960
  *       for expansion.
 
2961
  *
 
2962
  *   other errors: result of der decoding process.
 
2963
  **/
 
2964
asn1_retCode
 
2965
asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
 
2966
                          const char *octetName, const char *objectName)
 
2967
{
 
2968
  char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
 
2969
  asn1_retCode retCode = ASN1_SUCCESS, result;
 
2970
  int len, len2, len3;
 
2971
  ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
 
2972
  ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
 
2973
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
 
2974
 
 
2975
  if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
 
2976
    return ASN1_ELEMENT_NOT_FOUND;
 
2977
 
 
2978
  octetNode = asn1_find_node (*element, octetName);
 
2979
  if (octetNode == ASN1_TYPE_EMPTY)
 
2980
    return ASN1_ELEMENT_NOT_FOUND;
 
2981
  if (type_field (octetNode->type) != TYPE_OCTET_STRING)
 
2982
    return ASN1_ELEMENT_NOT_FOUND;
 
2983
  if (octetNode->value == NULL)
 
2984
    return ASN1_VALUE_NOT_FOUND;
 
2985
 
 
2986
  objectNode = asn1_find_node (*element, objectName);
 
2987
  if (objectNode == ASN1_TYPE_EMPTY)
 
2988
    return ASN1_ELEMENT_NOT_FOUND;
 
2989
 
 
2990
  if (type_field (objectNode->type) != TYPE_OBJECT_ID)
 
2991
    return ASN1_ELEMENT_NOT_FOUND;
 
2992
 
 
2993
  if (objectNode->value == NULL)
 
2994
    return ASN1_VALUE_NOT_FOUND;
 
2995
 
 
2996
 
 
2997
  /* search the OBJECT_ID into definitions */
 
2998
  p2 = definitions->down;
 
2999
  while (p2)
 
3000
    {
 
3001
      if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
 
3002
          (p2->type & CONST_ASSIGN))
 
3003
        {
 
3004
          strcpy (name, definitions->name);
 
3005
          strcat (name, ".");
 
3006
          strcat (name, p2->name);
 
3007
 
 
3008
          len = sizeof (value);
 
3009
          result = asn1_read_value (definitions, name, value, &len);
 
3010
 
 
3011
          if ((result == ASN1_SUCCESS)
 
3012
              && (!strcmp (objectNode->value, value)))
 
3013
            {
 
3014
 
 
3015
              p2 = p2->right;   /* pointer to the structure to 
 
3016
                                   use for expansion */
 
3017
              while ((p2) && (p2->type & CONST_ASSIGN))
 
3018
                p2 = p2->right;
 
3019
 
 
3020
              if (p2)
 
3021
                {
 
3022
                  strcpy (name, definitions->name);
 
3023
                  strcat (name, ".");
 
3024
                  strcat (name, p2->name);
 
3025
 
 
3026
                  result = asn1_create_element (definitions, name, &aux);
 
3027
                  if (result == ASN1_SUCCESS)
 
3028
                    {
 
3029
                      _asn1_set_name (aux, octetNode->name);
 
3030
                      len2 =
 
3031
                        asn1_get_length_der (octetNode->value,
 
3032
                                             octetNode->value_len, &len3);
 
3033
                      if (len2 < 0)
 
3034
                        return ASN1_DER_ERROR;
 
3035
 
 
3036
                      result =
 
3037
                        asn1_der_decoding (&aux, octetNode->value + len3,
 
3038
                                           len2, errorDescription);
 
3039
                      if (result == ASN1_SUCCESS)
 
3040
                        {
 
3041
 
 
3042
                          _asn1_set_right (aux, octetNode->right);
 
3043
                          _asn1_set_right (octetNode, aux);
 
3044
 
 
3045
                          result = asn1_delete_structure (&octetNode);
 
3046
                          if (result == ASN1_SUCCESS)
 
3047
                            {
 
3048
                              aux = ASN1_TYPE_EMPTY;
 
3049
                              break;
 
3050
                            }
 
3051
                          else
 
3052
                            {   /* error with asn1_delete_structure */
 
3053
                              asn1_delete_structure (&aux);
 
3054
                              retCode = result;
 
3055
                              break;
 
3056
                            }
 
3057
                        }
 
3058
                      else
 
3059
                        {       /* error with asn1_der_decoding */
 
3060
                          retCode = result;
 
3061
                          break;
 
3062
                        }
 
3063
                    }
 
3064
                  else
 
3065
                    {           /* error with asn1_create_element */
 
3066
                      retCode = result;
 
3067
                      break;
 
3068
                    }
 
3069
                }
 
3070
              else
 
3071
                {               /* error with the pointer to the structure to exapand */
 
3072
                  retCode = ASN1_VALUE_NOT_VALID;
 
3073
                  break;
 
3074
                }
 
3075
            }
 
3076
        }
 
3077
 
 
3078
      p2 = p2->right;
 
3079
 
 
3080
    }
 
3081
 
 
3082
  if (!p2)
 
3083
    retCode = ASN1_VALUE_NOT_VALID;
 
3084
 
 
3085
  return retCode;
 
3086
}