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

« back to all changes in this revision

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

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software
 
3
 * Foundation, Inc.
 
4
 *
 
5
 * This file is part of LIBTASN1.
 
6
 *
 
7
 * The LIBTASN1 library is free software; you can redistribute it
 
8
 * and/or modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful, but
 
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
20
 * 02110-1301, USA
 
21
 */
 
22
 
 
23
 
 
24
/*****************************************************/
 
25
/* File: coding.c                                    */
 
26
/* Description: Functions to create a DER coding of  */
 
27
/*   an ASN1 type.                                   */
 
28
/*****************************************************/
 
29
 
 
30
#include <int.h>
 
31
#include "parser_aux.h"
 
32
#include <gstr.h>
 
33
#include "element.h"
 
34
#include <structure.h>
 
35
 
 
36
#define MAX_TAG_LEN 16
 
37
 
 
38
/******************************************************/
 
39
/* Function : _asn1_error_description_value_not_found */
 
40
/* Description: creates the ErrorDescription string   */
 
41
/* for the ASN1_VALUE_NOT_FOUND error.                */
 
42
/* Parameters:                                        */
 
43
/*   node: node of the tree where the value is NULL.  */
 
44
/*   ErrorDescription: string returned.               */
 
45
/* Return:                                            */
 
46
/******************************************************/
 
47
static void
 
48
_asn1_error_description_value_not_found (ASN1_TYPE node,
 
49
                                         char *ErrorDescription)
 
50
{
 
51
 
 
52
  if (ErrorDescription == NULL)
 
53
    return;
 
54
 
 
55
  Estrcpy (ErrorDescription, ":: value of element '");
 
56
  _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
 
57
                           ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
 
58
  Estrcat (ErrorDescription, "' not found");
 
59
 
 
60
}
 
61
 
 
62
/**
 
63
 * asn1_length_der:
 
64
 * @len: value to convert.
 
65
 * @ans: string returned.
 
66
 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
 
67
 *
 
68
 * Creates the DER coding for the LEN parameter (only the length).
 
69
 * The @ans buffer is pre-allocated and must have room for the output.
 
70
 **/
 
71
void
 
72
asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
 
73
{
 
74
  int k;
 
75
  unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
 
76
 
 
77
  if (len < 128)
 
78
    {
 
79
      /* short form */
 
80
      if (ans != NULL)
 
81
        ans[0] = (unsigned char) len;
 
82
      *ans_len = 1;
 
83
    }
 
84
  else
 
85
    {
 
86
      /* Long form */
 
87
      k = 0;
 
88
      while (len)
 
89
        {
 
90
          temp[k++] = len & 0xFF;
 
91
          len = len >> 8;
 
92
        }
 
93
      *ans_len = k + 1;
 
94
      if (ans != NULL)
 
95
        {
 
96
          ans[0] = ((unsigned char) k & 0x7F) + 128;
 
97
          while (k--)
 
98
            ans[*ans_len - 1 - k] = temp[k];
 
99
        }
 
100
    }
 
101
}
 
102
 
 
103
/******************************************************/
 
104
/* Function : _asn1_tag_der                           */
 
105
/* Description: creates the DER coding for the CLASS  */
 
106
/* and TAG parameters.                                */
 
107
/* Parameters:                                        */
 
108
/*   class: value to convert.                         */
 
109
/*   tag_value: value to convert.                     */
 
110
/*   ans: string returned.                            */
 
111
/*   ans_len: number of meaningful bytes of ANS       */
 
112
/*            (ans[0]..ans[ans_len-1]).               */
 
113
/* Return:                                            */
 
114
/******************************************************/
 
115
static void
 
116
_asn1_tag_der (unsigned char class, unsigned int tag_value,
 
117
               unsigned char *ans, int *ans_len)
 
118
{
 
119
  int k;
 
120
  unsigned char temp[SIZEOF_UNSIGNED_INT];
 
121
 
 
122
  if (tag_value < 31)
 
123
    {
 
124
      /* short form */
 
125
      ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
 
126
      *ans_len = 1;
 
127
    }
 
128
  else
 
129
    {
 
130
      /* Long form */
 
131
      ans[0] = (class & 0xE0) + 31;
 
132
      k = 0;
 
133
      while (tag_value)
 
134
        {
 
135
          temp[k++] = tag_value & 0x7F;
 
136
          tag_value = tag_value >> 7;
 
137
        }
 
138
      *ans_len = k + 1;
 
139
      while (k--)
 
140
        ans[*ans_len - 1 - k] = temp[k] + 128;
 
141
      ans[*ans_len - 1] -= 128;
 
142
    }
 
143
}
 
144
 
 
145
/**
 
146
 * asn1_octet_der:
 
147
 * @str: OCTET string.
 
148
 * @str_len: STR length (str[0]..str[str_len-1]).
 
149
 * @der: string returned.
 
150
 * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
 
151
 *
 
152
 * Creates the DER coding for an OCTET type (length included).
 
153
 **/
 
154
void
 
155
asn1_octet_der (const unsigned char *str, int str_len,
 
156
                unsigned char *der, int *der_len)
 
157
{
 
158
  int len_len;
 
159
 
 
160
  if (der == NULL || str_len < 0)
 
161
    return;
 
162
  asn1_length_der (str_len, der, &len_len);
 
163
  memcpy (der + len_len, str, str_len);
 
164
  *der_len = str_len + len_len;
 
165
}
 
166
 
 
167
/******************************************************/
 
168
/* Function : _asn1_time_der                          */
 
169
/* Description: creates the DER coding for a TIME     */
 
170
/* type (length included).                            */
 
171
/* Parameters:                                        */
 
172
/*   str: TIME null-terminated string.                */
 
173
/*   der: string returned.                            */
 
174
/*   der_len: number of meaningful bytes of DER       */
 
175
/*            (der[0]..der[ans_len-1]). Initially it  */
 
176
/*            if must store the lenght of DER.        */
 
177
/* Return:                                            */
 
178
/*   ASN1_MEM_ERROR when DER isn't big enough         */
 
179
/*   ASN1_SUCCESS otherwise                           */
 
180
/******************************************************/
 
181
static asn1_retCode
 
182
_asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
 
183
{
 
184
  int len_len;
 
185
  int max_len;
 
186
 
 
187
  max_len = *der_len;
 
188
 
 
189
  asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
 
190
 
 
191
  if ((len_len + (int) strlen (str)) <= max_len)
 
192
    memcpy (der + len_len, str, strlen (str));
 
193
  *der_len = len_len + strlen (str);
 
194
 
 
195
  if ((*der_len) > max_len)
 
196
    return ASN1_MEM_ERROR;
 
197
 
 
198
  return ASN1_SUCCESS;
 
199
}
 
200
 
 
201
 
 
202
/*
 
203
void
 
204
_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
 
205
{
 
206
  int len_len,str_len;
 
207
  char temp[20];
 
208
 
 
209
  if(str==NULL) return;
 
210
  str_len=asn1_get_length_der(der,*der_len,&len_len);
 
211
  if (str_len<0) return;
 
212
  memcpy(temp,der+len_len,str_len);
 
213
  *der_len=str_len+len_len;
 
214
  switch(str_len){
 
215
  case 11:
 
216
    temp[10]=0;
 
217
    strcat(temp,"00+0000");
 
218
    break;
 
219
  case 13:
 
220
    temp[12]=0;
 
221
    strcat(temp,"+0000");
 
222
    break;
 
223
  case 15:
 
224
    temp[15]=0;
 
225
    memmove(temp+12,temp+10,6);
 
226
    temp[10]=temp[11]='0';
 
227
    break;
 
228
  case 17:
 
229
    temp[17]=0;
 
230
    break;
 
231
  default:
 
232
    return;
 
233
  }
 
234
  strcpy(str,temp);
 
235
}
 
236
*/
 
237
 
 
238
/******************************************************/
 
239
/* Function : _asn1_objectid_der                      */
 
240
/* Description: creates the DER coding for an         */
 
241
/* OBJECT IDENTIFIER  type (length included).         */
 
242
/* Parameters:                                        */
 
243
/*   str: OBJECT IDENTIFIER null-terminated string.   */
 
244
/*   der: string returned.                            */
 
245
/*   der_len: number of meaningful bytes of DER       */
 
246
/*            (der[0]..der[ans_len-1]). Initially it  */
 
247
/*            must store the length of DER.           */
 
248
/* Return:                                            */
 
249
/*   ASN1_MEM_ERROR when DER isn't big enough         */
 
250
/*   ASN1_SUCCESS otherwise                           */
 
251
/******************************************************/
 
252
static asn1_retCode
 
253
_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
 
254
{
 
255
  int len_len, counter, k, first, max_len;
 
256
  char *temp, *n_end, *n_start;
 
257
  unsigned char bit7;
 
258
  unsigned long val, val1 = 0;
 
259
 
 
260
  max_len = *der_len;
 
261
 
 
262
  temp = (char *) _asn1_malloc (strlen (str) + 2);
 
263
  if (temp == NULL)
 
264
    return ASN1_MEM_ALLOC_ERROR;
 
265
 
 
266
  strcpy (temp, str);
 
267
  strcat (temp, ".");
 
268
 
 
269
  counter = 0;
 
270
  n_start = temp;
 
271
  while ((n_end = strchr (n_start, '.')))
 
272
    {
 
273
      *n_end = 0;
 
274
      val = strtoul (n_start, NULL, 10);
 
275
      counter++;
 
276
 
 
277
      if (counter == 1)
 
278
        val1 = val;
 
279
      else if (counter == 2)
 
280
        {
 
281
          if (max_len > 0)
 
282
            der[0] = 40 * val1 + val;
 
283
          *der_len = 1;
 
284
        }
 
285
      else
 
286
        {
 
287
          first = 0;
 
288
          for (k = 4; k >= 0; k--)
 
289
            {
 
290
              bit7 = (val >> (k * 7)) & 0x7F;
 
291
              if (bit7 || first || !k)
 
292
                {
 
293
                  if (k)
 
294
                    bit7 |= 0x80;
 
295
                  if (max_len > (*der_len))
 
296
                    der[*der_len] = bit7;
 
297
                  (*der_len)++;
 
298
                  first = 1;
 
299
                }
 
300
            }
 
301
 
 
302
        }
 
303
      n_start = n_end + 1;
 
304
    }
 
305
 
 
306
  asn1_length_der (*der_len, NULL, &len_len);
 
307
  if (max_len >= (*der_len + len_len))
 
308
    {
 
309
      memmove (der + len_len, der, *der_len);
 
310
      asn1_length_der (*der_len, der, &len_len);
 
311
    }
 
312
  *der_len += len_len;
 
313
 
 
314
  _asn1_free (temp);
 
315
 
 
316
  if (max_len < (*der_len))
 
317
    return ASN1_MEM_ERROR;
 
318
 
 
319
  return ASN1_SUCCESS;
 
320
}
 
321
 
 
322
 
 
323
const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
 
324
 
 
325
/**
 
326
 * asn1_bit_der:
 
327
 * @str: BIT string.
 
328
 * @bit_len: number of meaningful bits in STR.
 
329
 * @der: string returned.
 
330
 * @der_len: number of meaningful bytes of DER
 
331
 *   (der[0]..der[ans_len-1]).
 
332
 *
 
333
 * Creates the DER coding for a BIT STRING type (length and pad
 
334
 * included).
 
335
 **/
 
336
void
 
337
asn1_bit_der (const unsigned char *str, int bit_len,
 
338
              unsigned char *der, int *der_len)
 
339
{
 
340
  int len_len, len_byte, len_pad;
 
341
 
 
342
  if (der == NULL)
 
343
    return;
 
344
  len_byte = bit_len >> 3;
 
345
  len_pad = 8 - (bit_len & 7);
 
346
  if (len_pad == 8)
 
347
    len_pad = 0;
 
348
  else
 
349
    len_byte++;
 
350
  asn1_length_der (len_byte + 1, der, &len_len);
 
351
  der[len_len] = len_pad;
 
352
  memcpy (der + len_len + 1, str, len_byte);
 
353
  der[len_len + len_byte] &= bit_mask[len_pad];
 
354
  *der_len = len_byte + len_len + 1;
 
355
}
 
356
 
 
357
 
 
358
/******************************************************/
 
359
/* Function : _asn1_complete_explicit_tag             */
 
360
/* Description: add the length coding to the EXPLICIT */
 
361
/* tags.                                              */
 
362
/* Parameters:                                        */
 
363
/*   node: pointer to the tree element.               */
 
364
/*   der: string with the DER coding of the whole tree*/
 
365
/*   counter: number of meaningful bytes of DER       */
 
366
/*            (der[0]..der[*counter-1]).              */
 
367
/*   max_len: size of der vector                      */
 
368
/* Return:                                            */
 
369
/*   ASN1_MEM_ERROR if der vector isn't big enough,   */
 
370
/*   otherwise ASN1_SUCCESS.                          */
 
371
/******************************************************/
 
372
static asn1_retCode
 
373
_asn1_complete_explicit_tag (ASN1_TYPE node, unsigned char *der,
 
374
                             int *counter, int *max_len)
 
375
{
 
376
  ASN1_TYPE p;
 
377
  int is_tag_implicit, len2, len3;
 
378
  unsigned char temp[SIZEOF_UNSIGNED_INT];
 
379
 
 
380
  is_tag_implicit = 0;
 
381
 
 
382
  if (node->type & CONST_TAG)
 
383
    {
 
384
      p = node->down;
 
385
      /* When there are nested tags we must complete them reverse to
 
386
         the order they were created. This is because completing a tag
 
387
         modifies all data within it, including the incomplete tags 
 
388
         which store buffer positions -- simon@josefsson.org 2002-09-06
 
389
       */
 
390
      while (p->right)
 
391
        p = p->right;
 
392
      while (p && p != node->down->left)
 
393
        {
 
394
          if (type_field (p->type) == TYPE_TAG)
 
395
            {
 
396
              if (p->type & CONST_EXPLICIT)
 
397
                {
 
398
                  len2 = strtol (p->name, NULL, 10);
 
399
                  _asn1_set_name (p, NULL);
 
400
                  asn1_length_der (*counter - len2, temp, &len3);
 
401
                  if (len3 <= (*max_len))
 
402
                    {
 
403
                      memmove (der + len2 + len3, der + len2,
 
404
                               *counter - len2);
 
405
                      memcpy (der + len2, temp, len3);
 
406
                    }
 
407
                  *max_len -= len3;
 
408
                  *counter += len3;
 
409
                  is_tag_implicit = 0;
 
410
                }
 
411
              else
 
412
                {               /* CONST_IMPLICIT */
 
413
                  if (!is_tag_implicit)
 
414
                    {
 
415
                      is_tag_implicit = 1;
 
416
                    }
 
417
                }
 
418
            }
 
419
          p = p->left;
 
420
        }
 
421
    }
 
422
 
 
423
  if (*max_len < 0)
 
424
    return ASN1_MEM_ERROR;
 
425
 
 
426
  return ASN1_SUCCESS;
 
427
}
 
428
 
 
429
 
 
430
/******************************************************/
 
431
/* Function : _asn1_insert_tag_der                    */
 
432
/* Description: creates the DER coding of tags of one */
 
433
/* NODE.                                              */
 
434
/* Parameters:                                        */
 
435
/*   node: pointer to the tree element.               */
 
436
/*   der: string returned                             */
 
437
/*   counter: number of meaningful bytes of DER       */
 
438
/*            (counter[0]..der[*counter-1]).          */
 
439
/*   max_len: size of der vector                      */
 
440
/* Return:                                            */
 
441
/*   ASN1_GENERIC_ERROR if the type is unknown,       */
 
442
/*   ASN1_MEM_ERROR if der vector isn't big enough,   */
 
443
/*   otherwise ASN1_SUCCESS.                          */
 
444
/******************************************************/
 
445
static asn1_retCode
 
446
_asn1_insert_tag_der (ASN1_TYPE node, unsigned char *der, int *counter,
 
447
                      int *max_len)
 
448
{
 
449
  ASN1_TYPE p;
 
450
  int tag_len, is_tag_implicit;
 
451
  unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
 
452
  unsigned long tag_implicit = 0;
 
453
  char tag_der[MAX_TAG_LEN];
 
454
 
 
455
  is_tag_implicit = 0;
 
456
 
 
457
  if (node->type & CONST_TAG)
 
458
    {
 
459
      p = node->down;
 
460
      while (p)
 
461
        {
 
462
          if (type_field (p->type) == TYPE_TAG)
 
463
            {
 
464
              if (p->type & CONST_APPLICATION)
 
465
                class = ASN1_CLASS_APPLICATION;
 
466
              else if (p->type & CONST_UNIVERSAL)
 
467
                class = ASN1_CLASS_UNIVERSAL;
 
468
              else if (p->type & CONST_PRIVATE)
 
469
                class = ASN1_CLASS_PRIVATE;
 
470
              else
 
471
                class = ASN1_CLASS_CONTEXT_SPECIFIC;
 
472
 
 
473
              if (p->type & CONST_EXPLICIT)
 
474
                {
 
475
                  if (is_tag_implicit)
 
476
                    _asn1_tag_der (class_implicit, tag_implicit, tag_der,
 
477
                                   &tag_len);
 
478
                  else
 
479
                    _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
 
480
                                   strtoul (p->value, NULL, 10), tag_der,
 
481
                                   &tag_len);
 
482
 
 
483
                  *max_len -= tag_len;
 
484
                  if (*max_len >= 0)
 
485
                    memcpy (der + *counter, tag_der, tag_len);
 
486
                  *counter += tag_len;
 
487
 
 
488
                  _asn1_ltostr (*counter, temp);
 
489
                  _asn1_set_name (p, temp);
 
490
 
 
491
                  is_tag_implicit = 0;
 
492
                }
 
493
              else
 
494
                {               /* CONST_IMPLICIT */
 
495
                  if (!is_tag_implicit)
 
496
                    {
 
497
                      if ((type_field (node->type) == TYPE_SEQUENCE) ||
 
498
                          (type_field (node->type) == TYPE_SEQUENCE_OF) ||
 
499
                          (type_field (node->type) == TYPE_SET) ||
 
500
                          (type_field (node->type) == TYPE_SET_OF))
 
501
                        class |= ASN1_CLASS_STRUCTURED;
 
502
                      class_implicit = class;
 
503
                      tag_implicit = strtoul (p->value, NULL, 10);
 
504
                      is_tag_implicit = 1;
 
505
                    }
 
506
                }
 
507
            }
 
508
          p = p->right;
 
509
        }
 
510
    }
 
511
 
 
512
  if (is_tag_implicit)
 
513
    {
 
514
      _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
 
515
    }
 
516
  else
 
517
    {
 
518
      switch (type_field (node->type))
 
519
        {
 
520
        case TYPE_NULL:
 
521
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
 
522
                         &tag_len);
 
523
          break;
 
524
        case TYPE_BOOLEAN:
 
525
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
 
526
                         &tag_len);
 
527
          break;
 
528
        case TYPE_INTEGER:
 
529
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
 
530
                         &tag_len);
 
531
          break;
 
532
        case TYPE_ENUMERATED:
 
533
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
 
534
                         &tag_len);
 
535
          break;
 
536
        case TYPE_OBJECT_ID:
 
537
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
 
538
                         &tag_len);
 
539
          break;
 
540
        case TYPE_TIME:
 
541
          if (node->type & CONST_UTC)
 
542
            {
 
543
              _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
 
544
                             &tag_len);
 
545
            }
 
546
          else
 
547
            _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
 
548
                           tag_der, &tag_len);
 
549
          break;
 
550
        case TYPE_OCTET_STRING:
 
551
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
 
552
                         &tag_len);
 
553
          break;
 
554
        case TYPE_GENERALSTRING:
 
555
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
 
556
                         tag_der, &tag_len);
 
557
          break;
 
558
        case TYPE_BIT_STRING:
 
559
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
 
560
                         &tag_len);
 
561
          break;
 
562
        case TYPE_SEQUENCE:
 
563
        case TYPE_SEQUENCE_OF:
 
564
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
 
565
                         ASN1_TAG_SEQUENCE, tag_der, &tag_len);
 
566
          break;
 
567
        case TYPE_SET:
 
568
        case TYPE_SET_OF:
 
569
          _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
 
570
                         ASN1_TAG_SET, tag_der, &tag_len);
 
571
          break;
 
572
        case TYPE_TAG:
 
573
          tag_len = 0;
 
574
          break;
 
575
        case TYPE_CHOICE:
 
576
          tag_len = 0;
 
577
          break;
 
578
        case TYPE_ANY:
 
579
          tag_len = 0;
 
580
          break;
 
581
        default:
 
582
          return ASN1_GENERIC_ERROR;
 
583
        }
 
584
    }
 
585
 
 
586
  *max_len -= tag_len;
 
587
  if (*max_len >= 0)
 
588
    memcpy (der + *counter, tag_der, tag_len);
 
589
  *counter += tag_len;
 
590
 
 
591
  if (*max_len < 0)
 
592
    return ASN1_MEM_ERROR;
 
593
 
 
594
  return ASN1_SUCCESS;
 
595
}
 
596
 
 
597
/******************************************************/
 
598
/* Function : _asn1_ordering_set                      */
 
599
/* Description: puts the elements of a SET type in    */
 
600
/* the correct order according to DER rules.          */
 
601
/* Parameters:                                        */
 
602
/*   der: string with the DER coding.                 */
 
603
/*   node: pointer to the SET element.                */
 
604
/* Return:                                            */
 
605
/******************************************************/
 
606
static void
 
607
_asn1_ordering_set (unsigned char *der, int der_len, ASN1_TYPE node)
 
608
{
 
609
  struct vet
 
610
  {
 
611
    int end;
 
612
    unsigned long value;
 
613
    struct vet *next, *prev;
 
614
  };
 
615
 
 
616
  int counter, len, len2;
 
617
  struct vet *first, *last, *p_vet, *p2_vet;
 
618
  ASN1_TYPE p;
 
619
  unsigned char class, *temp;
 
620
  unsigned long tag;
 
621
 
 
622
  counter = 0;
 
623
 
 
624
  if (type_field (node->type) != TYPE_SET)
 
625
    return;
 
626
 
 
627
  p = node->down;
 
628
  while ((type_field (p->type) == TYPE_TAG)
 
629
         || (type_field (p->type) == TYPE_SIZE))
 
630
    p = p->right;
 
631
 
 
632
  if ((p == NULL) || (p->right == NULL))
 
633
    return;
 
634
 
 
635
  first = last = NULL;
 
636
  while (p)
 
637
    {
 
638
      p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
 
639
      if (p_vet == NULL)
 
640
        return;
 
641
 
 
642
      p_vet->next = NULL;
 
643
      p_vet->prev = last;
 
644
      if (first == NULL)
 
645
        first = p_vet;
 
646
      else
 
647
        last->next = p_vet;
 
648
      last = p_vet;
 
649
 
 
650
      /* tag value calculation */
 
651
      if (asn1_get_tag_der
 
652
          (der + counter, der_len - counter, &class, &len2,
 
653
           &tag) != ASN1_SUCCESS)
 
654
        return;
 
655
      p_vet->value = (class << 24) | tag;
 
656
      counter += len2;
 
657
 
 
658
      /* extraction and length */
 
659
      len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
 
660
      if (len2 < 0)
 
661
        return;
 
662
      counter += len + len2;
 
663
 
 
664
      p_vet->end = counter;
 
665
      p = p->right;
 
666
    }
 
667
 
 
668
  p_vet = first;
 
669
 
 
670
  while (p_vet)
 
671
    {
 
672
      p2_vet = p_vet->next;
 
673
      counter = 0;
 
674
      while (p2_vet)
 
675
        {
 
676
          if (p_vet->value > p2_vet->value)
 
677
            {
 
678
              /* change position */
 
679
              temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
 
680
              if (temp == NULL)
 
681
                return;
 
682
 
 
683
              memcpy (temp, der + counter, p_vet->end - counter);
 
684
              memcpy (der + counter, der + p_vet->end,
 
685
                      p2_vet->end - p_vet->end);
 
686
              memcpy (der + counter + p2_vet->end - p_vet->end, temp,
 
687
                      p_vet->end - counter);
 
688
              _asn1_free (temp);
 
689
 
 
690
              tag = p_vet->value;
 
691
              p_vet->value = p2_vet->value;
 
692
              p2_vet->value = tag;
 
693
 
 
694
              p_vet->end = counter + (p2_vet->end - p_vet->end);
 
695
            }
 
696
          counter = p_vet->end;
 
697
 
 
698
          p2_vet = p2_vet->next;
 
699
          p_vet = p_vet->next;
 
700
        }
 
701
 
 
702
      if (p_vet != first)
 
703
        p_vet->prev->next = NULL;
 
704
      else
 
705
        first = NULL;
 
706
      _asn1_free (p_vet);
 
707
      p_vet = first;
 
708
    }
 
709
}
 
710
 
 
711
/******************************************************/
 
712
/* Function : _asn1_ordering_set_of                   */
 
713
/* Description: puts the elements of a SET OF type in */
 
714
/* the correct order according to DER rules.          */
 
715
/* Parameters:                                        */
 
716
/*   der: string with the DER coding.                 */
 
717
/*   node: pointer to the SET OF element.             */
 
718
/* Return:                                            */
 
719
/******************************************************/
 
720
static void
 
721
_asn1_ordering_set_of (unsigned char *der, int der_len, ASN1_TYPE node)
 
722
{
 
723
  struct vet
 
724
  {
 
725
    int end;
 
726
    struct vet *next, *prev;
 
727
  };
 
728
 
 
729
  int counter, len, len2, change;
 
730
  struct vet *first, *last, *p_vet, *p2_vet;
 
731
  ASN1_TYPE p;
 
732
  unsigned char *temp, class;
 
733
  unsigned long k, max;
 
734
 
 
735
  counter = 0;
 
736
 
 
737
  if (type_field (node->type) != TYPE_SET_OF)
 
738
    return;
 
739
 
 
740
  p = node->down;
 
741
  while ((type_field (p->type) == TYPE_TAG)
 
742
         || (type_field (p->type) == TYPE_SIZE))
 
743
    p = p->right;
 
744
  p = p->right;
 
745
 
 
746
  if ((p == NULL) || (p->right == NULL))
 
747
    return;
 
748
 
 
749
  first = last = NULL;
 
750
  while (p)
 
751
    {
 
752
      p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
 
753
      if (p_vet == NULL)
 
754
        return;
 
755
 
 
756
      p_vet->next = NULL;
 
757
      p_vet->prev = last;
 
758
      if (first == NULL)
 
759
        first = p_vet;
 
760
      else
 
761
        last->next = p_vet;
 
762
      last = p_vet;
 
763
 
 
764
      /* extraction of tag and length */
 
765
      if (der_len - counter > 0)
 
766
        {
 
767
 
 
768
          if (asn1_get_tag_der
 
769
              (der + counter, der_len - counter, &class, &len,
 
770
               NULL) != ASN1_SUCCESS)
 
771
            return;
 
772
          counter += len;
 
773
 
 
774
          len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
 
775
          if (len2 < 0)
 
776
            return;
 
777
          counter += len + len2;
 
778
        }
 
779
 
 
780
      p_vet->end = counter;
 
781
      p = p->right;
 
782
    }
 
783
 
 
784
  p_vet = first;
 
785
 
 
786
  while (p_vet)
 
787
    {
 
788
      p2_vet = p_vet->next;
 
789
      counter = 0;
 
790
      while (p2_vet)
 
791
        {
 
792
          if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
 
793
            max = p_vet->end - counter;
 
794
          else
 
795
            max = p2_vet->end - p_vet->end;
 
796
 
 
797
          change = -1;
 
798
          for (k = 0; k < max; k++)
 
799
            if (der[counter + k] > der[p_vet->end + k])
 
800
              {
 
801
                change = 1;
 
802
                break;
 
803
              }
 
804
            else if (der[counter + k] < der[p_vet->end + k])
 
805
              {
 
806
                change = 0;
 
807
                break;
 
808
              }
 
809
 
 
810
          if ((change == -1)
 
811
              && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
 
812
            change = 1;
 
813
 
 
814
          if (change == 1)
 
815
            {
 
816
              /* change position */
 
817
              temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
 
818
              if (temp == NULL)
 
819
                return;
 
820
 
 
821
              memcpy (temp, der + counter, (p_vet->end) - counter);
 
822
              memcpy (der + counter, der + (p_vet->end),
 
823
                      (p2_vet->end) - (p_vet->end));
 
824
              memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
 
825
                      (p_vet->end) - counter);
 
826
              _asn1_free (temp);
 
827
 
 
828
              p_vet->end = counter + (p2_vet->end - p_vet->end);
 
829
            }
 
830
          counter = p_vet->end;
 
831
 
 
832
          p2_vet = p2_vet->next;
 
833
          p_vet = p_vet->next;
 
834
        }
 
835
 
 
836
      if (p_vet != first)
 
837
        p_vet->prev->next = NULL;
 
838
      else
 
839
        first = NULL;
 
840
      _asn1_free (p_vet);
 
841
      p_vet = first;
 
842
    }
 
843
}
 
844
 
 
845
/**
 
846
  * asn1_der_coding - Creates the DER encoding for the NAME structure
 
847
  * @element: pointer to an ASN1 element
 
848
  * @name: the name of the structure you want to encode (it must be
 
849
  *   inside *POINTER).
 
850
  * @ider: vector that will contain the DER encoding. DER must be a
 
851
  *   pointer to memory cells already allocated.
 
852
  * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
 
853
  *   holds the sizeof of der vector.
 
854
  * @errorDescription : return the error description or an empty
 
855
  *   string if success.
 
856
  *
 
857
  * Creates the DER encoding for the NAME structure (inside *POINTER
 
858
  * structure).
 
859
  *
 
860
  * Returns:
 
861
  *
 
862
  *   ASN1_SUCCESS: DER encoding OK.
 
863
  *
 
864
  *   ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
 
865
  *
 
866
  *   ASN1_VALUE_NOT_FOUND: There is an element without a value.
 
867
  *
 
868
  *   ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
 
869
  *     LEN will contain the length needed.
 
870
  *
 
871
  **/
 
872
asn1_retCode
 
873
asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
 
874
                 char *ErrorDescription)
 
875
{
 
876
  ASN1_TYPE node, p, p2;
 
877
  char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
 
878
  int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
 
879
  asn1_retCode err;
 
880
  unsigned char *der = ider;
 
881
 
 
882
  node = asn1_find_node (element, name);
 
883
  if (node == NULL)
 
884
    return ASN1_ELEMENT_NOT_FOUND;
 
885
 
 
886
  /* Node is now a locally allocated variable.
 
887
   * That is because in some point we modify the
 
888
   * structure, and I don't know why! --nmav
 
889
   */
 
890
  node = _asn1_copy_structure3 (node);
 
891
  if (node == NULL)
 
892
    return ASN1_ELEMENT_NOT_FOUND;
 
893
 
 
894
  max_len = *len;
 
895
 
 
896
  counter = 0;
 
897
  move = DOWN;
 
898
  p = node;
 
899
  while (1)
 
900
    {
 
901
 
 
902
      counter_old = counter;
 
903
      max_len_old = max_len;
 
904
      if (move != UP)
 
905
        {
 
906
          err = _asn1_insert_tag_der (p, der, &counter, &max_len);
 
907
          if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
 
908
            goto error;
 
909
        }
 
910
      switch (type_field (p->type))
 
911
        {
 
912
        case TYPE_NULL:
 
913
          max_len--;
 
914
          if (max_len >= 0)
 
915
            der[counter] = 0;
 
916
          counter++;
 
917
          move = RIGHT;
 
918
          break;
 
919
        case TYPE_BOOLEAN:
 
920
          if ((p->type & CONST_DEFAULT) && (p->value == NULL))
 
921
            {
 
922
              counter = counter_old;
 
923
              max_len = max_len_old;
 
924
            }
 
925
          else
 
926
            {
 
927
              if (p->value == NULL)
 
928
                {
 
929
                  _asn1_error_description_value_not_found (p,
 
930
                                                           ErrorDescription);
 
931
                  err = ASN1_VALUE_NOT_FOUND;
 
932
                  goto error;
 
933
                }
 
934
              max_len -= 2;
 
935
              if (max_len >= 0)
 
936
                {
 
937
                  der[counter++] = 1;
 
938
                  if (p->value[0] == 'F')
 
939
                    der[counter++] = 0;
 
940
                  else
 
941
                    der[counter++] = 0xFF;
 
942
                }
 
943
              else
 
944
                counter += 2;
 
945
            }
 
946
          move = RIGHT;
 
947
          break;
 
948
        case TYPE_INTEGER:
 
949
        case TYPE_ENUMERATED:
 
950
          if ((p->type & CONST_DEFAULT) && (p->value == NULL))
 
951
            {
 
952
              counter = counter_old;
 
953
              max_len = max_len_old;
 
954
            }
 
955
          else
 
956
            {
 
957
              if (p->value == NULL)
 
958
                {
 
959
                  _asn1_error_description_value_not_found (p,
 
960
                                                           ErrorDescription);
 
961
                  err = ASN1_VALUE_NOT_FOUND;
 
962
                  goto error;
 
963
                }
 
964
              len2 = asn1_get_length_der (p->value, p->value_len, &len3);
 
965
              if (len2 < 0)
 
966
                {
 
967
                  err = ASN1_DER_ERROR;
 
968
                  goto error;
 
969
                }
 
970
              max_len -= len2 + len3;
 
971
              if (max_len >= 0)
 
972
                memcpy (der + counter, p->value, len3 + len2);
 
973
              counter += len3 + len2;
 
974
            }
 
975
          move = RIGHT;
 
976
          break;
 
977
        case TYPE_OBJECT_ID:
 
978
          if ((p->type & CONST_DEFAULT) && (p->value == NULL))
 
979
            {
 
980
              counter = counter_old;
 
981
              max_len = max_len_old;
 
982
            }
 
983
          else
 
984
            {
 
985
              if (p->value == NULL)
 
986
                {
 
987
                  _asn1_error_description_value_not_found (p,
 
988
                                                           ErrorDescription);
 
989
                  err = ASN1_VALUE_NOT_FOUND;
 
990
                  goto error;
 
991
                }
 
992
              len2 = max_len;
 
993
              err = _asn1_objectid_der (p->value, der + counter, &len2);
 
994
              if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
 
995
                goto error;
 
996
 
 
997
              max_len -= len2;
 
998
              counter += len2;
 
999
            }
 
1000
          move = RIGHT;
 
1001
          break;
 
1002
        case TYPE_TIME:
 
1003
          if (p->value == NULL)
 
1004
            {
 
1005
              _asn1_error_description_value_not_found (p, ErrorDescription);
 
1006
              err = ASN1_VALUE_NOT_FOUND;
 
1007
              goto error;
 
1008
            }
 
1009
          len2 = max_len;
 
1010
          err = _asn1_time_der (p->value, der + counter, &len2);
 
1011
          if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
 
1012
            goto error;
 
1013
 
 
1014
          max_len -= len2;
 
1015
          counter += len2;
 
1016
          move = RIGHT;
 
1017
          break;
 
1018
        case TYPE_OCTET_STRING:
 
1019
          if (p->value == NULL)
 
1020
            {
 
1021
              _asn1_error_description_value_not_found (p, ErrorDescription);
 
1022
              err = ASN1_VALUE_NOT_FOUND;
 
1023
              goto error;
 
1024
            }
 
1025
          len2 = asn1_get_length_der (p->value, p->value_len, &len3);
 
1026
          if (len2 < 0)
 
1027
            {
 
1028
              err = ASN1_DER_ERROR;
 
1029
              goto error;
 
1030
            }
 
1031
          max_len -= len2 + len3;
 
1032
          if (max_len >= 0)
 
1033
            memcpy (der + counter, p->value, len3 + len2);
 
1034
          counter += len3 + len2;
 
1035
          move = RIGHT;
 
1036
          break;
 
1037
        case TYPE_GENERALSTRING:
 
1038
          if (p->value == NULL)
 
1039
            {
 
1040
              _asn1_error_description_value_not_found (p, ErrorDescription);
 
1041
              err = ASN1_VALUE_NOT_FOUND;
 
1042
              goto error;
 
1043
            }
 
1044
          len2 = asn1_get_length_der (p->value, p->value_len, &len3);
 
1045
          if (len2 < 0)
 
1046
            {
 
1047
              err = ASN1_DER_ERROR;
 
1048
              goto error;
 
1049
            }
 
1050
          max_len -= len2 + len3;
 
1051
          if (max_len >= 0)
 
1052
            memcpy (der + counter, p->value, len3 + len2);
 
1053
          counter += len3 + len2;
 
1054
          move = RIGHT;
 
1055
          break;
 
1056
        case TYPE_BIT_STRING:
 
1057
          if (p->value == NULL)
 
1058
            {
 
1059
              _asn1_error_description_value_not_found (p, ErrorDescription);
 
1060
              err = ASN1_VALUE_NOT_FOUND;
 
1061
              goto error;
 
1062
            }
 
1063
          len2 = asn1_get_length_der (p->value, p->value_len, &len3);
 
1064
          if (len2 < 0)
 
1065
            {
 
1066
              err = ASN1_DER_ERROR;
 
1067
              goto error;
 
1068
            }
 
1069
          max_len -= len2 + len3;
 
1070
          if (max_len >= 0)
 
1071
            memcpy (der + counter, p->value, len3 + len2);
 
1072
          counter += len3 + len2;
 
1073
          move = RIGHT;
 
1074
          break;
 
1075
        case TYPE_SEQUENCE:
 
1076
        case TYPE_SET:
 
1077
          if (move != UP)
 
1078
            {
 
1079
              _asn1_ltostr (counter, temp);
 
1080
              tlen = strlen (temp);
 
1081
              if (tlen > 0)
 
1082
                _asn1_set_value (p, temp, tlen + 1);
 
1083
              if (p->down == NULL)
 
1084
                {
 
1085
                  move = UP;
 
1086
                  continue;
 
1087
                }
 
1088
              else
 
1089
                {
 
1090
                  p2 = p->down;
 
1091
                  while (p2 && (type_field (p2->type) == TYPE_TAG))
 
1092
                    p2 = p2->right;
 
1093
                  if (p2)
 
1094
                    {
 
1095
                      p = p2;
 
1096
                      move = RIGHT;
 
1097
                      continue;
 
1098
                    }
 
1099
                  move = UP;
 
1100
                  continue;
 
1101
                }
 
1102
            }
 
1103
          else
 
1104
            {                   /* move==UP */
 
1105
              len2 = strtol (p->value, NULL, 10);
 
1106
              _asn1_set_value (p, NULL, 0);
 
1107
              if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
 
1108
                _asn1_ordering_set (der + len2, max_len - len2, p);
 
1109
              asn1_length_der (counter - len2, temp, &len3);
 
1110
              max_len -= len3;
 
1111
              if (max_len >= 0)
 
1112
                {
 
1113
                  memmove (der + len2 + len3, der + len2, counter - len2);
 
1114
                  memcpy (der + len2, temp, len3);
 
1115
                }
 
1116
              counter += len3;
 
1117
              move = RIGHT;
 
1118
            }
 
1119
          break;
 
1120
        case TYPE_SEQUENCE_OF:
 
1121
        case TYPE_SET_OF:
 
1122
          if (move != UP)
 
1123
            {
 
1124
              _asn1_ltostr (counter, temp);
 
1125
              tlen = strlen (temp);
 
1126
 
 
1127
              if (tlen > 0)
 
1128
                _asn1_set_value (p, temp, tlen + 1);
 
1129
              p = p->down;
 
1130
              while ((type_field (p->type) == TYPE_TAG)
 
1131
                     || (type_field (p->type) == TYPE_SIZE))
 
1132
                p = p->right;
 
1133
              if (p->right)
 
1134
                {
 
1135
                  p = p->right;
 
1136
                  move = RIGHT;
 
1137
                  continue;
 
1138
                }
 
1139
              else
 
1140
                p = _asn1_find_up (p);
 
1141
              move = UP;
 
1142
            }
 
1143
          if (move == UP)
 
1144
            {
 
1145
              len2 = strtol (p->value, NULL, 10);
 
1146
              _asn1_set_value (p, NULL, 0);
 
1147
              if ((type_field (p->type) == TYPE_SET_OF)
 
1148
                  && (max_len - len2 > 0))
 
1149
                {
 
1150
                  _asn1_ordering_set_of (der + len2, max_len - len2, p);
 
1151
                }
 
1152
              asn1_length_der (counter - len2, temp, &len3);
 
1153
              max_len -= len3;
 
1154
              if (max_len >= 0)
 
1155
                {
 
1156
                  memmove (der + len2 + len3, der + len2, counter - len2);
 
1157
                  memcpy (der + len2, temp, len3);
 
1158
                }
 
1159
              counter += len3;
 
1160
              move = RIGHT;
 
1161
            }
 
1162
          break;
 
1163
        case TYPE_ANY:
 
1164
          if (p->value == NULL)
 
1165
            {
 
1166
              _asn1_error_description_value_not_found (p, ErrorDescription);
 
1167
              err = ASN1_VALUE_NOT_FOUND;
 
1168
              goto error;
 
1169
            }
 
1170
          len2 = asn1_get_length_der (p->value, p->value_len, &len3);
 
1171
          if (len2 < 0)
 
1172
            {
 
1173
              err = ASN1_DER_ERROR;
 
1174
              goto error;
 
1175
            }
 
1176
          max_len -= len2;
 
1177
          if (max_len >= 0)
 
1178
            memcpy (der + counter, p->value + len3, len2);
 
1179
          counter += len2;
 
1180
          move = RIGHT;
 
1181
          break;
 
1182
        default:
 
1183
          move = (move == UP) ? RIGHT : DOWN;
 
1184
          break;
 
1185
        }
 
1186
 
 
1187
      if ((move != DOWN) && (counter != counter_old))
 
1188
        {
 
1189
          err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
 
1190
          if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
 
1191
            goto error;
 
1192
        }
 
1193
 
 
1194
      if (p == node && move != DOWN)
 
1195
        break;
 
1196
 
 
1197
      if (move == DOWN)
 
1198
        {
 
1199
          if (p->down)
 
1200
            p = p->down;
 
1201
          else
 
1202
            move = RIGHT;
 
1203
        }
 
1204
      if (move == RIGHT)
 
1205
        {
 
1206
          if (p->right)
 
1207
            p = p->right;
 
1208
          else
 
1209
            move = UP;
 
1210
        }
 
1211
      if (move == UP)
 
1212
        p = _asn1_find_up (p);
 
1213
    }
 
1214
 
 
1215
  *len = counter;
 
1216
 
 
1217
  if (max_len < 0)
 
1218
    {
 
1219
      err = ASN1_MEM_ERROR;
 
1220
      goto error;
 
1221
    }
 
1222
 
 
1223
  err = ASN1_SUCCESS;
 
1224
 
 
1225
error:
 
1226
  asn1_delete_structure (&node);
 
1227
  return err;
 
1228
}