Coverage Report

Created: 2026-06-06 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/asn1.c
Line
Count
Source
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
0
{
46
0
  static const char *tags[] = {
47
0
    "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",  /* 0-4 */
48
0
    "NULL", "OBJECT IDENTIFIER", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
49
0
    "ENUMERATED", "Universal 11", "UTF8String", "Universal 13", /* 10-13 */
50
0
    "Universal 14", "Universal 15", "SEQUENCE", "SET",  /* 15-17 */
51
0
    "NumericString", "PrintableString", "T61String",  /* 18-20 */
52
0
    "VideotexString", "IA5String", "UTCTIME", "GENERALIZEDTIME",  /* 21-24 */
53
0
    "GraphicString", "VisibleString", "GeneralString",  /* 25-27 */
54
0
    "UniversalString", "Universal 29", "BMPString"  /* 28-30 */
55
0
  };
56
57
0
  if (tag > 30)
58
0
    return "(unknown)";
59
0
  return tags[tag];
60
0
}
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
232k
{
65
232k
  const u8 *p = *buf;
66
232k
  size_t left = buflen, len;
67
232k
  unsigned int cla, tag, i;
68
69
232k
  *buf = NULL;
70
71
232k
  if (left == 0 || !p || buflen == 0)
72
1.86k
    return SC_ERROR_INVALID_ASN1_OBJECT;
73
230k
  if (*p == 0xff || *p == 0) {
74
    /* end of data reached */
75
9.31k
    *taglen = 0;
76
9.31k
    *tag_out = SC_ASN1_TAG_EOC;
77
9.31k
    return SC_SUCCESS;
78
9.31k
  }
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
221k
  cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
85
221k
  tag = *p & SC_ASN1_TAG_PRIMITIVE;
86
221k
  if (left < 1)
87
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
88
221k
  p++;
89
221k
  left--;
90
221k
  if (tag == SC_ASN1_TAG_PRIMITIVE) {
91
    /* high tag number */
92
4.21k
    size_t n = SC_ASN1_TAGNUM_SIZE - 1;
93
    /* search the last tag octet */
94
5.99k
    do {
95
5.99k
      if (left == 0 || n == 0)
96
        /* either an invalid tag or it doesn't fit in
97
         * unsigned int */
98
840
        return SC_ERROR_INVALID_ASN1_OBJECT;
99
5.15k
      tag <<= 8;
100
5.15k
      tag |= *p;
101
5.15k
      p++;
102
5.15k
      left--;
103
5.15k
      n--;
104
5.15k
    } while (tag & 0x80);
105
4.21k
  }
106
107
  /* parse length byte(s) */
108
220k
  if (left == 0)
109
2.48k
    return SC_ERROR_INVALID_ASN1_OBJECT;
110
217k
  len = *p;
111
217k
  p++;
112
217k
  left--;
113
217k
  if (len & 0x80) {
114
32.2k
    len &= 0x7f;
115
32.2k
    unsigned int a = 0;
116
32.2k
    if (len > sizeof a || len > left)
117
17.1k
      return SC_ERROR_INVALID_ASN1_OBJECT;
118
23.8k
    for (i = 0; i < len; i++) {
119
8.75k
      a <<= 8;
120
8.75k
      a |= *p;
121
8.75k
      p++;
122
8.75k
      left--;
123
8.75k
    }
124
15.1k
    len = a;
125
15.1k
  }
126
127
200k
  *cla_out = cla;
128
200k
  *tag_out = tag;
129
200k
  *taglen = len;
130
200k
  *buf = p;
131
132
200k
  if (len > left)
133
30.2k
    return SC_ERROR_ASN1_END_OF_CONTENTS;
134
135
170k
  return SC_SUCCESS;
136
200k
}
137
138
void sc_format_asn1_entry(struct sc_asn1_entry *entry, void *parm, void *arg,
139
        int set_present)
140
1.29M
{
141
1.29M
  entry->parm = parm;
142
1.29M
  entry->arg  = arg;
143
1.29M
  if (set_present)
144
98.9k
    entry->flags |= SC_ASN1_PRESENT;
145
1.29M
}
146
147
void sc_copy_asn1_entry(const struct sc_asn1_entry *src,
148
      struct sc_asn1_entry *dest)
149
398k
{
150
1.69M
  while (src->name != NULL) {
151
1.30M
    *dest = *src;
152
1.30M
    dest++;
153
1.30M
    src++;
154
1.30M
  }
155
398k
  dest->name = NULL;
156
398k
}
157
158
static void print_indent(size_t depth)
159
0
{
160
0
  for (; depth > 0; depth--) {
161
0
    putchar(' ');
162
0
  }
163
0
}
164
165
static void print_hex(const u8 * buf, size_t buflen, size_t depth)
166
0
{
167
0
  size_t lines_len = buflen * 5 + 128;
168
0
  char *lines = malloc(lines_len);
169
0
  char *line = lines;
170
171
0
  if (buf == NULL || buflen == 0 || lines == NULL) {
172
0
    free(lines);
173
0
    return;
174
0
  }
175
176
0
  sc_hex_dump(buf, buflen, lines, lines_len);
177
178
0
  while (*line != '\0') {
179
0
    char *line_end = strchr(line, '\n');
180
0
    ptrdiff_t width = line_end - line;
181
0
    if (!line_end || width <= 1) {
182
      /* don't print empty lines */
183
0
      break;
184
0
    }
185
0
    if (buflen > 8) {
186
0
      putchar('\n');
187
0
      print_indent(depth);
188
0
    } else {
189
0
      printf(": ");
190
0
    }
191
0
    printf("%.*s", (int) width, line);
192
0
    line = line_end + 1;
193
0
  }
194
195
0
  free(lines);
196
0
}
197
198
static void print_ascii(const u8 * buf, size_t buflen)
199
0
{
200
0
  for (; 0 < buflen; buflen--, buf++) {
201
0
    if (isprint(*buf))
202
0
      printf("%c", *buf);
203
0
    else
204
0
      putchar('.');
205
0
  }
206
0
}
207
208
static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen, size_t depth)
209
0
{
210
0
  print_hex(buf, buflen, depth);
211
0
}
212
213
static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen)
214
0
{
215
  /* FIXME UTF-8 is not ASCII */
216
0
  print_ascii(buf, buflen);
217
0
}
218
219
static void sc_asn1_print_integer(const u8 * buf, size_t buflen)
220
0
{
221
0
  size_t a = 0;
222
223
0
  if (buflen > sizeof(a)) {
224
0
    printf("0x%s", sc_dump_hex(buf, buflen));
225
0
  } else {
226
0
    size_t i;
227
0
    for (i = 0; i < buflen; i++) {
228
0
      a <<= 8;
229
0
      a |= buf[i];
230
0
    }
231
0
    printf("%"SC_FORMAT_LEN_SIZE_T"u", a);
232
0
  }
233
0
}
234
235
static void sc_asn1_print_boolean(const u8 * buf, size_t buflen)
236
0
{
237
0
  if (!buflen)
238
0
    return;
239
240
0
  if (buf[0])
241
0
    printf("true");
242
0
  else
243
0
    printf("false");
244
0
}
245
246
static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen, size_t depth)
247
0
{
248
0
#ifndef _WIN32
249
0
  long long a = 0;
250
#else
251
  __int64 a = 0;
252
#endif
253
0
  int r, i;
254
255
0
  if (buflen > sizeof(a) + 1) {
256
0
    print_hex(buf, buflen, depth);
257
0
  } else {
258
0
    r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 1);
259
0
    if (r < 0) {
260
0
      printf("decode error, ");
261
      /* try again without the strict mode */
262
0
      r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 0);
263
0
      if (r < 0) {
264
0
        printf("even for lax decoding");
265
0
        return ;
266
0
      }
267
0
    }
268
0
    for (i = r - 1; i >= 0; i--) {
269
0
      printf("%c", ((a >> i) & 1) ? '1' : '0');
270
0
    }
271
0
  }
272
0
}
273
274
#ifdef ENABLE_OPENSSL
275
#include <openssl/objects.h>
276
277
static void openssl_print_object_sn(const char *s)
278
0
{
279
0
  ASN1_OBJECT *obj = OBJ_txt2obj(s, 0);
280
0
  if (obj) {
281
0
    int nid = OBJ_obj2nid(obj);
282
0
    if (nid != NID_undef) {
283
0
      printf(", %s", OBJ_nid2sn(nid));
284
0
    }
285
0
    ASN1_OBJECT_free(obj);
286
0
  }
287
0
}
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
0
{
296
0
  struct sc_object_id oid;
297
0
  const char *sbuf;
298
299
0
  if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
300
0
    printf("decode error");
301
0
    return;
302
0
  }
303
304
0
  sbuf = sc_dump_oid(&oid);
305
0
  printf(" %s", sbuf);
306
0
  openssl_print_object_sn(sbuf);
307
0
}
308
309
static void sc_asn1_print_utctime(const u8 * buf, size_t buflen)
310
0
{
311
0
  if (buflen < 8) {
312
0
    printf("Error in decoding.\n");
313
0
    return;
314
0
  }
315
316
0
  print_ascii(buf, 2);    /* YY */
317
0
  putchar('-');
318
0
  print_ascii(buf+2, 2);    /* MM */
319
0
  putchar('-');
320
0
  print_ascii(buf+4, 2);    /* DD */
321
0
  putchar(' ');
322
0
  print_ascii(buf+6, 2);    /* hh */
323
0
  buf += 8;
324
0
  buflen -= 8;
325
0
  if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
326
0
    putchar(':');
327
0
    print_ascii(buf, 2);  /* mm */
328
0
    buf += 2;
329
0
    buflen -= 2;
330
0
  }
331
0
  if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
332
0
    putchar(':');
333
0
    print_ascii(buf, 2);  /* ss */
334
0
    buf += 2;
335
0
    buflen -= 2;
336
0
  }
337
0
  if (buflen >= 4 && '.' == buf[0]) {
338
0
    print_ascii(buf, 4);  /* fff */
339
0
    buf += 4;
340
0
    buflen -= 4;
341
0
  }
342
343
0
  if (buflen >= 1 && 'Z' == buf[0]) {
344
0
    printf(" UTC");
345
0
  } else if (buflen >= 5 && ('-' == buf[0] || '+' == buf[0])) {
346
0
    putchar(' ');
347
0
    print_ascii(buf, 3);  /* +/-hh */
348
0
    putchar(':');
349
0
    print_ascii(buf+3, 2);  /* mm */
350
0
  }
351
0
}
352
353
static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen)
354
0
{
355
0
  if (buflen < 8) {
356
0
    printf("Error in decoding.\n");
357
0
    return;
358
0
  }
359
360
0
  print_ascii(buf, 2);
361
0
  sc_asn1_print_utctime(buf + 2, buflen - 2);
362
0
}
363
364
static void print_tags_recursive(const u8 * buf0, const u8 * buf,
365
         size_t buflen, size_t depth)
366
0
{
367
0
  int r;
368
0
  size_t i;
369
0
  size_t bytesleft = buflen;
370
0
  const char *classes[4] = {
371
0
    "Universal",
372
0
    "Application",
373
0
    "Context",
374
0
    "Private"
375
0
  };
376
0
  const u8 *p = buf;
377
378
0
  while (bytesleft >= 2) {
379
0
    unsigned int cla = 0, tag = 0;
380
0
    size_t hlen;
381
0
    const u8 *tagp = p;
382
0
    size_t len;
383
384
0
    r = sc_asn1_read_tag(&tagp, bytesleft, &cla, &tag, &len);
385
0
    if (r != SC_SUCCESS || (tagp == NULL && tag != SC_ASN1_TAG_EOC)) {
386
0
      printf("Error in decoding.\n");
387
0
      return;
388
0
    }
389
0
    hlen = tagp - p;
390
0
    if (cla == 0 && tag == 0) {
391
0
      printf("Zero tag, finishing\n");
392
0
      break;
393
0
    }
394
0
    print_indent(depth);
395
    /* let i be the length of the tag in bytes */
396
0
    for (i = 1; i < sizeof tag - 1; i++) {
397
0
      if (!(tag >> 8*i))
398
0
        break;
399
0
    }
400
0
    printf("%02X", cla<<(i-1)*8 | tag);
401
402
0
    if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) {
403
0
      printf(" %s", tag2str(tag));
404
0
    } else {
405
0
      printf(" %s %-2u",
406
0
          classes[cla >> 6],
407
0
          i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i-1)*8));
408
0
    }
409
0
    if (!((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL
410
0
          && tag == SC_ASN1_TAG_NULL && len == 0)) {
411
0
      printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)",
412
0
          len,
413
0
          len != 1 ? "s" : "");
414
0
    }
415
416
0
    if (len + hlen > bytesleft) {
417
0
      printf(" Illegal length!\n");
418
0
      return;
419
0
    }
420
0
    p += hlen + len;
421
0
    bytesleft -= hlen + len;
422
423
0
    if (cla & SC_ASN1_TAG_CONSTRUCTED) {
424
0
      putchar('\n');
425
0
      print_tags_recursive(buf0, tagp, len, depth + 2*i + 1);
426
0
      continue;
427
0
    }
428
429
0
    switch (tag) {
430
0
      case SC_ASN1_TAG_BIT_STRING:
431
0
        printf(": ");
432
0
        sc_asn1_print_bit_string(tagp, len, depth + 2*i + 1);
433
0
        break;
434
0
      case SC_ASN1_TAG_OCTET_STRING:
435
0
        sc_asn1_print_octet_string(tagp, len, depth + 2*i + 1);
436
0
        break;
437
0
      case SC_ASN1_TAG_OBJECT:
438
0
        printf(": ");
439
0
        sc_asn1_print_object_id(tagp, len);
440
0
        break;
441
0
      case SC_ASN1_TAG_INTEGER:
442
0
      case SC_ASN1_TAG_ENUMERATED:
443
0
        printf(": ");
444
0
        sc_asn1_print_integer(tagp, len);
445
0
        break;
446
0
      case SC_ASN1_TAG_IA5STRING:
447
0
      case SC_ASN1_TAG_PRINTABLESTRING:
448
0
      case SC_ASN1_TAG_T61STRING:
449
0
      case SC_ASN1_TAG_UTF8STRING:
450
0
        printf(": ");
451
0
        sc_asn1_print_utf8string(tagp, len);
452
0
        break;
453
0
      case SC_ASN1_TAG_BOOLEAN:
454
0
        printf(": ");
455
0
        sc_asn1_print_boolean(tagp, len);
456
0
        break;
457
0
      case SC_ASN1_GENERALIZEDTIME:
458
0
        printf(": ");
459
0
        sc_asn1_print_generalizedtime(tagp, len);
460
0
        break;
461
0
      case SC_ASN1_UTCTIME:
462
0
        printf(": ");
463
0
        sc_asn1_print_utctime(tagp, len);
464
0
        break;
465
0
    }
466
467
0
    if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) {
468
0
      print_hex(tagp, len, depth + 2*i + 1);
469
0
    }
470
471
0
    if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) {
472
0
      print_hex(tagp, len, depth + 2*i + 1);
473
0
    }
474
475
0
    putchar('\n');
476
0
  }
477
0
}
478
479
void sc_asn1_print_tags(const u8 * buf, size_t buflen)
480
0
{
481
0
  print_tags_recursive(buf, buf, buflen, 0);
482
0
}
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
31.9k
{
487
31.9k
  size_t left = buflen, taglen;
488
31.9k
  const u8 *p = buf;
489
490
31.9k
  *taglen_in = 0;
491
76.8k
  while (left >= 2) {
492
69.8k
    unsigned int cla = 0, tag, mask = 0xff00;
493
494
69.8k
    buf = p;
495
    /* read a tag */
496
69.8k
    if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
497
64.0k
        || p == NULL)
498
11.2k
      return NULL;
499
500
58.5k
    left -= (p - buf);
501
    /* we need to shift the class byte to the leftmost
502
     * byte of the tag */
503
59.3k
    while ((tag & mask) != 0) {
504
789
      cla  <<= 8;
505
789
      mask <<= 8;
506
789
    }
507
    /* compare the read tag with the given tag */
508
58.5k
    if ((tag | cla) == tag_in) {
509
      /* we have a match => return length and value part */
510
13.5k
      if (taglen > left)
511
0
        return NULL;
512
13.5k
      *taglen_in = taglen;
513
13.5k
      return p;
514
13.5k
    }
515
    /* otherwise continue reading tags */
516
44.9k
    left -= taglen;
517
44.9k
    p += taglen;
518
44.9k
  }
519
7.02k
  return NULL;
520
31.9k
}
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
108k
{
525
108k
  const u8 *p = *buf;
526
108k
  size_t len = *buflen, taglen;
527
108k
  unsigned int cla = 0, tag;
528
529
108k
  if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS
530
67.5k
      || p == NULL)
531
43.3k
    return NULL;
532
65.4k
  switch (cla & 0xC0) {
533
30.9k
  case SC_ASN1_TAG_UNIVERSAL:
534
30.9k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_UNI)
535
5.07k
      return NULL;
536
25.8k
    break;
537
25.8k
  case SC_ASN1_TAG_APPLICATION:
538
18.5k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_APP)
539
2.21k
      return NULL;
540
16.3k
    break;
541
16.3k
  case SC_ASN1_TAG_CONTEXT:
542
14.2k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_CTX)
543
8.49k
      return NULL;
544
5.76k
    break;
545
5.76k
  case SC_ASN1_TAG_PRIVATE:
546
1.68k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_PRV)
547
1.68k
      return NULL;
548
0
    break;
549
65.4k
  }
550
48.0k
  if (cla & SC_ASN1_TAG_CONSTRUCTED) {
551
20.6k
    if ((tag_in & SC_ASN1_CONS) == 0)
552
4.78k
      return NULL;
553
20.6k
  } else
554
27.3k
    if (tag_in & SC_ASN1_CONS)
555
2.60k
      return NULL;
556
40.6k
  if ((tag_in & SC_ASN1_TAG_MASK) != tag)
557
13.3k
    return NULL;
558
27.2k
  len -= (p - *buf);  /* header size */
559
27.2k
  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
27.2k
  *buflen -= (p - *buf) + taglen;
566
27.2k
  *buf = p + taglen;  /* point to next tag */
567
27.2k
  *taglen_out = taglen;
568
27.2k
  return p;
569
27.2k
}
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
800
{
574
800
  return sc_asn1_skip_tag(ctx, &buf, &buflen, tag_in, taglen_out);
575
800
}
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
940
{
580
940
  const u8 *in = inbuf;
581
940
  u8 *out = (u8 *) outbuf;
582
940
  int i, count = 0;
583
940
  int zero_bits;
584
940
  size_t octets_left;
585
586
940
  if (inlen < 1)
587
12
    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
928
  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
0
    if (inlen == 1 && *in != 0)
595
0
      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
0
    if ((*in & ~0x07) != 0)
598
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
599
0
  }
600
601
928
  memset(outbuf, 0, outlen);
602
928
  zero_bits = *in & 0x07;
603
928
  in++;
604
928
  octets_left = inlen - 1;
605
928
  if (outlen < octets_left)
606
13
    return SC_ERROR_BUFFER_TOO_SMALL;
607
608
22.8k
  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
21.9k
    int bits_to_go;
613
614
21.9k
    *out = 0;
615
21.9k
    if (octets_left == 1 && zero_bits > 0) {
616
532
      bits_to_go = 8 - zero_bits;
617
      /* Verify the padding is zero bits */
618
532
      if (*in & (1 << (zero_bits-1))) {
619
54
        return SC_ERROR_INVALID_ASN1_OBJECT;
620
54
      }
621
532
    } else
622
21.4k
      bits_to_go = 8;
623
21.9k
    if (invert)
624
7.83k
      for (i = 0; i < bits_to_go; i++) {
625
6.74k
        *out |= ((*in >> (7 - i)) & 1) << i;
626
6.74k
      }
627
20.8k
    else {
628
20.8k
      *out = *in;
629
20.8k
    }
630
21.9k
    out++;
631
21.9k
    in++;
632
21.9k
    octets_left--;
633
21.9k
    count++;
634
21.9k
  }
635
861
  return (count * 8) - zero_bits;
636
915
}
637
638
int sc_asn1_decode_bit_string(const u8 * inbuf, size_t inlen,
639
            void *outbuf, size_t outlen, const int strict)
640
0
{
641
0
  return decode_bit_string(inbuf, inlen, outbuf, outlen, 1, strict);
642
0
}
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
115
{
653
115
  const u8 *in = inbuf;
654
115
  u8 *out;
655
115
  size_t bytes, skipped = 0;
656
657
115
  bytes = BYTES4BITS(bits_left) + 1;
658
115
  *outbuf = out = malloc(bytes);
659
115
  if (out == NULL)
660
0
    return SC_ERROR_OUT_OF_MEMORY;
661
115
  *outlen = bytes;
662
115
  out += 1;
663
12.9k
  while (bits_left) {
664
12.8k
    size_t i, bits_to_go = 8;
665
666
12.8k
    *out = 0;
667
12.8k
    if (bits_left < 8) {
668
0
      bits_to_go = bits_left;
669
0
      skipped = 8 - bits_left;
670
0
    }
671
12.8k
    if (invert) {
672
0
      for (i = 0; i < bits_to_go; i++)
673
0
        *out |= ((*in >> i) & 1) << (7 - i);
674
12.8k
    } else {
675
12.8k
      *out = *in;
676
12.8k
      if (bits_left < 8)
677
0
        return SC_ERROR_NOT_SUPPORTED; /* FIXME */
678
12.8k
    }
679
12.8k
    bits_left -= bits_to_go;
680
12.8k
    out++, in++;
681
12.8k
  }
682
115
  out = *outbuf;
683
115
  out[0] = skipped;
684
115
  return 0;
685
115
}
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
693
{
693
693
  u8    data[sizeof(unsigned int)];
694
693
  unsigned int  field = 0;
695
693
  int   i, n;
696
697
693
  if (outlen != sizeof(data))
698
0
    return SC_ERROR_BUFFER_TOO_SMALL;
699
700
693
  n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1, strict);
701
693
  if (n < 0)
702
101
    return n;
703
704
1.67k
  for (i = 0; i < n; i += 8) {
705
1.07k
    field |= ((unsigned int) data[i/8] << i);
706
1.07k
  }
707
592
  memcpy(outbuf, &field, outlen);
708
592
  return 0;
709
693
}
710
711
static int encode_bit_field(const u8 *inbuf, size_t inlen,
712
          u8 **outbuf, size_t *outlen)
713
0
{
714
0
  u8    data[sizeof(unsigned int)];
715
0
  unsigned int  field = 0;
716
0
  size_t    i, bits;
717
718
0
  if (inlen != sizeof(data))
719
0
    return SC_ERROR_BUFFER_TOO_SMALL;
720
721
  /* count the bits */
722
0
  memcpy(&field, inbuf, inlen);
723
0
  for (bits = 0; field; bits++)
724
0
    field >>= 1;
725
726
0
  memcpy(&field, inbuf, inlen);
727
0
  for (i = 0; i < bits; i += 8)
728
0
    data[i/8] = field >> i;
729
730
0
  return encode_bit_string(data, bits, outbuf, outlen, 1);
731
0
}
732
733
int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out, int strict)
734
1.25k
{
735
1.25k
  int    a = 0, is_negative = 0;
736
1.25k
  size_t i = 0;
737
738
1.25k
  if (inlen == 0) {
739
78
    return SC_ERROR_INVALID_ASN1_OBJECT;
740
78
  }
741
1.17k
  if (inlen > sizeof(int)) {
742
38
    return SC_ERROR_NOT_SUPPORTED;
743
38
  }
744
1.13k
  if (inbuf[0] & 0x80) {
745
508
    if (strict && inlen > 1 && inbuf[0] == 0xff && (inbuf[1] & 0x80)) {
746
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
747
0
    }
748
508
    is_negative = 1;
749
508
    a |= 0xff^(*inbuf++);
750
508
    i = 1;
751
629
  } else {
752
629
    if (strict && inlen > 1 && inbuf[0] == 0x00 && (inbuf[1] & 0x80) == 0) {
753
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
754
0
    }
755
629
  }
756
2.85k
  for (; i < inlen; i++) {
757
1.71k
    if (a > (INT_MAX >> 8) || a < (INT_MIN + (1<<8))) {
758
0
      return SC_ERROR_NOT_SUPPORTED;
759
0
    }
760
1.71k
    a <<= 8;
761
1.71k
    if (is_negative) {
762
475
      a |= 0xff^(*inbuf++);
763
1.24k
    } else {
764
1.24k
      a |= *inbuf++;
765
1.24k
    }
766
1.71k
  }
767
1.13k
  if (is_negative) {
768
    /* Calculate Two's complement from previously positive number */
769
508
    a = (-1 * a) - 1;
770
508
  }
771
1.13k
  *out = a;
772
1.13k
  return 0;
773
1.13k
}
774
775
static int asn1_encode_integer(int in, u8 ** obj, size_t * objsize)
776
0
{
777
0
  int i = sizeof(in) * 8, skip_zero, skip_sign;
778
0
  u8 *p, b;
779
780
0
  if (in < 0)
781
0
  {
782
0
    skip_sign = 1;
783
0
    skip_zero= 0;
784
0
  }
785
0
  else
786
0
  {
787
0
    skip_sign = 0;
788
0
    skip_zero= 1;
789
0
  }
790
0
  *obj = p = malloc(sizeof(in)+1);
791
0
  if (*obj == NULL)
792
0
    return SC_ERROR_OUT_OF_MEMORY;
793
0
  do {
794
0
    i -= 8;
795
0
    b = in >> i;
796
0
    if (skip_sign)
797
0
    {
798
0
      if (b != 0xff)
799
0
        skip_sign = 0;
800
0
      if (b & 0x80)
801
0
      {
802
0
        *p = b;
803
0
        if (0xff == b)
804
0
          continue;
805
0
      }
806
0
      else
807
0
      {
808
0
        p++;
809
0
        skip_sign = 0;
810
0
      }
811
0
    }
812
0
    if (b == 0 && skip_zero)
813
0
      continue;
814
0
    if (skip_zero) {
815
0
      skip_zero = 0;
816
      /* prepend 0x00 if MSb is 1 and integer positive */
817
0
      if ((b & 0x80) != 0 && in > 0)
818
0
        *p++ = 0;
819
0
    }
820
0
    *p++ = b;
821
0
  } while (i > 0);
822
0
  if (skip_sign)
823
0
    p++;
824
0
  *objsize = p - *obj;
825
0
  if (*objsize == 0) {
826
0
    *objsize = 1;
827
0
    (*obj)[0] = 0;
828
0
  }
829
0
  return 0;
830
0
}
831
832
int
833
sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
834
7.09k
{
835
7.09k
  int large_second_octet = 0;
836
7.09k
  unsigned int a = 0;
837
7.09k
  const u8 *p = inbuf;
838
7.09k
  int *octet;
839
840
7.09k
  if (inlen == 0 || inbuf == NULL || id == NULL)
841
667
    return SC_ERROR_INVALID_ARGUMENTS;
842
843
6.43k
  sc_init_oid(id);
844
6.43k
  octet = id->value;
845
846
  /* The first octet can be 0, 1 or 2 and is derived from the first byte */
847
6.43k
  a = MIN(*p / 40, 2);
848
6.43k
  *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
6.43k
  if ((*p & 0x80) == 0) {
854
5.04k
    *octet++ = *p - (a * 40);
855
5.04k
    inlen--;
856
5.04k
  } else {
857
1.38k
    large_second_octet = 1;
858
1.38k
  }
859
860
24.9k
  while (inlen) {
861
20.8k
    if (!large_second_octet)
862
19.4k
      p++;
863
    /* This signalizes empty most significant bits, which means
864
     * the unsigned integer encoding is not minimal */
865
20.8k
    if (*p == 0x80) {
866
418
      sc_init_oid(id);
867
418
      return SC_ERROR_INVALID_ASN1_OBJECT;
868
418
    }
869
    /* Use unsigned type here so we can process the whole INT range.
870
     * Values can not be negative */
871
20.3k
    a = *p & 0x7F;
872
20.3k
    inlen--;
873
26.8k
    while (inlen && *p & 0x80) {
874
      /* Limit the OID values to int size and do not overflow */
875
6.60k
      if (a > (UINT_MAX>>7)) {
876
156
        sc_init_oid(id);
877
156
        return SC_ERROR_NOT_SUPPORTED;
878
156
      }
879
6.44k
      p++;
880
6.44k
      a <<= 7;
881
6.44k
      a |= *p & 0x7F;
882
6.44k
      inlen--;
883
6.44k
    }
884
20.2k
    if (*p & 0x80) {
885
      /* We dropped out from previous cycle on the end of
886
       * data while still expecting continuation of value */
887
921
      sc_init_oid(id);
888
921
      return SC_ERROR_INVALID_ASN1_OBJECT;
889
921
    }
890
19.3k
    if (large_second_octet) {
891
970
      a -= (2 * 40);
892
970
    }
893
19.3k
    if (a > INT_MAX) {
894
209
      sc_init_oid(id);
895
209
      return SC_ERROR_NOT_SUPPORTED;
896
209
    }
897
19.1k
    *octet++ = a;
898
19.1k
    if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS)   {
899
552
      sc_init_oid(id);
900
552
      return SC_ERROR_INVALID_ASN1_OBJECT;
901
552
    }
902
18.5k
    large_second_octet = 0;
903
18.5k
  }
904
905
4.17k
  return 0;
906
6.43k
}
907
908
int
909
sc_asn1_encode_object_id(u8 **buf, size_t *buflen, const struct sc_object_id *id)
910
3.65k
{
911
3.65k
  u8 temp[SC_MAX_OBJECT_ID_OCTETS*5], *p = temp;
912
3.65k
  int i;
913
914
3.65k
  if (!buflen || !id)
915
0
    return SC_ERROR_INVALID_ARGUMENTS;
916
917
  /* an OID must have at least two components */
918
3.65k
  if (id->value[0] == -1 || id->value[1] == -1)
919
0
    return SC_ERROR_INVALID_ARGUMENTS;
920
921
22.1k
  for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
922
22.1k
    unsigned int k, shift;
923
924
22.1k
    if (id->value[i] == -1)
925
3.65k
      break;
926
927
18.5k
    k = id->value[i];
928
18.5k
    switch (i) {
929
3.65k
    case 0:
930
3.65k
      if (k > 2)
931
0
        return SC_ERROR_INVALID_ARGUMENTS;
932
3.65k
      *p = k * 40;
933
3.65k
      break;
934
3.65k
    case 1:
935
3.65k
      if (k > 39 && id->value[0] < 2) {
936
0
        return SC_ERROR_INVALID_ARGUMENTS;
937
0
      }
938
      /* We can encode larger IDs to multiple bytes
939
       * similarly as the following IDs */
940
3.65k
      k += *p;
941
      /* fall through */
942
14.8k
    default:
943
14.8k
      shift = 28;
944
71.8k
      while (shift && (k >> shift) == 0)
945
56.9k
        shift -= 7;
946
17.4k
      while (shift) {
947
2.56k
        *p++ = 0x80 | ((k >> shift) & 0x7f);
948
2.56k
        shift -= 7;
949
2.56k
      }
950
14.8k
      *p++ = k & 0x7F;
951
14.8k
      break;
952
18.5k
    }
953
18.5k
  }
954
955
3.65k
  *buflen = p - temp;
956
957
3.65k
  if (buf)   {
958
3.65k
    *buf = malloc(*buflen);
959
3.65k
    if (!*buf)
960
0
      return SC_ERROR_OUT_OF_MEMORY;
961
3.65k
    memcpy(*buf, temp, *buflen);
962
3.65k
  }
963
3.65k
  return 0;
964
3.65k
}
965
966
static int sc_asn1_decode_utf8string(const u8 *inbuf, size_t inlen,
967
            u8 *out, size_t *outlen)
968
247
{
969
247
  if (inlen+1 > *outlen)
970
4
    return SC_ERROR_BUFFER_TOO_SMALL;
971
243
  *outlen = inlen+1;
972
243
  memcpy(out, inbuf, inlen);
973
243
  out[inlen] = 0;
974
243
  return 0;
975
247
}
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
4.51k
{
982
4.51k
  size_t c = 0;
983
4.51k
  unsigned int tag_len, ii;
984
4.51k
  u8 *p = out;
985
4.51k
  u8 tag_char[4] = {0, 0, 0, 0};
986
987
  /* Check tag */
988
4.51k
  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
9.02k
  for (tag_len = 0; tag; tag >>= 8) {
993
    /* Note: tag char will be reversed order. */
994
4.51k
    tag_char[tag_len++] = tag & 0xFF;
995
4.51k
  }
996
997
4.51k
  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
4.51k
  if (datalen > 127) {
1017
0
    c = 1;
1018
0
    while (datalen >> (c << 3))
1019
0
      c++;
1020
0
  }
1021
4.51k
  if (outlen == 0 || out == NULL) {
1022
    /* Caller only asks for the length that would be written. */
1023
0
    return (int)(tag_len + (c + 1) + datalen);
1024
0
  }
1025
  /* We will write the tag, so check the length. */
1026
4.51k
  if (outlen < tag_len + (c+1) + datalen)
1027
0
    return SC_ERROR_BUFFER_TOO_SMALL;
1028
9.02k
  for (ii=0;ii<tag_len;ii++)
1029
4.51k
    *p++ = tag_char[tag_len - ii - 1];
1030
1031
4.51k
  if (c > 0) {
1032
0
    *p++ = 0x80 | c;
1033
0
    while (c--)
1034
0
      *p++ = (datalen >> (c << 3)) & 0xFF;
1035
0
  }
1036
4.51k
  else {
1037
4.51k
    *p++ = datalen & 0x7F;
1038
4.51k
  }
1039
4.51k
  if(data && datalen > 0) {
1040
4.51k
    memcpy(p, data, datalen);
1041
4.51k
    p += datalen;
1042
4.51k
  }
1043
4.51k
  if (ptr != NULL)
1044
4.51k
    *ptr = p;
1045
4.51k
  return 0;
1046
4.51k
}
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
22.2k
{
1057
22.2k
  unsigned char t;
1058
22.2k
  unsigned char *buf, *p;
1059
22.2k
  int c = 0;
1060
22.2k
  unsigned short_tag;
1061
22.2k
  unsigned char tag_char[3] = {0, 0, 0};
1062
22.2k
  size_t tag_len, ii;
1063
1064
22.2k
  short_tag = tag & SC_ASN1_TAG_MASK;
1065
44.5k
  for (tag_len = 0; short_tag >> (8 * tag_len); tag_len++)
1066
22.2k
    tag_char[tag_len] = (short_tag >> (8 * tag_len)) & 0xFF;
1067
22.2k
  if (!tag_len)
1068
0
    tag_len = 1;
1069
1070
22.2k
  if (tag_len > 1)   {
1071
0
    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
0
    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
0
    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
0
  }
1081
1082
22.2k
  t = tag_char[tag_len - 1] & 0x1F;
1083
1084
22.2k
  switch (tag & SC_ASN1_CLASS_MASK) {
1085
4.88k
  case SC_ASN1_UNI:
1086
4.88k
    break;
1087
17.3k
  case SC_ASN1_APP:
1088
17.3k
    t |= SC_ASN1_TAG_APPLICATION;
1089
17.3k
    break;
1090
0
  case SC_ASN1_CTX:
1091
0
    t |= SC_ASN1_TAG_CONTEXT;
1092
0
    break;
1093
0
  case SC_ASN1_PRV:
1094
0
    t |= SC_ASN1_TAG_PRIVATE;
1095
0
    break;
1096
22.2k
  }
1097
22.2k
  if (tag & SC_ASN1_CONS)
1098
618
    t |= SC_ASN1_TAG_CONSTRUCTED;
1099
22.2k
  if (datalen > 127) {
1100
343
    c = 1;
1101
441
    while (datalen >> (c << 3))
1102
98
      c++;
1103
343
  }
1104
1105
22.2k
  *outlen = tag_len + 1 + c + datalen;
1106
22.2k
  buf = malloc(*outlen);
1107
22.2k
  if (buf == NULL)
1108
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1109
1110
22.2k
  *out = p = buf;
1111
22.2k
  *p++ = t;
1112
22.2k
  for (ii=1;ii<tag_len;ii++)
1113
0
    *p++ = tag_char[tag_len - ii - 1];
1114
1115
22.2k
  if (c) {
1116
343
    *p++ = 0x80 | c;
1117
784
    while (c--)
1118
441
      *p++ = (datalen >> (c << 3)) & 0xFF;
1119
343
  }
1120
21.9k
  else   {
1121
21.9k
    *p++ = datalen & 0x7F;
1122
21.9k
  }
1123
22.2k
  if (datalen && data) {
1124
22.2k
    memcpy(p, data, datalen);
1125
22.2k
  }
1126
1127
22.2k
  return SC_SUCCESS;
1128
22.2k
}
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
733
{
1151
733
  int idx, count, r;
1152
733
  struct sc_asn1_entry asn1_path_ext[3], asn1_path[5];
1153
733
  unsigned char path_value[SC_MAX_PATH_SIZE], aid_value[SC_MAX_AID_SIZE];
1154
733
  size_t path_len = sizeof(path_value), aid_len = sizeof(aid_value);
1155
1156
733
  memset(path, 0, sizeof(struct sc_path));
1157
1158
733
  sc_copy_asn1_entry(c_asn1_path_ext, asn1_path_ext);
1159
733
  sc_copy_asn1_entry(c_asn1_path, asn1_path);
1160
1161
733
  sc_format_asn1_entry(asn1_path_ext + 0, aid_value, &aid_len, 0);
1162
733
  sc_format_asn1_entry(asn1_path_ext + 1, path_value, &path_len, 0);
1163
1164
733
  sc_format_asn1_entry(asn1_path + 0, path_value, &path_len, 0);
1165
733
  sc_format_asn1_entry(asn1_path + 1, &idx, NULL, 0);
1166
733
  sc_format_asn1_entry(asn1_path + 2, &count, NULL, 0);
1167
733
  sc_format_asn1_entry(asn1_path + 3, asn1_path_ext, NULL, 0);
1168
1169
733
  r = asn1_decode(ctx, asn1_path, in, len, NULL, NULL, 0, depth + 1);
1170
733
  if (r)
1171
70
    return r;
1172
1173
663
  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
663
  else if (asn1_path[0].flags & SC_ASN1_PRESENT)   {
1182
    /* path present: set 'path' */
1183
367
    memcpy(path->value, path_value, path_len);
1184
367
    path->len = path_len;
1185
367
  }
1186
296
  else   {
1187
    /* failed if both 'path' and 'pathExtended' are absent */
1188
296
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1189
296
  }
1190
1191
367
  if (path->len == 2)
1192
91
    path->type = SC_PATH_TYPE_FILE_ID;
1193
276
  else   if (path->aid.len && path->len > 2)
1194
0
    path->type = SC_PATH_TYPE_FROM_CURRENT;
1195
276
  else
1196
276
    path->type = SC_PATH_TYPE_PATH;
1197
1198
367
  if ((asn1_path[1].flags & SC_ASN1_PRESENT) && (asn1_path[2].flags & SC_ASN1_PRESENT)) {
1199
39
    path->index = idx;
1200
39
    path->count = count;
1201
39
  }
1202
328
  else {
1203
328
    path->index = 0;
1204
328
    path->count = -1;
1205
328
  }
1206
1207
367
  return SC_SUCCESS;
1208
663
}
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
0
{
1213
0
  int r;
1214
0
  struct sc_asn1_entry asn1_path[5];
1215
0
  sc_path_t tpath = *path;
1216
1217
0
  sc_copy_asn1_entry(c_asn1_path, asn1_path);
1218
0
  sc_format_asn1_entry(asn1_path + 0, (void *) &tpath.value, (void *) &tpath.len, 1);
1219
1220
0
  asn1_path[0].flags |= parent_flags;
1221
0
  if (path->count > 0) {
1222
0
    sc_format_asn1_entry(asn1_path + 1, (void *) &tpath.index, NULL, 1);
1223
0
    sc_format_asn1_entry(asn1_path + 2, (void *) &tpath.count, NULL, 1);
1224
0
  }
1225
0
  r = asn1_encode(ctx, asn1_path, buf, bufsize, depth + 1);
1226
0
  return r;
1227
0
}
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
5
{
1245
5
  struct sc_pkcs15_sec_env_info **ses;
1246
5
  const unsigned char *ptr = obj;
1247
5
  size_t idx, ptrlen = objlen;
1248
5
  int ret;
1249
1250
5
  LOG_FUNC_CALLED(ctx);
1251
1252
5
  ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
1253
5
  if (ses == NULL) {
1254
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1255
0
  }
1256
1257
5
  for (idx=0; idx < SC_MAX_SE_NUM && ptrlen; )   {
1258
2
    struct sc_asn1_entry asn1_se[2];
1259
2
    struct sc_asn1_entry asn1_se_info[4];
1260
2
    struct sc_pkcs15_sec_env_info si;
1261
1262
2
    sc_copy_asn1_entry(c_asn1_se, asn1_se);
1263
2
    sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1264
1265
2
    si.aid.len = sizeof(si.aid.value);
1266
2
    sc_format_asn1_entry(asn1_se_info + 0, &si.se, NULL, 0);
1267
2
    sc_format_asn1_entry(asn1_se_info + 1, &si.owner, NULL, 0);
1268
2
    sc_format_asn1_entry(asn1_se_info + 2, &si.aid.value, &si.aid.len, 0);
1269
2
    sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 0);
1270
1271
2
    ret = asn1_decode(ctx, asn1_se, ptr, ptrlen, &ptr, &ptrlen, 0, depth+1);
1272
2
    if (ret != SC_SUCCESS)
1273
2
      goto err;
1274
0
    if (!(asn1_se_info[1].flags & SC_ASN1_PRESENT))
1275
0
      sc_init_oid(&si.owner);
1276
1277
0
    ses[idx] = calloc(1, sizeof(sc_pkcs15_sec_env_info_t));
1278
0
    if (ses[idx] == NULL) {
1279
0
      ret = SC_ERROR_OUT_OF_MEMORY;
1280
0
      goto err;
1281
0
    }
1282
1283
0
    memcpy(ses[idx], &si, sizeof(struct sc_pkcs15_sec_env_info));
1284
0
    idx++;
1285
0
  }
1286
1287
3
  *se  = ses;
1288
3
  *num = idx;
1289
3
  ret = SC_SUCCESS;
1290
5
err:
1291
5
  if (ret != SC_SUCCESS) {
1292
2
    size_t i;
1293
2
    for (i = 0; i < idx; i++)
1294
0
      if (ses[i])
1295
0
        free(ses[i]);
1296
2
    free(ses);
1297
2
  }
1298
1299
5
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, ret);
1300
5
}
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
0
{
1307
0
  unsigned char *ptr = NULL, *out = NULL, *p;
1308
0
  size_t ptrlen = 0, outlen = 0, idx;
1309
0
  int ret;
1310
1311
0
  for (idx=0; idx < se_num; idx++)   {
1312
0
    struct sc_asn1_entry asn1_se[2];
1313
0
    struct sc_asn1_entry asn1_se_info[4];
1314
1315
0
    sc_copy_asn1_entry(c_asn1_se, asn1_se);
1316
0
    sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1317
1318
0
    sc_format_asn1_entry(asn1_se_info + 0, &se[idx]->se, NULL, 1);
1319
0
    if (sc_valid_oid(&se[idx]->owner))
1320
0
      sc_format_asn1_entry(asn1_se_info + 1, &se[idx]->owner, NULL, 1);
1321
0
    if (se[idx]->aid.len)
1322
0
      sc_format_asn1_entry(asn1_se_info + 2, &se[idx]->aid.value, &se[idx]->aid.len, 1);
1323
0
    sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 1);
1324
1325
0
    ret = sc_asn1_encode(ctx, asn1_se, &ptr, &ptrlen);
1326
0
    if (ret != SC_SUCCESS)
1327
0
      goto err;
1328
1329
0
    if (!ptrlen)
1330
0
      continue;
1331
0
    p = (unsigned char *) realloc(out, outlen + ptrlen);
1332
0
    if (!p)   {
1333
0
      ret = SC_ERROR_OUT_OF_MEMORY;
1334
0
      goto err;
1335
0
    }
1336
0
    out = p;
1337
0
    memcpy(out + outlen, ptr, ptrlen);
1338
0
    outlen += ptrlen;
1339
0
    free(ptr);
1340
0
    ptr = NULL;
1341
0
    ptrlen = 0;
1342
0
  }
1343
1344
0
  *buf = out;
1345
0
  *bufsize = outlen;
1346
0
  ret = SC_SUCCESS;
1347
0
err:
1348
0
  if (ret != SC_SUCCESS && out != NULL)
1349
0
    free(out);
1350
0
  return ret;
1351
0
}
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
2.47k
{
1397
2.47k
  struct sc_pkcs15_object *p15_obj = obj->p15_obj;
1398
2.47k
  struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
1399
2.47k
  struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1400
2.47k
  size_t flags_len = sizeof(p15_obj->flags);
1401
2.47k
  size_t label_len = sizeof(p15_obj->label);
1402
2.47k
  size_t access_mode_len = sizeof(p15_obj->access_rules[0].access_mode);
1403
2.47k
  int r, ii;
1404
1405
22.2k
  for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)
1406
19.8k
    sc_copy_asn1_entry(c_asn1_access_control_rule, asn1_ac_rule[ii]);
1407
2.47k
  sc_copy_asn1_entry(c_asn1_access_control_rules, asn1_ac_rules);
1408
1409
1410
2.47k
  sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1411
2.47k
  sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1412
2.47k
  sc_format_asn1_entry(asn1_c_attr + 0, p15_obj->label, &label_len, 0);
1413
2.47k
  sc_format_asn1_entry(asn1_c_attr + 1, &p15_obj->flags, &flags_len, 0);
1414
2.47k
  sc_format_asn1_entry(asn1_c_attr + 2, &p15_obj->auth_id, NULL, 0);
1415
2.47k
  sc_format_asn1_entry(asn1_c_attr + 3, &p15_obj->user_consent, NULL, 0);
1416
1417
22.2k
  for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)   {
1418
19.8k
    sc_format_asn1_entry(asn1_ac_rule[ii] + 0, &p15_obj->access_rules[ii].access_mode, &access_mode_len, 0);
1419
19.8k
    sc_format_asn1_entry(asn1_ac_rule[ii] + 1, &p15_obj->access_rules[ii].auth_id, NULL, 0);
1420
19.8k
    sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 0);
1421
19.8k
  }
1422
2.47k
  sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 0);
1423
1424
2.47k
  sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 0);
1425
2.47k
  sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 0);
1426
2.47k
  sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 0);
1427
2.47k
  sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 0);
1428
1429
2.47k
  r = asn1_decode(ctx, asn1_p15_obj, in, len, NULL, NULL, 0, depth + 1);
1430
2.47k
  return r;
1431
2.47k
}
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
0
{
1436
0
  struct sc_pkcs15_object p15_obj = *obj->p15_obj;
1437
0
  struct sc_asn1_entry    asn1_c_attr[6], asn1_p15_obj[5];
1438
0
  struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1439
0
  size_t label_len = strlen(p15_obj.label);
1440
0
  size_t flags_len;
1441
0
  size_t access_mode_len;
1442
0
  int r, ii;
1443
1444
0
  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
0
  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
0
  sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1457
0
  sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1458
0
  if (label_len != 0)
1459
0
    sc_format_asn1_entry(asn1_c_attr + 0, (void *) p15_obj.label, &label_len, 1);
1460
0
  if (p15_obj.flags) {
1461
0
    flags_len = sizeof(p15_obj.flags);
1462
0
    sc_format_asn1_entry(asn1_c_attr + 1, (void *) &p15_obj.flags, &flags_len, 1);
1463
0
  }
1464
0
  if (p15_obj.auth_id.len)
1465
0
    sc_format_asn1_entry(asn1_c_attr + 2, (void *) &p15_obj.auth_id, NULL, 1);
1466
0
  if (p15_obj.user_consent)
1467
0
    sc_format_asn1_entry(asn1_c_attr + 3, (void *) &p15_obj.user_consent, NULL, 1);
1468
1469
0
  if (p15_obj.access_rules[0].access_mode)   {
1470
0
    for (ii = 0; ii < SC_PKCS15_MAX_ACCESS_RULES && 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
0
  sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 1);
1480
0
  sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 1);
1481
0
  if (obj->asn1_subclass_attr != NULL && obj->asn1_subclass_attr->name)
1482
0
    sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 1);
1483
0
  sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 1);
1484
1485
0
  r = asn1_encode(ctx, asn1_p15_obj, buf, bufsize, depth + 1);
1486
0
  return r;
1487
0
}
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
26.1k
{
1492
26.1k
  void *parm = entry->parm;
1493
26.1k
  int (*callback_func)(sc_context_t *nctx, void *arg, const u8 *nobj,
1494
26.1k
           size_t nobjlen, int ndepth);
1495
26.1k
  size_t *len = (size_t *) entry->arg;
1496
26.1k
  int r = 0;
1497
1498
26.1k
  callback_func = parm;
1499
1500
26.1k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s', raw data:%s%s\n",
1501
26.1k
    depth, depth, "", entry->name,
1502
26.1k
    sc_dump_hex(obj, objlen > 16  ? 16 : objlen),
1503
26.1k
    objlen > 16 ? "..." : "");
1504
1505
26.1k
  switch (entry->type) {
1506
7.32k
  case SC_ASN1_STRUCT:
1507
7.32k
    if (parm != NULL)
1508
6.73k
      r = asn1_decode(ctx, (struct sc_asn1_entry *) parm, obj,
1509
6.73k
               objlen, NULL, NULL, 0, depth + 1);
1510
7.32k
    break;
1511
206
  case SC_ASN1_NULL:
1512
206
    break;
1513
45
  case SC_ASN1_BOOLEAN:
1514
45
    if (parm != NULL) {
1515
45
      if (objlen != 1) {
1516
9
        sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1517
9
           "invalid ASN.1 object length: %"SC_FORMAT_LEN_SIZE_T"u\n",
1518
9
           objlen);
1519
9
        r = SC_ERROR_INVALID_ASN1_OBJECT;
1520
9
      } else
1521
36
        *((int *) parm) = obj[0] ? 1 : 0;
1522
45
    }
1523
45
    break;
1524
1.19k
  case SC_ASN1_INTEGER:
1525
1.26k
  case SC_ASN1_ENUMERATED:
1526
1.26k
    if (parm != NULL) {
1527
1.25k
      r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm, 0);
1528
1.25k
      if (r == SC_SUCCESS) {
1529
1.13k
        sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n",
1530
1.13k
            depth, depth, "", entry->name, *((int *)entry->parm));
1531
1.13k
      }
1532
1.25k
    }
1533
1.26k
    break;
1534
263
  case SC_ASN1_BIT_STRING_NI:
1535
408
  case SC_ASN1_BIT_STRING:
1536
408
    if (parm != NULL) {
1537
263
      int invert = entry->type == SC_ASN1_BIT_STRING ? 1 : 0;
1538
263
      if (len == NULL)
1539
0
        return SC_ERROR_INTERNAL;
1540
263
      if (objlen < 1) {
1541
16
        r = SC_ERROR_INVALID_ASN1_OBJECT;
1542
16
        break;
1543
16
      }
1544
247
      if (entry->flags & SC_ASN1_ALLOC) {
1545
247
        u8 **buf = (u8 **) parm;
1546
247
        if (objlen > 1) {
1547
209
          *buf = malloc(objlen-1);
1548
209
          if (*buf == NULL) {
1549
0
            r = SC_ERROR_OUT_OF_MEMORY;
1550
0
            break;
1551
0
          }
1552
209
        }
1553
247
        *len = objlen-1;
1554
247
        parm = *buf;
1555
247
      }
1556
247
      r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert, 0);
1557
247
      if (r >= 0) {
1558
223
        *len = r;
1559
223
        r = 0;
1560
223
      }
1561
247
    }
1562
392
    break;
1563
693
  case SC_ASN1_BIT_FIELD:
1564
693
    if (parm != NULL)
1565
693
      r = decode_bit_field(obj, objlen, (u8 *) parm, *len, 0);
1566
693
    break;
1567
10.2k
  case SC_ASN1_OCTET_STRING:
1568
10.2k
    if (parm != NULL) {
1569
10.2k
      size_t c;
1570
10.2k
      if (len == NULL)
1571
0
        return SC_ERROR_INTERNAL;
1572
1573
      /* Strip off padding zero */
1574
10.2k
      if ((entry->flags & SC_ASN1_UNSIGNED)
1575
7.11k
          && objlen > 1 && obj[0] == 0x00) {
1576
3.52k
        objlen--;
1577
3.52k
        obj++;
1578
3.52k
      }
1579
1580
      /* Allocate buffer if needed */
1581
10.2k
      if (entry->flags & SC_ASN1_ALLOC) {
1582
8.14k
        u8 **buf = (u8 **) parm;
1583
8.14k
        if (objlen > 0) {
1584
7.58k
          *buf = malloc(objlen);
1585
7.58k
          if (*buf == NULL) {
1586
0
            r = SC_ERROR_OUT_OF_MEMORY;
1587
0
            break;
1588
0
          }
1589
7.58k
        }
1590
8.14k
        c = *len = objlen;
1591
8.14k
        parm = *buf;
1592
8.14k
      } else
1593
2.07k
        c = objlen > *len ? *len : objlen;
1594
1595
10.2k
      memcpy(parm, obj, c);
1596
10.2k
      *len = c;
1597
10.2k
    }
1598
10.2k
    break;
1599
10.2k
  case SC_ASN1_GENERALIZEDTIME:
1600
4
    if (parm != NULL) {
1601
2
      size_t c;
1602
2
      if (len == NULL)
1603
0
        return SC_ERROR_INTERNAL;
1604
2
      if (entry->flags & SC_ASN1_ALLOC) {
1605
0
        u8 **buf = (u8 **) parm;
1606
0
        if (objlen > 0) {
1607
0
          *buf = malloc(objlen);
1608
0
          if (*buf == NULL) {
1609
0
            r = SC_ERROR_OUT_OF_MEMORY;
1610
0
            break;
1611
0
          }
1612
0
        }
1613
0
        c = *len = objlen;
1614
0
        parm = *buf;
1615
0
      } else
1616
2
        c = objlen > *len ? *len : objlen;
1617
1618
2
      memcpy(parm, obj, c);
1619
2
      *len = c;
1620
2
    }
1621
4
    break;
1622
582
  case SC_ASN1_OBJECT:
1623
582
    if (parm != NULL)
1624
578
      r = sc_asn1_decode_object_id(obj, objlen, (struct sc_object_id *) parm);
1625
582
    break;
1626
8
  case SC_ASN1_PRINTABLESTRING:
1627
254
  case SC_ASN1_UTF8STRING:
1628
254
    if (parm != NULL) {
1629
247
      if (len == NULL)
1630
0
        return SC_ERROR_INTERNAL;
1631
247
      if (entry->flags & SC_ASN1_ALLOC) {
1632
0
        u8 **buf = (u8 **) parm;
1633
0
        *buf = malloc(objlen+1);
1634
0
        if (*buf == NULL) {
1635
0
          r = SC_ERROR_OUT_OF_MEMORY;
1636
0
          break;
1637
0
        }
1638
0
        *len = objlen+1;
1639
0
        parm = *buf;
1640
0
      }
1641
247
      r = sc_asn1_decode_utf8string(obj, objlen, (u8 *) parm, len);
1642
247
      if (entry->flags & SC_ASN1_ALLOC) {
1643
0
        *len -= 1;
1644
0
      }
1645
247
    }
1646
254
    break;
1647
733
  case SC_ASN1_PATH:
1648
733
    if (entry->parm != NULL)
1649
733
      r = asn1_decode_path(ctx, obj, objlen, (sc_path_t *) parm, depth);
1650
733
    break;
1651
1.21k
  case SC_ASN1_PKCS15_ID:
1652
1.21k
    if (entry->parm != NULL) {
1653
1.21k
      struct sc_pkcs15_id *id = (struct sc_pkcs15_id *) parm;
1654
1.21k
      size_t c = objlen > sizeof(id->value) ? sizeof(id->value) : objlen;
1655
1656
1.21k
      memcpy(id->value, obj, c);
1657
1.21k
      id->len = c;
1658
1.21k
    }
1659
1.21k
    break;
1660
2.52k
  case SC_ASN1_PKCS15_OBJECT:
1661
2.52k
    if (entry->parm != NULL)
1662
2.47k
      r = asn1_decode_p15_object(ctx, obj, objlen, (struct sc_asn1_pkcs15_object *) parm, depth);
1663
2.52k
    break;
1664
424
  case SC_ASN1_ALGORITHM_ID:
1665
424
    if (entry->parm != NULL)
1666
424
      r = sc_asn1_decode_algorithm_id(ctx, obj, objlen, (struct sc_algorithm_id *) parm, depth);
1667
424
    break;
1668
5
  case SC_ASN1_SE_INFO:
1669
5
    if (entry->parm != NULL)
1670
5
      r = asn1_decode_se_info(ctx, obj, objlen, (sc_pkcs15_sec_env_info_t ***)entry->parm, len, depth);
1671
5
    break;
1672
284
  case SC_ASN1_CALLBACK:
1673
284
    if (entry->parm != NULL)
1674
284
      r = callback_func(ctx, entry->arg, obj, objlen, depth);
1675
284
    break;
1676
0
  default:
1677
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid ASN.1 type: %d\n", entry->type);
1678
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
1679
26.1k
  }
1680
26.1k
  if (r) {
1681
5.45k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "decoding of ASN.1 object '%s' failed: %s\n", entry->name,
1682
5.45k
          sc_strerror(r));
1683
5.45k
    return r;
1684
5.45k
  }
1685
20.7k
  entry->flags |= SC_ASN1_PRESENT;
1686
20.7k
  return 0;
1687
26.1k
}
1688
1689
108k
static void sc_free_entry(struct sc_asn1_entry *asn1) {
1690
108k
  int idx = 0;
1691
108k
  struct sc_asn1_entry *entry = asn1;
1692
1693
108k
  if (!asn1)
1694
2.56k
    return;
1695
1696
506k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
1697
400k
    entry = &asn1[idx];
1698
400k
    switch (entry->type) {
1699
31.3k
    case SC_ASN1_CHOICE:
1700
93.4k
    case SC_ASN1_STRUCT:
1701
93.4k
      sc_free_entry((struct sc_asn1_entry *) entry->parm);
1702
93.4k
      break;
1703
17.6k
    case SC_ASN1_OCTET_STRING:
1704
17.6k
    case SC_ASN1_BIT_STRING_NI:
1705
17.6k
    case SC_ASN1_BIT_STRING:
1706
19.8k
    case SC_ASN1_GENERALIZEDTIME:
1707
21.8k
    case SC_ASN1_PRINTABLESTRING:
1708
35.1k
    case SC_ASN1_UTF8STRING:
1709
35.1k
      if ((entry->flags & SC_ASN1_ALLOC) && (entry->flags & SC_ASN1_PRESENT)) {
1710
114
        u8 **buf = (u8 **)entry->parm;
1711
114
        free(*buf);
1712
114
        *buf = NULL;
1713
114
      }
1714
35.1k
      break;
1715
272k
    default:
1716
272k
      break;
1717
400k
    }
1718
400k
  }
1719
105k
}
1720
1721
static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1722
           const u8 *in, size_t len, const u8 **newp, size_t *len_left,
1723
           int choice, int depth)
1724
78.8k
{
1725
78.8k
  int r, idx = 0;
1726
78.8k
  const u8 *p = in, *obj;
1727
78.8k
  struct sc_asn1_entry *entry = asn1;
1728
78.8k
  size_t left = len, objlen;
1729
1730
78.8k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1731
78.8k
     "%*.*s""called, left=%"SC_FORMAT_LEN_SIZE_T"u, depth %d%s\n",
1732
78.8k
     depth, depth, "", left, depth, choice ? ", choice" : "");
1733
1734
78.8k
  if (!p)
1735
0
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1736
78.8k
  if (left < 2) {
1737
25.7k
    while (asn1->name && (asn1->flags & SC_ASN1_OPTIONAL))
1738
10.6k
      asn1++;
1739
    /* If all elements were optional, there's nothing
1740
     * to complain about */
1741
15.1k
    if (asn1->name == NULL)
1742
4.38k
      return 0;
1743
10.7k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "End of ASN.1 stream, "
1744
10.7k
            "non-optional field \"%s\" not found\n",
1745
10.7k
            asn1->name);
1746
10.7k
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1747
15.1k
  }
1748
63.7k
  if (p[0] == 0 || p[0] == 0xFF || len == 0)
1749
7.62k
    return SC_ERROR_ASN1_END_OF_CONTENTS;
1750
1751
142k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
1752
113k
    entry = &asn1[idx];
1753
1754
113k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Looking for '%s', tag 0x%x%s%s\n",
1755
113k
      entry->name, entry->tag, choice? ", CHOICE" : "",
1756
113k
      (entry->flags & SC_ASN1_OPTIONAL)? ", OPTIONAL": "");
1757
1758
    /* Special case CHOICE has no tag */
1759
113k
    if (entry->type == SC_ASN1_CHOICE) {
1760
5.83k
      r = asn1_decode(ctx,
1761
5.83k
        (struct sc_asn1_entry *) entry->parm,
1762
5.83k
        p, left, &p, &left, 1, depth + 1);
1763
      /* When the inner call fails it returns before writing
1764
       * back to *newp and *len_left, so the caller's p/left are
1765
       * unchanged.  Swallowing the error for an optional
1766
       * CHOICE is therefore safe: the next field will be
1767
       * attempted at the same position. */
1768
5.83k
      if (r >= 0 || (entry->flags & SC_ASN1_OPTIONAL))
1769
298
        r = 0;
1770
5.83k
      goto decode_ok;
1771
5.83k
    }
1772
1773
107k
    obj = sc_asn1_skip_tag(ctx, &p, &left, entry->tag, &objlen);
1774
107k
    if (obj == NULL) {
1775
81.0k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "'%s' not present\n", entry->name);
1776
81.0k
      if (choice)
1777
28.6k
        continue;
1778
52.4k
      if (entry->flags & SC_ASN1_OPTIONAL)
1779
37.7k
        continue;
1780
14.7k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "mandatory ASN.1 object '%s' not found\n", entry->name);
1781
14.7k
      if (left) {
1782
14.5k
        u8 line[128], *linep = line;
1783
14.5k
        size_t i;
1784
1785
14.5k
        line[0] = 0;
1786
88.2k
        for (i = 0; i < 10 && i < left; i++) {
1787
73.7k
          sprintf((char *) linep, "%02X ", p[i]);
1788
73.7k
          linep += 3;
1789
73.7k
        }
1790
14.5k
        sc_debug(ctx, SC_LOG_DEBUG_ASN1, "next tag: %s\n", line);
1791
14.5k
      }
1792
14.7k
      sc_free_entry(asn1);
1793
14.7k
      SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1794
14.7k
    }
1795
26.1k
    r = asn1_decode_entry(ctx, entry, obj, objlen, depth);
1796
1797
32.0k
decode_ok:
1798
32.0k
    if (r)
1799
10.9k
      return r;
1800
21.0k
    if (choice)
1801
559
      break;
1802
21.0k
  }
1803
30.4k
  if (choice && asn1[idx].name == NULL) /* No match */
1804
9.68k
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1805
20.7k
  if (newp != NULL)
1806
1.61k
    *newp = p;
1807
20.7k
  if (len_left != NULL)
1808
1.61k
    *len_left = left;
1809
20.7k
  if (choice)
1810
559
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, idx);
1811
20.1k
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, 0);
1812
20.1k
}
1813
1814
int sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1815
       const u8 *in, size_t len, const u8 **newp, size_t *len_left)
1816
51.5k
{
1817
51.5k
  return asn1_decode(ctx, asn1, in, len, newp, len_left, 0, 0);
1818
51.5k
}
1819
1820
int sc_asn1_decode_choice(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1821
        const u8 *in, size_t len, const u8 **newp, size_t *len_left)
1822
11.1k
{
1823
11.1k
  return asn1_decode(ctx, asn1, in, len, newp, len_left, 1, 0);
1824
11.1k
}
1825
1826
static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entry,
1827
           u8 **obj, size_t *objlen, int depth)
1828
39.7k
{
1829
39.7k
  void *parm = entry->parm;
1830
39.7k
  int (*callback_func)(sc_context_t *nctx, void *arg, u8 **nobj,
1831
39.7k
           size_t *nobjlen, int ndepth);
1832
39.7k
  const size_t *len = (const size_t *) entry->arg;
1833
39.7k
  int r = 0;
1834
39.7k
  u8 * buf = NULL;
1835
39.7k
  size_t buflen = 0;
1836
1837
39.7k
  callback_func = parm;
1838
1839
39.7k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sencoding '%s'%s\n",
1840
39.7k
          depth, depth, "", entry->name,
1841
39.7k
    (entry->flags & SC_ASN1_PRESENT)? "" : " (not present)");
1842
39.7k
  if (!(entry->flags & SC_ASN1_PRESENT))
1843
17.4k
    goto no_object;
1844
22.3k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1845
22.3k
     "%*.*stype=%d, tag=0x%02x, parm=%p, len=%"SC_FORMAT_LEN_SIZE_T"u\n",
1846
22.3k
     depth, depth, "", entry->type, entry->tag, parm,
1847
22.3k
     len ? *len : 0);
1848
1849
22.3k
  if (entry->type == SC_ASN1_CHOICE) {
1850
0
    const struct sc_asn1_entry *list, *choice = NULL;
1851
1852
0
    list = (const struct sc_asn1_entry *) parm;
1853
0
    while (list->name != NULL) {
1854
0
      if (list->flags & SC_ASN1_PRESENT) {
1855
0
        if (choice) {
1856
0
          sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1857
0
            "ASN.1 problem: more than "
1858
0
            "one CHOICE when encoding %s: "
1859
0
            "%s and %s both present\n",
1860
0
            entry->name,
1861
0
            choice->name,
1862
0
            list->name);
1863
0
          return SC_ERROR_INVALID_ASN1_OBJECT;
1864
0
        }
1865
0
        choice = list;
1866
0
      }
1867
0
      list++;
1868
0
    }
1869
0
    if (choice == NULL)
1870
0
      goto no_object;
1871
0
    return asn1_encode_entry(ctx, choice, obj, objlen, depth + 1);
1872
0
  }
1873
1874
22.3k
  if (entry->type != SC_ASN1_NULL && parm == NULL) {
1875
22
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "unexpected parm == NULL\n");
1876
22
    return SC_ERROR_INVALID_ASN1_OBJECT;
1877
22
  }
1878
1879
22.2k
  switch (entry->type) {
1880
293
  case SC_ASN1_STRUCT:
1881
293
    r = asn1_encode(ctx, (const struct sc_asn1_entry *) parm, &buf,
1882
293
        &buflen, depth + 1);
1883
293
    break;
1884
56
  case SC_ASN1_NULL:
1885
56
    buf = NULL;
1886
56
    buflen = 0;
1887
56
    break;
1888
0
  case SC_ASN1_BOOLEAN:
1889
0
    buf = malloc(1);
1890
0
    if (buf == NULL) {
1891
0
      r = SC_ERROR_OUT_OF_MEMORY;
1892
0
      break;
1893
0
    }
1894
0
    buf[0] = *((int *) parm) ? 0xFF : 0;
1895
0
    buflen = 1;
1896
0
    break;
1897
0
  case SC_ASN1_INTEGER:
1898
0
  case SC_ASN1_ENUMERATED:
1899
0
    r = asn1_encode_integer(*((int *) entry->parm), &buf, &buflen);
1900
0
    break;
1901
115
  case SC_ASN1_BIT_STRING_NI:
1902
115
  case SC_ASN1_BIT_STRING:
1903
115
    if (len != NULL) {
1904
115
      if (entry->type == SC_ASN1_BIT_STRING)
1905
0
        r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 1);
1906
115
      else
1907
115
        r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0);
1908
115
    } else {
1909
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1910
0
    }
1911
115
    break;
1912
0
  case SC_ASN1_BIT_FIELD:
1913
0
    if (len != NULL) {
1914
0
      r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen);
1915
0
    } else {
1916
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1917
0
    }
1918
0
    break;
1919
0
  case SC_ASN1_PRINTABLESTRING:
1920
18.0k
  case SC_ASN1_OCTET_STRING:
1921
18.0k
  case SC_ASN1_UTF8STRING:
1922
18.0k
    if (len != NULL) {
1923
18.0k
      buf = malloc(*len + 1);
1924
18.0k
      if (buf == NULL) {
1925
0
        r = SC_ERROR_OUT_OF_MEMORY;
1926
0
        break;
1927
0
      }
1928
18.0k
      buflen = 0;
1929
      /* If the integer is supposed to be unsigned, insert
1930
       * a padding byte if the MSB is one */
1931
18.0k
      if ((entry->flags & SC_ASN1_UNSIGNED)
1932
314
          && (((u8 *) parm)[0] & 0x80)) {
1933
117
        buf[buflen++] = 0x00;
1934
117
      }
1935
18.0k
      memcpy(buf + buflen, parm, *len);
1936
18.0k
      buflen += *len;
1937
18.0k
    } else {
1938
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1939
0
    }
1940
18.0k
    break;
1941
18.0k
  case SC_ASN1_GENERALIZEDTIME:
1942
0
    if (len != NULL) {
1943
0
      buf = malloc(*len);
1944
0
      if (buf == NULL) {
1945
0
        r = SC_ERROR_OUT_OF_MEMORY;
1946
0
        break;
1947
0
      }
1948
0
      memcpy(buf, parm, *len);
1949
0
      buflen = *len;
1950
0
    } else {
1951
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1952
0
    }
1953
0
    break;
1954
3.65k
  case SC_ASN1_OBJECT:
1955
3.65k
    r = sc_asn1_encode_object_id(&buf, &buflen, (struct sc_object_id *) parm);
1956
3.65k
    break;
1957
0
  case SC_ASN1_PATH:
1958
0
    r = asn1_encode_path(ctx, (const sc_path_t *) parm, &buf, &buflen, depth, entry->flags);
1959
0
    break;
1960
0
  case SC_ASN1_PKCS15_ID:
1961
0
    {
1962
0
      const struct sc_pkcs15_id *id = (const struct sc_pkcs15_id *) parm;
1963
1964
0
      buf = malloc(id->len);
1965
0
      if (buf == NULL) {
1966
0
        r = SC_ERROR_OUT_OF_MEMORY;
1967
0
        break;
1968
0
      }
1969
0
      memcpy(buf, id->value, id->len);
1970
0
      buflen = id->len;
1971
0
    }
1972
0
    break;
1973
0
  case SC_ASN1_PKCS15_OBJECT:
1974
0
    r = asn1_encode_p15_object(ctx, (const struct sc_asn1_pkcs15_object *) parm, &buf, &buflen, depth);
1975
0
    break;
1976
115
  case SC_ASN1_ALGORITHM_ID:
1977
115
    r = sc_asn1_encode_algorithm_id(ctx, &buf, &buflen, (const struct sc_algorithm_id *) parm, depth);
1978
115
    break;
1979
0
  case SC_ASN1_SE_INFO:
1980
0
    if (!len)
1981
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
1982
0
    r = asn1_encode_se_info(ctx, (struct sc_pkcs15_sec_env_info **)parm, *len, &buf, &buflen, depth);
1983
0
    break;
1984
0
  case SC_ASN1_CALLBACK:
1985
0
    r = callback_func(ctx, entry->arg, &buf, &buflen, depth);
1986
0
    break;
1987
0
  default:
1988
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid ASN.1 type: %d\n", entry->type);
1989
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
1990
22.2k
  }
1991
22.2k
  if (r) {
1992
30
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "encoding of ASN.1 object '%s' failed: %s\n", entry->name,
1993
30
          sc_strerror(r));
1994
30
    if (buf)
1995
0
      free(buf);
1996
30
    return r;
1997
30
  }
1998
1999
  /* Treatment of OPTIONAL elements:
2000
   *  - if the encoding has 0 length, and the element is OPTIONAL,
2001
   *  we don't write anything (unless it's an ASN1 NULL and the
2002
   *      SC_ASN1_PRESENT flag is set).
2003
   *  - if the encoding has 0 length, but the element is non-OPTIONAL,
2004
   *  constructed, we write a empty element (e.g. a SEQUENCE of
2005
   *      length 0). In case of an ASN1 NULL just write the tag and
2006
   *      length (i.e. 0x05,0x00).
2007
   *  - any other empty objects are considered bogus
2008
   */
2009
39.7k
no_object:
2010
39.7k
  if (!buflen && entry->flags & SC_ASN1_OPTIONAL && !(entry->flags & SC_ASN1_PRESENT)) {
2011
    /* This happens when we try to encode e.g. the
2012
     * subClassAttributes, which may be empty */
2013
17.4k
    *obj = NULL;
2014
17.4k
    *objlen = 0;
2015
17.4k
    r = 0;
2016
22.2k
  } else if (!buflen && (entry->flags & SC_ASN1_EMPTY_ALLOWED)) {
2017
0
    *obj = NULL;
2018
0
    *objlen = 0;
2019
0
    r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
2020
0
    if (r)
2021
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n", sc_strerror(r));
2022
22.2k
  } else if (buflen || entry->type == SC_ASN1_NULL || entry->tag & SC_ASN1_CONS) {
2023
22.2k
    r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
2024
22.2k
    if (r)
2025
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n",
2026
22.2k
          sc_strerror(r));
2027
22.2k
  } else if (!(entry->flags & SC_ASN1_PRESENT)) {
2028
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode non-optional ASN.1 object: not given by caller\n");
2029
0
    r = SC_ERROR_INVALID_ASN1_OBJECT;
2030
8
  } else {
2031
8
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode empty non-optional ASN.1 object\n");
2032
8
    r = SC_ERROR_INVALID_ASN1_OBJECT;
2033
8
  }
2034
39.7k
  if (buf)
2035
22.2k
    free(buf);
2036
39.7k
  if (r >= 0)
2037
39.6k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1,
2038
39.7k
       "%*.*slength of encoded item=%"SC_FORMAT_LEN_SIZE_T"u\n",
2039
39.7k
       depth, depth, "", *objlen);
2040
39.7k
  return r;
2041
22.2k
}
2042
2043
static int asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2044
          u8 **ptr, size_t *size, int depth)
2045
21.9k
{
2046
21.9k
  int r, idx = 0;
2047
21.9k
  u8 *obj = NULL, *buf = NULL, *tmp;
2048
21.9k
  size_t total = 0, objsize;
2049
2050
21.9k
  if (asn1 == NULL) {
2051
0
    return SC_ERROR_INVALID_ARGUMENTS;
2052
0
  }
2053
2054
61.6k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
2055
39.7k
    r = asn1_encode_entry(ctx, &asn1[idx], &obj, &objsize, depth);
2056
39.7k
    if (r) {
2057
60
      if (obj)
2058
0
        free(obj);
2059
60
      if (buf)
2060
10
        free(buf);
2061
60
      return r;
2062
60
    }
2063
    /* in case of an empty (optional) element continue with
2064
     * the next asn1 element */
2065
39.6k
    if (!objsize)
2066
17.4k
      continue;
2067
22.2k
    tmp = (u8 *) realloc(buf, total + objsize);
2068
22.2k
    if (!tmp) {
2069
0
      if (obj)
2070
0
        free(obj);
2071
0
      if (buf)
2072
0
        free(buf);
2073
0
      return SC_ERROR_OUT_OF_MEMORY;
2074
0
    }
2075
22.2k
    buf = tmp;
2076
22.2k
    memcpy(buf + total, obj, objsize);
2077
22.2k
    free(obj);
2078
22.2k
    obj = NULL;
2079
22.2k
    total += objsize;
2080
22.2k
  }
2081
21.9k
  *ptr = buf;
2082
21.9k
  *size = total;
2083
21.9k
  return 0;
2084
21.9k
}
2085
2086
int sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2087
       u8 **ptr, size_t *size)
2088
18.0k
{
2089
18.0k
  return asn1_encode(ctx, asn1, ptr, size, 0);
2090
18.0k
}
2091
2092
int _sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2093
        u8 **ptr, size_t *size, int depth)
2094
3.65k
{
2095
3.65k
  return asn1_encode(ctx, asn1, ptr, size, depth);
2096
3.65k
}
2097
2098
int
2099
_sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
2100
           const u8 *in, size_t len, const u8 **newp, size_t *left,
2101
           int choice, int depth)
2102
424
{
2103
424
  return asn1_decode(ctx, asn1, in, len, newp, left, choice, depth);
2104
424
}
2105
2106
int
2107
sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src)
2108
737
{
2109
737
  if (!dst || !src)
2110
0
    return SC_ERROR_INVALID_ARGUMENTS;
2111
737
  memset(dst, 0, sizeof(*dst));
2112
737
  if (src->len) {
2113
735
    if (!src->value)
2114
0
      return SC_ERROR_INVALID_ARGUMENTS;
2115
735
    dst->value = malloc(src->len);
2116
735
    if (!dst->value)
2117
0
      return SC_ERROR_OUT_OF_MEMORY;
2118
735
    dst->len = src->len;
2119
735
    memcpy(dst->value, src->value, src->len);
2120
735
  }
2121
737
  return SC_SUCCESS;
2122
737
}
2123
2124
int
2125
sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id,
2126
    unsigned char **out, size_t *size)
2127
3.53k
{
2128
3.53k
  static const struct sc_asn1_entry c_asn1_object_id[2] = {
2129
3.53k
    { "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_ALLOC, NULL, NULL },
2130
3.53k
    { NULL, 0, 0, 0, NULL, NULL }
2131
3.53k
  };
2132
3.53k
  struct sc_asn1_entry asn1_object_id[2];
2133
3.53k
  int rv;
2134
2135
3.53k
  sc_copy_asn1_entry(c_asn1_object_id, asn1_object_id);
2136
3.53k
  sc_format_asn1_entry(asn1_object_id + 0, id, NULL, 1);
2137
2138
3.53k
  rv = _sc_asn1_encode(ctx, asn1_object_id, out, size, 1);
2139
3.53k
  LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
2140
2141
3.53k
  return SC_SUCCESS;
2142
3.53k
}
2143
2144
2145
#define C_ASN1_SIG_VALUE_SIZE 2
2146
static struct sc_asn1_entry c_asn1_sig_value[C_ASN1_SIG_VALUE_SIZE] = {
2147
    { "ECDSA-Sig-Value", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2148
    { NULL, 0, 0, 0, NULL, NULL }
2149
};
2150
2151
#define C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE 3
2152
static struct sc_asn1_entry c_asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE] = {
2153
    { "r", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2154
    { "s", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2155
    { NULL, 0, 0, 0, NULL, NULL }
2156
};
2157
2158
2159
int
2160
sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char *in, size_t inlen,
2161
    unsigned char **buf, size_t *buflen)
2162
0
{
2163
0
  struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2164
0
  struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2165
0
  unsigned char *r = in, *s = in + inlen/2;
2166
0
  size_t r_len = inlen/2, s_len = inlen/2;
2167
0
  int rv;
2168
2169
0
  LOG_FUNC_CALLED(ctx);
2170
2171
  /* R/S are filled up with zeroes, we do not want that in sequence format */
2172
0
  while(r_len > 1 && *r == 0x00) {
2173
0
    r++;
2174
0
    r_len--;
2175
0
  }
2176
0
  while(s_len > 1 && *s == 0x00) {
2177
0
    s++;
2178
0
    s_len--;
2179
0
  }
2180
2181
0
  sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2182
0
  sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 1);
2183
2184
0
  sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2185
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 0, r, &r_len, 1);
2186
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 1, s, &s_len, 1);
2187
2188
0
  rv = sc_asn1_encode(ctx, asn1_sig_value, buf, buflen);
2189
0
  LOG_TEST_RET(ctx, rv, "ASN.1 encoding ECDSA-SIg-Value failed");
2190
2191
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2192
0
}
2193
2194
2195
int
2196
sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in, size_t inlen,
2197
    unsigned char *buf, size_t buflen)
2198
0
{
2199
0
  struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2200
0
  struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2201
0
  unsigned char *r = NULL, *s = NULL;
2202
0
  size_t r_len = 0, s_len = 0, halflen = buflen/2;
2203
0
  int rv;
2204
2205
0
  LOG_FUNC_CALLED(ctx);
2206
0
  if (!buf || !buflen)
2207
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2208
2209
0
  sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2210
0
  sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 0);
2211
2212
0
  sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2213
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 0, &r, &r_len, 0);
2214
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 1, &s, &s_len, 0);
2215
2216
0
  rv = sc_asn1_decode(ctx, asn1_sig_value, in, inlen, NULL, NULL);
2217
0
  LOG_TEST_GOTO_ERR(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed");
2218
2219
0
  if (halflen < r_len || halflen < s_len)   {
2220
0
    rv = SC_ERROR_BUFFER_TOO_SMALL;
2221
0
    goto err;
2222
0
  }
2223
2224
0
  memset(buf, 0, buflen);
2225
0
  if (r_len > 0)
2226
0
    memcpy(buf + (halflen - r_len), r, r_len);
2227
0
  if (s_len > 0)
2228
0
    memcpy(buf + (buflen - s_len), s, s_len);
2229
2230
0
  sc_log(ctx, "r(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2231
0
         sc_dump_hex(buf, halflen));
2232
0
  sc_log(ctx, "s(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2233
0
         sc_dump_hex(buf + halflen, halflen));
2234
2235
0
  rv = SC_SUCCESS;
2236
0
err:
2237
0
  free(r);
2238
0
  free(s);
2239
2240
0
  LOG_FUNC_RETURN(ctx, rv);
2241
0
}
2242
2243
0
int sc_asn1_decode_ecdsa_signature(sc_context_t *ctx, const u8 *data, size_t datalen, size_t fieldsize, u8 **out, size_t outlen) {
2244
0
  int i, r;
2245
0
  const unsigned char *pseq, *pint, *pend;
2246
0
  unsigned int cla, tag;
2247
0
  size_t seqlen, intlen;
2248
2249
0
  if (!ctx || !data || !out || !(*out)) {
2250
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2251
0
  }
2252
0
  if (outlen < 2 * fieldsize) {
2253
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Output too small for EC signature");
2254
0
  }
2255
2256
0
  memset(*out, 0, outlen);
2257
2258
0
  pseq = data;
2259
0
  r = sc_asn1_read_tag(&pseq, datalen, &cla, &tag, &seqlen);
2260
0
  if (pseq == NULL || r < 0 || seqlen == 0 || (cla | tag) != 0x30)
2261
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x30 tag");
2262
2263
0
  pint = pseq;
2264
0
  pend = pseq + seqlen;
2265
0
  for (i = 0; i < 2; i++) {
2266
0
    r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen);
2267
0
    if (pint == NULL || r < 0 || intlen == 0 || (cla | tag) != 0x02) {
2268
0
      r = SC_ERROR_INVALID_DATA;
2269
0
      LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x02");
2270
0
    }
2271
2272
0
    if (intlen == fieldsize + 1) { /* drop leading 00 if present */
2273
0
      if (*pint != 0x00) {
2274
0
        r = SC_ERROR_INVALID_DATA;
2275
0
        LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long");
2276
0
      }
2277
0
      pint++;
2278
0
      intlen--;
2279
0
    }
2280
0
    if (intlen > fieldsize) {
2281
0
      r = SC_ERROR_INVALID_DATA;
2282
0
      LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long");
2283
0
    }
2284
0
    memcpy(*out + fieldsize * i + fieldsize - intlen , pint, intlen);
2285
0
    pint += intlen; /* next integer */
2286
0
  }
2287
0
  r = (int)(2 * fieldsize);
2288
0
err:
2289
0
  LOG_FUNC_RETURN(ctx, r);
2290
0
}
2291