Coverage Report

Created: 2025-07-18 06:10

/src/opensc/src/libopensc/sc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * sc.c: General functions
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 <stdio.h>
26
#include <ctype.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <assert.h>
30
#ifdef HAVE_SYS_MMAN_H
31
#include <sys/mman.h>
32
#endif
33
#ifdef ENABLE_OPENSSL
34
#include <openssl/crypto.h>     /* for OPENSSL_cleanse */
35
#endif
36
37
38
#include "internal.h"
39
40
#ifdef PACKAGE_VERSION
41
static const char *sc_version = PACKAGE_VERSION;
42
#else
43
static const char *sc_version = "(undef)";
44
#endif
45
46
#ifdef _WIN32
47
#include <windows.h>
48
#define PAGESIZE 0
49
#else
50
#include <sys/mman.h>
51
#include <limits.h>
52
#include <unistd.h>
53
#ifndef PAGESIZE
54
#define PAGESIZE 0
55
#endif
56
#endif
57
58
const char *sc_get_version(void)
59
103k
{
60
103k
    return sc_version;
61
103k
}
62
63
int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen)
64
1.54M
{
65
1.54M
  const char *sc_hex_to_bin_separators = " :";
66
1.54M
  if (in == NULL || out == NULL || outlen == NULL) {
67
0
    return SC_ERROR_INVALID_ARGUMENTS;
68
0
  }
69
70
1.54M
  int byte_needs_nibble = 0;
71
1.54M
  int r = SC_SUCCESS;
72
1.54M
  size_t left = *outlen;
73
1.54M
  u8 byte = 0;
74
23.4M
  while (*in != '\0' && 0 != left) {
75
21.9M
    char c = *in++;
76
21.9M
    u8 nibble;
77
21.9M
    if      ('0' <= c && c <= '9')
78
11.4M
      nibble = c - '0';
79
10.4M
    else if ('a' <= c && c <= 'f')
80
2.39M
      nibble = c - 'a' + 10;
81
8.08M
    else if ('A' <= c && c <= 'F')
82
3.13M
      nibble = c - 'A' + 10;
83
4.94M
    else {
84
4.94M
      if (strchr(sc_hex_to_bin_separators, (int) c)) {
85
4.93M
        if (byte_needs_nibble) {
86
557
          r = SC_ERROR_INVALID_ARGUMENTS;
87
557
          goto err;
88
557
        }
89
4.93M
        continue;
90
4.93M
      }
91
16.0k
      r = SC_ERROR_INVALID_ARGUMENTS;
92
16.0k
      goto err;
93
4.94M
    }
94
95
16.9M
    if (byte_needs_nibble) {
96
8.47M
      byte |= nibble;
97
8.47M
      *out++ = (u8) byte;
98
8.47M
      left--;
99
8.47M
      byte_needs_nibble = 0;
100
8.52M
    } else {
101
8.52M
      byte  = nibble << 4;
102
8.52M
      byte_needs_nibble = 1;
103
8.52M
    }
104
16.9M
  }
105
106
1.53M
  if (left == *outlen && 1 == byte_needs_nibble && 0 != left) {
107
    /* no output written so far, but we have a valid nibble in the upper
108
     * bits. Allow this special case. */
109
36.8k
    *out = (u8) byte>>4;
110
36.8k
    left--;
111
36.8k
    byte_needs_nibble = 0;
112
36.8k
  }
113
114
  /* for ease of implementation we only accept completely hexed bytes. */
115
1.53M
  if (byte_needs_nibble) {
116
5.16k
    r = SC_ERROR_INVALID_ARGUMENTS;
117
5.16k
    goto err;
118
5.16k
  }
119
120
  /* skip all trailing separators to see if we missed something */
121
1.52M
  while (*in != '\0') {
122
993
    if (NULL == strchr(sc_hex_to_bin_separators, (int) *in))
123
382
      break;
124
611
    in++;
125
611
  }
126
1.52M
  if (*in != '\0') {
127
382
    r = SC_ERROR_BUFFER_TOO_SMALL;
128
382
    goto err;
129
382
  }
130
131
1.54M
err:
132
1.54M
  *outlen -= left;
133
1.54M
  return r;
134
1.52M
}
135
136
int sc_bin_to_hex(const u8 *in, size_t in_len, char *out, size_t out_len,
137
          int in_sep)
138
1.76M
{
139
1.76M
  if (in == NULL || out == NULL) {
140
0
    return SC_ERROR_INVALID_ARGUMENTS;
141
0
  }
142
143
1.76M
  if (in_sep > 0) {
144
1.72M
    if (out_len < in_len*3 || out_len < 1)
145
0
      return SC_ERROR_BUFFER_TOO_SMALL;
146
1.72M
  } else {
147
45.9k
    if (out_len < in_len*2 + 1)
148
55
      return SC_ERROR_BUFFER_TOO_SMALL;
149
45.9k
  }
150
151
1.76M
  const char hex[] = "0123456789abcdef";
152
16.7M
  while (in_len) {
153
14.9M
    unsigned char value = *in++;
154
14.9M
    *out++ = hex[(value >> 4) & 0xF];
155
14.9M
    *out++ = hex[ value       & 0xF];
156
14.9M
    in_len--;
157
14.9M
    if (in_len && in_sep > 0)
158
13.7M
      *out++ = (char)in_sep;
159
14.9M
  }
160
1.76M
  *out = '\0';
161
162
1.76M
  return SC_SUCCESS;
163
1.76M
}
164
165
/*
166
 * Right trim all non-printable characters
167
 */
168
43
size_t sc_right_trim(u8 *buf, size_t len) {
169
170
43
  size_t i;
171
172
43
  if (!buf)
173
0
    return 0;
174
175
43
  if (len > 0) {
176
724
    for(i = len-1; i > 0; i--) {
177
709
      if(!isprint(buf[i])) {
178
681
        buf[i] = '\0';
179
681
        len--;
180
681
        continue;
181
681
      }
182
28
      break;
183
709
    }
184
43
  }
185
43
  return len;
186
43
}
187
188
u8 *ulong2bebytes(u8 *buf, unsigned long x)
189
361k
{
190
361k
  if (buf != NULL) {
191
361k
    buf[3] = (u8) (x & 0xff);
192
361k
    buf[2] = (u8) ((x >> 8) & 0xff);
193
361k
    buf[1] = (u8) ((x >> 16) & 0xff);
194
361k
    buf[0] = (u8) ((x >> 24) & 0xff);
195
361k
  }
196
361k
  return buf;
197
361k
}
198
199
u8 *ushort2bebytes(u8 *buf, unsigned short x)
200
26.8k
{
201
26.8k
  if (buf != NULL) {
202
26.8k
    buf[1] = (u8) (x & 0xff);
203
26.8k
    buf[0] = (u8) ((x >> 8) & 0xff);
204
26.8k
  }
205
26.8k
  return buf;
206
26.8k
}
207
208
unsigned long bebytes2ulong(const u8 *buf)
209
665k
{
210
665k
  if (buf == NULL)
211
0
    return 0UL;
212
665k
  return (unsigned long)buf[0] << 24
213
665k
    | (unsigned long)buf[1] << 16
214
665k
    | (unsigned long)buf[2] << 8
215
665k
    | (unsigned long)buf[3];
216
665k
}
217
218
unsigned short bebytes2ushort(const u8 *buf)
219
1.04M
{
220
1.04M
  if (buf == NULL)
221
0
    return 0U;
222
1.04M
  return (unsigned short)buf[0] << 8
223
1.04M
    | (unsigned short)buf[1];
224
1.04M
}
225
226
unsigned short lebytes2ushort(const u8 *buf)
227
39.7k
{
228
39.7k
  if (buf == NULL)
229
0
    return 0U;
230
39.7k
  return (unsigned short)buf[1] << 8
231
39.7k
    | (unsigned short)buf[0];
232
39.7k
}
233
234
unsigned long lebytes2ulong(const u8 *buf)
235
3.59k
{
236
3.59k
  if (buf == NULL)
237
0
    return 0UL;
238
3.59k
  return (unsigned long)buf[3] << 24
239
3.59k
    | (unsigned long)buf[2] << 16
240
3.59k
    | (unsigned long)buf[1] << 8
241
3.59k
    | (unsigned long)buf[0];
242
3.59k
}
243
244
void set_string(char **strp, const char *value)
245
70.4k
{
246
70.4k
  if (strp == NULL) {
247
0
    return;
248
0
  }
249
250
70.4k
  free(*strp);
251
70.4k
  *strp = value ? strdup(value) : NULL;
252
70.4k
}
253
254
void sc_init_oid(struct sc_object_id *oid)
255
356k
{
256
356k
  int ii;
257
258
356k
  if (!oid)
259
0
    return;
260
6.06M
  for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
261
5.70M
    oid->value[ii] = -1;
262
356k
}
263
264
int sc_format_oid(struct sc_object_id *oid, const char *in)
265
115k
{
266
115k
  int        ii, ret = SC_ERROR_INVALID_ARGUMENTS;
267
115k
  const char *p;
268
115k
  char       *q;
269
270
115k
  if (oid == NULL || in == NULL)
271
0
    return SC_ERROR_INVALID_ARGUMENTS;
272
273
115k
  sc_init_oid(oid);
274
275
115k
  p = in;
276
942k
  for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++)   {
277
942k
    oid->value[ii] = (int)strtol(p, &q, 10);
278
942k
    if (!*q)
279
109k
      break;
280
281
832k
    if (!(q[0] == '.' && isdigit((unsigned char)q[1])))
282
5.22k
      goto out;
283
284
827k
    p = q + 1;
285
827k
  }
286
287
109k
  if (!sc_valid_oid(oid))
288
24
    goto out;
289
290
109k
  ret = SC_SUCCESS;
291
115k
out:
292
115k
  if (ret)
293
5.24k
    sc_init_oid(oid);
294
295
115k
  return ret;
296
109k
}
297
298
int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2)
299
290k
{
300
290k
  int i;
301
302
290k
  if (oid1 == NULL || oid2 == NULL) {
303
0
    return SC_ERROR_INVALID_ARGUMENTS;
304
0
  }
305
306
822k
  for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++)   {
307
822k
    if (oid1->value[i] != oid2->value[i])
308
266k
      return 0;
309
555k
    if (oid1->value[i] == -1)
310
23.9k
      break;
311
555k
  }
312
313
23.9k
  return 1;
314
290k
}
315
316
317
int sc_valid_oid(const struct sc_object_id *oid)
318
135k
{
319
135k
  int ii;
320
321
135k
  if (!oid)
322
0
    return 0;
323
135k
  if (oid->value[0] == -1 || oid->value[1] == -1)
324
1.35k
    return 0;
325
134k
  if (oid->value[0] > 2 || oid->value[1] > 39)
326
25
    return 0;
327
266k
  for (ii=0;ii<SC_MAX_OBJECT_ID_OCTETS;ii++)
328
258k
    if (oid->value[ii])
329
126k
      break;
330
134k
  if (ii==SC_MAX_OBJECT_ID_OCTETS)
331
8.25k
    return 0;
332
126k
  return 1;
333
134k
}
334
335
336
int sc_detect_card_presence(sc_reader_t *reader)
337
1.11k
{
338
1.11k
  int r;
339
1.11k
  LOG_FUNC_CALLED(reader->ctx);
340
1.11k
  if (reader->ops->detect_card_presence == NULL)
341
1.11k
    LOG_FUNC_RETURN(reader->ctx, SC_ERROR_NOT_SUPPORTED);
342
343
0
  r = reader->ops->detect_card_presence(reader);
344
345
  // Check that we get sane return value from backend
346
  // detect_card_presence should return 0 if no card is present.
347
0
  if (r && !(r & SC_READER_CARD_PRESENT))
348
0
    LOG_FUNC_RETURN(reader->ctx, SC_ERROR_INTERNAL);
349
350
0
  LOG_FUNC_RETURN(reader->ctx, r);
351
0
}
352
353
int sc_path_set(sc_path_t *path, int type, const u8 *id, size_t id_len,
354
  int idx, int count)
355
144k
{
356
144k
  if (path == NULL || id == NULL || id_len == 0 || id_len > SC_MAX_PATH_SIZE)
357
0
    return SC_ERROR_INVALID_ARGUMENTS;
358
359
144k
  memset(path, 0, sizeof(*path));
360
144k
  memcpy(path->value, id, id_len);
361
144k
  path->len   = id_len;
362
144k
  path->type  = type;
363
144k
  path->index = idx;
364
144k
  path->count = count;
365
366
144k
  return SC_SUCCESS;
367
144k
}
368
369
void sc_format_path(const char *str, sc_path_t *path)
370
822k
{
371
822k
  int type = SC_PATH_TYPE_PATH;
372
373
822k
  if (path) {
374
822k
    memset(path, 0, sizeof(*path));
375
822k
    if (*str == 'i' || *str == 'I') {
376
951
      type = SC_PATH_TYPE_FILE_ID;
377
951
      str++;
378
951
    }
379
822k
    path->len = sizeof(path->value);
380
822k
    if (sc_hex_to_bin(str, path->value, &path->len) >= 0) {
381
817k
      path->type = type;
382
817k
    }
383
822k
    path->count = -1;
384
822k
  }
385
822k
}
386
387
int sc_append_path(sc_path_t *dest, const sc_path_t *src)
388
1
{
389
1
  return sc_concatenate_path(dest, dest, src);
390
1
}
391
392
int sc_append_path_id(sc_path_t *dest, const u8 *id, size_t idlen)
393
1.55M
{
394
1.55M
  if (dest->len + idlen > SC_MAX_PATH_SIZE)
395
1.25M
    return SC_ERROR_INVALID_ARGUMENTS;
396
299k
  memcpy(dest->value + dest->len, id, idlen);
397
299k
  dest->len += idlen;
398
299k
  return SC_SUCCESS;
399
1.55M
}
400
401
int sc_append_file_id(sc_path_t *dest, unsigned int fid)
402
1.55M
{
403
1.55M
  u8 id[2] = { fid >> 8, fid & 0xff };
404
405
1.55M
  return sc_append_path_id(dest, id, 2);
406
1.55M
}
407
408
int sc_concatenate_path(sc_path_t *d, const sc_path_t *p1, const sc_path_t *p2)
409
105k
{
410
105k
  sc_path_t tpath;
411
412
105k
  if (d == NULL || p1 == NULL || p2 == NULL)
413
0
    return SC_ERROR_INVALID_ARGUMENTS;
414
415
105k
  if (p1->type == SC_PATH_TYPE_DF_NAME || p2->type == SC_PATH_TYPE_DF_NAME)
416
    /* we do not support concatenation of AIDs at the moment */
417
0
    return SC_ERROR_NOT_SUPPORTED;
418
419
105k
  if (p1->len + p2->len > SC_MAX_PATH_SIZE)
420
38
    return SC_ERROR_INVALID_ARGUMENTS;
421
422
105k
  memset(&tpath, 0, sizeof(sc_path_t));
423
105k
  memcpy(tpath.value, p1->value, p1->len);
424
105k
  memcpy(tpath.value + p1->len, p2->value, p2->len);
425
105k
  tpath.len  = p1->len + p2->len;
426
105k
  tpath.type = SC_PATH_TYPE_PATH;
427
  /* use 'index' and 'count' entry of the second path object */
428
105k
  tpath.index = p2->index;
429
105k
  tpath.count = p2->count;
430
  /* the result is currently always as path */
431
105k
  tpath.type  = SC_PATH_TYPE_PATH;
432
433
105k
  *d = tpath;
434
435
105k
  return SC_SUCCESS;
436
105k
}
437
438
const char *sc_print_path(const sc_path_t *path)
439
2.68M
{
440
2.68M
  static char buffer[SC_MAX_PATH_STRING_SIZE + SC_MAX_AID_STRING_SIZE];
441
442
2.68M
  if (sc_path_print(buffer, sizeof(buffer), path) != SC_SUCCESS)
443
0
    buffer[0] = '\0';
444
445
2.68M
  return buffer;
446
2.68M
}
447
448
int sc_path_print(char *buf, size_t buflen, const sc_path_t *path)
449
3.69M
{
450
3.69M
  size_t i;
451
452
3.69M
  if (buf == NULL || path == NULL)
453
0
    return SC_ERROR_INVALID_ARGUMENTS;
454
455
3.69M
  if (buflen < path->len * 2 + path->aid.len * 2 + 3)
456
3.11k
    return SC_ERROR_BUFFER_TOO_SMALL;
457
458
3.69M
  buf[0] = '\0';
459
3.69M
  if (path->aid.len)   {
460
7.54M
    for (i = 0; i < path->aid.len; i++)
461
6.60M
      snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->aid.value[i]);
462
942k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
463
942k
  }
464
465
17.7M
  for (i = 0; i < path->len; i++)
466
14.0M
    snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->value[i]);
467
3.69M
  if (!path->aid.len && path->type == SC_PATH_TYPE_DF_NAME)
468
177k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
469
470
3.69M
  return SC_SUCCESS;
471
3.69M
}
472
473
int sc_compare_path(const sc_path_t *path1, const sc_path_t *path2)
474
131k
{
475
131k
  return path1->len == path2->len
476
131k
    && !memcmp(path1->value, path2->value, path1->len);
477
131k
}
478
479
int sc_compare_path_prefix(const sc_path_t *prefix, const sc_path_t *path)
480
84.8k
{
481
84.8k
  sc_path_t tpath;
482
483
84.8k
  if (prefix->len > path->len)
484
3.91k
    return 0;
485
486
80.9k
  tpath     = *path;
487
80.9k
  tpath.len = prefix->len;
488
489
80.9k
  return sc_compare_path(&tpath, prefix);
490
84.8k
}
491
492
const sc_path_t *sc_get_mf_path(void)
493
106k
{
494
106k
  static const sc_path_t mf_path = {
495
106k
    {0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,
496
106k
    0,
497
106k
    0,
498
106k
    SC_PATH_TYPE_PATH,
499
106k
    {{0},0}
500
106k
  };
501
106k
  return &mf_path;
502
106k
}
503
504
int sc_file_add_acl_entry(sc_file_t *file, unsigned int operation,
505
                          unsigned int method, unsigned long key_ref)
506
7.38M
{
507
7.38M
  sc_acl_entry_t *p, *_new;
508
509
7.38M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
510
0
    return SC_ERROR_INVALID_ARGUMENTS;
511
0
  }
512
513
7.38M
  switch (method) {
514
3.37M
  case SC_AC_NEVER:
515
3.37M
    sc_file_clear_acl_entries(file, operation);
516
3.37M
    file->acl[operation] = (sc_acl_entry_t *) 1;
517
3.37M
    return SC_SUCCESS;
518
2.94M
  case SC_AC_NONE:
519
2.94M
    sc_file_clear_acl_entries(file, operation);
520
2.94M
    file->acl[operation] = (sc_acl_entry_t *) 2;
521
2.94M
    return SC_SUCCESS;
522
16.5k
  case SC_AC_UNKNOWN:
523
16.5k
    sc_file_clear_acl_entries(file, operation);
524
16.5k
    file->acl[operation] = (sc_acl_entry_t *) 3;
525
16.5k
    return SC_SUCCESS;
526
1.04M
  default:
527
    /* NONE and UNKNOWN get zapped when a new AC is added.
528
     * If the ACL is NEVER, additional entries will be
529
     * dropped silently. */
530
1.04M
    if (file->acl[operation] == (sc_acl_entry_t *) 1)
531
256
      return SC_SUCCESS;
532
1.04M
    if (file->acl[operation] == (sc_acl_entry_t *) 2
533
1.04M
     || file->acl[operation] == (sc_acl_entry_t *) 3)
534
19.0k
      file->acl[operation] = NULL;
535
7.38M
  }
536
537
  /* If the entry is already present (e.g. due to the mapping)
538
   * of the card's AC with OpenSC's), don't add it again. */
539
1.44M
  for (p = file->acl[operation]; p != NULL; p = p->next) {
540
416k
    if ((p->method == method) && (p->key_ref == key_ref))
541
18.4k
      return SC_SUCCESS;
542
416k
  }
543
544
1.02M
  _new = malloc(sizeof(sc_acl_entry_t));
545
1.02M
  if (_new == NULL)
546
0
    return SC_ERROR_OUT_OF_MEMORY;
547
1.02M
  _new->method = method;
548
1.02M
  _new->key_ref = (unsigned)key_ref;
549
1.02M
  _new->next = NULL;
550
551
1.02M
  p = file->acl[operation];
552
1.02M
  if (p == NULL) {
553
940k
    file->acl[operation] = _new;
554
940k
    return SC_SUCCESS;
555
940k
  }
556
387k
  while (p->next != NULL)
557
300k
    p = p->next;
558
87.3k
  p->next = _new;
559
560
87.3k
  return SC_SUCCESS;
561
1.02M
}
562
563
const sc_acl_entry_t * sc_file_get_acl_entry(const sc_file_t *file,
564
              unsigned int operation)
565
3.49M
{
566
3.49M
  sc_acl_entry_t *p;
567
3.49M
  static const sc_acl_entry_t e_never = {
568
3.49M
    SC_AC_NEVER, SC_AC_KEY_REF_NONE, NULL
569
3.49M
  };
570
3.49M
  static const sc_acl_entry_t e_none = {
571
3.49M
    SC_AC_NONE, SC_AC_KEY_REF_NONE, NULL
572
3.49M
  };
573
3.49M
  static const sc_acl_entry_t e_unknown = {
574
3.49M
    SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE, NULL
575
3.49M
  };
576
577
3.49M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
578
28
    return NULL;
579
28
  }
580
581
3.49M
  p = file->acl[operation];
582
3.49M
  if (p == (sc_acl_entry_t *) 1)
583
110k
    return &e_never;
584
3.38M
  if (p == (sc_acl_entry_t *) 2)
585
743k
    return &e_none;
586
2.63M
  if (p == (sc_acl_entry_t *) 3)
587
9.72k
    return &e_unknown;
588
589
2.62M
  return file->acl[operation];
590
2.63M
}
591
592
void sc_file_clear_acl_entries(sc_file_t *file, unsigned int operation)
593
67.9M
{
594
67.9M
  sc_acl_entry_t *e;
595
596
67.9M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
597
0
    return;
598
0
  }
599
600
67.9M
  e = file->acl[operation];
601
67.9M
  if (e == (sc_acl_entry_t *) 1 ||
602
67.9M
      e == (sc_acl_entry_t *) 2 ||
603
67.9M
      e == (sc_acl_entry_t *) 3) {
604
6.31M
    file->acl[operation] = NULL;
605
6.31M
    return;
606
6.31M
  }
607
608
62.6M
  while (e != NULL) {
609
1.02M
    sc_acl_entry_t *tmp = e->next;
610
1.02M
    free(e);
611
1.02M
    e = tmp;
612
1.02M
  }
613
61.6M
  file->acl[operation] = NULL;
614
61.6M
}
615
616
sc_file_t * sc_file_new(void)
617
1.98M
{
618
1.98M
  sc_file_t *file = (sc_file_t *)calloc(1, sizeof(sc_file_t));
619
1.98M
  if (file == NULL)
620
0
    return NULL;
621
622
1.98M
  file->magic = SC_FILE_MAGIC;
623
1.98M
  return file;
624
1.98M
}
625
626
void sc_file_free(sc_file_t *file)
627
3.42M
{
628
3.42M
  unsigned int i;
629
3.42M
  if (file == NULL || !sc_file_valid(file))
630
1.43M
    return;
631
1.98M
  file->magic = 0;
632
63.4M
  for (i = 0; i < SC_MAX_AC_OPS; i++)
633
61.4M
    sc_file_clear_acl_entries(file, i);
634
1.98M
  if (file->sec_attr)
635
24.9k
    free(file->sec_attr);
636
1.98M
  if (file->prop_attr)
637
16.6k
    free(file->prop_attr);
638
1.98M
  if (file->type_attr)
639
36.0k
    free(file->type_attr);
640
1.98M
  if (file->encoded_content)
641
557
    free(file->encoded_content);
642
1.98M
  free(file);
643
1.98M
}
644
645
void sc_file_dup(sc_file_t **dest, const sc_file_t *src)
646
103k
{
647
103k
  sc_file_t *newf;
648
103k
  const sc_acl_entry_t *e;
649
103k
  unsigned int op;
650
651
103k
  *dest = NULL;
652
103k
  if (!sc_file_valid(src))
653
0
    return;
654
103k
  newf = sc_file_new();
655
103k
  if (newf == NULL)
656
0
    return;
657
103k
  *dest = newf;
658
659
103k
  memcpy(&newf->path, &src->path, sizeof(struct sc_path));
660
103k
  memcpy(&newf->name, &src->name, sizeof(src->name));
661
103k
  newf->namelen = src->namelen;
662
103k
  newf->type    = src->type;
663
103k
  newf->shareable    = src->shareable;
664
103k
  newf->ef_structure = src->ef_structure;
665
103k
  newf->size    = src->size;
666
103k
  newf->id      = src->id;
667
103k
  newf->status  = src->status;
668
3.31M
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
669
3.20M
    newf->acl[op] = NULL;
670
3.20M
    e = sc_file_get_acl_entry(src, op);
671
3.20M
    if (e != NULL) {
672
654k
      if (sc_file_add_acl_entry(newf, op, e->method, e->key_ref) < 0)
673
0
        goto err;
674
654k
    }
675
3.20M
  }
676
103k
  newf->record_length = src->record_length;
677
103k
  newf->record_count  = src->record_count;
678
679
103k
  if (sc_file_set_sec_attr(newf, src->sec_attr, src->sec_attr_len) < 0)
680
0
    goto err;
681
103k
  if (sc_file_set_prop_attr(newf, src->prop_attr, src->prop_attr_len) < 0)
682
0
    goto err;
683
103k
  if (sc_file_set_type_attr(newf, src->type_attr, src->type_attr_len) < 0)
684
0
    goto err;
685
103k
  if (sc_file_set_content(newf, src->encoded_content, src->encoded_content_len) < 0)
686
0
    goto err;
687
103k
  return;
688
103k
err:
689
0
  sc_file_free(newf);
690
0
  *dest = NULL;
691
0
}
692
693
int sc_file_set_sec_attr(sc_file_t *file, const u8 *sec_attr,
694
       size_t sec_attr_len)
695
130k
{
696
130k
  u8 *tmp;
697
130k
  if (!sc_file_valid(file)) {
698
0
    return SC_ERROR_INVALID_ARGUMENTS;
699
0
  }
700
701
130k
  if (sec_attr == NULL || sec_attr_len == 0) {
702
105k
    if (file->sec_attr != NULL)
703
405
      free(file->sec_attr);
704
105k
    file->sec_attr = NULL;
705
105k
    file->sec_attr_len = 0;
706
105k
    return 0;
707
105k
   }
708
25.6k
  tmp = (u8 *) realloc(file->sec_attr, sec_attr_len);
709
25.6k
  if (!tmp) {
710
0
    if (file->sec_attr)
711
0
      free(file->sec_attr);
712
0
    file->sec_attr     = NULL;
713
0
    file->sec_attr_len = 0;
714
0
    return SC_ERROR_OUT_OF_MEMORY;
715
0
  }
716
25.6k
  file->sec_attr = tmp;
717
25.6k
  memcpy(file->sec_attr, sec_attr, sec_attr_len);
718
25.6k
  file->sec_attr_len = sec_attr_len;
719
720
25.6k
  return 0;
721
25.6k
}
722
723
int sc_file_set_prop_attr(sc_file_t *file, const u8 *prop_attr,
724
       size_t prop_attr_len)
725
125k
{
726
125k
  u8 *tmp;
727
125k
  if (!sc_file_valid(file)) {
728
0
    return SC_ERROR_INVALID_ARGUMENTS;
729
0
  }
730
731
125k
  if (prop_attr == NULL || prop_attr_len == 0) {
732
107k
    if (file->prop_attr != NULL)
733
612
      free(file->prop_attr);
734
107k
    file->prop_attr = NULL;
735
107k
    file->prop_attr_len = 0;
736
107k
    return SC_SUCCESS;
737
107k
   }
738
17.6k
  tmp = (u8 *) realloc(file->prop_attr, prop_attr_len);
739
17.6k
  if (!tmp) {
740
0
    if (file->prop_attr)
741
0
      free(file->prop_attr);
742
0
    file->prop_attr = NULL;
743
0
    file->prop_attr_len = 0;
744
0
    return SC_ERROR_OUT_OF_MEMORY;
745
0
  }
746
17.6k
  file->prop_attr = tmp;
747
17.6k
  memcpy(file->prop_attr, prop_attr, prop_attr_len);
748
17.6k
  file->prop_attr_len = prop_attr_len;
749
750
17.6k
  return SC_SUCCESS;
751
17.6k
}
752
753
int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr,
754
       size_t type_attr_len)
755
136k
{
756
136k
  u8 *tmp;
757
136k
  if (!sc_file_valid(file)) {
758
0
    return SC_ERROR_INVALID_ARGUMENTS;
759
0
  }
760
761
136k
  if (type_attr == NULL || type_attr_len == 0) {
762
97.9k
    if (file->type_attr != NULL)
763
0
      free(file->type_attr);
764
97.9k
    file->type_attr = NULL;
765
97.9k
    file->type_attr_len = 0;
766
97.9k
    return SC_SUCCESS;
767
97.9k
   }
768
38.9k
  tmp = (u8 *) realloc(file->type_attr, type_attr_len);
769
38.9k
  if (!tmp) {
770
0
    if (file->type_attr)
771
0
      free(file->type_attr);
772
0
    file->type_attr = NULL;
773
0
    file->type_attr_len = 0;
774
0
    return SC_ERROR_OUT_OF_MEMORY;
775
0
  }
776
38.9k
  file->type_attr = tmp;
777
38.9k
  memcpy(file->type_attr, type_attr, type_attr_len);
778
38.9k
  file->type_attr_len = type_attr_len;
779
780
38.9k
  return SC_SUCCESS;
781
38.9k
}
782
783
784
int sc_file_set_content(sc_file_t *file, const u8 *content,
785
       size_t content_len)
786
103k
{
787
103k
  u8 *tmp;
788
103k
  if (!sc_file_valid(file)) {
789
0
    return SC_ERROR_INVALID_ARGUMENTS;
790
0
  }
791
792
103k
  if (content == NULL || content_len == 0) {
793
103k
    if (file->encoded_content != NULL)
794
0
      free(file->encoded_content);
795
103k
    file->encoded_content = NULL;
796
103k
    file->encoded_content_len = 0;
797
103k
    return SC_SUCCESS;
798
103k
  }
799
800
525
  tmp = (u8 *) realloc(file->encoded_content, content_len);
801
525
  if (!tmp) {
802
0
    if (file->encoded_content)
803
0
      free(file->encoded_content);
804
0
    file->encoded_content = NULL;
805
0
    file->encoded_content_len = 0;
806
0
    return SC_ERROR_OUT_OF_MEMORY;
807
0
  }
808
809
525
  file->encoded_content = tmp;
810
525
  memcpy(file->encoded_content, content, content_len);
811
525
  file->encoded_content_len = content_len;
812
813
525
  return SC_SUCCESS;
814
525
}
815
816
817
2.58M
int sc_file_valid(const sc_file_t *file) {
818
2.58M
  if (file == NULL)
819
0
    return 0;
820
2.58M
  return file->magic == SC_FILE_MAGIC;
821
2.58M
}
822
823
int _sc_parse_atr(sc_reader_t *reader)
824
103k
{
825
103k
  u8 *p = reader->atr.value;
826
103k
  int atr_len = (int) reader->atr.len;
827
103k
  int n_hist, x;
828
103k
  int tx[4] = {-1, -1, -1, -1};
829
103k
  int i, FI, DI;
830
103k
  const int Fi_table[] = {
831
103k
    372, 372, 558, 744, 1116, 1488, 1860, -1,
832
103k
    -1, 512, 768, 1024, 1536, 2048, -1, -1 };
833
103k
  const int f_table[] = {
834
103k
    40, 50, 60, 80, 120, 160, 200, -1,
835
103k
    -1, 50, 75, 100, 150, 200, -1, -1 };
836
103k
  const int Di_table[] = {
837
103k
    -1, 1, 2, 4, 8, 16, 32, -1,
838
103k
    12, 20, -1, -1, -1, -1, -1, -1 };
839
840
103k
  reader->atr_info.hist_bytes_len = 0;
841
103k
  reader->atr_info.hist_bytes = NULL;
842
843
103k
  if (atr_len == 0) {
844
34.8k
    sc_log(reader->ctx, "empty ATR - card not present?\n");
845
34.8k
    return SC_ERROR_INTERNAL;
846
34.8k
  }
847
848
68.7k
  if (p[0] != 0x3B && p[0] != 0x3F) {
849
7.97k
    sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
850
7.97k
    return SC_ERROR_INTERNAL;
851
7.97k
  }
852
60.8k
  n_hist = p[1] & 0x0F;
853
60.8k
  x = p[1] >> 4;
854
60.8k
  p += 2;
855
60.8k
  atr_len -= 2;
856
303k
  for (i = 0; i < 4 && atr_len > 0; i++) {
857
242k
                if (x & (1 << i)) {
858
158k
                        tx[i] = *p;
859
158k
                        p++;
860
158k
                        atr_len--;
861
158k
                } else
862
84.5k
                        tx[i] = -1;
863
242k
        }
864
60.8k
  if (tx[0] >= 0) {
865
51.0k
    reader->atr_info.FI = FI = tx[0] >> 4;
866
51.0k
    reader->atr_info.DI = DI = tx[0] & 0x0F;
867
51.0k
    reader->atr_info.Fi = Fi_table[FI];
868
51.0k
    reader->atr_info.f = f_table[FI];
869
51.0k
    reader->atr_info.Di = Di_table[DI];
870
51.0k
  } else {
871
9.76k
    reader->atr_info.Fi = -1;
872
9.76k
    reader->atr_info.f = -1;
873
9.76k
    reader->atr_info.Di = -1;
874
9.76k
  }
875
60.8k
  if (tx[2] >= 0)
876
38.9k
    reader->atr_info.N = tx[3];
877
21.8k
  else
878
21.8k
    reader->atr_info.N = -1;
879
132k
  while (tx[3] > 0 && tx[3] & 0xF0 && atr_len > 0) {
880
71.9k
    x = tx[3] >> 4;
881
359k
    for (i = 0; i < 4 && atr_len > 0; i++) {
882
287k
                  if (x & (1 << i)) {
883
110k
                          tx[i] = *p;
884
110k
                          p++;
885
110k
                          atr_len--;
886
110k
                  } else
887
177k
                          tx[i] = -1;
888
287k
    }
889
71.9k
  }
890
60.8k
  if (atr_len <= 0)
891
628
    return SC_SUCCESS;
892
60.1k
  if (n_hist > atr_len)
893
3.83k
    n_hist = atr_len;
894
60.1k
  reader->atr_info.hist_bytes_len = n_hist;
895
60.1k
  reader->atr_info.hist_bytes = p;
896
60.1k
  return SC_SUCCESS;
897
60.8k
}
898
899
void *sc_mem_secure_alloc(size_t len)
900
41.1k
{
901
41.1k
  void *p;
902
903
#ifdef _WIN32
904
  p = VirtualAlloc(NULL, len, MEM_COMMIT, PAGE_READWRITE);
905
  if (p != NULL) {
906
    VirtualLock(p, len);
907
  }
908
#else
909
41.1k
  p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
910
41.1k
  if (p != NULL) {
911
41.1k
    mlock(p, len);
912
41.1k
  }
913
41.1k
#endif
914
915
41.1k
  return p;
916
41.1k
}
917
918
void sc_mem_secure_free(void *ptr, size_t len)
919
42.2k
{
920
#ifdef _WIN32
921
  VirtualUnlock(ptr, len);
922
  VirtualFree(ptr, 0, MEM_RELEASE);
923
#else
924
42.2k
  munlock(ptr, len);
925
42.2k
  munmap(ptr, len);
926
42.2k
#endif
927
42.2k
}
928
929
void sc_mem_clear(void *ptr, size_t len)
930
432k
{
931
432k
  if (len > 0)   {
932
#ifdef HAVE_MEMSET_S
933
    memset_s(ptr, len, 0, len);
934
#elif _WIN32
935
    SecureZeroMemory(ptr, len);
936
#elif HAVE_EXPLICIT_BZERO
937
    explicit_bzero(ptr, len);
938
#elif ENABLE_OPENSSL
939
    OPENSSL_cleanse(ptr, len);
940
#else
941
    memset(ptr, 0, len);
942
#endif
943
431k
  }
944
432k
}
945
946
int sc_mem_reverse(unsigned char *buf, size_t len)
947
0
{
948
0
  unsigned char ch;
949
0
  size_t ii;
950
951
0
  if (!buf || !len)
952
0
    return SC_ERROR_INVALID_ARGUMENTS;
953
954
0
  for (ii = 0; ii < len / 2; ii++)   {
955
0
    ch = *(buf + ii);
956
0
    *(buf + ii) = *(buf + len - 1 - ii);
957
0
    *(buf + len - 1 - ii) = ch;
958
0
  }
959
960
0
  return SC_SUCCESS;
961
0
}
962
963
static int
964
sc_remote_apdu_allocate(struct sc_remote_data *rdata,
965
    struct sc_remote_apdu **new_rapdu)
966
0
{
967
0
  struct sc_remote_apdu *rapdu = NULL, *rr;
968
969
0
  if (!rdata)
970
0
    return SC_ERROR_INVALID_ARGUMENTS;
971
972
0
  rapdu = calloc(1, sizeof(struct sc_remote_apdu));
973
0
  if (rapdu == NULL)
974
0
    return SC_ERROR_OUT_OF_MEMORY;
975
976
0
  rapdu->apdu.data = &rapdu->sbuf[0];
977
0
  rapdu->apdu.resp = &rapdu->rbuf[0];
978
0
  rapdu->apdu.resplen = sizeof(rapdu->rbuf);
979
980
0
  if (new_rapdu)
981
0
    *new_rapdu = rapdu;
982
983
0
  if (rdata->data == NULL)   {
984
0
    rdata->data = rapdu;
985
0
    rdata->length = 1;
986
0
    return SC_SUCCESS;
987
0
  }
988
989
0
  for (rr = rdata->data; rr->next; rr = rr->next)
990
0
    ;
991
0
  rr->next = rapdu;
992
0
  rdata->length++;
993
994
0
  return SC_SUCCESS;
995
0
}
996
997
static void
998
sc_remote_apdu_free (struct sc_remote_data *rdata)
999
0
{
1000
0
  struct sc_remote_apdu *rapdu = NULL;
1001
1002
0
  if (!rdata)
1003
0
    return;
1004
1005
0
  rapdu = rdata->data;
1006
0
  while(rapdu)   {
1007
0
    struct sc_remote_apdu *rr = rapdu->next;
1008
1009
0
    free(rapdu);
1010
0
    rapdu = rr;
1011
0
  }
1012
0
}
1013
1014
void sc_remote_data_init(struct sc_remote_data *rdata)
1015
0
{
1016
0
  if (!rdata)
1017
0
    return;
1018
0
  memset(rdata, 0, sizeof(struct sc_remote_data));
1019
1020
0
  rdata->alloc = sc_remote_apdu_allocate;
1021
0
  rdata->free = sc_remote_apdu_free;
1022
0
}
1023
1024
static unsigned long  sc_CRC_tab32[256];
1025
static int sc_CRC_tab32_initialized = 0;
1026
unsigned sc_crc32(const unsigned char *value, size_t len)
1027
0
{
1028
0
  size_t ii, jj;
1029
0
  unsigned long crc;
1030
0
  unsigned long index, long_c;
1031
1032
0
  if (!sc_CRC_tab32_initialized)   {
1033
0
    for (ii=0; ii<256; ii++) {
1034
0
      crc = (unsigned long) ii;
1035
0
      for (jj=0; jj<8; jj++) {
1036
0
        if ( crc & 0x00000001L )
1037
0
          crc = ( crc >> 1 ) ^ 0xEDB88320l;
1038
0
        else
1039
0
          crc =   crc >> 1;
1040
0
      }
1041
0
      sc_CRC_tab32[ii] = crc;
1042
0
    }
1043
0
    sc_CRC_tab32_initialized = 1;
1044
0
  }
1045
1046
0
  crc = 0xffffffffL;
1047
0
  for (ii=0; ii<len; ii++)   {
1048
0
    long_c = 0x000000ffL & (unsigned long) (*(value + ii));
1049
0
    index = crc ^ long_c;
1050
0
    crc = (crc >> 8) ^ sc_CRC_tab32[ index & 0xff ];
1051
0
  }
1052
1053
0
  crc ^= 0xffffffff;
1054
0
  return  crc%0xffff;
1055
0
}
1056
1057
const u8 *sc_compacttlv_find_tag(const u8 *buf, size_t len, u8 tag, size_t *outlen)
1058
6.23k
{
1059
6.23k
  if (buf != NULL) {
1060
6.23k
    size_t idx;
1061
6.23k
    u8 plain_tag = tag & 0xF0;
1062
6.23k
    size_t expected_len = tag & 0x0F;
1063
1064
89.3k
          for (idx = 0; idx < len; idx++) {
1065
85.0k
      if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len &&
1066
85.0k
          (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) {
1067
1.90k
        if (outlen != NULL)
1068
1.38k
          *outlen = buf[idx] & 0x0F;
1069
1.90k
        return buf + (idx + 1);
1070
1.90k
      }
1071
83.1k
      idx += (buf[idx] & 0x0F);
1072
83.1k
                }
1073
6.23k
        }
1074
4.33k
  return NULL;
1075
6.23k
}
1076
1077
/**************************** mutex functions ************************/
1078
1079
int sc_mutex_create(const sc_context_t *ctx, void **mutex)
1080
207k
{
1081
207k
  if (ctx == NULL)
1082
0
    return SC_ERROR_INVALID_ARGUMENTS;
1083
207k
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->create_mutex != NULL)
1084
30.3k
    return ctx->thread_ctx->create_mutex(mutex);
1085
177k
  else
1086
177k
    return SC_SUCCESS;
1087
207k
}
1088
1089
int sc_mutex_lock(const sc_context_t *ctx, void *mutex)
1090
12.4M
{
1091
12.4M
  if (ctx == NULL)
1092
0
    return SC_ERROR_INVALID_ARGUMENTS;
1093
12.4M
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->lock_mutex != NULL)
1094
1.08M
    return ctx->thread_ctx->lock_mutex(mutex);
1095
11.4M
  else
1096
11.4M
    return SC_SUCCESS;
1097
12.4M
}
1098
1099
int sc_mutex_unlock(const sc_context_t *ctx, void *mutex)
1100
12.4M
{
1101
12.4M
  if (ctx == NULL)
1102
0
    return SC_ERROR_INVALID_ARGUMENTS;
1103
12.4M
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->unlock_mutex != NULL)
1104
1.08M
    return ctx->thread_ctx->unlock_mutex(mutex);
1105
11.4M
  else
1106
11.4M
    return SC_SUCCESS;
1107
12.4M
}
1108
1109
int sc_mutex_destroy(const sc_context_t *ctx, void *mutex)
1110
0
{
1111
0
  if (ctx == NULL)
1112
0
    return SC_ERROR_INVALID_ARGUMENTS;
1113
0
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->destroy_mutex != NULL)
1114
0
    return ctx->thread_ctx->destroy_mutex(mutex);
1115
0
  else
1116
0
    return SC_SUCCESS;
1117
0
}
1118
1119
unsigned long sc_thread_id(const sc_context_t *ctx)
1120
0
{
1121
0
  if (ctx == NULL || ctx->thread_ctx == NULL ||
1122
0
      ctx->thread_ctx->thread_id == NULL)
1123
0
    return 0UL;
1124
0
  else
1125
0
    return ctx->thread_ctx->thread_id();
1126
0
}
1127
1128
void sc_free(void *p)
1129
0
{
1130
0
  free(p);
1131
0
}