Coverage Report

Created: 2024-02-29 06:05

/src/strongswan/src/libstrongswan/asn1/asn1.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2006 Martin Will
3
 * Copyright (C) 2000-2016 Andreas Steffen
4
 *
5
 *
6
 * Copyright (C) secunet Security Networks AG
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU General Public License as published by the
10
 * Free Software Foundation; either version 2 of the License, or (at your
11
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
12
 *
13
 * This program is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
 * for more details.
17
 */
18
19
#include <stdio.h>
20
#include <string.h>
21
#include <time.h>
22
23
#include <utils/debug.h>
24
25
#include "oid.h"
26
#include "asn1.h"
27
#include "asn1_parser.h"
28
29
/**
30
 * Commonly used ASN1 values.
31
 */
32
const chunk_t ASN1_INTEGER_0 = chunk_from_chars(0x02, 0x01, 0x00);
33
const chunk_t ASN1_INTEGER_1 = chunk_from_chars(0x02, 0x01, 0x01);
34
const chunk_t ASN1_INTEGER_2 = chunk_from_chars(0x02, 0x01, 0x02);
35
36
/*
37
 * Described in header
38
 */
39
chunk_t asn1_algorithmIdentifier_params(int oid, chunk_t params)
40
0
{
41
0
  return asn1_wrap(ASN1_SEQUENCE, "mm", asn1_build_known_oid(oid), params);
42
0
}
43
44
/*
45
 * Described in header
46
 */
47
chunk_t asn1_algorithmIdentifier(int oid)
48
0
{
49
0
  chunk_t parameters;
50
51
  /* some algorithmIdentifiers have a NULL parameters field and some do not */
52
0
  switch (oid)
53
0
  {
54
0
    case OID_ECDSA_WITH_SHA1:
55
0
    case OID_ECDSA_WITH_SHA224:
56
0
    case OID_ECDSA_WITH_SHA256:
57
0
    case OID_ECDSA_WITH_SHA384:
58
0
    case OID_ECDSA_WITH_SHA512:
59
0
    case OID_ED25519:
60
0
    case OID_ED448:
61
0
      parameters = chunk_empty;
62
0
      break;
63
0
    default:
64
0
      parameters = asn1_simple_object(ASN1_NULL, chunk_empty);
65
0
      break;
66
0
  }
67
0
  return asn1_algorithmIdentifier_params(oid, parameters);
68
0
}
69
70
/*
71
 * Defined in header.
72
 */
73
int asn1_known_oid(chunk_t object)
74
27.9k
{
75
27.9k
  int oid = 0;
76
77
415k
  while (object.len)
78
415k
  {
79
415k
    if (oid_names[oid].octet == *object.ptr)
80
96.5k
    {
81
96.5k
      if (--object.len == 0 || oid_names[oid].down == 0)
82
25.0k
      {
83
25.0k
        return oid;     /* found terminal symbol */
84
25.0k
      }
85
71.4k
      else
86
71.4k
      {
87
71.4k
        object.ptr++; oid++; /* advance to next hex octet */
88
71.4k
      }
89
96.5k
    }
90
319k
    else
91
319k
    {
92
319k
      if (oid_names[oid].next)
93
316k
      {
94
316k
        oid = oid_names[oid].next;
95
316k
      }
96
2.80k
      else
97
2.80k
      {
98
2.80k
        return OID_UNKNOWN;
99
2.80k
      }
100
319k
    }
101
415k
  }
102
59
  return OID_UNKNOWN;
103
27.9k
}
104
105
/*
106
 * Defined in header.
107
 */
108
chunk_t asn1_build_known_oid(int n)
109
0
{
110
0
  chunk_t oid;
111
0
  int i;
112
113
0
  if (n < 0 || n >= OID_MAX)
114
0
  {
115
0
    return chunk_empty;
116
0
  }
117
118
0
  i = oid_names[n].level + 1;
119
0
  oid = chunk_alloc(2 + i);
120
0
  oid.ptr[0] = ASN1_OID;
121
0
  oid.ptr[1] = i;
122
123
0
  do
124
0
  {
125
0
    if (oid_names[n].level >= i)
126
0
    {
127
0
      n--;
128
0
      continue;
129
0
    }
130
0
    oid.ptr[--i + 2] = oid_names[n--].octet;
131
0
  }
132
0
  while (i > 0);
133
134
0
  return oid;
135
0
}
136
137
/**
138
 * Returns the number of bytes required to encode the given OID node
139
 */
140
static int bytes_required(u_int val)
141
0
{
142
0
  int shift, required = 1;
143
144
  /* sufficient to handle 32 bit node numbers */
145
0
  for (shift = 28; shift; shift -= 7)
146
0
  {
147
0
    if (val >> shift)
148
0
    { /* do not encode leading zeroes */
149
0
      required++;
150
0
    }
151
0
  }
152
0
  return required;
153
0
}
154
155
/*
156
 * Defined in header.
157
 */
158
chunk_t asn1_oid_from_string(char *str)
159
0
{
160
0
  enumerator_t *enumerator;
161
0
  size_t buf_len = 64;
162
0
  u_char buf[buf_len];
163
0
  char *end;
164
0
  int i = 0, pos = 0, req, shift;
165
0
  u_int val, first = 0;
166
167
0
  enumerator = enumerator_create_token(str, ".", "");
168
0
  while (enumerator->enumerate(enumerator, &str))
169
0
  {
170
0
    val = strtoul(str, &end, 10);
171
0
    req = bytes_required(val);
172
0
    if (end == str || pos + req > buf_len)
173
0
    {
174
0
      pos = 0;
175
0
      break;
176
0
    }
177
0
    switch (i++)
178
0
    {
179
0
      case 0:
180
0
        first = val;
181
0
        break;
182
0
      case 1:
183
0
        buf[pos++] = first * 40 + val;
184
0
        break;
185
0
      default:
186
0
        for (shift = (req - 1) * 7; shift; shift -= 7)
187
0
        {
188
0
          buf[pos++] = 0x80 | ((val >> shift) & 0x7F);
189
0
        }
190
0
        buf[pos++] = val & 0x7F;
191
0
    }
192
0
  }
193
0
  enumerator->destroy(enumerator);
194
195
0
  return chunk_clone(chunk_create(buf, pos));
196
0
}
197
198
/*
199
 * Defined in header.
200
 */
201
char *asn1_oid_to_string(chunk_t oid)
202
1.44k
{
203
1.44k
  size_t len = 64;
204
1.44k
  char buf[len], *pos = buf;
205
1.44k
  int written;
206
1.44k
  u_int val;
207
208
1.44k
  if (!oid.len)
209
30
  {
210
30
    return NULL;
211
30
  }
212
1.41k
  val = oid.ptr[0] / 40;
213
1.41k
  written = snprintf(buf, len, "%u.%u", val, oid.ptr[0] - val * 40);
214
1.41k
  oid = chunk_skip(oid, 1);
215
1.41k
  if (written < 0 || written >= len)
216
0
  {
217
0
    return NULL;
218
0
  }
219
1.41k
  pos += written;
220
1.41k
  len -= written;
221
1.41k
  val = 0;
222
223
7.54k
  while (oid.len)
224
6.19k
  {
225
6.19k
    val = (val << 7) + (u_int)(oid.ptr[0] & 0x7f);
226
227
6.19k
    if (oid.ptr[0] < 128)
228
4.23k
    {
229
4.23k
      written = snprintf(pos, len, ".%u", val);
230
4.23k
      if (written < 0 || written >= len)
231
67
      {
232
67
        return NULL;
233
67
      }
234
4.17k
      pos += written;
235
4.17k
      len -= written;
236
4.17k
      val = 0;
237
4.17k
    }
238
6.13k
    oid = chunk_skip(oid, 1);
239
6.13k
  }
240
1.34k
  return (val == 0) ? strdup(buf) : NULL;
241
1.41k
}
242
243
/*
244
 * Defined in header.
245
 */
246
size_t asn1_length(chunk_t *blob)
247
196k
{
248
196k
  u_char n;
249
196k
  size_t len;
250
251
196k
  if (blob->len < 2)
252
83
  {
253
83
    DBG2(DBG_ASN, "insufficient number of octets to parse ASN.1 length");
254
83
    return ASN1_INVALID_LENGTH;
255
83
  }
256
257
  /* read length field, skip tag and length */
258
196k
  n = blob->ptr[1];
259
196k
  blob->ptr += 2;
260
196k
  blob->len -= 2;
261
262
196k
  if ((n & 0x80) == 0)
263
191k
  { /* single length octet */
264
191k
    if (n > blob->len)
265
421
    {
266
421
      DBG2(DBG_ASN, "length is larger than remaining blob size");
267
421
      return ASN1_INVALID_LENGTH;
268
421
    }
269
191k
    return n;
270
191k
  }
271
272
  /* composite length, determine number of length octets */
273
4.27k
  n &= 0x7f;
274
275
4.27k
  if (n == 0 || n > blob->len)
276
292
  {
277
292
    DBG2(DBG_ASN, "number of length octets invalid");
278
292
    return ASN1_INVALID_LENGTH;
279
292
  }
280
281
3.98k
  if (n > sizeof(len))
282
122
  {
283
122
    DBG2(DBG_ASN, "number of length octets is larger than limit of"
284
122
       " %d octets", (int)sizeof(len));
285
122
    return ASN1_INVALID_LENGTH;
286
122
  }
287
288
3.86k
  len = 0;
289
290
11.3k
  while (n-- > 0)
291
7.51k
  {
292
7.51k
    len = 256*len + *blob->ptr++;
293
7.51k
    blob->len--;
294
7.51k
  }
295
3.86k
  if (len > blob->len)
296
307
  {
297
307
    DBG2(DBG_ASN, "length is larger than remaining blob size");
298
307
    return ASN1_INVALID_LENGTH;
299
307
  }
300
3.55k
  return len;
301
3.86k
}
302
303
/*
304
 * See header.
305
 */
306
int asn1_unwrap(chunk_t *blob, chunk_t *inner)
307
4.27k
{
308
4.27k
  chunk_t res;
309
4.27k
  u_char len;
310
4.27k
  int type;
311
312
4.27k
  if (blob->len < 2)
313
7
  {
314
7
    return ASN1_INVALID;
315
7
  }
316
4.26k
  type = blob->ptr[0];
317
4.26k
  len = blob->ptr[1];
318
4.26k
  *blob = chunk_skip(*blob, 2);
319
320
4.26k
  if ((len & 0x80) == 0)
321
3.92k
  { /* single length octet */
322
3.92k
    res.len = len;
323
3.92k
  }
324
345
  else
325
345
  { /* composite length, determine number of length octets */
326
345
    len &= 0x7f;
327
345
    if (len == 0 || len > blob->len || len > sizeof(res.len))
328
43
    {
329
43
      return ASN1_INVALID;
330
43
    }
331
302
    res.len = 0;
332
1.84k
    while (len-- > 0)
333
1.53k
    {
334
1.53k
      res.len = 256 * res.len + blob->ptr[0];
335
1.53k
      *blob = chunk_skip(*blob, 1);
336
1.53k
    }
337
302
  }
338
4.22k
  if (res.len > blob->len)
339
195
  {
340
195
    return ASN1_INVALID;
341
195
  }
342
4.02k
  res.ptr = blob->ptr;
343
4.02k
  *blob = chunk_skip(*blob, res.len);
344
  /* updating inner not before we are finished allows a caller to pass
345
   * blob = inner */
346
4.02k
  *inner = res;
347
4.02k
  return type;
348
4.22k
}
349
350
static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
351
static const int tm_leap_1970 = 477;
352
353
/**
354
 * Converts ASN.1 UTCTIME or GENERALIZEDTIME into calendar time
355
 */
356
time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
357
61.3k
{
358
61.3k
  int tm_year, tm_mon, tm_day, tm_hour, tm_min, tm_sec;
359
61.3k
  int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
360
61.3k
  int tz_hour, tz_min, tz_offset;
361
61.3k
  time_t tm_days, tm_secs;
362
61.3k
  char buf[BUF_LEN], *eot = NULL;
363
364
61.3k
  snprintf(buf, sizeof(buf), "%.*s", (int)utctime->len, utctime->ptr);
365
366
61.3k
  if ((eot = strchr(buf, 'Z')) != NULL)
367
58.3k
  {
368
58.3k
    tz_offset = 0; /* Zulu time with a zero time zone offset */
369
58.3k
  }
370
3.00k
  else if ((eot = strchr(buf, '+')) != NULL)
371
578
  {
372
578
    if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
373
222
    {
374
222
      return 0; /* error in positive timezone offset format */
375
222
    }
376
356
    tz_offset = 3600*tz_hour + 60*tz_min;  /* positive time zone offset */
377
356
  }
378
2.42k
  else if ((eot = strchr(buf, '-')) != NULL)
379
832
  {
380
832
    if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2)
381
290
    {
382
290
      return 0; /* error in negative timezone offset format */
383
290
    }
384
542
    tz_offset = -3600*tz_hour - 60*tz_min;  /* negative time zone offset */
385
542
  }
386
1.59k
  else
387
1.59k
  {
388
1.59k
    return 0; /* error in time format */
389
1.59k
  }
390
391
  /* parse ASN.1 time string */
392
59.2k
  {
393
59.2k
    const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d":
394
59.2k
                           "%4d%2d%2d%2d%2d";
395
396
59.2k
    if (sscanf(buf, format, &tm_year, &tm_mon, &tm_day,
397
59.2k
                &tm_hour, &tm_min) != 5)
398
1.84k
    {
399
1.84k
      return 0; /* error in [yy]yymmddhhmm time format */
400
1.84k
    }
401
59.2k
  }
402
403
  /* is there a seconds field? */
404
57.4k
  if ((eot - buf) == ((type == ASN1_UTCTIME)?12:14))
405
56.3k
  {
406
56.3k
    if (sscanf(eot-2, "%2d", &tm_sec) != 1)
407
382
    {
408
382
      return 0; /* error in ss seconds field format */
409
382
    }
410
56.3k
  }
411
1.10k
  else
412
1.10k
  {
413
1.10k
    tm_sec = 0;
414
1.10k
  }
415
416
  /* representation of two-digit years */
417
57.0k
  if (type == ASN1_UTCTIME)
418
56.2k
  {
419
56.2k
    tm_year += (tm_year < 50) ? 2000 : 1900;
420
56.2k
  }
421
422
  /* prevent obvious 32 bit integer overflows */
423
57.0k
  if (sizeof(time_t) == 4 && (tm_year > 2038 || tm_year < 1901))
424
0
  {
425
0
    return TIME_32_BIT_SIGNED_MAX;
426
0
  }
427
428
  /* representation of months as 0..11*/
429
57.0k
  if (tm_mon < 1 || tm_mon > 12)
430
790
  {
431
790
    return 0;
432
790
  }
433
56.2k
  tm_mon--;
434
435
  /* representation of days as 0..30 */
436
56.2k
  if (tm_day < 1 || tm_day > 31)
437
862
  { /* we don't actually validate the day in relation to tm_year/tm_mon */
438
862
    return 0;
439
862
  }
440
55.3k
  tm_day--;
441
442
55.3k
  if (tm_hour < 0 || tm_hour > 23 ||
443
55.3k
    tm_min < 0 || tm_min > 59 ||
444
55.3k
    tm_sec < 0 || tm_sec > 60 /* allow leap seconds */)
445
1.30k
  {
446
1.30k
    return 0;
447
1.30k
  }
448
449
  /* number of leap years between last year and 1970? */
450
54.0k
  tm_leap_4 = (tm_year - 1) / 4;
451
54.0k
  tm_leap_100 = tm_leap_4 / 25;
452
54.0k
  tm_leap_400 = tm_leap_100 / 4;
453
54.0k
  tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970;
454
455
  /* if date later then February, is the current year a leap year? */
456
54.0k
  if (tm_mon > 1 && (tm_year % 4 == 0) &&
457
54.0k
    (tm_year % 100 != 0 || tm_year % 400 == 0))
458
10.7k
  {
459
10.7k
    tm_leap++;
460
10.7k
  }
461
54.0k
  tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
462
54.0k
  tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec - tz_offset;
463
464
54.0k
  if (sizeof(time_t) == 4)
465
0
  { /* has a 32 bit signed integer overflow occurred? */
466
0
    if (tm_year > 1970 && tm_secs < 0)
467
0
    { /* depending on the time zone, the first days in 1970 may result in
468
       * a negative value, but dates after 1970 never will */
469
0
      return TIME_32_BIT_SIGNED_MAX;
470
0
    }
471
0
    if (tm_year < 1969 && tm_secs > 0)
472
0
    { /* similarly, tm_secs is not positive for dates before 1970, except
473
       * for the last days in 1969, depending on the time zone */
474
0
      return TIME_32_BIT_SIGNED_MAX;
475
0
    }
476
0
  }
477
54.0k
  return tm_secs;
478
54.0k
}
479
480
/**
481
 *  Convert a date into ASN.1 UTCTIME or GENERALIZEDTIME format
482
 */
483
chunk_t asn1_from_time(const time_t *time, asn1_t type)
484
0
{
485
0
  int offset;
486
0
  const char *format;
487
0
  char buf[BUF_LEN];
488
0
  chunk_t formatted_time;
489
0
  struct tm t = {};
490
491
0
  gmtime_r(time, &t);
492
  /* RFC 5280 says that dates through the year 2049 MUST be encoded as UTCTIME
493
   * and dates in 2050 or later MUST be encoded as GENERALIZEDTIME. We only
494
   * enforce the latter to avoid overflows but allow callers to force the
495
   * encoding to GENERALIZEDTIME */
496
0
  type = (t.tm_year >= 150) ? ASN1_GENERALIZEDTIME : type;
497
0
  if (type == ASN1_GENERALIZEDTIME)
498
0
  {
499
0
    format = "%04d%02d%02d%02d%02d%02dZ";
500
0
    offset = 1900;
501
0
  }
502
0
  else /* ASN1_UTCTIME */
503
0
  {
504
0
    format = "%02d%02d%02d%02d%02d%02dZ";
505
0
    offset = (t.tm_year < 100) ? 0 : -100;
506
0
  }
507
0
  snprintf(buf, BUF_LEN, format, t.tm_year + offset,
508
0
       t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
509
0
  formatted_time.ptr = buf;
510
0
  formatted_time.len = strlen(buf);
511
0
  return asn1_simple_object(type, formatted_time);
512
0
}
513
514
/*
515
 * Defined in header.
516
 */
517
void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
518
90.5k
{
519
90.5k
  int oid;
520
521
90.5k
  switch (type)
522
90.5k
  {
523
13.9k
    case ASN1_OID:
524
13.9k
      oid = asn1_known_oid(object);
525
13.9k
      if (oid == OID_UNKNOWN)
526
1.44k
      {
527
1.44k
        char *oid_str = asn1_oid_to_string(object);
528
529
1.44k
        if (!oid_str)
530
491
        {
531
491
          break;
532
491
        }
533
954
        DBG2(DBG_ASN, "  %s", oid_str);
534
954
        free(oid_str);
535
954
      }
536
12.5k
      else
537
12.5k
      {
538
12.5k
        DBG2(DBG_ASN, "  '%s'", oid_names[oid].name);
539
12.5k
      }
540
13.5k
      return;
541
13.5k
    case ASN1_UTF8STRING:
542
0
    case ASN1_IA5STRING:
543
0
    case ASN1_PRINTABLESTRING:
544
0
    case ASN1_T61STRING:
545
0
    case ASN1_VISIBLESTRING:
546
0
      DBG2(DBG_ASN, "  '%.*s'", (int)object.len, object.ptr);
547
0
      return;
548
30.0k
    case ASN1_UTCTIME:
549
30.6k
    case ASN1_GENERALIZEDTIME:
550
30.6k
      {
551
30.6k
#if DEBUG_LEVEL >= 2
552
30.6k
        time_t time = asn1_to_time(&object, type);
553
30.6k
        DBG2(DBG_ASN, "  '%T'", &time, TRUE);
554
30.6k
#endif
555
30.6k
      }
556
30.6k
      return;
557
45.8k
    default:
558
45.8k
      break;
559
90.5k
  }
560
46.3k
  if (private)
561
0
  {
562
0
    DBG4(DBG_ASN, "%B", &object);
563
0
  }
564
46.3k
  else
565
46.3k
  {
566
46.3k
    DBG3(DBG_ASN, "%B", &object);
567
46.3k
  }
568
46.3k
}
569
570
/**
571
 * parse an ASN.1 simple type
572
 */
573
bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const char* name)
574
75
{
575
75
  size_t len;
576
577
  /* an ASN.1 object must possess at least a tag and length field */
578
75
  if (object->len < 2)
579
2
  {
580
2
    DBG2(DBG_ASN, "L%d - %s:  ASN.1 object smaller than 2 octets", level,
581
2
       name);
582
2
    return FALSE;
583
2
  }
584
585
73
  if (*object->ptr != type)
586
12
  {
587
12
    DBG2(DBG_ASN, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
588
12
       level, name, type, *object->ptr);
589
12
    return FALSE;
590
12
  }
591
592
61
  len = asn1_length(object);
593
594
61
  if (len == ASN1_INVALID_LENGTH)
595
2
  {
596
2
    DBG2(DBG_ASN, "L%d - %s:  length of ASN.1 object invalid or too large",
597
2
       level, name);
598
2
    return FALSE;
599
2
  }
600
601
59
  DBG2(DBG_ASN, "L%d - %s:", level, name);
602
59
  asn1_debug_simple_object(*object, type, FALSE);
603
59
  return TRUE;
604
61
}
605
606
/*
607
 * Described in header
608
 */
609
uint64_t asn1_parse_integer_uint64(chunk_t blob)
610
234
{
611
234
  uint64_t val = 0;
612
234
  int i;
613
614
5.95k
  for (i = 0; i < blob.len; i++)
615
5.71k
  { /* if it is longer than 8 bytes, we just use the 8 LSBs */
616
5.71k
    val <<= 8;
617
5.71k
    val |= (uint64_t)blob.ptr[i];
618
5.71k
  }
619
234
  return val;
620
234
}
621
622
/*
623
 * Described in header
624
 */
625
chunk_t asn1_integer_from_uint64(uint64_t val)
626
0
{
627
0
  u_char buf[sizeof(val)];
628
0
  chunk_t enc = chunk_empty;
629
630
0
  if (val < 0x100)
631
0
  {
632
0
    buf[0] = (u_char)val;
633
0
    return chunk_clone(chunk_create(buf, 1));
634
0
  }
635
0
  for (enc.ptr = buf + sizeof(val); val; enc.len++, val >>= 8)
636
0
  { /* fill the buffer from the end */
637
0
    *(--enc.ptr) = val & 0xff;
638
0
  }
639
0
  return chunk_clone(enc);
640
0
}
641
642
/*
643
 * Described in header
644
 */
645
int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters)
646
2.21k
{
647
2.21k
  chunk_t object;
648
2.21k
  int alg = OID_UNKNOWN;
649
650
2.21k
  if (asn1_unwrap(&blob, &blob) == ASN1_SEQUENCE)
651
2.05k
  {
652
2.05k
    if (level0 >= 0)
653
2.05k
    {
654
2.05k
      DBG2(DBG_ASN, "L%d - algorithmIdentifier:", level0);
655
2.05k
    }
656
657
2.05k
    if (asn1_unwrap(&blob, &object) == ASN1_OID)
658
1.85k
    {
659
1.85k
      if (level0 >= 0)
660
1.85k
      {
661
1.85k
        DBG2(DBG_ASN, "L%d - algorithm:", level0+1);
662
1.85k
        asn1_debug_simple_object(object, ASN1_OID, FALSE);
663
1.85k
      }
664
1.85k
      alg = asn1_known_oid(object);
665
666
1.85k
      if (blob.len)
667
1.38k
      {
668
1.38k
        if (level0 >= 0)
669
1.38k
        {
670
1.38k
          DBG2(DBG_ASN, "L%d - parameters:", level0+1);
671
1.38k
          DBG3(DBG_ASN, "%B", &blob);
672
1.38k
        }
673
1.38k
        if (parameters)
674
1.23k
        {
675
1.23k
          *parameters = blob;
676
1.23k
        }
677
1.38k
      }
678
1.85k
    }
679
2.05k
  }
680
2.21k
  return alg;
681
2.21k
}
682
683
/*
684
 *  tests if a blob contains a valid ASN.1 set or sequence
685
 */
686
bool is_asn1(chunk_t blob)
687
3.89k
{
688
3.89k
  u_int len;
689
3.89k
  u_char tag;
690
691
3.89k
  if (!blob.len || !blob.ptr)
692
0
  {
693
0
    return FALSE;
694
0
  }
695
696
3.89k
  tag = *blob.ptr;
697
3.89k
  if (tag != ASN1_SEQUENCE && tag != ASN1_SET && tag != ASN1_OCTET_STRING)
698
1.94k
  {
699
1.94k
    DBG2(DBG_ASN, "  file content is not binary ASN.1");
700
1.94k
    return FALSE;
701
1.94k
  }
702
703
1.95k
  len = asn1_length(&blob);
704
705
1.95k
  if (len == ASN1_INVALID_LENGTH)
706
177
  {
707
177
    return FALSE;
708
177
  }
709
710
  /* exact match */
711
1.77k
  if (len == blob.len)
712
1.66k
  {
713
1.66k
    return TRUE;
714
1.66k
  }
715
716
  /* some websites append a surplus newline character to the blob */
717
117
  if (len + 1 == blob.len && *(blob.ptr + len) == '\n')
718
11
  {
719
11
    return TRUE;
720
11
  }
721
722
106
  DBG2(DBG_ASN, "  file size does not match ASN.1 coded length");
723
106
  return FALSE;
724
117
}
725
726
/*
727
 * Defined in header.
728
 */
729
bool asn1_is_printablestring(chunk_t str)
730
0
{
731
0
  const char printablestring_charset[] =
732
0
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '()+,-./:=?";
733
0
  u_int i;
734
735
0
  for (i = 0; i < str.len; i++)
736
0
  {
737
0
    if (strchr(printablestring_charset, str.ptr[i]) == NULL)
738
0
    {
739
0
      return FALSE;
740
0
    }
741
0
  }
742
0
  return TRUE;
743
0
}
744
745
/**
746
 * codes ASN.1 lengths up to a size of 16'777'215 bytes
747
 */
748
static void asn1_code_length(size_t length, chunk_t *code)
749
0
{
750
0
  if (length < 128)
751
0
  {
752
0
    code->ptr[0] = length;
753
0
    code->len = 1;
754
0
  }
755
0
  else if (length < 256)
756
0
  {
757
0
    code->ptr[0] = 0x81;
758
0
    code->ptr[1] = (u_char) length;
759
0
    code->len = 2;
760
0
  }
761
0
  else if (length < 65536)
762
0
  {
763
0
    code->ptr[0] = 0x82;
764
0
    code->ptr[1] = length >> 8;
765
0
    code->ptr[2] = length & 0x00ff;
766
0
    code->len = 3;
767
0
  }
768
0
  else
769
0
  {
770
0
    code->ptr[0] = 0x83;
771
0
    code->ptr[1] = length >> 16;
772
0
    code->ptr[2] = (length >> 8) & 0x00ff;
773
0
    code->ptr[3] = length & 0x0000ff;
774
0
    code->len = 4;
775
0
  }
776
0
}
777
778
/**
779
 * build an empty asn.1 object with tag and length fields already filled in
780
 */
781
u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen)
782
0
{
783
0
  u_char length_buf[4];
784
0
  chunk_t length = { length_buf, 0 };
785
0
  u_char *pos;
786
787
  /* code the asn.1 length field */
788
0
  asn1_code_length(datalen, &length);
789
790
  /* allocate memory for the asn.1 TLV object */
791
0
  object->len = 1 + length.len + datalen;
792
0
  object->ptr = malloc(object->len);
793
794
  /* set position pointer at the start of the object */
795
0
  pos = object->ptr;
796
797
  /* copy the asn.1 tag field and advance the pointer */
798
0
  *pos++ = type;
799
800
  /* copy the asn.1 length field and advance the pointer */
801
0
  memcpy(pos, length.ptr, length.len);
802
0
  pos += length.len;
803
804
0
  return pos;
805
0
}
806
807
/**
808
 * Build a simple ASN.1 object
809
 */
810
chunk_t asn1_simple_object(asn1_t tag, chunk_t content)
811
0
{
812
0
  chunk_t object;
813
814
0
  u_char *pos = asn1_build_object(&object, tag, content.len);
815
0
  memcpy(pos, content.ptr, content.len);
816
817
0
  return object;
818
0
}
819
820
/**
821
 * Build an ASN.1 BIT_STRING object
822
 */
823
chunk_t asn1_bitstring(const char *mode, chunk_t content)
824
0
{
825
0
  chunk_t object;
826
0
  u_char *pos = asn1_build_object(&object, ASN1_BIT_STRING, 1 + content.len);
827
828
0
  *pos++ = 0x00;
829
0
  memcpy(pos, content.ptr, content.len);
830
0
  if (*mode == 'm')
831
0
  {
832
0
    free(content.ptr);
833
0
  }
834
0
  return object;
835
0
}
836
837
/**
838
 * Build an ASN.1 INTEGER object
839
 */
840
chunk_t asn1_integer(const char *mode, chunk_t content)
841
0
{
842
0
  chunk_t zero = chunk_from_chars(0x00), object;
843
0
  size_t len;
844
0
  u_char *pos;
845
0
  bool move;
846
847
0
  if (content.len == 0)
848
0
  { /* make sure 0 is encoded properly */
849
0
    content = zero;
850
0
    move = FALSE;
851
0
  }
852
0
  else
853
0
  {
854
0
    move = (*mode == 'm');
855
0
  }
856
857
  /* ASN.1 integers must be positive numbers in two's complement */
858
0
  len = content.len + ((*content.ptr & 0x80) ? 1 : 0);
859
0
  pos = asn1_build_object(&object, ASN1_INTEGER, len);
860
0
  if (len > content.len)
861
0
  {
862
0
    *pos++ = 0x00;
863
0
  }
864
0
  memcpy(pos, content.ptr, content.len);
865
866
0
  if (move)
867
0
  {
868
0
    free(content.ptr);
869
0
  }
870
0
  return object;
871
0
}
872
873
/**
874
 * Build an ASN.1 object from a variable number of individual chunks.
875
 * Depending on the mode, chunks either are moved ('m') or copied ('c').
876
 */
877
chunk_t asn1_wrap(asn1_t type, const char *mode, ...)
878
0
{
879
0
  chunk_t construct;
880
0
  va_list chunks;
881
0
  u_char *pos;
882
0
  int i;
883
0
  int count = strlen(mode);
884
885
  /* sum up lengths of individual chunks */
886
0
  va_start(chunks, mode);
887
0
  construct.len = 0;
888
0
  for (i = 0; i < count; i++)
889
0
  {
890
0
    chunk_t ch = va_arg(chunks, chunk_t);
891
0
    construct.len += ch.len;
892
0
  }
893
0
  va_end(chunks);
894
895
  /* allocate needed memory for construct */
896
0
  pos = asn1_build_object(&construct, type, construct.len);
897
898
  /* copy or move the chunks */
899
0
  va_start(chunks, mode);
900
0
  for (i = 0; i < count; i++)
901
0
  {
902
0
    chunk_t ch = va_arg(chunks, chunk_t);
903
904
0
    memcpy(pos, ch.ptr, ch.len);
905
0
    pos += ch.len;
906
907
0
    switch (*mode++)
908
0
    {
909
0
      case 's':
910
0
        chunk_clear(&ch);
911
0
        break;
912
0
      case 'm':
913
0
        free(ch.ptr);
914
0
        break;
915
0
      default:
916
0
        break;
917
0
    }
918
0
  }
919
0
  va_end(chunks);
920
921
0
  return construct;
922
0
}
923
924
/**
925
 * ASN.1 definition of time
926
 */
927
static const asn1Object_t timeObjects[] = {
928
  { 0, "utcTime",     ASN1_UTCTIME,     ASN1_OPT|ASN1_BODY  }, /* 0 */
929
  { 0, "end opt",     ASN1_EOC,       ASN1_END      }, /* 1 */
930
  { 0, "generalizeTime",  ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY  }, /* 2 */
931
  { 0, "end opt",     ASN1_EOC,       ASN1_END      }, /* 3 */
932
  { 0, "exit",      ASN1_EOC,       ASN1_EXIT     }
933
};
934
#ifdef TIME_UTC
935
/* used by C11 timespec_get(), <time.h> */
936
# undef TIME_UTC
937
#endif
938
220k
#define TIME_UTC      0
939
64.8k
#define TIME_GENERALIZED  2
940
941
/**
942
 * extracts and converts a UTCTIME or GENERALIZEDTIME object
943
 */
944
time_t asn1_parse_time(chunk_t blob, int level0)
945
32.1k
{
946
32.1k
  asn1_parser_t *parser;
947
32.1k
  chunk_t object;
948
32.1k
  int objectID;
949
32.1k
  time_t utc_time = 0;
950
951
32.1k
  parser= asn1_parser_create(timeObjects, blob);
952
32.1k
  parser->set_top_level(parser, level0);
953
954
127k
  while (parser->iterate(parser, &objectID, &object))
955
94.9k
  {
956
94.9k
    if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
957
30.6k
    {
958
30.6k
      utc_time = asn1_to_time(&object, (objectID == TIME_UTC)
959
30.6k
                  ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
960
30.6k
    }
961
94.9k
  }
962
32.1k
  parser->destroy(parser);
963
32.1k
  return utc_time;
964
32.1k
}