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
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
52.7k
{
65
52.7k
  const u8 *p = *buf;
66
52.7k
  size_t left = buflen, len;
67
52.7k
  unsigned int cla, tag, i;
68
69
52.7k
  *buf = NULL;
70
71
52.7k
  if (left == 0 || !p || buflen == 0)
72
157
    return SC_ERROR_INVALID_ASN1_OBJECT;
73
52.6k
  if (*p == 0xff || *p == 0) {
74
    /* end of data reached */
75
4.76k
    *taglen = 0;
76
4.76k
    *tag_out = SC_ASN1_TAG_EOC;
77
4.76k
    return SC_SUCCESS;
78
4.76k
  }
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
47.8k
  cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
85
47.8k
  tag = *p & SC_ASN1_TAG_PRIMITIVE;
86
47.8k
  if (left < 1)
87
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
88
47.8k
  p++;
89
47.8k
  left--;
90
47.8k
  if (tag == SC_ASN1_TAG_PRIMITIVE) {
91
    /* high tag number */
92
1.03k
    size_t n = SC_ASN1_TAGNUM_SIZE - 1;
93
    /* search the last tag octet */
94
1.56k
    do {
95
1.56k
      if (left == 0 || n == 0)
96
        /* either an invalid tag or it doesn't fit in
97
         * unsigned int */
98
73
        return SC_ERROR_INVALID_ASN1_OBJECT;
99
1.49k
      tag <<= 8;
100
1.49k
      tag |= *p;
101
1.49k
      p++;
102
1.49k
      left--;
103
1.49k
      n--;
104
1.49k
    } while (tag & 0x80);
105
1.03k
  }
106
107
  /* parse length byte(s) */
108
47.7k
  if (left == 0)
109
108
    return SC_ERROR_INVALID_ASN1_OBJECT;
110
47.6k
  len = *p;
111
47.6k
  p++;
112
47.6k
  left--;
113
47.6k
  if (len & 0x80) {
114
7.90k
    len &= 0x7f;
115
7.90k
    unsigned int a = 0;
116
7.90k
    if (len > sizeof a || len > left)
117
6.87k
      return SC_ERROR_INVALID_ASN1_OBJECT;
118
1.60k
    for (i = 0; i < len; i++) {
119
578
      a <<= 8;
120
578
      a |= *p;
121
578
      p++;
122
578
      left--;
123
578
    }
124
1.02k
    len = a;
125
1.02k
  }
126
127
40.7k
  *cla_out = cla;
128
40.7k
  *tag_out = tag;
129
40.7k
  *taglen = len;
130
40.7k
  *buf = p;
131
132
40.7k
  if (len > left)
133
6.03k
    return SC_ERROR_ASN1_END_OF_CONTENTS;
134
135
34.7k
  return SC_SUCCESS;
136
40.7k
}
137
138
void sc_format_asn1_entry(struct sc_asn1_entry *entry, void *parm, void *arg,
139
        int set_present)
140
49.0k
{
141
49.0k
  entry->parm = parm;
142
49.0k
  entry->arg  = arg;
143
49.0k
  if (set_present)
144
2.92k
    entry->flags |= SC_ASN1_PRESENT;
145
49.0k
}
146
147
void sc_copy_asn1_entry(const struct sc_asn1_entry *src,
148
      struct sc_asn1_entry *dest)
149
18.3k
{
150
67.3k
  while (src->name != NULL) {
151
49.0k
    *dest = *src;
152
49.0k
    dest++;
153
49.0k
    src++;
154
49.0k
  }
155
18.3k
  dest->name = NULL;
156
18.3k
}
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
6.60k
{
487
6.60k
  size_t left = buflen, taglen;
488
6.60k
  const u8 *p = buf;
489
490
6.60k
  *taglen_in = 0;
491
10.9k
  while (left >= 2) {
492
9.68k
    unsigned int cla = 0, tag, mask = 0xff00;
493
494
9.68k
    buf = p;
495
    /* read a tag */
496
9.68k
    if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
497
9.68k
        || p == NULL)
498
1.21k
      return NULL;
499
500
8.46k
    left -= (p - buf);
501
    /* we need to shift the class byte to the leftmost
502
     * byte of the tag */
503
9.44k
    while ((tag & mask) != 0) {
504
981
      cla  <<= 8;
505
981
      mask <<= 8;
506
981
    }
507
    /* compare the read tag with the given tag */
508
8.46k
    if ((tag | cla) == tag_in) {
509
      /* we have a match => return length and value part */
510
4.12k
      if (taglen > left)
511
0
        return NULL;
512
4.12k
      *taglen_in = taglen;
513
4.12k
      return p;
514
4.12k
    }
515
    /* otherwise continue reading tags */
516
4.33k
    left -= taglen;
517
4.33k
    p += taglen;
518
4.33k
  }
519
1.26k
  return NULL;
520
6.60k
}
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
35.2k
{
525
35.2k
  const u8 *p = *buf;
526
35.2k
  size_t len = *buflen, taglen;
527
35.2k
  unsigned int cla = 0, tag;
528
529
35.2k
  if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS
530
35.2k
      || p == NULL)
531
14.9k
    return NULL;
532
20.2k
  switch (cla & 0xC0) {
533
645
  case SC_ASN1_TAG_UNIVERSAL:
534
645
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_UNI)
535
645
      return NULL;
536
0
    break;
537
4.21k
  case SC_ASN1_TAG_APPLICATION:
538
4.21k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_APP)
539
4.21k
      return NULL;
540
0
    break;
541
15.2k
  case SC_ASN1_TAG_CONTEXT:
542
15.2k
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_CTX)
543
0
      return NULL;
544
15.2k
    break;
545
15.2k
  case SC_ASN1_TAG_PRIVATE:
546
149
    if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_PRV)
547
149
      return NULL;
548
0
    break;
549
20.2k
  }
550
15.2k
  if (cla & SC_ASN1_TAG_CONSTRUCTED) {
551
283
    if ((tag_in & SC_ASN1_CONS) == 0)
552
283
      return NULL;
553
283
  } else
554
14.9k
    if (tag_in & SC_ASN1_CONS)
555
0
      return NULL;
556
14.9k
  if ((tag_in & SC_ASN1_TAG_MASK) != tag)
557
6.90k
    return NULL;
558
8.06k
  len -= (p - *buf);  /* header size */
559
8.06k
  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
8.06k
  *buflen -= (p - *buf) + taglen;
566
8.06k
  *buf = p + taglen;  /* point to next tag */
567
8.06k
  *taglen_out = taglen;
568
8.06k
  return p;
569
8.06k
}
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
0
{
574
0
  return sc_asn1_skip_tag(ctx, &buf, &buflen, tag_in, taglen_out);
575
0
}
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
0
{
580
0
  const u8 *in = inbuf;
581
0
  u8 *out = (u8 *) outbuf;
582
0
  int i, count = 0;
583
0
  int zero_bits;
584
0
  size_t octets_left;
585
586
0
  if (inlen < 1)
587
0
    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
0
  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
0
  memset(outbuf, 0, outlen);
602
0
  zero_bits = *in & 0x07;
603
0
  in++;
604
0
  octets_left = inlen - 1;
605
0
  if (outlen < octets_left)
606
0
    return SC_ERROR_BUFFER_TOO_SMALL;
607
608
0
  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
0
    int bits_to_go;
613
614
0
    *out = 0;
615
0
    if (octets_left == 1 && zero_bits > 0) {
616
0
      bits_to_go = 8 - zero_bits;
617
      /* Verify the padding is zero bits */
618
0
      if (*in & (1 << (zero_bits-1))) {
619
0
        return SC_ERROR_INVALID_ASN1_OBJECT;
620
0
      }
621
0
    } else
622
0
      bits_to_go = 8;
623
0
    if (invert)
624
0
      for (i = 0; i < bits_to_go; i++) {
625
0
        *out |= ((*in >> (7 - i)) & 1) << i;
626
0
      }
627
0
    else {
628
0
      *out = *in;
629
0
    }
630
0
    out++;
631
0
    in++;
632
0
    octets_left--;
633
0
    count++;
634
0
  }
635
0
  return (count * 8) - zero_bits;
636
0
}
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
0
{
653
0
  const u8 *in = inbuf;
654
0
  u8 *out;
655
0
  size_t bytes, skipped = 0;
656
657
0
  bytes = BYTES4BITS(bits_left) + 1;
658
0
  *outbuf = out = malloc(bytes);
659
0
  if (out == NULL)
660
0
    return SC_ERROR_OUT_OF_MEMORY;
661
0
  *outlen = bytes;
662
0
  out += 1;
663
0
  while (bits_left) {
664
0
    size_t i, bits_to_go = 8;
665
666
0
    *out = 0;
667
0
    if (bits_left < 8) {
668
0
      bits_to_go = bits_left;
669
0
      skipped = 8 - bits_left;
670
0
    }
671
0
    if (invert) {
672
0
      for (i = 0; i < bits_to_go; i++)
673
0
        *out |= ((*in >> i) & 1) << (7 - i);
674
0
    } else {
675
0
      *out = *in;
676
0
      if (bits_left < 8)
677
0
        return SC_ERROR_NOT_SUPPORTED; /* FIXME */
678
0
    }
679
0
    bits_left -= bits_to_go;
680
0
    out++, in++;
681
0
  }
682
0
  out = *outbuf;
683
0
  out[0] = skipped;
684
0
  return 0;
685
0
}
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
0
{
693
0
  u8    data[sizeof(unsigned int)];
694
0
  unsigned int  field = 0;
695
0
  int   i, n;
696
697
0
  if (outlen != sizeof(data))
698
0
    return SC_ERROR_BUFFER_TOO_SMALL;
699
700
0
  n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1, strict);
701
0
  if (n < 0)
702
0
    return n;
703
704
0
  for (i = 0; i < n; i += 8) {
705
0
    field |= ((unsigned int) data[i/8] << i);
706
0
  }
707
0
  memcpy(outbuf, &field, outlen);
708
0
  return 0;
709
0
}
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
0
{
735
0
  int    a = 0, is_negative = 0;
736
0
  size_t i = 0;
737
738
0
  if (inlen == 0) {
739
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
740
0
  }
741
0
  if (inlen > sizeof(int)) {
742
0
    return SC_ERROR_NOT_SUPPORTED;
743
0
  }
744
0
  if (inbuf[0] & 0x80) {
745
0
    if (strict && inlen > 1 && inbuf[0] == 0xff && (inbuf[1] & 0x80)) {
746
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
747
0
    }
748
0
    is_negative = 1;
749
0
    a |= 0xff^(*inbuf++);
750
0
    i = 1;
751
0
  } else {
752
0
    if (strict && inlen > 1 && inbuf[0] == 0x00 && (inbuf[1] & 0x80) == 0) {
753
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
754
0
    }
755
0
  }
756
0
  for (; i < inlen; i++) {
757
0
    if (a > (INT_MAX >> 8) || a < (INT_MIN + (1<<8))) {
758
0
      return SC_ERROR_NOT_SUPPORTED;
759
0
    }
760
0
    a <<= 8;
761
0
    if (is_negative) {
762
0
      a |= 0xff^(*inbuf++);
763
0
    } else {
764
0
      a |= *inbuf++;
765
0
    }
766
0
  }
767
0
  if (is_negative) {
768
    /* Calculate Two's complement from previously positive number */
769
0
    a = (-1 * a) - 1;
770
0
  }
771
0
  *out = a;
772
0
  return 0;
773
0
}
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
0
{
835
0
  int large_second_octet = 0;
836
0
  unsigned int a = 0;
837
0
  const u8 *p = inbuf;
838
0
  int *octet;
839
840
0
  if (inlen == 0 || inbuf == NULL || id == NULL)
841
0
    return SC_ERROR_INVALID_ARGUMENTS;
842
843
0
  sc_init_oid(id);
844
0
  octet = id->value;
845
846
  /* The first octet can be 0, 1 or 2 and is derived from the first byte */
847
0
  a = MIN(*p / 40, 2);
848
0
  *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
0
  if ((*p & 0x80) == 0) {
854
0
    *octet++ = *p - (a * 40);
855
0
    inlen--;
856
0
  } else {
857
0
    large_second_octet = 1;
858
0
  }
859
860
0
  while (inlen) {
861
0
    if (!large_second_octet)
862
0
      p++;
863
    /* This signalizes empty most significant bits, which means
864
     * the unsigned integer encoding is not minimal */
865
0
    if (*p == 0x80) {
866
0
      sc_init_oid(id);
867
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
868
0
    }
869
    /* Use unsigned type here so we can process the whole INT range.
870
     * Values can not be negative */
871
0
    a = *p & 0x7F;
872
0
    inlen--;
873
0
    while (inlen && *p & 0x80) {
874
      /* Limit the OID values to int size and do not overflow */
875
0
      if (a > (UINT_MAX>>7)) {
876
0
        sc_init_oid(id);
877
0
        return SC_ERROR_NOT_SUPPORTED;
878
0
      }
879
0
      p++;
880
0
      a <<= 7;
881
0
      a |= *p & 0x7F;
882
0
      inlen--;
883
0
    }
884
0
    if (*p & 0x80) {
885
      /* We dropped out from previous cycle on the end of
886
       * data while still expecting continuation of value */
887
0
      sc_init_oid(id);
888
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
889
0
    }
890
0
    if (large_second_octet) {
891
0
      a -= (2 * 40);
892
0
    }
893
0
    if (a > INT_MAX) {
894
0
      sc_init_oid(id);
895
0
      return SC_ERROR_NOT_SUPPORTED;
896
0
    }
897
0
    *octet++ = a;
898
0
    if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS)   {
899
0
      sc_init_oid(id);
900
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
901
0
    }
902
0
    large_second_octet = 0;
903
0
  }
904
905
0
  return 0;
906
0
}
907
908
int
909
sc_asn1_encode_object_id(u8 **buf, size_t *buflen, const struct sc_object_id *id)
910
2.92k
{
911
2.92k
  u8 temp[SC_MAX_OBJECT_ID_OCTETS*5], *p = temp;
912
2.92k
  int i;
913
914
2.92k
  if (!buflen || !id)
915
0
    return SC_ERROR_INVALID_ARGUMENTS;
916
917
  /* an OID must have at least two components */
918
2.92k
  if (id->value[0] == -1 || id->value[1] == -1)
919
0
    return SC_ERROR_INVALID_ARGUMENTS;
920
921
20.7k
  for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
922
20.7k
    unsigned int k, shift;
923
924
20.7k
    if (id->value[i] == -1)
925
2.92k
      break;
926
927
17.8k
    k = id->value[i];
928
17.8k
    switch (i) {
929
2.92k
    case 0:
930
2.92k
      if (k > 2)
931
0
        return SC_ERROR_INVALID_ARGUMENTS;
932
2.92k
      *p = k * 40;
933
2.92k
      break;
934
2.92k
    case 1:
935
2.92k
      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
2.92k
      k += *p;
941
      /* fall through */
942
14.8k
    default:
943
14.8k
      shift = 28;
944
69.8k
      while (shift && (k >> shift) == 0)
945
55.0k
        shift -= 7;
946
19.3k
      while (shift) {
947
4.49k
        *p++ = 0x80 | ((k >> shift) & 0x7f);
948
4.49k
        shift -= 7;
949
4.49k
      }
950
14.8k
      *p++ = k & 0x7F;
951
14.8k
      break;
952
17.8k
    }
953
17.8k
  }
954
955
2.92k
  *buflen = p - temp;
956
957
2.92k
  if (buf)   {
958
2.92k
    *buf = malloc(*buflen);
959
2.92k
    if (!*buf)
960
0
      return SC_ERROR_OUT_OF_MEMORY;
961
2.92k
    memcpy(*buf, temp, *buflen);
962
2.92k
  }
963
2.92k
  return 0;
964
2.92k
}
965
966
static int sc_asn1_decode_utf8string(const u8 *inbuf, size_t inlen,
967
            u8 *out, size_t *outlen)
968
0
{
969
0
  if (inlen+1 > *outlen)
970
0
    return SC_ERROR_BUFFER_TOO_SMALL;
971
0
  *outlen = inlen+1;
972
0
  memcpy(out, inbuf, inlen);
973
0
  out[inlen] = 0;
974
0
  return 0;
975
0
}
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
43.7k
{
982
43.7k
  size_t c = 0;
983
43.7k
  unsigned int tag_len, ii;
984
43.7k
  u8 *p = out;
985
43.7k
  u8 tag_char[4] = {0, 0, 0, 0};
986
987
  /* Check tag */
988
43.7k
  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
87.5k
  for (tag_len = 0; tag; tag >>= 8) {
993
    /* Note: tag char will be reversed order. */
994
43.7k
    tag_char[tag_len++] = tag & 0xFF;
995
43.7k
  }
996
997
43.7k
  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
43.7k
  if (datalen > 127) {
1017
66
    c = 1;
1018
78
    while (datalen >> (c << 3))
1019
12
      c++;
1020
66
  }
1021
43.7k
  if (outlen == 0 || out == NULL) {
1022
    /* Caller only asks for the length that would be written. */
1023
196
    return (int)(tag_len + (c + 1) + datalen);
1024
196
  }
1025
  /* We will write the tag, so check the length. */
1026
43.5k
  if (outlen < tag_len + (c+1) + datalen)
1027
0
    return SC_ERROR_BUFFER_TOO_SMALL;
1028
87.1k
  for (ii=0;ii<tag_len;ii++)
1029
43.5k
    *p++ = tag_char[tag_len - ii - 1];
1030
1031
43.5k
  if (c > 0) {
1032
33
    *p++ = 0x80 | c;
1033
72
    while (c--)
1034
39
      *p++ = (datalen >> (c << 3)) & 0xFF;
1035
33
  }
1036
43.5k
  else {
1037
43.5k
    *p++ = datalen & 0x7F;
1038
43.5k
  }
1039
43.5k
  if(data && datalen > 0) {
1040
43.4k
    memcpy(p, data, datalen);
1041
43.4k
    p += datalen;
1042
43.4k
  }
1043
43.5k
  if (ptr != NULL)
1044
43.5k
    *ptr = p;
1045
43.5k
  return 0;
1046
43.5k
}
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
2.92k
{
1057
2.92k
  unsigned char t;
1058
2.92k
  unsigned char *buf, *p;
1059
2.92k
  int c = 0;
1060
2.92k
  unsigned short_tag;
1061
2.92k
  unsigned char tag_char[3] = {0, 0, 0};
1062
2.92k
  size_t tag_len, ii;
1063
1064
2.92k
  short_tag = tag & SC_ASN1_TAG_MASK;
1065
5.85k
  for (tag_len = 0; short_tag >> (8 * tag_len); tag_len++)
1066
2.92k
    tag_char[tag_len] = (short_tag >> (8 * tag_len)) & 0xFF;
1067
2.92k
  if (!tag_len)
1068
0
    tag_len = 1;
1069
1070
2.92k
  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
2.92k
  t = tag_char[tag_len - 1] & 0x1F;
1083
1084
2.92k
  switch (tag & SC_ASN1_CLASS_MASK) {
1085
2.92k
  case SC_ASN1_UNI:
1086
2.92k
    break;
1087
0
  case SC_ASN1_APP:
1088
0
    t |= SC_ASN1_TAG_APPLICATION;
1089
0
    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
2.92k
  }
1097
2.92k
  if (tag & SC_ASN1_CONS)
1098
0
    t |= SC_ASN1_TAG_CONSTRUCTED;
1099
2.92k
  if (datalen > 127) {
1100
0
    c = 1;
1101
0
    while (datalen >> (c << 3))
1102
0
      c++;
1103
0
  }
1104
1105
2.92k
  *outlen = tag_len + 1 + c + datalen;
1106
2.92k
  buf = malloc(*outlen);
1107
2.92k
  if (buf == NULL)
1108
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1109
1110
2.92k
  *out = p = buf;
1111
2.92k
  *p++ = t;
1112
2.92k
  for (ii=1;ii<tag_len;ii++)
1113
0
    *p++ = tag_char[tag_len - ii - 1];
1114
1115
2.92k
  if (c) {
1116
0
    *p++ = 0x80 | c;
1117
0
    while (c--)
1118
0
      *p++ = (datalen >> (c << 3)) & 0xFF;
1119
0
  }
1120
2.92k
  else   {
1121
2.92k
    *p++ = datalen & 0x7F;
1122
2.92k
  }
1123
2.92k
  if (datalen && data) {
1124
2.92k
    memcpy(p, data, datalen);
1125
2.92k
  }
1126
1127
2.92k
  return SC_SUCCESS;
1128
2.92k
}
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
0
{
1151
0
  int idx, count, r;
1152
0
  struct sc_asn1_entry asn1_path_ext[3], asn1_path[5];
1153
0
  unsigned char path_value[SC_MAX_PATH_SIZE], aid_value[SC_MAX_AID_SIZE];
1154
0
  size_t path_len = sizeof(path_value), aid_len = sizeof(aid_value);
1155
1156
0
  memset(path, 0, sizeof(struct sc_path));
1157
1158
0
  sc_copy_asn1_entry(c_asn1_path_ext, asn1_path_ext);
1159
0
  sc_copy_asn1_entry(c_asn1_path, asn1_path);
1160
1161
0
  sc_format_asn1_entry(asn1_path_ext + 0, aid_value, &aid_len, 0);
1162
0
  sc_format_asn1_entry(asn1_path_ext + 1, path_value, &path_len, 0);
1163
1164
0
  sc_format_asn1_entry(asn1_path + 0, path_value, &path_len, 0);
1165
0
  sc_format_asn1_entry(asn1_path + 1, &idx, NULL, 0);
1166
0
  sc_format_asn1_entry(asn1_path + 2, &count, NULL, 0);
1167
0
  sc_format_asn1_entry(asn1_path + 3, asn1_path_ext, NULL, 0);
1168
1169
0
  r = asn1_decode(ctx, asn1_path, in, len, NULL, NULL, 0, depth + 1);
1170
0
  if (r)
1171
0
    return r;
1172
1173
0
  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
0
  else if (asn1_path[0].flags & SC_ASN1_PRESENT)   {
1182
    /* path present: set 'path' */
1183
0
    memcpy(path->value, path_value, path_len);
1184
0
    path->len = path_len;
1185
0
  }
1186
0
  else   {
1187
    /* failed if both 'path' and 'pathExtended' are absent */
1188
0
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1189
0
  }
1190
1191
0
  if (path->len == 2)
1192
0
    path->type = SC_PATH_TYPE_FILE_ID;
1193
0
  else   if (path->aid.len && path->len > 2)
1194
0
    path->type = SC_PATH_TYPE_FROM_CURRENT;
1195
0
  else
1196
0
    path->type = SC_PATH_TYPE_PATH;
1197
1198
0
  if ((asn1_path[1].flags & SC_ASN1_PRESENT) && (asn1_path[2].flags & SC_ASN1_PRESENT)) {
1199
0
    path->index = idx;
1200
0
    path->count = count;
1201
0
  }
1202
0
  else {
1203
0
    path->index = 0;
1204
0
    path->count = -1;
1205
0
  }
1206
1207
0
  return SC_SUCCESS;
1208
0
}
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
0
{
1245
0
  struct sc_pkcs15_sec_env_info **ses;
1246
0
  const unsigned char *ptr = obj;
1247
0
  size_t idx, ptrlen = objlen;
1248
0
  int ret;
1249
1250
0
  LOG_FUNC_CALLED(ctx);
1251
1252
0
  ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
1253
0
  if (ses == NULL) {
1254
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1255
0
  }
1256
1257
0
  for (idx=0; idx < SC_MAX_SE_NUM && ptrlen; )   {
1258
0
    struct sc_asn1_entry asn1_se[2];
1259
0
    struct sc_asn1_entry asn1_se_info[4];
1260
0
    struct sc_pkcs15_sec_env_info si;
1261
1262
0
    sc_copy_asn1_entry(c_asn1_se, asn1_se);
1263
0
    sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1264
1265
0
    si.aid.len = sizeof(si.aid.value);
1266
0
    sc_format_asn1_entry(asn1_se_info + 0, &si.se, NULL, 0);
1267
0
    sc_format_asn1_entry(asn1_se_info + 1, &si.owner, NULL, 0);
1268
0
    sc_format_asn1_entry(asn1_se_info + 2, &si.aid.value, &si.aid.len, 0);
1269
0
    sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 0);
1270
1271
0
    ret = asn1_decode(ctx, asn1_se, ptr, ptrlen, &ptr, &ptrlen, 0, depth+1);
1272
0
    if (ret != SC_SUCCESS)
1273
0
      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
0
  *se  = ses;
1288
0
  *num = idx;
1289
0
  ret = SC_SUCCESS;
1290
0
err:
1291
0
  if (ret != SC_SUCCESS) {
1292
0
    size_t i;
1293
0
    for (i = 0; i < idx; i++)
1294
0
      if (ses[i])
1295
0
        free(ses[i]);
1296
0
    free(ses);
1297
0
  }
1298
1299
0
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, ret);
1300
0
}
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
0
{
1397
0
  struct sc_pkcs15_object *p15_obj = obj->p15_obj;
1398
0
  struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
1399
0
  struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1400
0
  size_t flags_len = sizeof(p15_obj->flags);
1401
0
  size_t label_len = sizeof(p15_obj->label);
1402
0
  size_t access_mode_len = sizeof(p15_obj->access_rules[0].access_mode);
1403
0
  int r, ii;
1404
1405
0
  for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)
1406
0
    sc_copy_asn1_entry(c_asn1_access_control_rule, asn1_ac_rule[ii]);
1407
0
  sc_copy_asn1_entry(c_asn1_access_control_rules, asn1_ac_rules);
1408
1409
1410
0
  sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1411
0
  sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1412
0
  sc_format_asn1_entry(asn1_c_attr + 0, p15_obj->label, &label_len, 0);
1413
0
  sc_format_asn1_entry(asn1_c_attr + 1, &p15_obj->flags, &flags_len, 0);
1414
0
  sc_format_asn1_entry(asn1_c_attr + 2, &p15_obj->auth_id, NULL, 0);
1415
0
  sc_format_asn1_entry(asn1_c_attr + 3, &p15_obj->user_consent, NULL, 0);
1416
1417
0
  for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)   {
1418
0
    sc_format_asn1_entry(asn1_ac_rule[ii] + 0, &p15_obj->access_rules[ii].access_mode, &access_mode_len, 0);
1419
0
    sc_format_asn1_entry(asn1_ac_rule[ii] + 1, &p15_obj->access_rules[ii].auth_id, NULL, 0);
1420
0
    sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 0);
1421
0
  }
1422
0
  sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 0);
1423
1424
0
  sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 0);
1425
0
  sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 0);
1426
0
  sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 0);
1427
0
  sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 0);
1428
1429
0
  r = asn1_decode(ctx, asn1_p15_obj, in, len, NULL, NULL, 0, depth + 1);
1430
0
  return r;
1431
0
}
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; 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
8.06k
{
1492
8.06k
  void *parm = entry->parm;
1493
8.06k
  int (*callback_func)(sc_context_t *nctx, void *arg, const u8 *nobj,
1494
8.06k
           size_t nobjlen, int ndepth);
1495
8.06k
  size_t *len = (size_t *) entry->arg;
1496
8.06k
  int r = 0;
1497
1498
8.06k
  callback_func = parm;
1499
1500
8.06k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s', raw data:%s%s\n",
1501
8.06k
    depth, depth, "", entry->name,
1502
8.06k
    sc_dump_hex(obj, objlen > 16  ? 16 : objlen),
1503
8.06k
    objlen > 16 ? "..." : "");
1504
1505
8.06k
  switch (entry->type) {
1506
0
  case SC_ASN1_STRUCT:
1507
0
    if (parm != NULL)
1508
0
      r = asn1_decode(ctx, (struct sc_asn1_entry *) parm, obj,
1509
0
               objlen, NULL, NULL, 0, depth + 1);
1510
0
    break;
1511
0
  case SC_ASN1_NULL:
1512
0
    break;
1513
0
  case SC_ASN1_BOOLEAN:
1514
0
    if (parm != NULL) {
1515
0
      if (objlen != 1) {
1516
0
        sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1517
0
           "invalid ASN.1 object length: %"SC_FORMAT_LEN_SIZE_T"u\n",
1518
0
           objlen);
1519
0
        r = SC_ERROR_INVALID_ASN1_OBJECT;
1520
0
      } else
1521
0
        *((int *) parm) = obj[0] ? 1 : 0;
1522
0
    }
1523
0
    break;
1524
0
  case SC_ASN1_INTEGER:
1525
0
  case SC_ASN1_ENUMERATED:
1526
0
    if (parm != NULL) {
1527
0
      r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm, 0);
1528
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "",
1529
0
          entry->name, *((int *) entry->parm));
1530
0
    }
1531
0
    break;
1532
0
  case SC_ASN1_BIT_STRING_NI:
1533
0
  case SC_ASN1_BIT_STRING:
1534
0
    if (parm != NULL) {
1535
0
      int invert = entry->type == SC_ASN1_BIT_STRING ? 1 : 0;
1536
0
      assert(len != NULL);
1537
0
      if (objlen < 1) {
1538
0
        r = SC_ERROR_INVALID_ASN1_OBJECT;
1539
0
        break;
1540
0
      }
1541
0
      if (entry->flags & SC_ASN1_ALLOC) {
1542
0
        u8 **buf = (u8 **) parm;
1543
0
        if (objlen > 1) {
1544
0
          *buf = malloc(objlen-1);
1545
0
          if (*buf == NULL) {
1546
0
            r = SC_ERROR_OUT_OF_MEMORY;
1547
0
            break;
1548
0
          }
1549
0
        }
1550
0
        *len = objlen-1;
1551
0
        parm = *buf;
1552
0
      }
1553
0
      r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert, 0);
1554
0
      if (r >= 0) {
1555
0
        *len = r;
1556
0
        r = 0;
1557
0
      }
1558
0
    }
1559
0
    break;
1560
0
  case SC_ASN1_BIT_FIELD:
1561
0
    if (parm != NULL)
1562
0
      r = decode_bit_field(obj, objlen, (u8 *) parm, *len, 0);
1563
0
    break;
1564
8.06k
  case SC_ASN1_OCTET_STRING:
1565
8.06k
    if (parm != NULL) {
1566
8.06k
      size_t c;
1567
8.06k
      assert(len != NULL);
1568
1569
      /* Strip off padding zero */
1570
8.06k
      if ((entry->flags & SC_ASN1_UNSIGNED)
1571
8.06k
          && objlen > 1 && obj[0] == 0x00) {
1572
0
        objlen--;
1573
0
        obj++;
1574
0
      }
1575
1576
      /* Allocate buffer if needed */
1577
8.06k
      if (entry->flags & SC_ASN1_ALLOC) {
1578
0
        u8 **buf = (u8 **) parm;
1579
0
        if (objlen > 0) {
1580
0
          *buf = malloc(objlen);
1581
0
          if (*buf == NULL) {
1582
0
            r = SC_ERROR_OUT_OF_MEMORY;
1583
0
            break;
1584
0
          }
1585
0
        }
1586
0
        c = *len = objlen;
1587
0
        parm = *buf;
1588
0
      } else
1589
8.06k
        c = objlen > *len ? *len : objlen;
1590
1591
8.06k
      memcpy(parm, obj, c);
1592
8.06k
      *len = c;
1593
8.06k
    }
1594
8.06k
    break;
1595
8.06k
  case SC_ASN1_GENERALIZEDTIME:
1596
0
    if (parm != NULL) {
1597
0
      size_t c;
1598
0
      assert(len != NULL);
1599
0
      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
0
        c = objlen > *len ? *len : objlen;
1612
1613
0
      memcpy(parm, obj, c);
1614
0
      *len = c;
1615
0
    }
1616
0
    break;
1617
0
  case SC_ASN1_OBJECT:
1618
0
    if (parm != NULL)
1619
0
      r = sc_asn1_decode_object_id(obj, objlen, (struct sc_object_id *) parm);
1620
0
    break;
1621
0
  case SC_ASN1_PRINTABLESTRING:
1622
0
  case SC_ASN1_UTF8STRING:
1623
0
    if (parm != NULL) {
1624
0
      assert(len != NULL);
1625
0
      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
0
      r = sc_asn1_decode_utf8string(obj, objlen, (u8 *) parm, len);
1636
0
      if (entry->flags & SC_ASN1_ALLOC) {
1637
0
        *len -= 1;
1638
0
      }
1639
0
    }
1640
0
    break;
1641
0
  case SC_ASN1_PATH:
1642
0
    if (entry->parm != NULL)
1643
0
      r = asn1_decode_path(ctx, obj, objlen, (sc_path_t *) parm, depth);
1644
0
    break;
1645
0
  case SC_ASN1_PKCS15_ID:
1646
0
    if (entry->parm != NULL) {
1647
0
      struct sc_pkcs15_id *id = (struct sc_pkcs15_id *) parm;
1648
0
      size_t c = objlen > sizeof(id->value) ? sizeof(id->value) : objlen;
1649
1650
0
      memcpy(id->value, obj, c);
1651
0
      id->len = c;
1652
0
    }
1653
0
    break;
1654
0
  case SC_ASN1_PKCS15_OBJECT:
1655
0
    if (entry->parm != NULL)
1656
0
      r = asn1_decode_p15_object(ctx, obj, objlen, (struct sc_asn1_pkcs15_object *) parm, depth);
1657
0
    break;
1658
0
  case SC_ASN1_ALGORITHM_ID:
1659
0
    if (entry->parm != NULL)
1660
0
      r = sc_asn1_decode_algorithm_id(ctx, obj, objlen, (struct sc_algorithm_id *) parm, depth);
1661
0
    break;
1662
0
  case SC_ASN1_SE_INFO:
1663
0
    if (entry->parm != NULL)
1664
0
      r = asn1_decode_se_info(ctx, obj, objlen, (sc_pkcs15_sec_env_info_t ***)entry->parm, len, depth);
1665
0
    break;
1666
0
  case SC_ASN1_CALLBACK:
1667
0
    if (entry->parm != NULL)
1668
0
      r = callback_func(ctx, entry->arg, obj, objlen, depth);
1669
0
    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
8.06k
  }
1674
8.06k
  if (r) {
1675
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "decoding of ASN.1 object '%s' failed: %s\n", entry->name,
1676
0
          sc_strerror(r));
1677
0
    return r;
1678
0
  }
1679
8.06k
  entry->flags |= SC_ASN1_PRESENT;
1680
8.06k
  return 0;
1681
8.06k
}
1682
1683
12.7k
static void sc_free_entry(struct sc_asn1_entry *asn1) {
1684
12.7k
  int idx = 0;
1685
12.7k
  struct sc_asn1_entry *entry = asn1;
1686
1687
12.7k
  if (!asn1)
1688
0
    return;
1689
1690
50.9k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
1691
38.2k
    entry = &asn1[idx];
1692
38.2k
    switch (entry->type) {
1693
0
    case SC_ASN1_CHOICE:
1694
0
    case SC_ASN1_STRUCT:
1695
0
      sc_free_entry((struct sc_asn1_entry *) entry->parm);
1696
0
      break;
1697
38.2k
    case SC_ASN1_OCTET_STRING:
1698
38.2k
    case SC_ASN1_BIT_STRING_NI:
1699
38.2k
    case SC_ASN1_BIT_STRING:
1700
38.2k
    case SC_ASN1_GENERALIZEDTIME:
1701
38.2k
    case SC_ASN1_PRINTABLESTRING:
1702
38.2k
    case SC_ASN1_UTF8STRING:
1703
38.2k
      if ((entry->flags & SC_ASN1_ALLOC) && (entry->flags & SC_ASN1_PRESENT)) {
1704
0
        u8 **buf = (u8 **)entry->parm;
1705
0
        free(*buf);
1706
0
        *buf = NULL;
1707
0
      }
1708
38.2k
      break;
1709
0
    default:
1710
0
      break;
1711
38.2k
    }
1712
38.2k
  }
1713
12.7k
}
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
15.3k
{
1719
15.3k
  int r, idx = 0;
1720
15.3k
  const u8 *p = in, *obj;
1721
15.3k
  struct sc_asn1_entry *entry = asn1;
1722
15.3k
  size_t left = len, objlen;
1723
1724
15.3k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1725
15.3k
     "%*.*s""called, left=%"SC_FORMAT_LEN_SIZE_T"u, depth %d%s\n",
1726
15.3k
     depth, depth, "", left, depth, choice ? ", choice" : "");
1727
1728
15.3k
  if (!p)
1729
0
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1730
15.3k
  if (left < 2) {
1731
668
    while (asn1->name && (asn1->flags & SC_ASN1_OPTIONAL))
1732
334
      asn1++;
1733
    /* If all elements were optional, there's nothing
1734
     * to complain about */
1735
334
    if (asn1->name == NULL)
1736
0
      return 0;
1737
334
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "End of ASN.1 stream, "
1738
334
            "non-optional field \"%s\" not found\n",
1739
334
            asn1->name);
1740
334
    return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1741
334
  }
1742
15.0k
  if (p[0] == 0 || p[0] == 0xFF || len == 0)
1743
598
    return SC_ERROR_ASN1_END_OF_CONTENTS;
1744
1745
36.9k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
1746
35.2k
    entry = &asn1[idx];
1747
1748
35.2k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Looking for '%s', tag 0x%x%s%s\n",
1749
35.2k
      entry->name, entry->tag, choice? ", CHOICE" : "",
1750
35.2k
      (entry->flags & SC_ASN1_OPTIONAL)? ", OPTIONAL": "");
1751
1752
    /* Special case CHOICE has no tag */
1753
35.2k
    if (entry->type == SC_ASN1_CHOICE) {
1754
0
      r = asn1_decode(ctx,
1755
0
        (struct sc_asn1_entry *) entry->parm,
1756
0
        p, left, &p, &left, 1, depth + 1);
1757
0
      if (r >= 0)
1758
0
        r = 0;
1759
0
      goto decode_ok;
1760
0
    }
1761
1762
35.2k
    obj = sc_asn1_skip_tag(ctx, &p, &left, entry->tag, &objlen);
1763
35.2k
    if (obj == NULL) {
1764
27.1k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "'%s' not present\n", entry->name);
1765
27.1k
      if (choice)
1766
0
        continue;
1767
27.1k
      if (entry->flags & SC_ASN1_OPTIONAL)
1768
14.4k
        continue;
1769
12.7k
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "mandatory ASN.1 object '%s' not found\n", entry->name);
1770
12.7k
      if (left) {
1771
12.5k
        u8 line[128], *linep = line;
1772
12.5k
        size_t i;
1773
1774
12.5k
        line[0] = 0;
1775
110k
        for (i = 0; i < 10 && i < left; i++) {
1776
98.1k
          sprintf((char *) linep, "%02X ", p[i]);
1777
98.1k
          linep += 3;
1778
98.1k
        }
1779
12.5k
        sc_debug(ctx, SC_LOG_DEBUG_ASN1, "next tag: %s\n", line);
1780
12.5k
      }
1781
12.7k
      sc_free_entry(asn1);
1782
12.7k
      SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1783
12.7k
    }
1784
8.06k
    r = asn1_decode_entry(ctx, entry, obj, objlen, depth);
1785
1786
8.06k
decode_ok:
1787
8.06k
    if (r)
1788
0
      return r;
1789
8.06k
    if (choice)
1790
0
      break;
1791
8.06k
  }
1792
1.70k
  if (choice && asn1[idx].name == NULL) /* No match */
1793
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1794
1.70k
  if (newp != NULL)
1795
0
    *newp = p;
1796
1.70k
  if (len_left != NULL)
1797
0
    *len_left = left;
1798
1.70k
  if (choice)
1799
0
    SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, idx);
1800
1.70k
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, 0);
1801
1.70k
}
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
15.3k
{
1806
15.3k
  return asn1_decode(ctx, asn1, in, len, newp, len_left, 0, 0);
1807
15.3k
}
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
0
{
1812
0
  return asn1_decode(ctx, asn1, in, len, newp, len_left, 1, 0);
1813
0
}
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
2.92k
{
1818
2.92k
  void *parm = entry->parm;
1819
2.92k
  int (*callback_func)(sc_context_t *nctx, void *arg, u8 **nobj,
1820
2.92k
           size_t *nobjlen, int ndepth);
1821
2.92k
  const size_t *len = (const size_t *) entry->arg;
1822
2.92k
  int r = 0;
1823
2.92k
  u8 * buf = NULL;
1824
2.92k
  size_t buflen = 0;
1825
1826
2.92k
  callback_func = parm;
1827
1828
2.92k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sencoding '%s'%s\n",
1829
2.92k
          depth, depth, "", entry->name,
1830
2.92k
    (entry->flags & SC_ASN1_PRESENT)? "" : " (not present)");
1831
2.92k
  if (!(entry->flags & SC_ASN1_PRESENT))
1832
0
    goto no_object;
1833
2.92k
  sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1834
2.92k
     "%*.*stype=%d, tag=0x%02x, parm=%p, len=%"SC_FORMAT_LEN_SIZE_T"u\n",
1835
2.92k
     depth, depth, "", entry->type, entry->tag, parm,
1836
2.92k
     len ? *len : 0);
1837
1838
2.92k
  if (entry->type == SC_ASN1_CHOICE) {
1839
0
    const struct sc_asn1_entry *list, *choice = NULL;
1840
1841
0
    list = (const struct sc_asn1_entry *) parm;
1842
0
    while (list->name != NULL) {
1843
0
      if (list->flags & SC_ASN1_PRESENT) {
1844
0
        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
0
        choice = list;
1855
0
      }
1856
0
      list++;
1857
0
    }
1858
0
    if (choice == NULL)
1859
0
      goto no_object;
1860
0
    return asn1_encode_entry(ctx, choice, obj, objlen, depth + 1);
1861
0
  }
1862
1863
2.92k
  if (entry->type != SC_ASN1_NULL && parm == NULL) {
1864
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "unexpected parm == NULL\n");
1865
0
    return SC_ERROR_INVALID_ASN1_OBJECT;
1866
0
  }
1867
1868
2.92k
  switch (entry->type) {
1869
0
  case SC_ASN1_STRUCT:
1870
0
    r = asn1_encode(ctx, (const struct sc_asn1_entry *) parm, &buf,
1871
0
        &buflen, depth + 1);
1872
0
    break;
1873
0
  case SC_ASN1_NULL:
1874
0
    buf = NULL;
1875
0
    buflen = 0;
1876
0
    break;
1877
0
  case SC_ASN1_BOOLEAN:
1878
0
    buf = malloc(1);
1879
0
    if (buf == NULL) {
1880
0
      r = SC_ERROR_OUT_OF_MEMORY;
1881
0
      break;
1882
0
    }
1883
0
    buf[0] = *((int *) parm) ? 0xFF : 0;
1884
0
    buflen = 1;
1885
0
    break;
1886
0
  case SC_ASN1_INTEGER:
1887
0
  case SC_ASN1_ENUMERATED:
1888
0
    r = asn1_encode_integer(*((int *) entry->parm), &buf, &buflen);
1889
0
    break;
1890
0
  case SC_ASN1_BIT_STRING_NI:
1891
0
  case SC_ASN1_BIT_STRING:
1892
0
    if (len != NULL) {
1893
0
      if (entry->type == SC_ASN1_BIT_STRING)
1894
0
        r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 1);
1895
0
      else
1896
0
        r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0);
1897
0
    } else {
1898
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1899
0
    }
1900
0
    break;
1901
0
  case SC_ASN1_BIT_FIELD:
1902
0
    if (len != NULL) {
1903
0
      r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen);
1904
0
    } else {
1905
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1906
0
    }
1907
0
    break;
1908
0
  case SC_ASN1_PRINTABLESTRING:
1909
0
  case SC_ASN1_OCTET_STRING:
1910
0
  case SC_ASN1_UTF8STRING:
1911
0
    if (len != NULL) {
1912
0
      buf = malloc(*len + 1);
1913
0
      if (buf == NULL) {
1914
0
        r = SC_ERROR_OUT_OF_MEMORY;
1915
0
        break;
1916
0
      }
1917
0
      buflen = 0;
1918
      /* If the integer is supposed to be unsigned, insert
1919
       * a padding byte if the MSB is one */
1920
0
      if ((entry->flags & SC_ASN1_UNSIGNED)
1921
0
          && (((u8 *) parm)[0] & 0x80)) {
1922
0
        buf[buflen++] = 0x00;
1923
0
      }
1924
0
      memcpy(buf + buflen, parm, *len);
1925
0
      buflen += *len;
1926
0
    } else {
1927
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1928
0
    }
1929
0
    break;
1930
0
  case SC_ASN1_GENERALIZEDTIME:
1931
0
    if (len != NULL) {
1932
0
      buf = malloc(*len);
1933
0
      if (buf == NULL) {
1934
0
        r = SC_ERROR_OUT_OF_MEMORY;
1935
0
        break;
1936
0
      }
1937
0
      memcpy(buf, parm, *len);
1938
0
      buflen = *len;
1939
0
    } else {
1940
0
      r = SC_ERROR_INVALID_ARGUMENTS;
1941
0
    }
1942
0
    break;
1943
2.92k
  case SC_ASN1_OBJECT:
1944
2.92k
    r = sc_asn1_encode_object_id(&buf, &buflen, (struct sc_object_id *) parm);
1945
2.92k
    break;
1946
0
  case SC_ASN1_PATH:
1947
0
    r = asn1_encode_path(ctx, (const sc_path_t *) parm, &buf, &buflen, depth, entry->flags);
1948
0
    break;
1949
0
  case SC_ASN1_PKCS15_ID:
1950
0
    {
1951
0
      const struct sc_pkcs15_id *id = (const struct sc_pkcs15_id *) parm;
1952
1953
0
      buf = malloc(id->len);
1954
0
      if (buf == NULL) {
1955
0
        r = SC_ERROR_OUT_OF_MEMORY;
1956
0
        break;
1957
0
      }
1958
0
      memcpy(buf, id->value, id->len);
1959
0
      buflen = id->len;
1960
0
    }
1961
0
    break;
1962
0
  case SC_ASN1_PKCS15_OBJECT:
1963
0
    r = asn1_encode_p15_object(ctx, (const struct sc_asn1_pkcs15_object *) parm, &buf, &buflen, depth);
1964
0
    break;
1965
0
  case SC_ASN1_ALGORITHM_ID:
1966
0
    r = sc_asn1_encode_algorithm_id(ctx, &buf, &buflen, (const struct sc_algorithm_id *) parm, depth);
1967
0
    break;
1968
0
  case SC_ASN1_SE_INFO:
1969
0
    if (!len)
1970
0
      return SC_ERROR_INVALID_ASN1_OBJECT;
1971
0
    r = asn1_encode_se_info(ctx, (struct sc_pkcs15_sec_env_info **)parm, *len, &buf, &buflen, depth);
1972
0
    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
2.92k
  }
1980
2.92k
  if (r) {
1981
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "encoding of ASN.1 object '%s' failed: %s\n", entry->name,
1982
0
          sc_strerror(r));
1983
0
    if (buf)
1984
0
      free(buf);
1985
0
    return r;
1986
0
  }
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
2.92k
no_object:
1999
2.92k
  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
0
    *obj = NULL;
2003
0
    *objlen = 0;
2004
0
    r = 0;
2005
2.92k
  } else if (!buflen && (entry->flags & SC_ASN1_EMPTY_ALLOWED)) {
2006
0
    *obj = NULL;
2007
0
    *objlen = 0;
2008
0
    r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
2009
0
    if (r)
2010
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n", sc_strerror(r));
2011
2.92k
  } else if (buflen || entry->type == SC_ASN1_NULL || entry->tag & SC_ASN1_CONS) {
2012
2.92k
    r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
2013
2.92k
    if (r)
2014
0
      sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n",
2015
2.92k
          sc_strerror(r));
2016
2.92k
  } else if (!(entry->flags & SC_ASN1_PRESENT)) {
2017
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode non-optional ASN.1 object: not given by caller\n");
2018
0
    r = SC_ERROR_INVALID_ASN1_OBJECT;
2019
0
  } else {
2020
0
    sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode empty non-optional ASN.1 object\n");
2021
0
    r = SC_ERROR_INVALID_ASN1_OBJECT;
2022
0
  }
2023
2.92k
  if (buf)
2024
2.92k
    free(buf);
2025
2.92k
  if (r >= 0)
2026
2.92k
    sc_debug(ctx, SC_LOG_DEBUG_ASN1,
2027
2.92k
       "%*.*slength of encoded item=%"SC_FORMAT_LEN_SIZE_T"u\n",
2028
2.92k
       depth, depth, "", *objlen);
2029
2.92k
  return r;
2030
2.92k
}
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
2.92k
{
2035
2.92k
  int r, idx = 0;
2036
2.92k
  u8 *obj = NULL, *buf = NULL, *tmp;
2037
2.92k
  size_t total = 0, objsize;
2038
2039
2.92k
  if (asn1 == NULL) {
2040
0
    return SC_ERROR_INVALID_ARGUMENTS;
2041
0
  }
2042
2043
5.85k
  for (idx = 0; asn1[idx].name != NULL; idx++) {
2044
2.92k
    r = asn1_encode_entry(ctx, &asn1[idx], &obj, &objsize, depth);
2045
2.92k
    if (r) {
2046
0
      if (obj)
2047
0
        free(obj);
2048
0
      if (buf)
2049
0
        free(buf);
2050
0
      return r;
2051
0
    }
2052
    /* in case of an empty (optional) element continue with
2053
     * the next asn1 element */
2054
2.92k
    if (!objsize)
2055
0
      continue;
2056
2.92k
    tmp = (u8 *) realloc(buf, total + objsize);
2057
2.92k
    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
2.92k
    buf = tmp;
2065
2.92k
    memcpy(buf + total, obj, objsize);
2066
2.92k
    free(obj);
2067
2.92k
    obj = NULL;
2068
2.92k
    total += objsize;
2069
2.92k
  }
2070
2.92k
  *ptr = buf;
2071
2.92k
  *size = total;
2072
2.92k
  return 0;
2073
2.92k
}
2074
2075
int sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2076
       u8 **ptr, size_t *size)
2077
0
{
2078
0
  return asn1_encode(ctx, asn1, ptr, size, 0);
2079
0
}
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
2.92k
{
2084
2.92k
  return asn1_encode(ctx, asn1, ptr, size, depth);
2085
2.92k
}
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
0
{
2092
0
  return asn1_decode(ctx, asn1, in, len, newp, left, choice, depth);
2093
0
}
2094
2095
int
2096
sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src)
2097
0
{
2098
0
  if (!dst || !src)
2099
0
    return SC_ERROR_INVALID_ARGUMENTS;
2100
0
  memset(dst, 0, sizeof(*dst));
2101
0
  if (src->len) {
2102
0
    if (!src->value)
2103
0
      return SC_ERROR_INVALID_ARGUMENTS;
2104
0
    dst->value = malloc(src->len);
2105
0
    if (!dst->value)
2106
0
      return SC_ERROR_OUT_OF_MEMORY;
2107
0
    dst->len = src->len;
2108
0
    memcpy(dst->value, src->value, src->len);
2109
0
  }
2110
0
  return SC_SUCCESS;
2111
0
}
2112
2113
int
2114
sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id,
2115
    unsigned char **out, size_t *size)
2116
2.92k
{
2117
2.92k
  static const struct sc_asn1_entry c_asn1_object_id[2] = {
2118
2.92k
    { "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_ALLOC, NULL, NULL },
2119
2.92k
    { NULL, 0, 0, 0, NULL, NULL }
2120
2.92k
  };
2121
2.92k
  struct sc_asn1_entry asn1_object_id[2];
2122
2.92k
  int rv;
2123
2124
2.92k
  sc_copy_asn1_entry(c_asn1_object_id, asn1_object_id);
2125
2.92k
  sc_format_asn1_entry(asn1_object_id + 0, id, NULL, 1);
2126
2127
2.92k
  rv = _sc_asn1_encode(ctx, asn1_object_id, out, size, 1);
2128
2.92k
  LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
2129
2130
2.92k
  return SC_SUCCESS;
2131
2.92k
}
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
0
{
2152
0
  struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2153
0
  struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2154
0
  unsigned char *r = in, *s = in + inlen/2;
2155
0
  size_t r_len = inlen/2, s_len = inlen/2;
2156
0
  int rv;
2157
2158
0
  LOG_FUNC_CALLED(ctx);
2159
2160
  /* R/S are filled up with zeroes, we do not want that in sequence format */
2161
0
  while(r_len > 1 && *r == 0x00) {
2162
0
    r++;
2163
0
    r_len--;
2164
0
  }
2165
0
  while(s_len > 1 && *s == 0x00) {
2166
0
    s++;
2167
0
    s_len--;
2168
0
  }
2169
2170
0
  sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2171
0
  sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 1);
2172
2173
0
  sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2174
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 0, r, &r_len, 1);
2175
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 1, s, &s_len, 1);
2176
2177
0
  rv = sc_asn1_encode(ctx, asn1_sig_value, buf, buflen);
2178
0
  LOG_TEST_RET(ctx, rv, "ASN.1 encoding ECDSA-SIg-Value failed");
2179
2180
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2181
0
}
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
0
{
2188
0
  struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2189
0
  struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2190
0
  unsigned char *r = NULL, *s = NULL;
2191
0
  size_t r_len = 0, s_len = 0, halflen = buflen/2;
2192
0
  int rv;
2193
2194
0
  LOG_FUNC_CALLED(ctx);
2195
0
  if (!buf || !buflen)
2196
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2197
2198
0
  sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2199
0
  sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 0);
2200
2201
0
  sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2202
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 0, &r, &r_len, 0);
2203
0
  sc_format_asn1_entry(asn1_sig_value_coefficients + 1, &s, &s_len, 0);
2204
2205
0
  rv = sc_asn1_decode(ctx, asn1_sig_value, in, inlen, NULL, NULL);
2206
0
  LOG_TEST_GOTO_ERR(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed");
2207
2208
0
  if (halflen < r_len || halflen < s_len)   {
2209
0
    rv = SC_ERROR_BUFFER_TOO_SMALL;
2210
0
    goto err;
2211
0
  }
2212
2213
0
  memset(buf, 0, buflen);
2214
0
  if (r_len > 0)
2215
0
    memcpy(buf + (halflen - r_len), r, r_len);
2216
0
  if (s_len > 0)
2217
0
    memcpy(buf + (buflen - s_len), s, s_len);
2218
2219
0
  sc_log(ctx, "r(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2220
0
         sc_dump_hex(buf, halflen));
2221
0
  sc_log(ctx, "s(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2222
0
         sc_dump_hex(buf + halflen, halflen));
2223
2224
0
  rv = SC_SUCCESS;
2225
0
err:
2226
0
  free(r);
2227
0
  free(s);
2228
2229
0
  LOG_FUNC_RETURN(ctx, rv);
2230
0
}
2231
2232
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) {
2233
0
  int i, r;
2234
0
  const unsigned char *pseq, *pint, *pend;
2235
0
  unsigned int cla, tag;
2236
0
  size_t seqlen, intlen;
2237
2238
0
  if (!ctx || !data || !out || !(*out)) {
2239
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2240
0
  }
2241
0
  if (outlen < 2 * fieldsize) {
2242
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Output too small for EC signature");
2243
0
  }
2244
2245
0
  memset(*out, 0, outlen);
2246
2247
0
  pseq = data;
2248
0
  r = sc_asn1_read_tag(&pseq, datalen, &cla, &tag, &seqlen);
2249
0
  if (pseq == NULL || r < 0 || seqlen == 0 || (cla | tag) != 0x30)
2250
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x30 tag");
2251
2252
0
  pint = pseq;
2253
0
  pend = pseq + seqlen;
2254
0
  for (i = 0; i < 2; i++) {
2255
0
    r = sc_asn1_read_tag(&pint, (pend - pint), &cla, &tag, &intlen);
2256
0
    if (pint == NULL || r < 0 || intlen == 0 || (cla | tag) != 0x02) {
2257
0
      r = SC_ERROR_INVALID_DATA;
2258
0
      LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Can not find 0x02");
2259
0
    }
2260
2261
0
    if (intlen == fieldsize + 1) { /* drop leading 00 if present */
2262
0
      if (*pint != 0x00) {
2263
0
        r = SC_ERROR_INVALID_DATA;
2264
0
        LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long");
2265
0
      }
2266
0
      pint++;
2267
0
      intlen--;
2268
0
    }
2269
0
    if (intlen > fieldsize) {
2270
0
      r = SC_ERROR_INVALID_DATA;
2271
0
      LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_DATA, "Signature too long");
2272
0
    }
2273
0
    memcpy(*out + fieldsize * i + fieldsize - intlen , pint, intlen);
2274
0
    pint += intlen; /* next integer */
2275
0
  }
2276
0
  r = (int)(2 * fieldsize);
2277
0
err:
2278
0
  LOG_FUNC_RETURN(ctx, r);
2279
0
}
2280