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

« back to all changes in this revision

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

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2008, 2009, 2010
 
3
 * Free Software 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
/* File: element.c                                   */
 
25
/* Description: Functions with the read and write    */
 
26
/*   functions.                                      */
 
27
/*****************************************************/
 
28
 
 
29
 
 
30
#include <int.h>
 
31
#include "parser_aux.h"
 
32
#include <gstr.h>
 
33
#include "structure.h"
 
34
 
 
35
#include "element.h"
 
36
 
 
37
void
 
38
_asn1_hierarchical_name (ASN1_TYPE node, char *name, int name_size)
 
39
{
 
40
  ASN1_TYPE p;
 
41
  char tmp_name[64];
 
42
 
 
43
  p = node;
 
44
 
 
45
  name[0] = 0;
 
46
 
 
47
  while (p != NULL)
 
48
    {
 
49
      if (p->name != NULL)
 
50
        {
 
51
          _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
 
52
            _asn1_str_cpy (name, name_size, p->name);
 
53
          _asn1_str_cat (name, name_size, ".");
 
54
          _asn1_str_cat (name, name_size, tmp_name);
 
55
        }
 
56
      p = _asn1_find_up (p);
 
57
    }
 
58
 
 
59
  if (name[0] == 0)
 
60
    _asn1_str_cpy (name, name_size, "ROOT");
 
61
}
 
62
 
 
63
 
 
64
/******************************************************************/
 
65
/* Function : _asn1_convert_integer                               */
 
66
/* Description: converts an integer from a null terminated string */
 
67
/*              to der decoding. The convertion from a null       */
 
68
/*              terminated string to an integer is made with      */
 
69
/*              the 'strtol' function.                            */
 
70
/* Parameters:                                                    */
 
71
/*   value: null terminated string to convert.                    */
 
72
/*   value_out: convertion result (memory must be already         */
 
73
/*              allocated).                                       */
 
74
/*   value_out_size: number of bytes of value_out.                */
 
75
/*   len: number of significant byte of value_out.                */
 
76
/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS                         */
 
77
/******************************************************************/
 
78
asn1_retCode
 
79
_asn1_convert_integer (const char *value, unsigned char *value_out,
 
80
                       int value_out_size, int *len)
 
81
{
 
82
  char negative;
 
83
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
 
84
  long valtmp;
 
85
  int k, k2;
 
86
 
 
87
  valtmp = strtol (value, NULL, 10);
 
88
 
 
89
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
 
90
    {
 
91
      val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
 
92
    }
 
93
 
 
94
  if (val[0] & 0x80)
 
95
    negative = 1;
 
96
  else
 
97
    negative = 0;
 
98
 
 
99
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
 
100
    {
 
101
      if (negative && (val[k] != 0xFF))
 
102
        break;
 
103
      else if (!negative && val[k])
 
104
        break;
 
105
    }
 
106
 
 
107
  if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
 
108
    k--;
 
109
 
 
110
  *len = SIZEOF_UNSIGNED_LONG_INT - k;
 
111
 
 
112
  if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
 
113
    /* VALUE_OUT is too short to contain the value conversion */
 
114
    return ASN1_MEM_ERROR;
 
115
 
 
116
  if (value_out != NULL)
 
117
    {
 
118
      for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
 
119
        value_out[k2 - k] = val[k2];
 
120
    }
 
121
 
 
122
#if 0
 
123
  printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
 
124
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
 
125
    printf (", vOut[%d]=%d", k, value_out[k]);
 
126
  printf ("\n");
 
127
#endif
 
128
 
 
129
  return ASN1_SUCCESS;
 
130
}
 
131
 
 
132
 
 
133
int
 
134
_asn1_append_sequence_set (ASN1_TYPE node)
 
135
{
 
136
  ASN1_TYPE p, p2;
 
137
  char temp[10];
 
138
  long n;
 
139
 
 
140
  if (!node || !(node->down))
 
141
    return ASN1_GENERIC_ERROR;
 
142
 
 
143
  p = node->down;
 
144
  while ((type_field (p->type) == TYPE_TAG)
 
145
         || (type_field (p->type) == TYPE_SIZE))
 
146
    p = p->right;
 
147
  p2 = _asn1_copy_structure3 (p);
 
148
  while (p->right)
 
149
    p = p->right;
 
150
  _asn1_set_right (p, p2);
 
151
 
 
152
  if (p->name == NULL)
 
153
    _asn1_str_cpy (temp, sizeof (temp), "?1");
 
154
  else
 
155
    {
 
156
      n = strtol (p->name + 1, NULL, 0);
 
157
      n++;
 
158
      temp[0] = '?';
 
159
      _asn1_ltostr (n, temp + 1);
 
160
    }
 
161
  _asn1_set_name (p2, temp);
 
162
  /*  p2->type |= CONST_OPTION; */
 
163
 
 
164
  return ASN1_SUCCESS;
 
165
}
 
166
 
 
167
 
 
168
/**
 
169
  * asn1_write_value - Set the value of one element inside a structure.
 
170
  * @node_root: pointer to a structure
 
171
  * @name: the name of the element inside the structure that you want to set.
 
172
  * @ivalue: vector used to specify the value to set. If len is >0,
 
173
  *   VALUE must be a two's complement form integer.  if len=0 *VALUE
 
174
  *   must be a null terminated string with an integer value.
 
175
  * @len: number of bytes of *value to use to set the value:
 
176
  *   value[0]..value[len-1] or 0 if value is a null terminated string
 
177
  *
 
178
  * Set the value of one element inside a structure.
 
179
  *
 
180
  * If an element is OPTIONAL and you want to delete it, you must use
 
181
  * the value=NULL and len=0.  Using "pkix.asn":
 
182
  *
 
183
  * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
 
184
  * NULL, 0);
 
185
  *
 
186
  * Description for each type:
 
187
  *
 
188
  * INTEGER: VALUE must contain a two's complement form integer.
 
189
  *
 
190
  *            value[0]=0xFF ,               len=1 -> integer=-1.
 
191
  *            value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
 
192
  *            value[0]=0x01 ,               len=1 -> integer= 1.
 
193
  *            value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
 
194
  *            value="123"                 , len=0 -> integer= 123.
 
195
  *
 
196
  * ENUMERATED: As INTEGER (but only with not negative numbers).
 
197
  *
 
198
  * BOOLEAN: VALUE must be the null terminated string "TRUE" or
 
199
  *   "FALSE" and LEN != 0.
 
200
  *
 
201
  *            value="TRUE" , len=1 -> boolean=TRUE.
 
202
  *            value="FALSE" , len=1 -> boolean=FALSE.
 
203
  *
 
204
  * OBJECT IDENTIFIER: VALUE must be a null terminated string with
 
205
  *   each number separated by a dot (e.g. "1.2.3.543.1").  LEN != 0.
 
206
  *
 
207
  *            value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
 
208
  *
 
209
  * UTCTime: VALUE must be a null terminated string in one of these
 
210
  *   formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
 
211
  *   "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
 
212
  *   "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'".  LEN != 0.
 
213
  *
 
214
  *            value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
 
215
  *            at 12h 00m Greenwich Mean Time
 
216
  *
 
217
  * GeneralizedTime: VALUE must be in one of this format:
 
218
  *   "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
 
219
  *   "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
 
220
  *   "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
 
221
  *   indicates the seconds with any precision like "10.1" or "01.02".
 
222
  *   LEN != 0
 
223
  *
 
224
  *            value="2001010112001.12-0700" , len=1 -> time=Jannuary
 
225
  *            1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
 
226
  *
 
227
  * OCTET STRING: VALUE contains the octet string and LEN is the
 
228
  *   number of octets.
 
229
  *
 
230
  *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
 
231
  *            len=3 -> three bytes octet string
 
232
  *
 
233
  * GeneralString: VALUE contains the generalstring and LEN is the
 
234
  *   number of octets.
 
235
  *
 
236
  *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
 
237
  *            len=3 -> three bytes generalstring
 
238
  *
 
239
  * BIT STRING: VALUE contains the bit string organized by bytes and
 
240
  *   LEN is the number of bits.
 
241
  *
 
242
  *   value="$\backslash$xCF" , len=6 -> bit string="110011" (six
 
243
  *   bits)
 
244
  *
 
245
  * CHOICE: if NAME indicates a choice type, VALUE must specify one of
 
246
  *   the alternatives with a null terminated string. LEN != 0. Using
 
247
  *   "pkix.asn"\:
 
248
  *
 
249
  *           result=asn1_write_value(cert,
 
250
  *           "certificate1.tbsCertificate.subject", "rdnSequence",
 
251
  *           1);
 
252
  *
 
253
  * ANY: VALUE indicates the der encoding of a structure.  LEN != 0.
 
254
  *
 
255
  * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
 
256
  *   LEN != 0. With this instruction another element is appended in
 
257
  *   the sequence. The name of this element will be "?1" if it's the
 
258
  *   first one, "?2" for the second and so on.
 
259
  *
 
260
  *   Using "pkix.asn"\:
 
261
  *
 
262
  *   result=asn1_write_value(cert,
 
263
  *   "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
 
264
  *
 
265
  * SET OF: the same as SEQUENCE OF.  Using "pkix.asn":
 
266
  *
 
267
  *           result=asn1_write_value(cert,
 
268
  *           "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
 
269
  *
 
270
  * Returns:
 
271
  *
 
272
  *   ASN1_SUCCESS: Set value OK.
 
273
  *
 
274
  *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
 
275
  *
 
276
  *   ASN1_VALUE_NOT_VALID: VALUE has a wrong format.
 
277
  *
 
278
  **/
 
279
asn1_retCode
 
280
asn1_write_value (ASN1_TYPE node_root, const char *name,
 
281
                  const void *ivalue, int len)
 
282
{
 
283
  ASN1_TYPE node, p, p2;
 
284
  unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
 
285
  int len2, k, k2, negative;
 
286
  size_t i;
 
287
  const unsigned char *value = ivalue;
 
288
 
 
289
  node = asn1_find_node (node_root, name);
 
290
  if (node == NULL)
 
291
    return ASN1_ELEMENT_NOT_FOUND;
 
292
 
 
293
  if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
 
294
    {
 
295
      asn1_delete_structure (&node);
 
296
      return ASN1_SUCCESS;
 
297
    }
 
298
 
 
299
  if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
 
300
      && (len == 0))
 
301
    {
 
302
      p = node->down;
 
303
      while ((type_field (p->type) == TYPE_TAG)
 
304
             || (type_field (p->type) == TYPE_SIZE))
 
305
        p = p->right;
 
306
 
 
307
      while (p->right)
 
308
        asn1_delete_structure (&p->right);
 
309
 
 
310
      return ASN1_SUCCESS;
 
311
    }
 
312
 
 
313
  switch (type_field (node->type))
 
314
    {
 
315
    case TYPE_BOOLEAN:
 
316
      if (!strcmp (value, "TRUE"))
 
317
        {
 
318
          if (node->type & CONST_DEFAULT)
 
319
            {
 
320
              p = node->down;
 
321
              while (type_field (p->type) != TYPE_DEFAULT)
 
322
                p = p->right;
 
323
              if (p->type & CONST_TRUE)
 
324
                _asn1_set_value (node, NULL, 0);
 
325
              else
 
326
                _asn1_set_value (node, "T", 1);
 
327
            }
 
328
          else
 
329
            _asn1_set_value (node, "T", 1);
 
330
        }
 
331
      else if (!strcmp (value, "FALSE"))
 
332
        {
 
333
          if (node->type & CONST_DEFAULT)
 
334
            {
 
335
              p = node->down;
 
336
              while (type_field (p->type) != TYPE_DEFAULT)
 
337
                p = p->right;
 
338
              if (p->type & CONST_FALSE)
 
339
                _asn1_set_value (node, NULL, 0);
 
340
              else
 
341
                _asn1_set_value (node, "F", 1);
 
342
            }
 
343
          else
 
344
            _asn1_set_value (node, "F", 1);
 
345
        }
 
346
      else
 
347
        return ASN1_VALUE_NOT_VALID;
 
348
      break;
 
349
    case TYPE_INTEGER:
 
350
    case TYPE_ENUMERATED:
 
351
      if (len == 0)
 
352
        {
 
353
          if ((isdigit (value[0])) || (value[0] == '-'))
 
354
            {
 
355
              value_temp =
 
356
                (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
 
357
              if (value_temp == NULL)
 
358
                return ASN1_MEM_ALLOC_ERROR;
 
359
 
 
360
              _asn1_convert_integer (value, value_temp,
 
361
                                     SIZEOF_UNSIGNED_LONG_INT, &len);
 
362
            }
 
363
          else
 
364
            {                   /* is an identifier like v1 */
 
365
              if (!(node->type & CONST_LIST))
 
366
                return ASN1_VALUE_NOT_VALID;
 
367
              p = node->down;
 
368
              while (p)
 
369
                {
 
370
                  if (type_field (p->type) == TYPE_CONSTANT)
 
371
                    {
 
372
                      if ((p->name) && (!strcmp (p->name, value)))
 
373
                        {
 
374
                          value_temp =
 
375
                            (unsigned char *)
 
376
                            _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
 
377
                          if (value_temp == NULL)
 
378
                            return ASN1_MEM_ALLOC_ERROR;
 
379
 
 
380
                          _asn1_convert_integer (p->value,
 
381
                                                 value_temp,
 
382
                                                 SIZEOF_UNSIGNED_LONG_INT,
 
383
                                                 &len);
 
384
                          break;
 
385
                        }
 
386
                    }
 
387
                  p = p->right;
 
388
                }
 
389
              if (p == NULL)
 
390
                return ASN1_VALUE_NOT_VALID;
 
391
            }
 
392
        }
 
393
      else
 
394
        {                       /* len != 0 */
 
395
          value_temp = (unsigned char *) _asn1_malloc (len);
 
396
          if (value_temp == NULL)
 
397
            return ASN1_MEM_ALLOC_ERROR;
 
398
          memcpy (value_temp, value, len);
 
399
        }
 
400
 
 
401
 
 
402
      if (value_temp[0] & 0x80)
 
403
        negative = 1;
 
404
      else
 
405
        negative = 0;
 
406
 
 
407
      if (negative && (type_field (node->type) == TYPE_ENUMERATED))
 
408
        {
 
409
          _asn1_free (value_temp);
 
410
          return ASN1_VALUE_NOT_VALID;
 
411
        }
 
412
 
 
413
      for (k = 0; k < len - 1; k++)
 
414
        if (negative && (value_temp[k] != 0xFF))
 
415
          break;
 
416
        else if (!negative && value_temp[k])
 
417
          break;
 
418
 
 
419
      if ((negative && !(value_temp[k] & 0x80)) ||
 
420
          (!negative && (value_temp[k] & 0x80)))
 
421
        k--;
 
422
 
 
423
      _asn1_set_value_octet (node, value_temp + k, len - k);
 
424
 
 
425
      if (node->type & CONST_DEFAULT)
 
426
        {
 
427
          p = node->down;
 
428
          while (type_field (p->type) != TYPE_DEFAULT)
 
429
            p = p->right;
 
430
          if ((isdigit (p->value[0])) || (p->value[0] == '-'))
 
431
            {
 
432
              default_temp =
 
433
                (unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
 
434
              if (default_temp == NULL)
 
435
                {
 
436
                  _asn1_free (value_temp);
 
437
                  return ASN1_MEM_ALLOC_ERROR;
 
438
                }
 
439
 
 
440
              _asn1_convert_integer (p->value, default_temp,
 
441
                                     SIZEOF_UNSIGNED_LONG_INT, &len2);
 
442
            }
 
443
          else
 
444
            {                   /* is an identifier like v1 */
 
445
              if (!(node->type & CONST_LIST))
 
446
                {
 
447
                  _asn1_free (value_temp);
 
448
                  return ASN1_VALUE_NOT_VALID;
 
449
                }
 
450
              p2 = node->down;
 
451
              while (p2)
 
452
                {
 
453
                  if (type_field (p2->type) == TYPE_CONSTANT)
 
454
                    {
 
455
                      if ((p2->name) && (!strcmp (p2->name, p->value)))
 
456
                        {
 
457
                          default_temp =
 
458
                            (unsigned char *)
 
459
                            _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
 
460
                          if (default_temp == NULL)
 
461
                            {
 
462
                              _asn1_free (value_temp);
 
463
                              return ASN1_MEM_ALLOC_ERROR;
 
464
                            }
 
465
 
 
466
                          _asn1_convert_integer (p2->value,
 
467
                                                 default_temp,
 
468
                                                 SIZEOF_UNSIGNED_LONG_INT,
 
469
                                                 &len2);
 
470
                          break;
 
471
                        }
 
472
                    }
 
473
                  p2 = p2->right;
 
474
                }
 
475
              if (p2 == NULL)
 
476
                {
 
477
                  _asn1_free (value_temp);
 
478
                  return ASN1_VALUE_NOT_VALID;
 
479
                }
 
480
            }
 
481
 
 
482
 
 
483
          if ((len - k) == len2)
 
484
            {
 
485
              for (k2 = 0; k2 < len2; k2++)
 
486
                if (value_temp[k + k2] != default_temp[k2])
 
487
                  {
 
488
                    break;
 
489
                  }
 
490
              if (k2 == len2)
 
491
                _asn1_set_value (node, NULL, 0);
 
492
            }
 
493
          _asn1_free (default_temp);
 
494
        }
 
495
      _asn1_free (value_temp);
 
496
      break;
 
497
    case TYPE_OBJECT_ID:
 
498
      for (i = 0; i < strlen (value); i++)
 
499
        if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
 
500
          return ASN1_VALUE_NOT_VALID;
 
501
      if (node->type & CONST_DEFAULT)
 
502
        {
 
503
          p = node->down;
 
504
          while (type_field (p->type) != TYPE_DEFAULT)
 
505
            p = p->right;
 
506
          if (!strcmp (value, p->value))
 
507
            {
 
508
              _asn1_set_value (node, NULL, 0);
 
509
              break;
 
510
            }
 
511
        }
 
512
      _asn1_set_value (node, value, strlen (value) + 1);
 
513
      break;
 
514
    case TYPE_TIME:
 
515
      if (node->type & CONST_UTC)
 
516
        {
 
517
          if (strlen (value) < 11)
 
518
            return ASN1_VALUE_NOT_VALID;
 
519
          for (k = 0; k < 10; k++)
 
520
            if (!isdigit (value[k]))
 
521
              return ASN1_VALUE_NOT_VALID;
 
522
          switch (strlen (value))
 
523
            {
 
524
            case 11:
 
525
              if (value[10] != 'Z')
 
526
                return ASN1_VALUE_NOT_VALID;
 
527
              break;
 
528
            case 13:
 
529
              if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
 
530
                  (value[12] != 'Z'))
 
531
                return ASN1_VALUE_NOT_VALID;
 
532
              break;
 
533
            case 15:
 
534
              if ((value[10] != '+') && (value[10] != '-'))
 
535
                return ASN1_VALUE_NOT_VALID;
 
536
              for (k = 11; k < 15; k++)
 
537
                if (!isdigit (value[k]))
 
538
                  return ASN1_VALUE_NOT_VALID;
 
539
              break;
 
540
            case 17:
 
541
              if ((!isdigit (value[10])) || (!isdigit (value[11])))
 
542
                return ASN1_VALUE_NOT_VALID;
 
543
              if ((value[12] != '+') && (value[12] != '-'))
 
544
                return ASN1_VALUE_NOT_VALID;
 
545
              for (k = 13; k < 17; k++)
 
546
                if (!isdigit (value[k]))
 
547
                  return ASN1_VALUE_NOT_VALID;
 
548
              break;
 
549
            default:
 
550
              return ASN1_VALUE_NOT_FOUND;
 
551
            }
 
552
          _asn1_set_value (node, value, strlen (value) + 1);
 
553
        }
 
554
      else
 
555
        {                       /* GENERALIZED TIME */
 
556
          if (value)
 
557
            _asn1_set_value (node, value, strlen (value) + 1);
 
558
        }
 
559
      break;
 
560
    case TYPE_OCTET_STRING:
 
561
      if (len == 0)
 
562
        len = strlen (value);
 
563
      _asn1_set_value_octet (node, value, len);
 
564
      break;
 
565
    case TYPE_GENERALSTRING:
 
566
      if (len == 0)
 
567
        len = strlen (value);
 
568
      _asn1_set_value_octet (node, value, len);
 
569
      break;
 
570
    case TYPE_BIT_STRING:
 
571
      if (len == 0)
 
572
        len = strlen (value);
 
573
      asn1_length_der ((len >> 3) + 2, NULL, &len2);
 
574
      temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
 
575
      if (temp == NULL)
 
576
        return ASN1_MEM_ALLOC_ERROR;
 
577
 
 
578
      asn1_bit_der (value, len, temp, &len2);
 
579
      _asn1_set_value_m (node, temp, len2);
 
580
      temp = NULL;
 
581
      break;
 
582
    case TYPE_CHOICE:
 
583
      p = node->down;
 
584
      while (p)
 
585
        {
 
586
          if (!strcmp (p->name, value))
 
587
            {
 
588
              p2 = node->down;
 
589
              while (p2)
 
590
                {
 
591
                  if (p2 != p)
 
592
                    {
 
593
                      asn1_delete_structure (&p2);
 
594
                      p2 = node->down;
 
595
                    }
 
596
                  else
 
597
                    p2 = p2->right;
 
598
                }
 
599
              break;
 
600
            }
 
601
          p = p->right;
 
602
        }
 
603
      if (!p)
 
604
        return ASN1_ELEMENT_NOT_FOUND;
 
605
      break;
 
606
    case TYPE_ANY:
 
607
      _asn1_set_value_octet (node, value, len);
 
608
      break;
 
609
    case TYPE_SEQUENCE_OF:
 
610
    case TYPE_SET_OF:
 
611
      if (strcmp (value, "NEW"))
 
612
        return ASN1_VALUE_NOT_VALID;
 
613
      _asn1_append_sequence_set (node);
 
614
      break;
 
615
    default:
 
616
      return ASN1_ELEMENT_NOT_FOUND;
 
617
      break;
 
618
    }
 
619
 
 
620
  return ASN1_SUCCESS;
 
621
}
 
622
 
 
623
 
 
624
#define PUT_VALUE( ptr, ptr_size, data, data_size) \
 
625
        *len = data_size; \
 
626
        if (ptr_size < data_size) { \
 
627
                return ASN1_MEM_ERROR; \
 
628
        } else { \
 
629
                if (ptr && data_size > 0) \
 
630
                  memcpy( ptr, data, data_size); \
 
631
        }
 
632
 
 
633
#define PUT_STR_VALUE( ptr, ptr_size, data) \
 
634
        *len = strlen(data) + 1; \
 
635
        if (ptr_size < *len) { \
 
636
                return ASN1_MEM_ERROR; \
 
637
        } else { \
 
638
                /* this strcpy is checked */ \
 
639
                if (ptr) { \
 
640
                  strcpy(ptr, data); \
 
641
                } \
 
642
        }
 
643
 
 
644
#define ADD_STR_VALUE( ptr, ptr_size, data) \
 
645
        *len += strlen(data); \
 
646
        if (ptr_size < (int) *len) { \
 
647
                (*len)++; \
 
648
                return ASN1_MEM_ERROR; \
 
649
        } else { \
 
650
                /* this strcat is checked */ \
 
651
                if (ptr) strcat(ptr, data); \
 
652
        }
 
653
 
 
654
/**
 
655
  * asn1_read_value - Returns the value of one element inside a structure
 
656
  * @root: pointer to a structure.
 
657
  * @name: the name of the element inside a structure that you want to read.
 
658
  * @ivalue: vector that will contain the element's content, must be a
 
659
  *   pointer to memory cells already allocated (may be %NULL).
 
660
  * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
 
661
  *   holds the sizeof value.
 
662
  *
 
663
  * Returns the value of one element inside a structure. 
 
664
  * If an element is OPTIONAL and this returns
 
665
  * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
 
666
  * in the der encoding that created the structure.  The first element
 
667
  * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
 
668
  * so on.
 
669
  *
 
670
  * Note that there can be valid values with length zero. In these case
 
671
  * this function will succeed and @len will be zero.
 
672
  *
 
673
  * INTEGER: VALUE will contain a two's complement form integer.
 
674
  *
 
675
  *            integer=-1  -> value[0]=0xFF , len=1.
 
676
  *            integer=1   -> value[0]=0x01 , len=1.
 
677
  *
 
678
  * ENUMERATED: As INTEGER (but only with not negative numbers).
 
679
  *
 
680
  * BOOLEAN: VALUE will be the null terminated string "TRUE" or
 
681
  *   "FALSE" and LEN=5 or LEN=6.
 
682
  *
 
683
  * OBJECT IDENTIFIER: VALUE will be a null terminated string with
 
684
  *   each number separated by a dot (i.e. "1.2.3.543.1").
 
685
  *
 
686
  *                      LEN = strlen(VALUE)+1
 
687
  *
 
688
  * UTCTime: VALUE will be a null terminated string in one of these
 
689
  *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
 
690
  *   LEN=strlen(VALUE)+1.
 
691
  *
 
692
  * GeneralizedTime: VALUE will be a null terminated string in the
 
693
  *   same format used to set the value.
 
694
  *
 
695
  * OCTET STRING: VALUE will contain the octet string and LEN will be
 
696
  *   the number of octets.
 
697
  *
 
698
  * GeneralString: VALUE will contain the generalstring and LEN will
 
699
  *   be the number of octets.
 
700
  *
 
701
  * BIT STRING: VALUE will contain the bit string organized by bytes
 
702
  *   and LEN will be the number of bits.
 
703
  *
 
704
  * CHOICE: If NAME indicates a choice type, VALUE will specify the
 
705
  *   alternative selected.
 
706
  *
 
707
  * ANY: If NAME indicates an any type, VALUE will indicate the DER
 
708
  *   encoding of the structure actually used.
 
709
  *
 
710
  * Returns:
 
711
  *
 
712
  *   ASN1_SUCCESS: Set value OK.
 
713
  *
 
714
  *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
 
715
  *
 
716
  *   ASN1_VALUE_NOT_FOUND: There isn't any value for the element selected.
 
717
  *
 
718
  *   ASN1_MEM_ERROR: The value vector isn't big enough to store the result.
 
719
  *   In this case LEN will contain the number of bytes needed.
 
720
  *
 
721
  **/
 
722
asn1_retCode
 
723
asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
 
724
{
 
725
  ASN1_TYPE node, p, p2;
 
726
  int len2, len3;
 
727
  int value_size = *len;
 
728
  unsigned char *value = ivalue;
 
729
 
 
730
  node = asn1_find_node (root, name);
 
731
  if (node == NULL)
 
732
    return ASN1_ELEMENT_NOT_FOUND;
 
733
 
 
734
  if ((type_field (node->type) != TYPE_NULL) &&
 
735
      (type_field (node->type) != TYPE_CHOICE) &&
 
736
      !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
 
737
      (node->value == NULL))
 
738
    return ASN1_VALUE_NOT_FOUND;
 
739
 
 
740
  switch (type_field (node->type))
 
741
    {
 
742
    case TYPE_NULL:
 
743
      PUT_STR_VALUE (value, value_size, "NULL");
 
744
      break;
 
745
    case TYPE_BOOLEAN:
 
746
      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
 
747
        {
 
748
          p = node->down;
 
749
          while (type_field (p->type) != TYPE_DEFAULT)
 
750
            p = p->right;
 
751
          if (p->type & CONST_TRUE)
 
752
            {
 
753
              PUT_STR_VALUE (value, value_size, "TRUE");
 
754
            }
 
755
          else
 
756
            {
 
757
              PUT_STR_VALUE (value, value_size, "FALSE");
 
758
            }
 
759
        }
 
760
      else if (node->value[0] == 'T')
 
761
        {
 
762
          PUT_STR_VALUE (value, value_size, "TRUE");
 
763
        }
 
764
      else
 
765
        {
 
766
          PUT_STR_VALUE (value, value_size, "FALSE");
 
767
        }
 
768
      break;
 
769
    case TYPE_INTEGER:
 
770
    case TYPE_ENUMERATED:
 
771
      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
 
772
        {
 
773
          p = node->down;
 
774
          while (type_field (p->type) != TYPE_DEFAULT)
 
775
            p = p->right;
 
776
          if ((isdigit (p->value[0])) || (p->value[0] == '-')
 
777
              || (p->value[0] == '+'))
 
778
            {
 
779
              if (_asn1_convert_integer
 
780
                  (p->value, value, value_size, len) != ASN1_SUCCESS)
 
781
                return ASN1_MEM_ERROR;
 
782
            }
 
783
          else
 
784
            {                   /* is an identifier like v1 */
 
785
              p2 = node->down;
 
786
              while (p2)
 
787
                {
 
788
                  if (type_field (p2->type) == TYPE_CONSTANT)
 
789
                    {
 
790
                      if ((p2->name) && (!strcmp (p2->name, p->value)))
 
791
                        {
 
792
                          if (_asn1_convert_integer
 
793
                              (p2->value, value, value_size,
 
794
                               len) != ASN1_SUCCESS)
 
795
                            return ASN1_MEM_ERROR;
 
796
                          break;
 
797
                        }
 
798
                    }
 
799
                  p2 = p2->right;
 
800
                }
 
801
            }
 
802
        }
 
803
      else
 
804
        {
 
805
          len2 = -1;
 
806
          if (asn1_get_octet_der
 
807
              (node->value, node->value_len, &len2, value, value_size,
 
808
               len) != ASN1_SUCCESS)
 
809
            return ASN1_MEM_ERROR;
 
810
        }
 
811
      break;
 
812
    case TYPE_OBJECT_ID:
 
813
      if (node->type & CONST_ASSIGN)
 
814
        {
 
815
          *len = 0;
 
816
          if (value)
 
817
                value[0] = 0;
 
818
          p = node->down;
 
819
          while (p)
 
820
            {
 
821
              if (type_field (p->type) == TYPE_CONSTANT)
 
822
                {
 
823
                  ADD_STR_VALUE (value, value_size, p->value);
 
824
                  if (p->right)
 
825
                    {
 
826
                      ADD_STR_VALUE (value, value_size, ".");
 
827
                    }
 
828
                }
 
829
              p = p->right;
 
830
            }
 
831
          (*len)++;
 
832
        }
 
833
      else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
 
834
        {
 
835
          p = node->down;
 
836
          while (type_field (p->type) != TYPE_DEFAULT)
 
837
            p = p->right;
 
838
          PUT_STR_VALUE (value, value_size, p->value);
 
839
        }
 
840
      else
 
841
        {
 
842
          PUT_STR_VALUE (value, value_size, node->value);
 
843
        }
 
844
      break;
 
845
    case TYPE_TIME:
 
846
      PUT_STR_VALUE (value, value_size, node->value);
 
847
      break;
 
848
    case TYPE_OCTET_STRING:
 
849
      len2 = -1;
 
850
      if (asn1_get_octet_der
 
851
          (node->value, node->value_len, &len2, value, value_size,
 
852
           len) != ASN1_SUCCESS)
 
853
        return ASN1_MEM_ERROR;
 
854
      break;
 
855
    case TYPE_GENERALSTRING:
 
856
      len2 = -1;
 
857
      if (asn1_get_octet_der
 
858
          (node->value, node->value_len, &len2, value, value_size,
 
859
           len) != ASN1_SUCCESS)
 
860
        return ASN1_MEM_ERROR;
 
861
      break;
 
862
    case TYPE_BIT_STRING:
 
863
      len2 = -1;
 
864
      if (asn1_get_bit_der
 
865
          (node->value, node->value_len, &len2, value, value_size,
 
866
           len) != ASN1_SUCCESS)
 
867
        return ASN1_MEM_ERROR;
 
868
      break;
 
869
    case TYPE_CHOICE:
 
870
      PUT_STR_VALUE (value, value_size, node->down->name);
 
871
      break;
 
872
    case TYPE_ANY:
 
873
      len3 = -1;
 
874
      len2 = asn1_get_length_der (node->value, node->value_len, &len3);
 
875
      if (len2 < 0)
 
876
        return ASN1_DER_ERROR;
 
877
      PUT_VALUE (value, value_size, node->value + len3, len2);
 
878
      break;
 
879
    default:
 
880
      return ASN1_ELEMENT_NOT_FOUND;
 
881
      break;
 
882
    }
 
883
  return ASN1_SUCCESS;
 
884
}
 
885
 
 
886
 
 
887
/**
 
888
  * asn1_read_tag - Returns the TAG of one element inside a structure
 
889
  * @root: pointer to a structure
 
890
  * @name: the name of the element inside a structure.
 
891
  * @tagValue:  variable that will contain the TAG value.
 
892
  * @classValue: variable that will specify the TAG type.
 
893
  *
 
894
  * Returns the TAG and the CLASS of one element inside a structure.
 
895
  * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
 
896
  * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
 
897
  * %ASN1_CLASS_CONTEXT_SPECIFIC.
 
898
  *
 
899
  * Returns:
 
900
  *
 
901
  *   ASN1_SUCCESS: Set value OK.
 
902
  *
 
903
  *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
 
904
  *
 
905
  **/
 
906
asn1_retCode
 
907
asn1_read_tag (ASN1_TYPE root, const char *name, int *tagValue,
 
908
               int *classValue)
 
909
{
 
910
  ASN1_TYPE node, p, pTag;
 
911
 
 
912
  node = asn1_find_node (root, name);
 
913
  if (node == NULL)
 
914
    return ASN1_ELEMENT_NOT_FOUND;
 
915
 
 
916
  p = node->down;
 
917
 
 
918
  /* pTag will points to the IMPLICIT TAG */
 
919
  pTag = NULL;
 
920
  if (node->type & CONST_TAG)
 
921
    {
 
922
      while (p)
 
923
        {
 
924
          if (type_field (p->type) == TYPE_TAG)
 
925
            {
 
926
              if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
 
927
                pTag = p;
 
928
              else if (p->type & CONST_EXPLICIT)
 
929
                pTag = NULL;
 
930
            }
 
931
          p = p->right;
 
932
        }
 
933
    }
 
934
 
 
935
  if (pTag)
 
936
    {
 
937
      *tagValue = strtoul (pTag->value, NULL, 10);
 
938
 
 
939
      if (pTag->type & CONST_APPLICATION)
 
940
        *classValue = ASN1_CLASS_APPLICATION;
 
941
      else if (pTag->type & CONST_UNIVERSAL)
 
942
        *classValue = ASN1_CLASS_UNIVERSAL;
 
943
      else if (pTag->type & CONST_PRIVATE)
 
944
        *classValue = ASN1_CLASS_PRIVATE;
 
945
      else
 
946
        *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
 
947
    }
 
948
  else
 
949
    {
 
950
      *classValue = ASN1_CLASS_UNIVERSAL;
 
951
 
 
952
      switch (type_field (node->type))
 
953
        {
 
954
        case TYPE_NULL:
 
955
          *tagValue = ASN1_TAG_NULL;
 
956
          break;
 
957
        case TYPE_BOOLEAN:
 
958
          *tagValue = ASN1_TAG_BOOLEAN;
 
959
          break;
 
960
        case TYPE_INTEGER:
 
961
          *tagValue = ASN1_TAG_INTEGER;
 
962
          break;
 
963
        case TYPE_ENUMERATED:
 
964
          *tagValue = ASN1_TAG_ENUMERATED;
 
965
          break;
 
966
        case TYPE_OBJECT_ID:
 
967
          *tagValue = ASN1_TAG_OBJECT_ID;
 
968
          break;
 
969
        case TYPE_TIME:
 
970
          if (node->type & CONST_UTC)
 
971
            {
 
972
              *tagValue = ASN1_TAG_UTCTime;
 
973
            }
 
974
          else
 
975
            *tagValue = ASN1_TAG_GENERALIZEDTime;
 
976
          break;
 
977
        case TYPE_OCTET_STRING:
 
978
          *tagValue = ASN1_TAG_OCTET_STRING;
 
979
          break;
 
980
        case TYPE_GENERALSTRING:
 
981
          *tagValue = ASN1_TAG_GENERALSTRING;
 
982
          break;
 
983
        case TYPE_BIT_STRING:
 
984
          *tagValue = ASN1_TAG_BIT_STRING;
 
985
          break;
 
986
        case TYPE_SEQUENCE:
 
987
        case TYPE_SEQUENCE_OF:
 
988
          *tagValue = ASN1_TAG_SEQUENCE;
 
989
          break;
 
990
        case TYPE_SET:
 
991
        case TYPE_SET_OF:
 
992
          *tagValue = ASN1_TAG_SET;
 
993
          break;
 
994
        case TYPE_TAG:
 
995
        case TYPE_CHOICE:
 
996
        case TYPE_ANY:
 
997
          break;
 
998
        default:
 
999
          break;
 
1000
        }
 
1001
    }
 
1002
 
 
1003
 
 
1004
  return ASN1_SUCCESS;
 
1005
 
 
1006
}