Coverage Report

Created: 2025-07-11 06:59

/src/opensc/src/libopensc/asn1.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * asn1.c: ASN.1 decoding functions (DER)
3
 *
4
 * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#ifdef HAVE_CONFIG_H
22
#include "config.h"
23
#endif
24
25
#include <assert.h>
26
#include <ctype.h>
27
#include <stddef.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
#include <limits.h>
32
33
#include "internal.h"
34
#include "asn1.h"
35
36
static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
37
           const u8 *in, size_t len, const u8 **newp, size_t *len_left,
38
           int choice, int depth);
39
static int asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
40
           u8 **ptr, size_t *size, int depth);
41
static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
42
    const u8 * data, size_t datalen, u8 ** out, size_t * outlen);
43
44
static const char *tag2str(unsigned int tag)
45
75.6k
{
46
75.6k
  static const char *tags[] = {
47
75.6k
    "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",  /* 0-4 */
48
75.6k
    "NULL", "OBJECT IDENTIFIER", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
49
75.6k
    "ENUMERATED", "Universal 11", "UTF8String", "Universal 13", /* 10-13 */
50
75.6k
    "Universal 14", "Universal 15", "SEQUENCE", "SET",  /* 15-17 */
51
75.6k
    "NumericString", "PrintableString", "T61String",  /* 18-20 */
52
75.6k
    "VideotexString", "IA5String", "UTCTIME", "GENERALIZEDTIME",  /* 21-24 */
53
75.6k
    "GraphicString", "VisibleString", "GeneralString",  /* 25-27 */
54
75.6k
    "UniversalString", "Universal 29", "BMPString"  /* 28-30 */
55
75.6k
  };
56
57
75.6k
  if (tag > 30)
58
5.72k
    return "(unknown)";
59
69.9k
  return tags[tag];
60
75.6k
}
61
62
int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
63
         unsigned int *tag_out, size_t *taglen)
64
3.51M
{
65
3.51M
  const u8 *p = *buf;
66
3.51M
  size_t left = buflen, len;
67
3.51M
  unsigned int cla, tag, i;
68
69
3.51M
  *buf = NULL;
70
71
3.51M
  if (left == 0 || !p || buflen == 0)
72
39.4k
    return SC_ERROR_INVALID_ASN1_OBJECT;
73
3.47M
  if (*p == 0xff || *p == 0) {
74
    /* end of data reached */
75
218k
    *taglen = 0;
76
218k
    *tag_out = SC_ASN1_TAG_EOC;
77
218k
    return SC_SUCCESS;
78
218k
  }
79
80
  /* parse tag byte(s)
81
   * Resulted tag is presented by integer that has not to be
82
   * confused with the 'tag number' part of ASN.1 tag.
83
   */
84
3.25M
  cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
85
3.25M
  tag = *p & SC_ASN1_TAG_PRIMITIVE;
86
3.25M
  if (left < 1)
87
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
88
3.25M
  p++;
89
3.25M
  left--;
90
3.25M
  if (tag == SC_ASN1_TAG_PRIMITIVE) {
91
    /* high tag number */
92
80.1k
    size_t n = SC_ASN1_TAGNUM_SIZE - 1;
93
    /* search the last tag octet */
94
96.6k
    do {
95
96.6k
      if (left == 0 || n == 0)
96
        /* either an invalid tag or it doesn't fit in
97
         * unsigned int */
98
5.34k
        return SC_ERROR_INVALID_ASN1_OBJECT;
99
91.3k
      tag <<= 8;
100
91.3k
      tag |= *p;
101
91.3k
      p++;
102
91.3k
      left--;
103
91.3k
      n--;
104
91.3k
    } while (tag & 0x80);
105
80.1k
  }
106
107
  /* parse length byte(s) */
108
3.25M
  if (left == 0)
109
48.2k
    return SC_ERROR_INVALID_ASN1_OBJECT;
110
3.20M
  len = *p;
111
3.20M
  p++;
112
3.20M
  left--;
113
3.20M
  if (len & 0x80) {
114
1.21M
    len &= 0x7f;
115
1.21M
    unsigned int a = 0;
116
1.21M
    if (len > sizeof a || len > left)
117
84.7k
      return SC_ERROR_INVALID_ASN1_OBJECT;
118
1.24M
    for (i = 0; i < len; i++) {
119
113k
      a <<= 8;
120
113k
      a |= *p;
121
113k
      p++;
122
113k
      left--;
123
113k
    }
124
1.13M
    len = a;
125
1.13M
  }
126
127
3.11M
  *cla_out = cla;
128
3.11M
  *tag_out = tag;
129
3.11M
  *taglen = len;
130
3.11M
  *buf = p;
131
132
3.11M
  if (len > left)
133
195k
    return SC_ERROR_ASN1_END_OF_CONTENTS;
134
135
2.92M
  return SC_SUCCESS;
136
3.11M
}
137
138
void sc_format_asn1_entry(struct sc_asn1_entry *entry, void *parm, void *arg,
139
        int set_present)
140
2.98M
{
141
2.98M
  entry->parm = parm;
142
2.98M
  entry->arg  = arg;
143
2.98M
  if (set_present)
144
549k
    entry->flags |= SC_ASN1_PRESENT;
145
2.98M
}
146
147
void sc_copy_asn1_entry(const struct sc_asn1_entry *src,
148
      struct sc_asn1_entry *dest)
149
1.02M
{
150
4.28M
  while (src->name != NULL) {
151
3.26M
    *dest = *src;
152
3.26M
    dest++;
153
3.26M
    src++;
154
3.26M
  }
155
1.02M
  dest->name = NULL;
156
1.02M
}
157
158
static void print_indent(size_t depth)
159
626k
{
160
2.37M
  for (; depth > 0; depth--) {
161
1.75M
    putchar(' ');
162
1.75M
  }
163
626k
}
164
165
static void print_hex(const u8 * buf, size_t buflen, size_t depth)
166
23.1k
{
167
23.1k
  size_t lines_len = buflen * 5 + 128;
168
23.1k
  char *lines = malloc(lines_len);
169
23.1k
  char *line = lines;
170
171
23.1k
  if (buf == NULL || buflen == 0 || lines == NULL) {
172
2.75k
    free(lines);
173
2.75k
    return;
174
2.75k
  }
175
176
20.3k
  sc_hex_dump(buf, buflen, lines, lines_len);
177
178
549k
  while (*line != '\0') {
179
529k
    char *line_end = strchr(line, '\n');
180
529k
    ptrdiff_t width = line_end - line;
181
529k
    if (!line_end || width <= 1) {
182
      /* don't print empty lines */
183
0
      break;
184
0
    }
185
529k
    if (buflen > 8) {
186
524k
      putchar('\n');
187
524k
      print_indent(depth);
188
524k
    } else {
189
4.66k
      printf(": ");
190
4.66k
    }
191
529k
    printf("%.*s", (int) width, line);
192
529k
    line = line_end + 1;
193
529k
  }
194
195
20.3k
  free(lines);
196
20.3k
}
197
198
static void print_ascii(const u8 * buf, size_t buflen)
199
47.2k
{
200
2.14M
  for (; 0 < buflen; buflen--, buf++) {
201
2.09M
    if (isprint(*buf))
202
1.03M
      printf("%c", *buf);
203
1.06M
    else
204
1.06M
      putchar('.');
205
2.09M
  }
206
47.2k
}
207
208
static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen, size_t depth)
209
1.08k
{
210
1.08k
  print_hex(buf, buflen, depth);
211
1.08k
}
212
213
static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen)
214
10.3k
{
215
  /* FIXME UTF-8 is not ASCII */
216
10.3k
  print_ascii(buf, buflen);
217
10.3k
}
218
219
static void sc_asn1_print_integer(const u8 * buf, size_t buflen)
220
10.7k
{
221
10.7k
  size_t a = 0;
222
223
10.7k
  if (buflen > sizeof(a)) {
224
8.15k
    printf("0x%s", sc_dump_hex(buf, buflen));
225
8.15k
  } else {
226
2.62k
    size_t i;
227
8.44k
    for (i = 0; i < buflen; i++) {
228
5.82k
      a <<= 8;
229
5.82k
      a |= buf[i];
230
5.82k
    }
231
2.62k
    printf("%"SC_FORMAT_LEN_SIZE_T"u", a);
232
2.62k
  }
233
10.7k
}
234
235
static void sc_asn1_print_boolean(const u8 * buf, size_t buflen)
236
7.96k
{
237
7.96k
  if (!buflen)
238
731
    return;
239
240
7.22k
  if (buf[0])
241
6.93k
    printf("true");
242
295
  else
243
295
    printf("false");
244
7.22k
}
245
246
static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen, size_t depth)
247
12.1k
{
248
12.1k
#ifndef _WIN32
249
12.1k
  long long a = 0;
250
#else
251
  __int64 a = 0;
252
#endif
253
12.1k
  int r, i;
254
255
12.1k
  if (buflen > sizeof(a) + 1) {
256
1.19k
    print_hex(buf, buflen, depth);
257
10.9k
  } else {
258
10.9k
    r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 1);
259
10.9k
    if (r < 0) {
260
6.45k
      printf("decode error, ");
261
      /* try again without the strict mode */
262
6.45k
      r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 0);
263
6.45k
      if (r < 0) {
264
4.74k
        printf("even for lax decoding");
265
4.74k
        return ;
266
4.74k
      }
267
6.45k
    }
268
96.5k
    for (i = r - 1; i >= 0; i--) {
269
90.3k
      printf("%c", ((a >> i) & 1) ? '1' : '0');
270
90.3k
    }
271
6.18k
  }
272
12.1k
}
273
274
#ifdef ENABLE_OPENSSL
275
#include <openssl/objects.h>
276
277
static void openssl_print_object_sn(const char *s)
278
8.32k
{
279
8.32k
  ASN1_OBJECT *obj = OBJ_txt2obj(s, 0);
280
8.32k
  if (obj) {
281
8.32k
    int nid = OBJ_obj2nid(obj);
282
8.32k
    if (nid != NID_undef) {
283
939
      printf(", %s", OBJ_nid2sn(nid));
284
939
    }
285
8.32k
    ASN1_OBJECT_free(obj);
286
8.32k
  }
287
8.32k
}
288
#else
289
static void openssl_print_object_sn(const char *s)
290
{
291
}
292
#endif
293
294
static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
295
12.0k
{
296
12.0k
  struct sc_object_id oid;
297
12.0k
  const char *sbuf;
298
299
12.0k
  if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
300
3.68k
    printf("decode error");
301
3.68k
    return;
302
3.68k
  }
303
304
8.32k
  sbuf = sc_dump_oid(&oid);
305
8.32k
  printf(" %s", sbuf);
306
8.32k
  openssl_print_object_sn(sbuf);
307
8.32k
}
308
309
static void sc_asn1_print_utctime(const u8 * buf, size_t buflen)
310
11.3k
{
311
11.3k
  if (buflen < 8) {
312
3.60k
    printf("Error in decoding.\n");
313
3.60k
    return;
314
3.60k
  }
315
316
7.77k
  print_ascii(buf, 2);    /* YY */
317
7.77k
  putchar('-');
318
7.77k
  print_ascii(buf+2, 2);    /* MM */
319
7.77k
  putchar('-');
320
7.77k
  print_ascii(buf+4, 2);    /* DD */
321
7.77k
  putchar(' ');
322
7.77k
  print_ascii(buf+6, 2);    /* hh */
323
7.77k
  buf += 8;
324
7.77k
  buflen -= 8;
325
7.77k
  if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
326
1.38k
    putchar(':');
327
1.38k
    print_ascii(buf, 2);  /* mm */
328
1.38k
    buf += 2;
329
1.38k
    buflen -= 2;
330
1.38k
  }
331
7.77k
  if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
332
611
    putchar(':');
333
611
    print_ascii(buf, 2);  /* ss */
334
611
    buf += 2;
335
611
    buflen -= 2;
336
611
  }
337
7.77k
  if (buflen >= 4 && '.' == buf[0]) {
338
450
    print_ascii(buf, 4);  /* fff */
339
450
    buf += 4;
340
450
    buflen -= 4;
341
450
  }
342
343
7.77k
  if (buflen >= 1 && 'Z' == buf[0]) {
344
685
    printf(" UTC");
345
7.09k
  } else if (buflen >= 5 && ('-' == buf[0] || '+' == buf[0])) {
346
1.05k
    putchar(' ');
347
1.05k
    print_ascii(buf, 3);  /* +/-hh */
348
1.05k
    putchar(':');
349
1.05k
    print_ascii(buf+3, 2);  /* mm */
350
1.05k
  }
351
7.77k
}
352
353
static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen)
354
1.44k
{
355
1.44k
  if (buflen < 8) {
356
228
    printf("Error in decoding.\n");
357
228
    return;
358
228
  }
359
360
1.21k
  print_ascii(buf, 2);
361
1.21k
  sc_asn1_print_utctime(buf + 2, buflen - 2);
362
1.21k
}
363
364
static void print_tags_recursive(const u8 * buf0, const u8 * buf,
365
         size_t buflen, size_t depth)
366
21.8k
{
367
21.8k
  int r;
368
21.8k
  size_t i;
369
21.8k
  size_t bytesleft = buflen;
370
21.8k
  const char *classes[4] = {
371
21.8k
    "Universal",
372
21.8k
    "Application",
373
21.8k
    "Context",
374
21.8k
    "Private"
375
21.8k
  };
376
21.8k
  const u8 *p = buf;
377
378
123k
  while (bytesleft >= 2) {
379
116k
    unsigned int cla = 0, tag = 0;
380
116k
    size_t hlen;
381
116k
    const u8 *tagp = p;
382
116k
    size_t len;
383
384
116k
    r = sc_asn1_read_tag(&tagp, bytesleft, &cla, &tag, &len);
385
116k
    if (r != SC_SUCCESS || (tagp == NULL && tag != SC_ASN1_TAG_EOC)) {
386
13.4k
      printf("Error in decoding.\n");
387
13.4k
      return;
388
13.4k
    }
389
103k
    hlen = tagp - p;
390
103k
    if (cla == 0 && tag == 0) {
391
1.11k
      printf("Zero tag, finishing\n");
392
1.11k
      break;
393
1.11k
    }
394
101k
    print_indent(depth);
395
    /* let i be the length of the tag in bytes */
396
111k
    for (i = 1; i < sizeof tag - 1; i++) {
397
108k
      if (!(tag >> 8*i))
398
99.0k
        break;
399
108k
    }
400
101k
    printf("%02X", cla<<(i-1)*8 | tag);
401
402
101k
    if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) {
403
75.6k
      printf(" %s", tag2str(tag));
404
75.6k
    } else {
405
26.2k
      printf(" %s %-2u",
406
26.2k
          classes[cla >> 6],
407
26.2k
          i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i-1)*8));
408
26.2k
    }
409
101k
    if (!((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL
410
101k
          && tag == SC_ASN1_TAG_NULL && len == 0)) {
411
100k
      printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)",
412
100k
          len,
413
100k
          len != 1 ? "s" : "");
414
100k
    }
415
416
101k
    if (len + hlen > bytesleft) {
417
0
      printf(" Illegal length!\n");
418
0
      return;
419
0
    }
420
101k
    p += hlen + len;
421
101k
    bytesleft -= hlen + len;
422
423
101k
    if (cla & SC_ASN1_TAG_CONSTRUCTED) {
424
20.5k
      putchar('\n');
425
20.5k
      print_tags_recursive(buf0, tagp, len, depth + 2*i + 1);
426
20.5k
      continue;
427
20.5k
    }
428
429
81.3k
    switch (tag) {
430
12.1k
      case SC_ASN1_TAG_BIT_STRING:
431
12.1k
        printf(": ");
432
12.1k
        sc_asn1_print_bit_string(tagp, len, depth + 2*i + 1);
433
12.1k
        break;
434
1.08k
      case SC_ASN1_TAG_OCTET_STRING:
435
1.08k
        sc_asn1_print_octet_string(tagp, len, depth + 2*i + 1);
436
1.08k
        break;
437
12.0k
      case SC_ASN1_TAG_OBJECT:
438
12.0k
        printf(": ");
439
12.0k
        sc_asn1_print_object_id(tagp, len);
440
12.0k
        break;
441
9.24k
      case SC_ASN1_TAG_INTEGER:
442
10.7k
      case SC_ASN1_TAG_ENUMERATED:
443
10.7k
        printf(": ");
444
10.7k
        sc_asn1_print_integer(tagp, len);
445
10.7k
        break;
446
219
      case SC_ASN1_TAG_IA5STRING:
447
779
      case SC_ASN1_TAG_PRINTABLESTRING:
448
1.04k
      case SC_ASN1_TAG_T61STRING:
449
10.3k
      case SC_ASN1_TAG_UTF8STRING:
450
10.3k
        printf(": ");
451
10.3k
        sc_asn1_print_utf8string(tagp, len);
452
10.3k
        break;
453
7.96k
      case SC_ASN1_TAG_BOOLEAN:
454
7.96k
        printf(": ");
455
7.96k
        sc_asn1_print_boolean(tagp, len);
456
7.96k
        break;
457
1.44k
      case SC_ASN1_GENERALIZEDTIME:
458
1.44k
        printf(": ");
459
1.44k
        sc_asn1_print_generalizedtime(tagp, len);
460
1.44k
        break;
461
10.1k
      case SC_ASN1_UTCTIME:
462
10.1k
        printf(": ");
463
10.1k
        sc_asn1_print_utctime(tagp, len);
464
10.1k
        break;
465
81.3k
    }
466
467
81.3k
    if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) {
468
15.4k
      print_hex(tagp, len, depth + 2*i + 1);
469
15.4k
    }
470
471
81.3k
    if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) {
472
5.41k
      print_hex(tagp, len, depth + 2*i + 1);
473
5.41k
    }
474
475
81.3k
    putchar('\n');
476
81.3k
  }
477
21.8k
}
478
479
void sc_asn1_print_tags(const u8 * buf, size_t buflen)
480
1.30k
{
481
1.30k
  print_tags_recursive(buf, buf, buflen, 0);
482
1.30k
}
483
484
const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf,
485
  size_t buflen, unsigned int tag_in, size_t *taglen_in)
486
244k
{
487
244k
  size_t left = buflen, taglen;
488
244k
  const u8 *p = buf;
489
490
244k
  *taglen_in = 0;
491
570k
  while (left >= 2) {
492
524k
    unsigned int cla = 0, tag, mask = 0xff00;
493
494
524k
    buf = p;
495
    /* read a tag */
496
524k
    if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
497
524k
        || p == NULL)
498
79.0k
      return NULL;
499
500
445k
    left -= (p - buf);
501
    /* we need to shift the class byte to the leftmost
502
     * byte of the tag */
503
454k
    while ((tag & mask) != 0) {
504
8.39k
      cla  <<= 8;
505
8.39k
      mask <<= 8;
506
8.39k
    }
507
    /* compare the read tag with the given tag */
508
445k
    if ((tag | cla) == tag_in) {
509
      /* we have a match => return length and value part */
510
120k
      if (taglen > left)
511
0
        return NULL;
512
120k
      *taglen_in = taglen;
513
120k
      return p;
514
120k
    }
515
    /* otherwise continue reading tags */
516
325k
    left -= taglen;
517
325k
    p += taglen;
518
325k
  }
519
45.2k
  return NULL;
520
244k
}
521
522
const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen,
523
         unsigned int tag_in, size_t *taglen_out)
524
608k
{
525
608k
  const u8 *p = *buf;
526
608k
  size_t len = *buflen, taglen;
527
608k
  unsigned int cla = 0, tag;
528
529
608k
  if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS
530
608k
      || p == NULL)
531
164k
    return NULL;
532
444k
  switch (cla & 0xC0) {
533
238k
  case SC_ASN1_TAG_UNIVERSAL:
534
238k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_UNI)
535
30.8k
      return NULL;
536
207k
    break;
537
207k
  case SC_ASN1_TAG_APPLICATION:
538
63.3k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_APP)
539
19.3k
      return NULL;
540
43.9k
    break;
541
133k
  case SC_ASN1_TAG_CONTEXT:
542
133k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_CTX)
543
17.4k
      return NULL;
544
115k
    break;
545
115k
  case SC_ASN1_TAG_PRIVATE:
546
9.10k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_PRV)
547
9.10k
      return NULL;
548
0
    break;
549
444k
  }
550
367k
  if (cla & SC_ASN1_TAG_CONSTRUCTED) {
551
195k
    if ((tag_in & SC_ASN1_CONS) == 0)
552
17.6k
      return NULL;
553
195k
  } else
554
172k
    if (tag_in & SC_ASN1_CONS)
555
11.5k
      return NULL;
556
338k
  if ((tag_in & SC_ASN1_TAG_MASK) != tag)
557
99.3k
    return NULL;
558
239k
  len -= (p - *buf);  /* header size */
559
239k
  if (taglen > len) {
560
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1,
561
0
       "too long ASN.1 object (size %"SC_FORMAT_LEN_SIZE_T"u while only %"SC_FORMAT_LEN_SIZE_T"u available)\n",
562
0
       taglen, len);
563
0
    return NULL;
564
0
  }
565
239k
  *buflen -= (p - *buf) + taglen;
566
239k
  *buf = p + taglen;  /* point to next tag */
567
239k
  *taglen_out = taglen;
568
239k
  return p;
569
239k
}
570
571
const u8 *sc_asn1_verify_tag(sc_context_t *ctx, const u8 * buf, size_t buflen,
572
           unsigned int tag_in, size_t *taglen_out)
573
8.02k
{
574
8.02k
  return sc_asn1_skip_tag(ctx, &buf, &buflen, tag_in, taglen_out);
575
8.02k
}
576
577
static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf,
578
           size_t outlen, int invert, const int strict)
579
28.3k
{
580
28.3k
  const u8 *in = inbuf;
581
28.3k
  u8 *out = (u8 *) outbuf;
582
28.3k
  int i, count = 0;
583
28.3k
  int zero_bits;
584
28.3k
  size_t octets_left;
585
586
28.3k
  if (inlen < 1)
587
1.43k
    return SC_ERROR_INVALID_ASN1_OBJECT;
588
589
  /* The formatting is only enforced by SHALL keyword so we should accept
590
   * by default also non-strict values. */
591
26.9k
  if (strict) {
592
    /* 8.6.2.3 If the bitstring is empty, there shall be no
593
     * subsequent octets,and the initial octet shall be zero. */
594
10.2k
    if (inlen == 1 && *in != 0)
595
3.05k
      return SC_ERROR_INVALID_ASN1_OBJECT;
596
    /* ITU-T Rec. X.690 8.6.2.2: The number shall be in the range zero to seven. */
597
7.18k
    if ((*in & ~0x07) != 0)
598
1.49k
      return SC_ERROR_INVALID_ASN1_OBJECT;
599
7.18k
  }
600
601
22.3k
  memset(outbuf, 0, outlen);
602
22.3k
  zero_bits = *in & 0x07;
603
22.3k
  in++;
604
22.3k
  octets_left = inlen - 1;
605
22.3k
  if (outlen < octets_left)
606
48
    return SC_ERROR_BUFFER_TOO_SMALL;
607
608
386k
  while (octets_left) {
609
    /* 1st octet of input:  ABCDEFGH, where A is the MSB */
610
    /* 1st octet of output: HGFEDCBA, where A is the LSB */
611
    /* first bit in bit string is the LSB in first resulting octet */
612
367k
    int bits_to_go;
613
614
367k
    *out = 0;
615
367k
    if (octets_left == 1 && zero_bits > 0) {
616
11.8k
      bits_to_go = 8 - zero_bits;
617
      /* Verify the padding is zero bits */
618
11.8k
      if (*in & (1 << (zero_bits-1))) {
619
2.59k
        return SC_ERROR_INVALID_ASN1_OBJECT;
620
2.59k
      }
621
11.8k
    } else
622
355k
      bits_to_go = 8;
623
364k
    if (invert)
624
193k
      for (i = 0; i < bits_to_go; i++) {
625
169k
        *out |= ((*in >> (7 - i)) & 1) << i;
626
169k
      }
627
339k
    else {
628
339k
      *out = *in;
629
339k
    }
630
364k
    out++;
631
364k
    in++;
632
364k
    octets_left--;
633
364k
    count++;
634
364k
  }
635
19.7k
  return (count * 8) - zero_bits;
636
22.3k
}
637
638
int sc_asn1_decode_bit_string(const u8 * inbuf, size_t inlen,
639
            void *outbuf, size_t outlen, const int strict)
640
17.3k
{
641
17.3k
  return decode_bit_string(inbuf, inlen, outbuf, outlen, 1, strict);
642
17.3k
}
643
644
int sc_asn1_decode_bit_string_ni(const u8 * inbuf, size_t inlen,
645
         void *outbuf, size_t outlen, const int strict)
646
0
{
647
0
  return decode_bit_string(inbuf, inlen, outbuf, outlen, 0, strict);
648
0
}
649
650
static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
651
           size_t *outlen, int invert)
652
18.4k
{
653
18.4k
  const u8 *in = inbuf;
654
18.4k
  u8 *out;
655
18.4k
  size_t bytes, skipped = 0;
656
657
18.4k
  bytes = BYTES4BITS(bits_left) + 1;
658
18.4k
  *outbuf = out = malloc(bytes);
659
18.4k
  if (out == NULL)
660
0
    return SC_ERROR_OUT_OF_MEMORY;
661
18.4k
  *outlen = bytes;
662
18.4k
  out += 1;
663
201k
  while (bits_left) {
664
183k
    size_t i, bits_to_go = 8;
665
666
183k
    *out = 0;
667
183k
    if (bits_left < 8) {
668
14.5k
      bits_to_go = bits_left;
669
14.5k
      skipped = 8 - bits_left;
670
14.5k
    }
671
183k
    if (invert) {
672
73.5k
      for (i = 0; i < bits_to_go; i++)
673
57.1k
        *out |= ((*in >> i) & 1) << (7 - i);
674
167k
    } else {
675
167k
      *out = *in;
676
167k
      if (bits_left < 8)
677
0
        return SC_ERROR_NOT_SUPPORTED; /* FIXME */
678
167k
    }
679
183k
    bits_left -= bits_to_go;
680
183k
    out++, in++;
681
183k
  }
682
18.4k
  out = *outbuf;
683
18.4k
  out[0] = skipped;
684
18.4k
  return 0;
685
18.4k
}
686
687
/*
688
 * Bitfields are just bit strings, stored in an unsigned int
689
 * (taking endianness into account)
690
 */
691
static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t outlen, const int strict)
692
6.04k
{
693
6.04k
  u8    data[sizeof(unsigned int)];
694
6.04k
  unsigned int  field = 0;
695
6.04k
  int   i, n;
696
697
6.04k
  if (outlen != sizeof(data))
698
0
    return SC_ERROR_BUFFER_TOO_SMALL;
699
700
6.04k
  n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1, strict);
701
6.04k
  if (n < 0)
702
297
    return n;
703
704
14.8k
  for (i = 0; i < n; i += 8) {
705
9.12k
    field |= ((unsigned int) data[i/8] << i);
706
9.12k
  }
707
5.74k
  memcpy(outbuf, &field, outlen);
708
5.74k
  return 0;
709
6.04k
}
710
711
static int encode_bit_field(const u8 *inbuf, size_t inlen,
712
          u8 **outbuf, size_t *outlen)
713
15.6k
{
714
15.6k
  u8    data[sizeof(unsigned int)];
715
15.6k
  unsigned int  field = 0;
716
15.6k
  size_t    i, bits;
717
718
15.6k
  if (inlen != sizeof(data))
719
0
    return SC_ERROR_BUFFER_TOO_SMALL;
720
721
  /* count the bits */
722
15.6k
  memcpy(&field, inbuf, inlen);
723
72.8k
  for (bits = 0; field; bits++)
724
57.1k
    field >>= 1;
725
726
15.6k
  memcpy(&field, inbuf, inlen);
727
32.0k
  for (i = 0; i < bits; i += 8)
728
16.3k
    data[i/8] = field >> i;
729
730
15.6k
  return encode_bit_string(data, bits, outbuf, outlen, 1);
731
15.6k
}
732
733
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out, int strict)
734
14.0k
{
735
14.0k
  int    a = 0, is_negative = 0;
736
14.0k
  size_t i = 0;
737
738
14.0k
  if (inlen == 0) {
739
78
    return SC_ERROR_INVALID_ASN1_OBJECT;
740
78
  }
741
14.0k
  if (inlen > sizeof(int)) {
742
100
    return SC_ERROR_NOT_SUPPORTED;
743
100
  }
744
13.9k
  if (inbuf[0] & 0x80) {
745
4.09k
    if (strict && inlen > 1 && inbuf[0] == 0xff && (inbuf[1] & 0x80)) {
746
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
747
0
    }
748
4.09k
    is_negative = 1;
749
4.09k
    a |= 0xff^(*inbuf++);
750
4.09k
    i = 1;
751
9.81k
  } else {
752
9.81k
    if (strict && inlen > 1 && inbuf[0] == 0x00 && (inbuf[1] & 0x80) == 0) {
753
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
754
0
    }
755
9.81k
  }
756
31.0k
  for (; i < inlen; i++) {
757
17.1k
    if (a > (INT_MAX >> 8) || a < (INT_MIN + (1<<8))) {
758
0
      return SC_ERROR_NOT_SUPPORTED;
759
0
    }
760
17.1k
    a <<= 8;
761
17.1k
    if (is_negative) {
762
4.11k
      a |= 0xff^(*inbuf++);
763
13.0k
    } else {
764
13.0k
      a |= *inbuf++;
765
13.0k
    }
766
17.1k
  }
767
13.9k
  if (is_negative) {
768
    /* Calculate Two's complement from previously positive number */
769
4.09k
    a = (-1 * a) - 1;
770
4.09k
  }
771
13.9k
  *out = a;
772
13.9k
  return 0;
773
13.9k
}
774
775
static int asn1_encode_integer(int in, u8 ** obj, size_t * objsize)
776
36.0k
{
777
36.0k
  int i = sizeof(in) * 8, skip_zero, skip_sign;
778
36.0k
  u8 *p, b;
779
780
36.0k
  if (in < 0)
781
439
  {
782
439
    skip_sign = 1;
783
439
    skip_zero= 0;
784
439
  }
785
35.6k
  else
786
35.6k
  {
787
35.6k
    skip_sign = 0;
788
35.6k
    skip_zero= 1;
789
35.6k
  }
790
36.0k
  *obj = p = malloc(sizeof(in)+1);
791
36.0k
  if (*obj == NULL)
792
0
    return SC_ERROR_OUT_OF_MEMORY;
793
144k
  do {
794
144k
    i -= 8;
795
144k
    b = in >> i;
796
144k
    if (skip_sign)
797
1.60k
    {
798
1.60k
      if (b != 0xff)
799
243
        skip_sign = 0;
800
1.60k
      if (b & 0x80)
801
1.59k
      {
802
1.59k
        *p = b;
803
1.59k
        if (0xff == b)
804
1.36k
          continue;
805
1.59k
      }
806
16
      else
807
16
      {
808
16
        p++;
809
16
        skip_sign = 0;
810
16
      }
811
1.60k
    }
812
143k
    if (b == 0 && skip_zero)
813
107k
      continue;
814
35.8k
    if (skip_zero) {
815
25.3k
      skip_zero = 0;
816
      /* prepend 0x00 if MSb is 1 and integer positive */
817
25.3k
      if ((b & 0x80) != 0 && in > 0)
818
1.68k
        *p++ = 0;
819
25.3k
    }
820
35.8k
    *p++ = b;
821
144k
  } while (i > 0);
822
36.0k
  if (skip_sign)
823
196
    p++;
824
36.0k
  *objsize = p - *obj;
825
36.0k
  if (*objsize == 0) {
826
10.2k
    *objsize = 1;
827
10.2k
    (*obj)[0] = 0;
828
10.2k
  }
829
36.0k
  return 0;
830
36.0k
}
831
832
int
833
sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
834
64.9k
{
835
64.9k
  int large_second_octet = 0;
836
64.9k
  unsigned int a = 0;
837
64.9k
  const u8 *p = inbuf;
838
64.9k
  int *octet;
839
840
64.9k
  if (inlen == 0 || inbuf == NULL || id == NULL)
841
4.41k
    return SC_ERROR_INVALID_ARGUMENTS;
842
843
60.5k
  sc_init_oid(id);
844
60.5k
  octet = id->value;
845
846
  /* The first octet can be 0, 1 or 2 and is derived from the first byte */
847
60.5k
  a = MIN(*p / 40, 2);
848
60.5k
  *octet++ = a;
849
850
  /* The second octet fits here if the previous was 0 or 1 and second one is smaller than 40.
851
   * for the value 2 we can go up to 47. Otherwise the first bit needs to be set
852
   * and we continue reading further */
853
60.5k
  if ((*p & 0x80) == 0) {
854
49.4k
    *octet++ = *p - (a * 40);
855
49.4k
    inlen--;
856
49.4k
  } else {
857
11.0k
    large_second_octet = 1;
858
11.0k
  }
859
860
280k
  while (inlen) {
861
235k
    if (!large_second_octet)
862
224k
      p++;
863
    /* This signalizes empty most significant bits, which means
864
     * the unsigned integer encoding is not minimal */
865
235k
    if (*p == 0x80) {
866
5.04k
      sc_init_oid(id);
867
5.04k
      return SC_ERROR_INVALID_ASN1_OBJECT;
868
5.04k
    }
869
    /* Use unsigned type here so we can process the whole INT range.
870
     * Values can not be negative */
871
230k
    a = *p & 0x7F;
872
230k
    inlen--;
873
319k
    while (inlen && *p & 0x80) {
874
      /* Limit the OID values to int size and do not overflow */
875
91.5k
      if (a > (UINT_MAX>>7)) {
876
2.20k
        sc_init_oid(id);
877
2.20k
        return SC_ERROR_NOT_SUPPORTED;
878
2.20k
      }
879
89.3k
      p++;
880
89.3k
      a <<= 7;
881
89.3k
      a |= *p & 0x7F;
882
89.3k
      inlen--;
883
89.3k
    }
884
228k
    if (*p & 0x80) {
885
      /* We dropped out from previous cycle on the end of
886
       * data while still expecting continuation of value */
887
5.92k
      sc_init_oid(id);
888
5.92k
      return SC_ERROR_INVALID_ASN1_OBJECT;
889
5.92k
    }
890
222k
    if (large_second_octet) {
891
5.90k
      a -= (2 * 40);
892
5.90k
    }
893
222k
    if (a > INT_MAX) {
894
928
      sc_init_oid(id);
895
928
      return SC_ERROR_NOT_SUPPORTED;
896
928
    }
897
221k
    *octet++ = a;
898
221k
    if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS)   {
899
1.48k
      sc_init_oid(id);
900
1.48k
      return SC_ERROR_INVALID_ASN1_OBJECT;
901
1.48k
    }
902
219k
    large_second_octet = 0;
903
219k
  }
904
905
44.9k
  return 0;
906
60.5k
}
907
908
int
909
sc_asn1_encode_object_id(u8 **buf, size_t *buflen, const struct sc_object_id *id)
910
50.7k
{
911
50.7k
  u8 temp[SC_MAX_OBJECT_ID_OCTETS*5], *p = temp;
912
50.7k
  int i;
913
914
50.7k
  if (!buflen || !id)
915
0
    return SC_ERROR_INVALID_ARGUMENTS;
916
917
  /* an OID must have at least two components */
918
50.7k
  if (id->value[0] == -1 || id->value[1] == -1)
919
0
    return SC_ERROR_INVALID_ARGUMENTS;
920
921
408k
  for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
922
408k
    unsigned int k, shift;
923
924
408k
    if (id->value[i] == -1)
925
50.6k
      break;
926
927
357k
    k = id->value[i];
928
357k
    switch (i) {
929
50.7k
    case 0:
930
50.7k
      if (k > 2)
931
19
        return SC_ERROR_INVALID_ARGUMENTS;
932
50.7k
      *p = k * 40;
933
50.7k
      break;
934
50.7k
    case 1:
935
50.7k
      if (k > 39 && id->value[0] < 2) {
936
12
        return SC_ERROR_INVALID_ARGUMENTS;
937
12
      }
938
      /* We can encode larger IDs to multiple bytes
939
       * similarly as the following IDs */
940
50.7k
      k += *p;
941
      /* fall through */
942
306k
    default:
943
306k
      shift = 28;
944
1.46M
      while (shift && (k >> shift) == 0)
945
1.15M
        shift -= 7;
946
375k
      while (shift) {
947
68.2k
        *p++ = 0x80 | ((k >> shift) & 0x7f);
948
68.2k
        shift -= 7;
949
68.2k
      }
950
306k
      *p++ = k & 0x7F;
951
306k
      break;
952
357k
    }
953
357k
  }
954
955
50.7k
  *buflen = p - temp;
956
957
50.7k
  if (buf)   {
958
50.7k
    *buf = malloc(*buflen);
959
50.7k
    if (!*buf)
960
0
      return SC_ERROR_OUT_OF_MEMORY;
961
50.7k
    memcpy(*buf, temp, *buflen);
962
50.7k
  }
963
50.7k
  return 0;
964
50.7k
}
965
966
static int sc_asn1_decode_utf8string(const u8 *inbuf, size_t inlen,
967
            u8 *out, size_t *outlen)
968
5.60k
{
969
5.60k
  if (inlen+1 > *outlen)
970
7
    return SC_ERROR_BUFFER_TOO_SMALL;
971
5.59k
  *outlen = inlen+1;
972
5.59k
  memcpy(out, inbuf, inlen);
973
5.59k
  out[inlen] = 0;
974
5.59k
  return 0;
975
5.60k
}
976
977
/*
978
 * This assumes the tag is already encoded
979
 */
980
int sc_asn1_put_tag(unsigned int tag, const u8 * data, size_t datalen, u8 * out, size_t outlen, u8 **ptr)
981
106k
{
982
106k
  size_t c = 0;
983
106k
  unsigned int tag_len, ii;
984
106k
  u8 *p = out;
985
106k
  u8 tag_char[4] = {0, 0, 0, 0};
986
987
  /* Check tag */
988
106k
  if (tag == 0 || tag > 0xFFFFFFFF) {
989
    /* A tag of 0x00 is not valid and at most 4-byte tag names are supported. */
990
0
    return SC_ERROR_INVALID_DATA;
991
0
  }
992
212k
  for (tag_len = 0; tag; tag >>= 8) {
993
    /* Note: tag char will be reversed order. */
994
106k
    tag_char[tag_len++] = tag & 0xFF;
995
106k
  }
996
997
106k
  if (tag_len > 1)   {
998
0
    if ((tag_char[tag_len - 1] & SC_ASN1_TAG_PRIMITIVE) != SC_ASN1_TAG_ESCAPE_MARKER) {
999
      /* First byte is not escape marker. */
1000
0
      return SC_ERROR_INVALID_DATA;
1001
0
    }
1002
0
    for (ii = 1; ii < tag_len - 1; ii++) {
1003
0
      if ((tag_char[ii] & 0x80) != 0x80) {
1004
        /* MS bit is not 'one'. */
1005
0
        return SC_ERROR_INVALID_DATA;
1006
0
      }
1007
0
    }
1008
0
    if ((tag_char[0] & 0x80) != 0x00) {
1009
      /* MS bit of the last byte is not 'zero'. */
1010
0
      return SC_ERROR_INVALID_DATA;
1011
0
    }
1012
0
  }
1013
1014
  /* Calculate the number of additional bytes necessary to encode the length. */
1015
  /* c+1 is the size of the length field. */
1016
106k
  if (datalen > 127) {
1017
919
    c = 1;
1018
1.48k
    while (datalen >> (c << 3))
1019
568
      c++;
1020
919
  }
1021
106k
  if (outlen == 0 || out == NULL) {
1022
    /* Caller only asks for the length that would be written. */
1023
5.37k
    return (int)(tag_len + (c + 1) + datalen);
1024
5.37k
  }
1025
  /* We will write the tag, so check the length. */
1026
100k
  if (outlen < tag_len + (c+1) + datalen)
1027
44
    return SC_ERROR_BUFFER_TOO_SMALL;
1028
201k
  for (ii=0;ii<tag_len;ii++)
1029
100k
    *p++ = tag_char[tag_len - ii - 1];
1030
1031
100k
  if (c > 0) {
1032
545
    *p++ = 0x80 | c;
1033
1.41k
    while (c--)
1034
872
      *p++ = (datalen >> (c << 3)) & 0xFF;
1035
545
  }
1036
100k
  else {
1037
100k
    *p++ = datalen & 0x7F;
1038
100k
  }
1039
100k
  if(data && datalen > 0) {
1040
94.5k
    memcpy(p, data, datalen);
1041
94.5k
    p += datalen;
1042
94.5k
  }
1043
100k
  if (ptr != NULL)
1044
100k
    *ptr = p;
1045
100k
  return 0;
1046
100k
}
1047
1048
int sc_asn1_write_element(sc_context_t *ctx, unsigned int tag,
1049
  const u8 * data, size_t datalen, u8 ** out, size_t * outlen)
1050
0
{
1051
0
  return asn1_write_element(ctx, tag, data, datalen, out, outlen);
1052
0
}
1053
1054
static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
1055
  const u8 * data, size_t datalen, u8 ** out, size_t * outlen)
1056
391k
{
1057
391k
  unsigned char t;
1058
391k
  unsigned char *buf, *p;
1059
391k
  int c = 0;
1060
391k
  unsigned short_tag;
1061
391k
  unsigned char tag_char[3] = {0, 0, 0};
1062
391k
  size_t tag_len, ii;
1063
1064
391k
  short_tag = tag & SC_ASN1_TAG_MASK;
1065
776k
  for (tag_len = 0; short_tag >> (8 * tag_len); tag_len++)
1066
384k
    tag_char[tag_len] = (short_tag >> (8 * tag_len)) & 0xFF;
1067
391k
  if (!tag_len)
1068
10.7k
    tag_len = 1;
1069
1070
391k
  if (tag_len > 1)   {
1071
3.37k
    if ((tag_char[tag_len - 1] & SC_ASN1_TAG_PRIMITIVE) != SC_ASN1_TAG_ESCAPE_MARKER)
1072
0
      SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "First byte of the long tag is not 'escape marker'");
1073
1074
3.37k
    for (ii = 1; ii < tag_len - 1; ii++)
1075
0
      if (!(tag_char[ii] & 0x80))
1076
0
        SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "MS bit expected to be 'one'");
1077
1078
3.37k
    if (tag_char[0] & 0x80)
1079
0
      SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "MS bit of the last byte expected to be 'zero'");
1080
3.37k
  }
1081
1082
391k
  t = tag_char[tag_len - 1] & 0x1F;
1083
1084
391k
  switch (tag & SC_ASN1_CLASS_MASK) {
1085
290k
  case SC_ASN1_UNI:
1086
290k
    break;
1087
63.4k
  case SC_ASN1_APP:
1088
63.4k
    t |= SC_ASN1_TAG_APPLICATION;
1089
63.4k
    break;
1090
37.8k
  case SC_ASN1_CTX:
1091
37.8k
    t |= SC_ASN1_TAG_CONTEXT;
1092
37.8k
    break;
1093
0
  case SC_ASN1_PRV:
1094
0
    t |= SC_ASN1_TAG_PRIVATE;
1095
0
    break;
1096
391k
  }
1097
391k
  if (tag & SC_ASN1_CONS)
1098
140k
    t |= SC_ASN1_TAG_CONSTRUCTED;
1099
391k
  if (datalen > 127) {
1100
5.99k
    c = 1;
1101
8.05k
    while (datalen >> (c << 3))
1102
2.05k
      c++;
1103
5.99k
  }
1104
1105
391k
  *outlen = tag_len + 1 + c + datalen;
1106
391k
  buf = malloc(*outlen);
1107
391k
  if (buf == NULL)
1108
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1109
1110
391k
  *out = p = buf;
1111
391k
  *p++ = t;
1112
395k
  for (ii=1;ii<tag_len;ii++)
1113
3.37k
    *p++ = tag_char[tag_len - ii - 1];
1114
1115
391k
  if (c) {
1116
5.99k
    *p++ = 0x80 | c;
1117
14.0k
    while (c--)
1118
8.05k
      *p++ = (datalen >> (c << 3)) & 0xFF;
1119
5.99k
  }
1120
385k
  else   {
1121
385k
    *p++ = datalen & 0x7F;
1122
385k
  }
1123
391k
  if (datalen && data) {
1124
388k
    memcpy(p, data, datalen);
1125
388k
  }
1126
1127
391k
  return SC_SUCCESS;
1128
391k
}
1129
1130
static const struct sc_asn1_entry c_asn1_path_ext[3] = {
1131
  { "aid",  SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x0F, 0, NULL, NULL },
1132
  { "path", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
1133
  { NULL, 0, 0, 0, NULL, NULL }
1134
};
1135
static const struct sc_asn1_entry c_asn1_path[5] = {
1136
  { "path",   SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1137
  { "index",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
1138
  { "length", SC_ASN1_INTEGER, SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
1139
/* For some multi-applications PKCS#15 card the ODF records can hold the references to
1140
 * the xDF files and objects placed elsewhere then under the application DF of the ODF itself.
1141
 * In such a case the 'path' ASN1 data includes also the ID of the target application (AID).
1142
 * This path extension do not make a part of PKCS#15 standard.
1143
 */
1144
  { "pathExtended", SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1145
  { NULL, 0, 0, 0, NULL, NULL }
1146
};
1147
1148
static int asn1_decode_path(sc_context_t *ctx, const u8 *in, size_t len,
1149
          sc_path_t *path, int depth)
1150
15.4k
{
1151
15.4k
  int idx, count, r;
1152
15.4k
  struct sc_asn1_entry asn1_path_ext[3], asn1_path[5];
1153
15.4k
  unsigned char path_value[SC_MAX_PATH_SIZE], aid_value[SC_MAX_AID_SIZE];
1154
15.4k
  size_t path_len = sizeof(path_value), aid_len = sizeof(aid_value);
1155
1156
15.4k
  memset(path, 0, sizeof(struct sc_path));
1157
1158
15.4k
  sc_copy_asn1_entry(c_asn1_path_ext, asn1_path_ext);
1159
15.4k
  sc_copy_asn1_entry(c_asn1_path, asn1_path);
1160
1161
15.4k
  sc_format_asn1_entry(asn1_path_ext + 0, aid_value, &aid_len, 0);
1162
15.4k
  sc_format_asn1_entry(asn1_path_ext + 1, path_value, &path_len, 0);
1163
1164
15.4k
  sc_format_asn1_entry(asn1_path + 0, path_value, &path_len, 0);
1165
15.4k
  sc_format_asn1_entry(asn1_path + 1, &idx, NULL, 0);
1166
15.4k
  sc_format_asn1_entry(asn1_path + 2, &count, NULL, 0);
1167
15.4k
  sc_format_asn1_entry(asn1_path + 3, asn1_path_ext, NULL, 0);
1168
1169
15.4k
  r = asn1_decode(ctx, asn1_path, in, len, NULL, NULL, 0, depth + 1);
1170
15.4k
  if (r)
1171
168
    return r;
1172
1173
15.2k
  if (asn1_path[3].flags & SC_ASN1_PRESENT)   {
1174
    /* extended path present: set 'path' and 'aid' */
1175
0
    memcpy(path->aid.value, aid_value, aid_len);
1176
0
    path->aid.len = aid_len;
1177
1178
0
    memcpy(path->value, path_value, path_len);
1179
0
    path->len = path_len;
1180
0
  }
1181
15.2k
  else if (asn1_path[0].flags & SC_ASN1_PRESENT)   {
1182
    /* path present: set 'path' */
1183
14.6k
    memcpy(path->value, path_value, path_len);
1184
14.6k
    path->len = path_len;
1185
14.6k
  }
1186
643
  else   {
1187
    /* failed if both 'path' and 'pathExtended' are absent */
1188
643
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1189
643
  }
1190
1191
14.6k
  if (path->len == 2)
1192
2.25k
    path->type = SC_PATH_TYPE_FILE_ID;
1193
12.3k
  else   if (path->aid.len && path->len > 2)
1194
0
    path->type = SC_PATH_TYPE_FROM_CURRENT;
1195
12.3k
  else
1196
12.3k
    path->type = SC_PATH_TYPE_PATH;
1197
1198
14.6k
  if ((asn1_path[1].flags & SC_ASN1_PRESENT) && (asn1_path[2].flags & SC_ASN1_PRESENT)) {
1199
176
    path->index = idx;
1200
176
    path->count = count;
1201
176
  }
1202
14.4k
  else {
1203
14.4k
    path->index = 0;
1204
14.4k
    path->count = -1;
1205
14.4k
  }
1206
1207
14.6k
  return SC_SUCCESS;
1208
15.2k
}
1209
1210
static int asn1_encode_path(sc_context_t *ctx, const sc_path_t *path,
1211
          u8 **buf, size_t *bufsize, int depth, unsigned int parent_flags)
1212
25.3k
{
1213
25.3k
  int r;
1214
25.3k
  struct sc_asn1_entry asn1_path[5];
1215
25.3k
  sc_path_t tpath = *path;
1216
1217
25.3k
  sc_copy_asn1_entry(c_asn1_path, asn1_path);
1218
25.3k
  sc_format_asn1_entry(asn1_path + 0, (void *) &tpath.value, (void *) &tpath.len, 1);
1219
1220
25.3k
  asn1_path[0].flags |= parent_flags;
1221
25.3k
  if (path->count > 0) {
1222
5.29k
    sc_format_asn1_entry(asn1_path + 1, (void *) &tpath.index, NULL, 1);
1223
5.29k
    sc_format_asn1_entry(asn1_path + 2, (void *) &tpath.count, NULL, 1);
1224
5.29k
  }
1225
25.3k
  r = asn1_encode(ctx, asn1_path, buf, bufsize, depth + 1);
1226
25.3k
  return r;
1227
25.3k
}
1228
1229
1230
static const struct sc_asn1_entry c_asn1_se[2] = {
1231
  { "seInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1232
  { NULL, 0, 0, 0, NULL, NULL }
1233
};
1234
1235
static const struct sc_asn1_entry c_asn1_se_info[4] = {
1236
  { "se",   SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
1237
  { "owner",SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
1238
  { "aid",  SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1239
  { NULL, 0, 0, 0, NULL, NULL }
1240
};
1241
1242
static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
1243
             sc_pkcs15_sec_env_info_t ***se, size_t *num, int depth)
1244
122
{
1245
122
  struct sc_pkcs15_sec_env_info **ses;
1246
122
  const unsigned char *ptr = obj;
1247
122
  size_t idx, ptrlen = objlen;
1248
122
  int ret;
1249
1250
122
  LOG_FUNC_CALLED(ctx);
1251
1252
122
  ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
1253
122
  if (ses == NULL) {
1254
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1255
0
  }
1256
1257
189
  for (idx=0; idx < SC_MAX_SE_NUM && ptrlen; )   {
1258
97
    struct sc_asn1_entry asn1_se[2];
1259
97
    struct sc_asn1_entry asn1_se_info[4];
1260
97
    struct sc_pkcs15_sec_env_info si;
1261
1262
97
    sc_copy_asn1_entry(c_asn1_se, asn1_se);
1263
97
    sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1264
1265
97
    si.aid.len = sizeof(si.aid.value);
1266
97
    sc_format_asn1_entry(asn1_se_info + 0, &si.se, NULL, 0);
1267
97
    sc_format_asn1_entry(asn1_se_info + 1, &si.owner, NULL, 0);
1268
97
    sc_format_asn1_entry(asn1_se_info + 2, &si.aid.value, &si.aid.len, 0);
1269
97
    sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 0);
1270
1271
97
    ret = asn1_decode(ctx, asn1_se, ptr, ptrlen, &ptr, &ptrlen, 0, depth+1);
1272
97
    if (ret != SC_SUCCESS)
1273
30
      goto err;
1274
67
    if (!(asn1_se_info[1].flags & SC_ASN1_PRESENT))
1275
37
      sc_init_oid(&si.owner);
1276
1277
67
    ses[idx] = calloc(1, sizeof(sc_pkcs15_sec_env_info_t));
1278
67
    if (ses[idx] == NULL) {
1279
0
      ret = SC_ERROR_OUT_OF_MEMORY;
1280
0
      goto err;
1281
0
    }
1282
1283
67
    memcpy(ses[idx], &si, sizeof(struct sc_pkcs15_sec_env_info));
1284
67
    idx++;
1285
67
  }
1286
1287
92
  *se  = ses;
1288
92
  *num = idx;
1289
92
  ret = SC_SUCCESS;
1290
122
err:
1291
122
  if (ret != SC_SUCCESS) {
1292
30
    size_t i;
1293
52
    for (i = 0; i < idx; i++)
1294
22
      if (ses[i])
1295
22
        free(ses[i]);
1296
30
    free(ses);
1297
30
  }
1298
1299
122
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, ret);
1300
122
}
1301
1302
1303
static int asn1_encode_se_info(sc_context_t *ctx,
1304
    struct sc_pkcs15_sec_env_info **se, size_t se_num,
1305
    unsigned char **buf, size_t *bufsize, int depth)
1306
9
{
1307
9
  unsigned char *ptr = NULL, *out = NULL, *p;
1308
9
  size_t ptrlen = 0, outlen = 0, idx;
1309
9
  int ret;
1310
1311
41
  for (idx=0; idx < se_num; idx++)   {
1312
32
    struct sc_asn1_entry asn1_se[2];
1313
32
    struct sc_asn1_entry asn1_se_info[4];
1314
1315
32
    sc_copy_asn1_entry(c_asn1_se, asn1_se);
1316
32
    sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1317
1318
32
    sc_format_asn1_entry(asn1_se_info + 0, &se[idx]->se, NULL, 1);
1319
32
    if (sc_valid_oid(&se[idx]->owner))
1320
13
      sc_format_asn1_entry(asn1_se_info + 1, &se[idx]->owner, NULL, 1);
1321
32
    if (se[idx]->aid.len)
1322
18
      sc_format_asn1_entry(asn1_se_info + 2, &se[idx]->aid.value, &se[idx]->aid.len, 1);
1323
32
    sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 1);
1324
1325
32
    ret = sc_asn1_encode(ctx, asn1_se, &ptr, &ptrlen);
1326
32
    if (ret != SC_SUCCESS)
1327
0
      goto err;
1328
1329
32
    if (!ptrlen)
1330
0
      continue;
1331
32
    p = (unsigned char *) realloc(out, outlen + ptrlen);
1332
32
    if (!p)   {
1333
0
      ret = SC_ERROR_OUT_OF_MEMORY;
1334
0
      goto err;
1335
0
    }
1336
32
    out = p;
1337
32
    memcpy(out + outlen, ptr, ptrlen);
1338
32
    outlen += ptrlen;
1339
32
    free(ptr);
1340
32
    ptr = NULL;
1341
32
    ptrlen = 0;
1342
32
  }
1343
1344
9
  *buf = out;
1345
9
  *bufsize = outlen;
1346
9
  ret = SC_SUCCESS;
1347
9
err:
1348
9
  if (ret != SC_SUCCESS && out != NULL)
1349
0
    free(out);
1350
9
  return ret;
1351
9
}
1352
1353
/* TODO: According to specification type of 'SecurityCondition' is 'CHOICE'.
1354
 *       Do it at least for SC_ASN1_PKCS15_ID(authId), SC_ASN1_STRUCT(authReference) and NULL(always). */
1355
static const struct sc_asn1_entry c_asn1_access_control_rule[3] = {
1356
  { "accessMode", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1357
  { "securityCondition", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1358
  { NULL, 0, 0, 0, NULL, NULL }
1359
};
1360
1361
/*
1362
 * in src/libopensc/pkcs15.h SC_PKCS15_MAX_ACCESS_RULES  defined as 8
1363
 */
1364
static const struct sc_asn1_entry c_asn1_access_control_rules[SC_PKCS15_MAX_ACCESS_RULES + 1] = {
1365
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1366
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1367
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1368
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1369
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1370
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1371
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1372
  { "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1373
  { NULL, 0, 0, 0, NULL, NULL }
1374
};
1375
1376
static const struct sc_asn1_entry c_asn1_com_obj_attr[6] = {
1377
  { "label", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1378
  { "flags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1379
  { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1380
  { "userConsent", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
1381
  { "accessControlRules", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1382
  { NULL, 0, 0, 0, NULL, NULL }
1383
};
1384
1385
static const struct sc_asn1_entry c_asn1_p15_obj[5] = {
1386
  { "commonObjectAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1387
  { "classAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1388
  { "subClassAttributes", SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1389
  { "typeAttributes", SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL, NULL },
1390
  { NULL, 0, 0, 0, NULL, NULL }
1391
};
1392
1393
static int asn1_decode_p15_object(sc_context_t *ctx, const u8 *in,
1394
          size_t len, struct sc_asn1_pkcs15_object *obj,
1395
          int depth)
1396
4.32k
{
1397
4.32k
  struct sc_pkcs15_object *p15_obj = obj->p15_obj;
1398
4.32k
  struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
1399
4.32k
  struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1400
4.32k
  size_t flags_len = sizeof(p15_obj->flags);
1401
4.32k
  size_t label_len = sizeof(p15_obj->label);
1402
4.32k
  size_t access_mode_len = sizeof(p15_obj->access_rules[0].access_mode);
1403
4.32k
  int r, ii;
1404
1405
38.9k
  for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)
1406
34.6k
    sc_copy_asn1_entry(c_asn1_access_control_rule, asn1_ac_rule[ii]);
1407
4.32k
  sc_copy_asn1_entry(c_asn1_access_control_rules, asn1_ac_rules);
1408
1409
1410
4.32k
  sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1411
4.32k
  sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1412
4.32k
  sc_format_asn1_entry(asn1_c_attr + 0, p15_obj->label, &label_len, 0);
1413
4.32k
  sc_format_asn1_entry(asn1_c_attr + 1, &p15_obj->flags, &flags_len, 0);
1414
4.32k
  sc_format_asn1_entry(asn1_c_attr + 2, &p15_obj->auth_id, NULL, 0);
1415
4.32k
  sc_format_asn1_entry(asn1_c_attr + 3, &p15_obj->user_consent, NULL, 0);
1416
1417
38.9k
  for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)   {
1418
34.6k
    sc_format_asn1_entry(asn1_ac_rule[ii] + 0, &p15_obj->access_rules[ii].access_mode, &access_mode_len, 0);
1419
34.6k
    sc_format_asn1_entry(asn1_ac_rule[ii] + 1, &p15_obj->access_rules[ii].auth_id, NULL, 0);
1420
34.6k
    sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 0);
1421
34.6k
  }
1422
4.32k
  sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 0);
1423
1424
4.32k
  sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 0);
1425
4.32k
  sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 0);
1426
4.32k
  sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 0);
1427
4.32k
  sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 0);
1428
1429
4.32k
  r = asn1_decode(ctx, asn1_p15_obj, in, len, NULL, NULL, 0, depth + 1);
1430
4.32k
  return r;
1431
4.32k
}
1432
1433
static int asn1_encode_p15_object(sc_context_t *ctx, const struct sc_asn1_pkcs15_object *obj,
1434
          u8 **buf, size_t *bufsize, int depth)
1435
20.8k
{
1436
20.8k
  struct sc_pkcs15_object p15_obj = *obj->p15_obj;
1437
20.8k
  struct sc_asn1_entry    asn1_c_attr[6], asn1_p15_obj[5];
1438
20.8k
  struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1439
20.8k
  size_t label_len = strlen(p15_obj.label);
1440
20.8k
  size_t flags_len;
1441
20.8k
  size_t access_mode_len;
1442
20.8k
  int r, ii;
1443
1444
20.8k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "encode p15 obj(type:0x%X,access_mode:0x%X)", p15_obj.type, p15_obj.access_rules[0].access_mode);
1445
20.8k
  if (p15_obj.access_rules[0].access_mode)   {
1446
0
    for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)   {
1447
0
      sc_copy_asn1_entry(c_asn1_access_control_rule, asn1_ac_rule[ii]);
1448
0
      if (p15_obj.access_rules[ii].auth_id.len == 0)   {
1449
0
        asn1_ac_rule[ii][1].type = SC_ASN1_NULL;
1450
0
        asn1_ac_rule[ii][1].tag = SC_ASN1_TAG_NULL;
1451
0
      }
1452
0
    }
1453
0
    sc_copy_asn1_entry(c_asn1_access_control_rules, asn1_ac_rules);
1454
0
  }
1455
1456
20.8k
  sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1457
20.8k
  sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1458
20.8k
  if (label_len != 0)
1459
19.2k
    sc_format_asn1_entry(asn1_c_attr + 0, (void *) p15_obj.label, &label_len, 1);
1460
20.8k
  if (p15_obj.flags) {
1461
7.21k
    flags_len = sizeof(p15_obj.flags);
1462
7.21k
    sc_format_asn1_entry(asn1_c_attr + 1, (void *) &p15_obj.flags, &flags_len, 1);
1463
7.21k
  }
1464
20.8k
  if (p15_obj.auth_id.len)
1465
2.98k
    sc_format_asn1_entry(asn1_c_attr + 2, (void *) &p15_obj.auth_id, NULL, 1);
1466
20.8k
  if (p15_obj.user_consent)
1467
73
    sc_format_asn1_entry(asn1_c_attr + 3, (void *) &p15_obj.user_consent, NULL, 1);
1468
1469
20.8k
  if (p15_obj.access_rules[0].access_mode)   {
1470
0
    for (ii=0; p15_obj.access_rules[ii].access_mode; ii++)   {
1471
0
      access_mode_len = sizeof(p15_obj.access_rules[ii].access_mode);
1472
0
      sc_format_asn1_entry(asn1_ac_rule[ii] + 0, (void *) &p15_obj.access_rules[ii].access_mode, &access_mode_len, 1);
1473
0
      sc_format_asn1_entry(asn1_ac_rule[ii] + 1, (void *) &p15_obj.access_rules[ii].auth_id, NULL, 1);
1474
0
      sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 1);
1475
0
    }
1476
0
    sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 1);
1477
0
  }
1478
1479
20.8k
  sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 1);
1480
20.8k
  sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 1);
1481
20.8k
  if (obj->asn1_subclass_attr != NULL && obj->asn1_subclass_attr->name)
1482
70
    sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 1);
1483
20.8k
  sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 1);
1484
1485
20.8k
  r = asn1_encode(ctx, asn1_p15_obj, buf, bufsize, depth + 1);
1486
20.8k
  return r;
1487
20.8k
}
1488
1489
static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
1490
           const u8 *obj, size_t objlen, int depth)
1491
222k
{
1492
222k
  void *parm = entry->parm;
1493
222k
  int (*callback_func)(sc_context_t *nctx, void *arg, const u8 *nobj,
1494
222k
           size_t nobjlen, int ndepth);
1495
222k
  size_t *len = (size_t *) entry->arg;
1496
222k
  int r = 0;
1497
1498
222k
  callback_func = parm;
1499
1500
222k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s', raw data:%s%s\n",
1501
222k
    depth, depth, "", entry->name,
1502
222k
    sc_dump_hex(obj, objlen > 16  ? 16 : objlen),
1503
222k
    objlen > 16 ? "..." : "");
1504
1505
222k
  switch (entry->type) {
1506
56.8k
  case SC_ASN1_STRUCT:
1507
56.8k
    if (parm != NULL)
1508
46.0k
      r = asn1_decode(ctx, (struct sc_asn1_entry *) parm, obj,
1509
46.0k
               objlen, NULL, NULL, 0, depth + 1);
1510
56.8k
    break;
1511
3.20k
  case SC_ASN1_NULL:
1512
3.20k
    break;
1513
158
  case SC_ASN1_BOOLEAN:
1514
158
    if (parm != NULL) {
1515
158
      if (objlen != 1) {
1516
19
        sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1517
19
           "invalid ASN.1 object length: %"SC_FORMAT_LEN_SIZE_T"u\n",
1518
19
           objlen);
1519
19
        r = SC_ERROR_INVALID_ASN1_OBJECT;
1520
19
      } else
1521
139
        *((int *) parm) = obj[0] ? 1 : 0;
1522
158
    }
1523
158
    break;
1524
13.8k
  case SC_ASN1_INTEGER:
1525
14.0k
  case SC_ASN1_ENUMERATED:
1526
14.0k
    if (parm != NULL) {
1527
14.0k
      r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm, 0);
1528
14.0k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "",
1529
14.0k
          entry->name, *((int *) entry->parm));
1530
14.0k
    }
1531
14.0k
    break;
1532
4.99k
  case SC_ASN1_BIT_STRING_NI:
1533
9.05k
  case SC_ASN1_BIT_STRING:
1534
9.05k
    if (parm != NULL) {
1535
4.99k
      int invert = entry->type == SC_ASN1_BIT_STRING ? 1 : 0;
1536
4.99k
      assert(len != NULL);
1537
4.99k
      if (objlen < 1) {
1538
56
        r = SC_ERROR_INVALID_ASN1_OBJECT;
1539
56
        break;
1540
56
      }
1541
4.93k
      if (entry->flags & SC_ASN1_ALLOC) {
1542
4.93k
        u8 **buf = (u8 **) parm;
1543
4.93k
        if (objlen > 1) {
1544
4.76k
          *buf = malloc(objlen-1);
1545
4.76k
          if (*buf == NULL) {
1546
0
            r = SC_ERROR_OUT_OF_MEMORY;
1547
0
            break;
1548
0
          }
1549
4.76k
        }
1550
4.93k
        *len = objlen-1;
1551
4.93k
        parm = *buf;
1552
4.93k
      }
1553
4.93k
      r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert, 0);
1554
4.93k
      if (r >= 0) {
1555
4.81k
        *len = r;
1556
4.81k
        r = 0;
1557
4.81k
      }
1558
4.93k
    }
1559
8.99k
    break;
1560
8.99k
  case SC_ASN1_BIT_FIELD:
1561
6.04k
    if (parm != NULL)
1562
6.04k
      r = decode_bit_field(obj, objlen, (u8 *) parm, *len, 0);
1563
6.04k
    break;
1564
72.8k
  case SC_ASN1_OCTET_STRING:
1565
72.8k
    if (parm != NULL) {
1566
72.4k
      size_t c;
1567
72.4k
      assert(len != NULL);
1568
1569
      /* Strip off padding zero */
1570
72.4k
      if ((entry->flags & SC_ASN1_UNSIGNED)
1571
72.4k
          && objlen > 1 && obj[0] == 0x00) {
1572
5.46k
        objlen--;
1573
5.46k
        obj++;
1574
5.46k
      }
1575
1576
      /* Allocate buffer if needed */
1577
72.4k
      if (entry->flags & SC_ASN1_ALLOC) {
1578
32.3k
        u8 **buf = (u8 **) parm;
1579
32.3k
        if (objlen > 0) {
1580
28.4k
          *buf = malloc(objlen);
1581
28.4k
          if (*buf == NULL) {
1582
0
            r = SC_ERROR_OUT_OF_MEMORY;
1583
0
            break;
1584
0
          }
1585
28.4k
        }
1586
32.3k
        c = *len = objlen;
1587
32.3k
        parm = *buf;
1588
32.3k
      } else
1589
40.0k
        c = objlen > *len ? *len : objlen;
1590
1591
72.4k
      memcpy(parm, obj, c);
1592
72.4k
      *len = c;
1593
72.4k
    }
1594
72.8k
    break;
1595
72.8k
  case SC_ASN1_GENERALIZEDTIME:
1596
98
    if (parm != NULL) {
1597
86
      size_t c;
1598
86
      assert(len != NULL);
1599
86
      if (entry->flags & SC_ASN1_ALLOC) {
1600
0
        u8 **buf = (u8 **) parm;
1601
0
        if (objlen > 0) {
1602
0
          *buf = malloc(objlen);
1603
0
          if (*buf == NULL) {
1604
0
            r = SC_ERROR_OUT_OF_MEMORY;
1605
0
            break;
1606
0
          }
1607
0
        }
1608
0
        c = *len = objlen;
1609
0
        parm = *buf;
1610
0
      } else
1611
86
        c = objlen > *len ? *len : objlen;
1612
1613
86
      memcpy(parm, obj, c);
1614
86
      *len = c;
1615
86
    }
1616
98
    break;
1617
16.7k
  case SC_ASN1_OBJECT:
1618
16.7k
    if (parm != NULL)
1619
16.6k
      r = sc_asn1_decode_object_id(obj, objlen, (struct sc_object_id *) parm);
1620
16.7k
    break;
1621
31
  case SC_ASN1_PRINTABLESTRING:
1622
5.62k
  case SC_ASN1_UTF8STRING:
1623
5.62k
    if (parm != NULL) {
1624
5.60k
      assert(len != NULL);
1625
5.60k
      if (entry->flags & SC_ASN1_ALLOC) {
1626
0
        u8 **buf = (u8 **) parm;
1627
0
        *buf = malloc(objlen+1);
1628
0
        if (*buf == NULL) {
1629
0
          r = SC_ERROR_OUT_OF_MEMORY;
1630
0
          break;
1631
0
        }
1632
0
        *len = objlen+1;
1633
0
        parm = *buf;
1634
0
      }
1635
5.60k
      r = sc_asn1_decode_utf8string(obj, objlen, (u8 *) parm, len);
1636
5.60k
      if (entry->flags & SC_ASN1_ALLOC) {
1637
0
        *len -= 1;
1638
0
      }
1639
5.60k
    }
1640
5.62k
    break;
1641
15.5k
  case SC_ASN1_PATH:
1642
15.5k
    if (entry->parm != NULL)
1643
15.4k
      r = asn1_decode_path(ctx, obj, objlen, (sc_path_t *) parm, depth);
1644
15.5k
    break;
1645
2.92k
  case SC_ASN1_PKCS15_ID:
1646
2.92k
    if (entry->parm != NULL) {
1647
2.92k
      struct sc_pkcs15_id *id = (struct sc_pkcs15_id *) parm;
1648
2.92k
      size_t c = objlen > sizeof(id->value) ? sizeof(id->value) : objlen;
1649
1650
2.92k
      memcpy(id->value, obj, c);
1651
2.92k
      id->len = c;
1652
2.92k
    }
1653
2.92k
    break;
1654
4.36k
  case SC_ASN1_PKCS15_OBJECT:
1655
4.36k
    if (entry->parm != NULL)
1656
4.32k
      r = asn1_decode_p15_object(ctx, obj, objlen, (struct sc_asn1_pkcs15_object *) parm, depth);
1657
4.36k
    break;
1658
9.43k
  case SC_ASN1_ALGORITHM_ID:
1659
9.43k
    if (entry->parm != NULL)
1660
9.43k
      r = sc_asn1_decode_algorithm_id(ctx, obj, objlen, (struct sc_algorithm_id *) parm, depth);
1661
9.43k
    break;
1662
122
  case SC_ASN1_SE_INFO:
1663
122
    if (entry->parm != NULL)
1664
122
      r = asn1_decode_se_info(ctx, obj, objlen, (sc_pkcs15_sec_env_info_t ***)entry->parm, len, depth);
1665
122
    break;
1666
5.31k
  case SC_ASN1_CALLBACK:
1667
5.31k
    if (entry->parm != NULL)
1668
5.31k
      r = callback_func(ctx, entry->arg, obj, objlen, depth);
1669
5.31k
    break;
1670
0
  default:
1671
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid ASN.1 type: %d\n", entry->type);
1672
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
1673
222k
  }
1674
222k
  if (r) {
1675
10.8k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "decoding of ASN.1 object '%s' failed: %s\n", entry->name,
1676
10.8k
          sc_strerror(r));
1677
10.8k
    return r;
1678
10.8k
  }
1679
211k
  entry->flags |= SC_ASN1_PRESENT;
1680
211k
  return 0;
1681
222k
}
1682
1683
177k
static void sc_free_entry(struct sc_asn1_entry *asn1) {
1684
177k
  int idx = 0;
1685
177k
  struct sc_asn1_entry *entry = asn1;
1686
1687
177k
  if (!asn1)
1688
4.46k
    return;
1689
1690
806k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
1691
633k
    entry = &asn1[idx];
1692
633k
    switch (entry->type) {
1693
41.6k
    case SC_ASN1_CHOICE:
1694
131k
    case SC_ASN1_STRUCT:
1695
131k
      sc_free_entry((struct sc_asn1_entry *) entry->parm);
1696
131k
      break;
1697
107k
    case SC_ASN1_OCTET_STRING:
1698
107k
    case SC_ASN1_BIT_STRING_NI:
1699
107k
    case SC_ASN1_BIT_STRING:
1700
110k
    case SC_ASN1_GENERALIZEDTIME:
1701
113k
    case SC_ASN1_PRINTABLESTRING:
1702
133k
    case SC_ASN1_UTF8STRING:
1703
133k
      if ((entry->flags & SC_ASN1_ALLOC) && (entry->flags & SC_ASN1_PRESENT)) {
1704
1.16k
        u8 **buf = (u8 **)entry->parm;
1705
1.16k
        free(*buf);
1706
1.16k
        *buf = NULL;
1707
1.16k
      }
1708
133k
      break;
1709
368k
    default:
1710
368k
      break;
1711
633k
    }
1712
633k
  }
1713
172k
}
1714
1715
static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1716
           const u8 *in, size_t len, const u8 **newp, size_t *len_left,
1717
           int choice, int depth)
1718
267k
{
1719
267k
  int r, idx = 0;
1720
267k
  const u8 *p = in, *obj;
1721
267k
  struct sc_asn1_entry *entry = asn1;
1722
267k
  size_t left = len, objlen;
1723
1724
267k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1725
267k
     "%*.*s""called, left=%"SC_FORMAT_LEN_SIZE_T"u, depth %d%s\n",
1726
267k
     depth, depth, "", left, depth, choice ? ", choice" : "");
1727
1728
267k
  if (!p)
1729
18
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1730
267k
  if (left < 2) {
1731
46.8k
    while (asn1->name && (asn1->flags & SC_ASN1_OPTIONAL))
1732
24.1k
      asn1++;
1733
    /* If all elements were optional, there's nothing
1734
     * to complain about */
1735
22.7k
    if (asn1->name == NULL)
1736
10.4k
      return 0;
1737
12.3k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "End of ASN.1 stream, "
1738
12.3k
            "non-optional field \"%s\" not found\n",
1739
12.3k
            asn1->name);
1740
12.3k
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1741
22.7k
  }
1742
244k
  if (p[0] == 0 || p[0] == 0xFF || len == 0)
1743
20.8k
    return SC_ERROR_ASN1_END_OF_CONTENTS;
1744
1745
736k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
1746
595k
    entry = &asn1[idx];
1747
1748
595k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Looking for '%s', tag 0x%x%s%s\n",
1749
595k
      entry->name, entry->tag, choice? ", CHOICE" : "",
1750
595k
      (entry->flags & SC_ASN1_OPTIONAL)? ", OPTIONAL": "");
1751
1752
    /* Special case CHOICE has no tag */
1753
595k
    if (entry->type == SC_ASN1_CHOICE) {
1754
7.72k
      r = asn1_decode(ctx,
1755
7.72k
        (struct sc_asn1_entry *) entry->parm,
1756
7.72k
        p, left, &p, &left, 1, depth + 1);
1757
7.72k
      if (r >= 0)
1758
1.38k
        r = 0;
1759
7.72k
      goto decode_ok;
1760
7.72k
    }
1761
1762
587k
    obj = sc_asn1_skip_tag(ctx, &p, &left, entry->tag, &objlen);
1763
587k
    if (obj == NULL) {
1764
365k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "'%s' not present\n", entry->name);
1765
365k
      if (choice)
1766
89.7k
        continue;
1767
275k
      if (entry->flags & SC_ASN1_OPTIONAL)
1768
229k
        continue;
1769
45.7k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "mandatory ASN.1 object '%s' not found\n", entry->name);
1770
45.7k
      if (left) {
1771
44.5k
        u8 line[128], *linep = line;
1772
44.5k
        size_t i;
1773
1774
44.5k
        line[0] = 0;
1775
365k
        for (i = 0; i < 10 && i < left; i++) {
1776
320k
          sprintf((char *) linep, "%02X ", p[i]);
1777
320k
          linep += 3;
1778
320k
        }
1779
44.5k
        sc_debug(ctx, SC_LOG_DEBUG_ASN1, "next tag: %s\n", line);
1780
44.5k
      }
1781
45.7k
      sc_free_entry(asn1);
1782
45.7k
      SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1783
45.7k
    }
1784
222k
    r = asn1_decode_entry(ctx, entry, obj, objlen, depth);
1785
1786
230k
decode_ok:
1787
230k
    if (r)
1788
17.1k
      return r;
1789
212k
    if (choice)
1790
19.8k
      break;
1791
212k
  }
1792
161k
  if (choice && asn1[idx].name == NULL) /* No match */
1793
10.8k
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1794
150k
  if (newp != NULL)
1795
31.6k
    *newp = p;
1796
150k
  if (len_left != NULL)
1797
31.6k
    *len_left = left;
1798
150k
  if (choice)
1799
19.8k
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, idx);
1800
130k
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, 0);
1801
130k
}
1802
1803
int sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1804
       const u8 *in, size_t len, const u8 **newp, size_t *len_left)
1805
149k
{
1806
149k
  return asn1_decode(ctx, asn1, in, len, newp, len_left, 0, 0);
1807
149k
}
1808
1809
int sc_asn1_decode_choice(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1810
        const u8 *in, size_t len, const u8 **newp, size_t *len_left)
1811
33.4k
{
1812
33.4k
  return asn1_decode(ctx, asn1, in, len, newp, len_left, 1, 0);
1813
33.4k
}
1814
1815
static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entry,
1816
           u8 **obj, size_t *objlen, int depth)
1817
660k
{
1818
660k
  void *parm = entry->parm;
1819
660k
  int (*callback_func)(sc_context_t *nctx, void *arg, u8 **nobj,
1820
660k
           size_t *nobjlen, int ndepth);
1821
660k
  const size_t *len = (const size_t *) entry->arg;
1822
660k
  int r = 0;
1823
660k
  u8 * buf = NULL;
1824
660k
  size_t buflen = 0;
1825
1826
660k
  callback_func = parm;
1827
1828
660k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sencoding '%s'%s\n",
1829
660k
          depth, depth, "", entry->name,
1830
660k
    (entry->flags & SC_ASN1_PRESENT)? "" : " (not present)");
1831
660k
  if (!(entry->flags & SC_ASN1_PRESENT))
1832
261k
    goto no_object;
1833
398k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1834
398k
     "%*.*stype=%d, tag=0x%02x, parm=%p, len=%"SC_FORMAT_LEN_SIZE_T"u\n",
1835
398k
     depth, depth, "", entry->type, entry->tag, parm,
1836
398k
     len ? *len : 0);
1837
1838
398k
  if (entry->type == SC_ASN1_CHOICE) {
1839
5.13k
    const struct sc_asn1_entry *list, *choice = NULL;
1840
1841
5.13k
    list = (const struct sc_asn1_entry *) parm;
1842
19.2k
    while (list->name != NULL) {
1843
14.1k
      if (list->flags & SC_ASN1_PRESENT) {
1844
5.13k
        if (choice) {
1845
0
          sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1846
0
            "ASN.1 problem: more than "
1847
0
            "one CHOICE when encoding %s: "
1848
0
            "%s and %s both present\n",
1849
0
            entry->name,
1850
0
            choice->name,
1851
0
            list->name);
1852
0
          return SC_ERROR_INVALID_ASN1_OBJECT;
1853
0
        }
1854
5.13k
        choice = list;
1855
5.13k
      }
1856
14.1k
      list++;
1857
14.1k
    }
1858
5.13k
    if (choice == NULL)
1859
0
      goto no_object;
1860
5.13k
    return asn1_encode_entry(ctx, choice, obj, objlen, depth + 1);
1861
5.13k
  }
1862
1863
393k
  if (entry->type != SC_ASN1_NULL && parm == NULL) {
1864
96
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "unexpected parm == NULL\n");
1865
96
    return SC_ERROR_INVALID_ASN1_OBJECT;
1866
96
  }
1867
1868
393k
  switch (entry->type) {
1869
85.8k
  case SC_ASN1_STRUCT:
1870
85.8k
    r = asn1_encode(ctx, (const struct sc_asn1_entry *) parm, &buf,
1871
85.8k
        &buflen, depth + 1);
1872
85.8k
    break;
1873
1.95k
  case SC_ASN1_NULL:
1874
1.95k
    buf = NULL;
1875
1.95k
    buflen = 0;
1876
1.95k
    break;
1877
102
  case SC_ASN1_BOOLEAN:
1878
102
    buf = malloc(1);
1879
102
    if (buf == NULL) {
1880
0
      r = SC_ERROR_OUT_OF_MEMORY;
1881
0
      break;
1882
0
    }
1883
102
    buf[0] = *((int *) parm) ? 0xFF : 0;
1884
102
    buflen = 1;
1885
102
    break;
1886
32.5k
  case SC_ASN1_INTEGER:
1887
36.0k
  case SC_ASN1_ENUMERATED:
1888
36.0k
    r = asn1_encode_integer(*((int *) entry->parm), &buf, &buflen);
1889
36.0k
    break;
1890
2.70k
  case SC_ASN1_BIT_STRING_NI:
1891
2.70k
  case SC_ASN1_BIT_STRING:
1892
2.70k
    if (len != NULL) {
1893
2.70k
      if (entry->type == SC_ASN1_BIT_STRING)
1894
0
        r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 1);
1895
2.70k
      else
1896
2.70k
        r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0);
1897
2.70k
    } else {
1898
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1899
0
    }
1900
2.70k
    break;
1901
15.6k
  case SC_ASN1_BIT_FIELD:
1902
15.6k
    if (len != NULL) {
1903
15.6k
      r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen);
1904
15.6k
    } else {
1905
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1906
0
    }
1907
15.6k
    break;
1908
1.34k
  case SC_ASN1_PRINTABLESTRING:
1909
106k
  case SC_ASN1_OCTET_STRING:
1910
142k
  case SC_ASN1_UTF8STRING:
1911
142k
    if (len != NULL) {
1912
142k
      buf = malloc(*len + 1);
1913
142k
      if (buf == NULL) {
1914
0
        r = SC_ERROR_OUT_OF_MEMORY;
1915
0
        break;
1916
0
      }
1917
142k
      buflen = 0;
1918
      /* If the integer is supposed to be unsigned, insert
1919
       * a padding byte if the MSB is one */
1920
142k
      if ((entry->flags & SC_ASN1_UNSIGNED)
1921
142k
          && (((u8 *) parm)[0] & 0x80)) {
1922
1.25k
        buf[buflen++] = 0x00;
1923
1.25k
      }
1924
142k
      memcpy(buf + buflen, parm, *len);
1925
142k
      buflen += *len;
1926
142k
    } else {
1927
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1928
0
    }
1929
142k
    break;
1930
142k
  case SC_ASN1_GENERALIZEDTIME:
1931
529
    if (len != NULL) {
1932
529
      buf = malloc(*len);
1933
529
      if (buf == NULL) {
1934
0
        r = SC_ERROR_OUT_OF_MEMORY;
1935
0
        break;
1936
0
      }
1937
529
      memcpy(buf, parm, *len);
1938
529
      buflen = *len;
1939
529
    } else {
1940
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1941
0
    }
1942
529
    break;
1943
50.7k
  case SC_ASN1_OBJECT:
1944
50.7k
    r = sc_asn1_encode_object_id(&buf, &buflen, (struct sc_object_id *) parm);
1945
50.7k
    break;
1946
25.3k
  case SC_ASN1_PATH:
1947
25.3k
    r = asn1_encode_path(ctx, (const sc_path_t *) parm, &buf, &buflen, depth, entry->flags);
1948
25.3k
    break;
1949
9.01k
  case SC_ASN1_PKCS15_ID:
1950
9.01k
    {
1951
9.01k
      const struct sc_pkcs15_id *id = (const struct sc_pkcs15_id *) parm;
1952
1953
9.01k
      buf = malloc(id->len);
1954
9.01k
      if (buf == NULL) {
1955
0
        r = SC_ERROR_OUT_OF_MEMORY;
1956
0
        break;
1957
0
      }
1958
9.01k
      memcpy(buf, id->value, id->len);
1959
9.01k
      buflen = id->len;
1960
9.01k
    }
1961
0
    break;
1962
20.8k
  case SC_ASN1_PKCS15_OBJECT:
1963
20.8k
    r = asn1_encode_p15_object(ctx, (const struct sc_asn1_pkcs15_object *) parm, &buf, &buflen, depth);
1964
20.8k
    break;
1965
2.70k
  case SC_ASN1_ALGORITHM_ID:
1966
2.70k
    r = sc_asn1_encode_algorithm_id(ctx, &buf, &buflen, (const struct sc_algorithm_id *) parm, depth);
1967
2.70k
    break;
1968
9
  case SC_ASN1_SE_INFO:
1969
9
    if (!len)
1970
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
1971
9
    r = asn1_encode_se_info(ctx, (struct sc_pkcs15_sec_env_info **)parm, *len, &buf, &buflen, depth);
1972
9
    break;
1973
0
  case SC_ASN1_CALLBACK:
1974
0
    r = callback_func(ctx, entry->arg, &buf, &buflen, depth);
1975
0
    break;
1976
0
  default:
1977
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid ASN.1 type: %d\n", entry->type);
1978
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
1979
393k
  }
1980
393k
  if (r) {
1981
1.41k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "encoding of ASN.1 object '%s' failed: %s\n", entry->name,
1982
1.41k
          sc_strerror(r));
1983
1.41k
    if (buf)
1984
0
      free(buf);
1985
1.41k
    return r;
1986
1.41k
  }
1987
1988
  /* Treatment of OPTIONAL elements:
1989
   *  - if the encoding has 0 length, and the element is OPTIONAL,
1990
   *  we don't write anything (unless it's an ASN1 NULL and the
1991
   *      SC_ASN1_PRESENT flag is set).
1992
   *  - if the encoding has 0 length, but the element is non-OPTIONAL,
1993
   *  constructed, we write a empty element (e.g. a SEQUENCE of
1994
   *      length 0). In case of an ASN1 NULL just write the tag and
1995
   *      length (i.e. 0x05,0x00).
1996
   *  - any other empty objects are considered bogus
1997
   */
1998
653k
no_object:
1999
653k
  if (!buflen && entry->flags & SC_ASN1_OPTIONAL && !(entry->flags & SC_ASN1_PRESENT)) {
2000
    /* This happens when we try to encode e.g. the
2001
     * subClassAttributes, which may be empty */
2002
261k
    *obj = NULL;
2003
261k
    *objlen = 0;
2004
261k
    r = 0;
2005
392k
  } else if (!buflen && (entry->flags & SC_ASN1_EMPTY_ALLOWED)) {
2006
282
    *obj = NULL;
2007
282
    *objlen = 0;
2008
282
    r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
2009
282
    if (r)
2010
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n", sc_strerror(r));
2011
392k
  } else if (buflen || entry->type == SC_ASN1_NULL || entry->tag & SC_ASN1_CONS) {
2012
391k
    r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
2013
391k
    if (r)
2014
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n",
2015
391k
          sc_strerror(r));
2016
391k
  } else if (!(entry->flags & SC_ASN1_PRESENT)) {
2017
103
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode non-optional ASN.1 object: not given by caller\n");
2018
103
    r = SC_ERROR_INVALID_ASN1_OBJECT;
2019
436
  } else {
2020
436
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode empty non-optional ASN.1 object\n");
2021
436
    r = SC_ERROR_INVALID_ASN1_OBJECT;
2022
436
  }
2023
653k
  if (buf)
2024
388k
    free(buf);
2025
653k
  if (r >= 0)
2026
653k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1,
2027
653k
       "%*.*slength of encoded item=%"SC_FORMAT_LEN_SIZE_T"u\n",
2028
653k
       depth, depth, "", *objlen);
2029
653k
  return r;
2030
393k
}
2031
2032
static int asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2033
          u8 **ptr, size_t *size, int depth)
2034
273k
{
2035
273k
  int r, idx = 0;
2036
273k
  u8 *obj = NULL, *buf = NULL, *tmp;
2037
273k
  size_t total = 0, objsize;
2038
2039
273k
  if (asn1 == NULL) {
2040
0
    return SC_ERROR_INVALID_ARGUMENTS;
2041
0
  }
2042
2043
926k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
2044
655k
    r = asn1_encode_entry(ctx, &asn1[idx], &obj, &objsize, depth);
2045
655k
    if (r) {
2046
2.05k
      if (obj)
2047
0
        free(obj);
2048
2.05k
      if (buf)
2049
620
        free(buf);
2050
2.05k
      return r;
2051
2.05k
    }
2052
    /* in case of an empty (optional) element continue with
2053
     * the next asn1 element */
2054
653k
    if (!objsize)
2055
261k
      continue;
2056
391k
    tmp = (u8 *) realloc(buf, total + objsize);
2057
391k
    if (!tmp) {
2058
0
      if (obj)
2059
0
        free(obj);
2060
0
      if (buf)
2061
0
        free(buf);
2062
0
      return SC_ERROR_OUT_OF_MEMORY;
2063
0
    }
2064
391k
    buf = tmp;
2065
391k
    memcpy(buf + total, obj, objsize);
2066
391k
    free(obj);
2067
391k
    obj = NULL;
2068
391k
    total += objsize;
2069
391k
  }
2070
271k
  *ptr = buf;
2071
271k
  *size = total;
2072
271k
  return 0;
2073
273k
}
2074
2075
int sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2076
       u8 **ptr, size_t *size)
2077
101k
{
2078
101k
  return asn1_encode(ctx, asn1, ptr, size, 0);
2079
101k
}
2080
2081
int _sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2082
        u8 **ptr, size_t *size, int depth)
2083
39.6k
{
2084
39.6k
  return asn1_encode(ctx, asn1, ptr, size, depth);
2085
39.6k
}
2086
2087
int
2088
_sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
2089
           const u8 *in, size_t len, const u8 **newp, size_t *left,
2090
           int choice, int depth)
2091
11.0k
{
2092
11.0k
  return asn1_decode(ctx, asn1, in, len, newp, left, choice, depth);
2093
11.0k
}
2094
2095
int
2096
sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src)
2097
12.5k
{
2098
12.5k
  if (!dst || !src)
2099
0
    return SC_ERROR_INVALID_ARGUMENTS;
2100
12.5k
  memset(dst, 0, sizeof(*dst));
2101
12.5k
  if (src->len) {
2102
12.5k
    if (!src->value)
2103
0
      return SC_ERROR_INVALID_ARGUMENTS;
2104
12.5k
    dst->value = malloc(src->len);
2105
12.5k
    if (!dst->value)
2106
0
      return SC_ERROR_OUT_OF_MEMORY;
2107
12.5k
    dst->len = src->len;
2108
12.5k
    memcpy(dst->value, src->value, src->len);
2109
12.5k
  }
2110
12.5k
  return SC_SUCCESS;
2111
12.5k
}
2112
2113
int
2114
sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id,
2115
    unsigned char **out, size_t *size)
2116
35.2k
{
2117
35.2k
  static const struct sc_asn1_entry c_asn1_object_id[2] = {
2118
35.2k
    { "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_ALLOC, NULL, NULL },
2119
35.2k
    { NULL, 0, 0, 0, NULL, NULL }
2120
35.2k
  };
2121
35.2k
  struct sc_asn1_entry asn1_object_id[2];
2122
35.2k
  int rv;
2123
2124
35.2k
  sc_copy_asn1_entry(c_asn1_object_id, asn1_object_id);
2125
35.2k
  sc_format_asn1_entry(asn1_object_id + 0, id, NULL, 1);
2126
2127
35.2k
  rv = _sc_asn1_encode(ctx, asn1_object_id, out, size, 1);
2128
35.2k
  LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
2129
2130
35.2k
  return SC_SUCCESS;
2131
35.2k
}
2132
2133
2134
#define C_ASN1_SIG_VALUE_SIZE 2
2135
static struct sc_asn1_entry c_asn1_sig_value[C_ASN1_SIG_VALUE_SIZE] = {
2136
    { "ECDSA-Sig-Value", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2137
    { NULL, 0, 0, 0, NULL, NULL }
2138
};
2139
2140
#define C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE 3
2141
static struct sc_asn1_entry c_asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE] = {
2142
    { "r", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2143
    { "s", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2144
    { NULL, 0, 0, 0, NULL, NULL }
2145
};
2146
2147
2148
int
2149
sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char *in, size_t inlen,
2150
    unsigned char **buf, size_t *buflen)
2151
522
{
2152
522
  struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2153
522
  struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2154
522
  unsigned char *r = in, *s = in + inlen/2;
2155
522
  size_t r_len = inlen/2, s_len = inlen/2;
2156
522
  int rv;
2157
2158
522
  LOG_FUNC_CALLED(ctx);
2159
2160
  /* R/S are filled up with zeroes, we do not want that in sequence format */
2161
3.94k
  while(r_len > 1 && *r == 0x00) {
2162
3.42k
    r++;
2163
3.42k
    r_len--;
2164
3.42k
  }
2165
1.65M
  while(s_len > 1 && *s == 0x00) {
2166
1.65M
    s++;
2167
1.65M
    s_len--;
2168
1.65M
  }
2169
2170
522
  sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2171
522
  sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 1);
2172
2173
522
  sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2174
522
  sc_format_asn1_entry(asn1_sig_value_coefficients + 0, r, &r_len, 1);
2175
522
  sc_format_asn1_entry(asn1_sig_value_coefficients + 1, s, &s_len, 1);
2176
2177
522
  rv = sc_asn1_encode(ctx, asn1_sig_value, buf, buflen);
2178
522
  LOG_TEST_RET(ctx, rv, "ASN.1 encoding ECDSA-SIg-Value failed");
2179
2180
520
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2181
520
}
2182
2183
2184
int
2185
sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in, size_t inlen,
2186
    unsigned char *buf, size_t buflen)
2187
491
{
2188
491
  struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2189
491
  struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2190
491
  unsigned char *r = NULL, *s = NULL;
2191
491
  size_t r_len = 0, s_len = 0, halflen = buflen/2;
2192
491
  int rv;
2193
2194
491
  LOG_FUNC_CALLED(ctx);
2195
491
  if (!buf || !buflen)
2196
491
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2197
2198
491
  sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2199
491
  sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 0);
2200
2201
491
  sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2202
491
  sc_format_asn1_entry(asn1_sig_value_coefficients + 0, &r, &r_len, 0);
2203
491
  sc_format_asn1_entry(asn1_sig_value_coefficients + 1, &s, &s_len, 0);
2204
2205
491
  rv = sc_asn1_decode(ctx, asn1_sig_value, in, inlen, NULL, NULL);
2206
491
  LOG_TEST_GOTO_ERR(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed");
2207
2208
159
  if (halflen < r_len || halflen < s_len)   {
2209
0
    rv = SC_ERROR_BUFFER_TOO_SMALL;
2210
0
    goto err;
2211
0
  }
2212
2213
159
  memset(buf, 0, buflen);
2214
159
  if (r_len > 0)
2215
71
    memcpy(buf + (halflen - r_len), r, r_len);
2216
159
  if (s_len > 0)
2217
95
    memcpy(buf + (buflen - s_len), s, s_len);
2218
2219
159
  sc_log(ctx, "r(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2220
159
         sc_dump_hex(buf, halflen));
2221
159
  sc_log(ctx, "s(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2222
159
         sc_dump_hex(buf + halflen, halflen));
2223
2224
159
  rv = SC_SUCCESS;
2225
491
err:
2226
491
  free(r);
2227
491
  free(s);
2228
2229
491
  LOG_FUNC_RETURN(ctx, rv);
2230
491
}
2231
2232
216
int sc_asn1_decode_ecdsa_signature(sc_context_t *ctx, const u8 *data, size_t datalen, size_t fieldsize, u8 **out, size_t outlen) {
2233
216
  int i, r;
2234
216
  const unsigned char *pseq, *pint, *pend;
2235
216
  unsigned int cla, tag;
2236
216
  size_t seqlen, intlen;
2237
2238
216
  if (!ctx || !data || !out || !(*out)) {
2239
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2240
0
  }
2241
216
  if (outlen < 2 * fieldsize) {
2242
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Output too small for EC signature");
2243
0
  }
2244
2245
216
  memset(*out, 0, outlen);
2246
2247
216
  pseq = data;
2248
216
  r = sc_asn1_read_tag(&pseq, datalen, &cla, &tag, &seqlen);
2249
216
  if (pseq == NULL || r < 0 || seqlen == 0 || (cla | tag) != 0x30)
2250
216
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x30 tag");
2251
2252
31
  pint = pseq;
2253
31
  pend = pseq + seqlen;
2254
67
  for (i = 0; i < 2; i++) {
2255
53
    r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen);
2256
53
    if (pint == NULL || r < 0 || intlen == 0 || (cla | tag) != 0x02) {
2257
13
      r = SC_ERROR_INVALID_DATA;
2258
13
      LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x02");
2259
13
    }
2260
2261
40
    if (intlen == fieldsize + 1) { /* drop leading 00 if present */
2262
12
      if (*pint != 0x00) {
2263
2
        r = SC_ERROR_INVALID_DATA;
2264
2
        LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long");
2265
2
      }
2266
10
      pint++;
2267
10
      intlen--;
2268
10
    }
2269
38
    if (intlen > fieldsize) {
2270
2
      r = SC_ERROR_INVALID_DATA;
2271
2
      LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long");
2272
2
    }
2273
36
    memcpy(*out + fieldsize * i + fieldsize - intlen , pint, intlen);
2274
36
    pint += intlen; /* next integer */
2275
36
  }
2276
14
  r = (int)(2 * fieldsize);
2277
31
err:
2278
31
  LOG_FUNC_RETURN(ctx, r);
2279
31
}
2280