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

« back to all changes in this revision

Viewing changes to .pc/CVE-2012-1569.diff/lib/decoding.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-04-24 14:36:17 UTC
  • mfrom: (4.2.1 experimental)
  • Revision ID: package-import@ubuntu.com-20120424143617-6qpy14d5p4r3pj5a
Tags: 2.7-1ubuntu1.1
* SECURITY UPDATE: denial of service and possible code execution via
  certain large length values.
  - debian/patches/CVE-2012-1569.diff: return an error when the decoded
    length value plus @len would exceed @der_len in lib/decoding.c.
  - CVE-2012-1569

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