Coverage Report

Created: 2025-09-04 06:45

/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
9.35k
{
60
9.35k
    return sc_version;
61
9.35k
}
62
63
int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen)
64
38.8k
{
65
38.8k
  const char *sc_hex_to_bin_separators = " :";
66
38.8k
  if (in == NULL || out == NULL || outlen == NULL) {
67
0
    return SC_ERROR_INVALID_ARGUMENTS;
68
0
  }
69
70
38.8k
  int byte_needs_nibble = 0;
71
38.8k
  int r = SC_SUCCESS;
72
38.8k
  size_t left = *outlen;
73
38.8k
  u8 byte = 0;
74
1.52M
  while (*in != '\0' && 0 != left) {
75
1.49M
    char c = *in++;
76
1.49M
    u8 nibble;
77
1.49M
    if      ('0' <= c && c <= '9')
78
641k
      nibble = c - '0';
79
849k
    else if ('a' <= c && c <= 'f')
80
214k
      nibble = c - 'a' + 10;
81
635k
    else if ('A' <= c && c <= 'F')
82
201k
      nibble = c - 'A' + 10;
83
434k
    else {
84
434k
      if (strchr(sc_hex_to_bin_separators, (int) c)) {
85
434k
        if (byte_needs_nibble) {
86
0
          r = SC_ERROR_INVALID_ARGUMENTS;
87
0
          goto err;
88
0
        }
89
434k
        continue;
90
434k
      }
91
0
      r = SC_ERROR_INVALID_ARGUMENTS;
92
0
      goto err;
93
434k
    }
94
95
1.05M
    if (byte_needs_nibble) {
96
528k
      byte |= nibble;
97
528k
      *out++ = (u8) byte;
98
528k
      left--;
99
528k
      byte_needs_nibble = 0;
100
528k
    } else {
101
528k
      byte  = nibble << 4;
102
528k
      byte_needs_nibble = 1;
103
528k
    }
104
1.05M
  }
105
106
38.8k
  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
0
    *out = (u8) byte>>4;
110
0
    left--;
111
0
    byte_needs_nibble = 0;
112
0
  }
113
114
  /* for ease of implementation we only accept completely hexed bytes. */
115
38.8k
  if (byte_needs_nibble) {
116
0
    r = SC_ERROR_INVALID_ARGUMENTS;
117
0
    goto err;
118
0
  }
119
120
  /* skip all trailing separators to see if we missed something */
121
38.8k
  while (*in != '\0') {
122
0
    if (NULL == strchr(sc_hex_to_bin_separators, (int) *in))
123
0
      break;
124
0
    in++;
125
0
  }
126
38.8k
  if (*in != '\0') {
127
0
    r = SC_ERROR_BUFFER_TOO_SMALL;
128
0
    goto err;
129
0
  }
130
131
38.8k
err:
132
38.8k
  *outlen -= left;
133
38.8k
  return r;
134
38.8k
}
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
179k
{
139
179k
  if (in == NULL || out == NULL) {
140
0
    return SC_ERROR_INVALID_ARGUMENTS;
141
0
  }
142
143
179k
  if (in_sep > 0) {
144
179k
    if (out_len < in_len*3 || out_len < 1)
145
0
      return SC_ERROR_BUFFER_TOO_SMALL;
146
179k
  } else {
147
0
    if (out_len < in_len*2 + 1)
148
0
      return SC_ERROR_BUFFER_TOO_SMALL;
149
0
  }
150
151
179k
  const char hex[] = "0123456789abcdef";
152
1.30M
  while (in_len) {
153
1.12M
    unsigned char value = *in++;
154
1.12M
    *out++ = hex[(value >> 4) & 0xF];
155
1.12M
    *out++ = hex[ value       & 0xF];
156
1.12M
    in_len--;
157
1.12M
    if (in_len && in_sep > 0)
158
1.04M
      *out++ = (char)in_sep;
159
1.12M
  }
160
179k
  *out = '\0';
161
162
179k
  return SC_SUCCESS;
163
179k
}
164
165
/*
166
 * Right trim all non-printable characters
167
 */
168
0
size_t sc_right_trim(u8 *buf, size_t len) {
169
170
0
  size_t i;
171
172
0
  if (!buf)
173
0
    return 0;
174
175
0
  if (len > 0) {
176
0
    for(i = len-1; i > 0; i--) {
177
0
      if(!isprint(buf[i])) {
178
0
        buf[i] = '\0';
179
0
        len--;
180
0
        continue;
181
0
      }
182
0
      break;
183
0
    }
184
0
  }
185
0
  return len;
186
0
}
187
188
u8 *ulong2bebytes(u8 *buf, unsigned long x)
189
5.29k
{
190
5.29k
  if (buf != NULL) {
191
5.29k
    buf[3] = (u8) (x & 0xff);
192
5.29k
    buf[2] = (u8) ((x >> 8) & 0xff);
193
5.29k
    buf[1] = (u8) ((x >> 16) & 0xff);
194
5.29k
    buf[0] = (u8) ((x >> 24) & 0xff);
195
5.29k
  }
196
5.29k
  return buf;
197
5.29k
}
198
199
u8 *ushort2bebytes(u8 *buf, unsigned short x)
200
23.9k
{
201
23.9k
  if (buf != NULL) {
202
23.9k
    buf[1] = (u8) (x & 0xff);
203
23.9k
    buf[0] = (u8) ((x >> 8) & 0xff);
204
23.9k
  }
205
23.9k
  return buf;
206
23.9k
}
207
208
unsigned long bebytes2ulong(const u8 *buf)
209
103k
{
210
103k
  if (buf == NULL)
211
0
    return 0UL;
212
103k
  return (unsigned long)buf[0] << 24
213
103k
    | (unsigned long)buf[1] << 16
214
103k
    | (unsigned long)buf[2] << 8
215
103k
    | (unsigned long)buf[3];
216
103k
}
217
218
unsigned short bebytes2ushort(const u8 *buf)
219
300k
{
220
300k
  if (buf == NULL)
221
0
    return 0U;
222
300k
  return (unsigned short)buf[0] << 8
223
300k
    | (unsigned short)buf[1];
224
300k
}
225
226
unsigned short lebytes2ushort(const u8 *buf)
227
1.94k
{
228
1.94k
  if (buf == NULL)
229
0
    return 0U;
230
1.94k
  return (unsigned short)buf[1] << 8
231
1.94k
    | (unsigned short)buf[0];
232
1.94k
}
233
234
unsigned long lebytes2ulong(const u8 *buf)
235
0
{
236
0
  if (buf == NULL)
237
0
    return 0UL;
238
0
  return (unsigned long)buf[3] << 24
239
0
    | (unsigned long)buf[2] << 16
240
0
    | (unsigned long)buf[1] << 8
241
0
    | (unsigned long)buf[0];
242
0
}
243
244
void set_string(char **strp, const char *value)
245
0
{
246
0
  if (strp == NULL) {
247
0
    return;
248
0
  }
249
250
0
  free(*strp);
251
0
  *strp = value ? strdup(value) : NULL;
252
0
}
253
254
void sc_init_oid(struct sc_object_id *oid)
255
22.3k
{
256
22.3k
  int ii;
257
258
22.3k
  if (!oid)
259
0
    return;
260
380k
  for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
261
358k
    oid->value[ii] = -1;
262
22.3k
}
263
264
int sc_format_oid(struct sc_object_id *oid, const char *in)
265
3.84k
{
266
3.84k
  int        ii, ret = SC_ERROR_INVALID_ARGUMENTS;
267
3.84k
  const char *p;
268
3.84k
  char       *q;
269
270
3.84k
  if (oid == NULL || in == NULL)
271
0
    return SC_ERROR_INVALID_ARGUMENTS;
272
273
3.84k
  sc_init_oid(oid);
274
275
3.84k
  p = in;
276
26.2k
  for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++)   {
277
26.2k
    oid->value[ii] = (int)strtol(p, &q, 10);
278
26.2k
    if (!*q)
279
3.84k
      break;
280
281
22.3k
    if (!(q[0] == '.' && isdigit((unsigned char)q[1])))
282
0
      goto out;
283
284
22.3k
    p = q + 1;
285
22.3k
  }
286
287
3.84k
  if (!sc_valid_oid(oid))
288
0
    goto out;
289
290
3.84k
  ret = SC_SUCCESS;
291
3.84k
out:
292
3.84k
  if (ret)
293
0
    sc_init_oid(oid);
294
295
3.84k
  return ret;
296
3.84k
}
297
298
int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2)
299
25.5k
{
300
25.5k
  int i;
301
302
25.5k
  if (oid1 == NULL || oid2 == NULL) {
303
0
    return SC_ERROR_INVALID_ARGUMENTS;
304
0
  }
305
306
59.9k
  for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++)   {
307
59.9k
    if (oid1->value[i] != oid2->value[i])
308
23.0k
      return 0;
309
36.8k
    if (oid1->value[i] == -1)
310
2.54k
      break;
311
36.8k
  }
312
313
2.54k
  return 1;
314
25.5k
}
315
316
317
int sc_valid_oid(const struct sc_object_id *oid)
318
3.84k
{
319
3.84k
  int ii;
320
321
3.84k
  if (!oid)
322
0
    return 0;
323
3.84k
  if (oid->value[0] == -1 || oid->value[1] == -1)
324
0
    return 0;
325
3.84k
  if (oid->value[0] > 2 || oid->value[1] > 39)
326
0
    return 0;
327
3.84k
  for (ii=0;ii<SC_MAX_OBJECT_ID_OCTETS;ii++)
328
3.84k
    if (oid->value[ii])
329
3.84k
      break;
330
3.84k
  if (ii==SC_MAX_OBJECT_ID_OCTETS)
331
0
    return 0;
332
3.84k
  return 1;
333
3.84k
}
334
335
336
int sc_detect_card_presence(sc_reader_t *reader)
337
0
{
338
0
  int r;
339
0
  LOG_FUNC_CALLED(reader->ctx);
340
0
  if (reader->ops->detect_card_presence == NULL)
341
0
    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
5.73k
{
356
5.73k
  if (path == NULL || id == NULL || id_len == 0 || id_len > SC_MAX_PATH_SIZE)
357
0
    return SC_ERROR_INVALID_ARGUMENTS;
358
359
5.73k
  memset(path, 0, sizeof(*path));
360
5.73k
  memcpy(path->value, id, id_len);
361
5.73k
  path->len   = id_len;
362
5.73k
  path->type  = type;
363
5.73k
  path->index = idx;
364
5.73k
  path->count = count;
365
366
5.73k
  return SC_SUCCESS;
367
5.73k
}
368
369
void sc_format_path(const char *str, sc_path_t *path)
370
14.7k
{
371
14.7k
  int type = SC_PATH_TYPE_PATH;
372
373
14.7k
  if (path) {
374
14.7k
    memset(path, 0, sizeof(*path));
375
14.7k
    if (*str == 'i' || *str == 'I') {
376
0
      type = SC_PATH_TYPE_FILE_ID;
377
0
      str++;
378
0
    }
379
14.7k
    path->len = sizeof(path->value);
380
14.7k
    if (sc_hex_to_bin(str, path->value, &path->len) >= 0) {
381
14.7k
      path->type = type;
382
14.7k
    }
383
14.7k
    path->count = -1;
384
14.7k
  }
385
14.7k
}
386
387
int sc_append_path(sc_path_t *dest, const sc_path_t *src)
388
0
{
389
0
  return sc_concatenate_path(dest, dest, src);
390
0
}
391
392
int sc_append_path_id(sc_path_t *dest, const u8 *id, size_t idlen)
393
1.29M
{
394
1.29M
  if (dest->len + idlen > SC_MAX_PATH_SIZE)
395
1.24M
    return SC_ERROR_INVALID_ARGUMENTS;
396
52.4k
  memcpy(dest->value + dest->len, id, idlen);
397
52.4k
  dest->len += idlen;
398
52.4k
  return SC_SUCCESS;
399
1.29M
}
400
401
int sc_append_file_id(sc_path_t *dest, unsigned int fid)
402
1.29M
{
403
1.29M
  u8 id[2] = { fid >> 8, fid & 0xff };
404
405
1.29M
  return sc_append_path_id(dest, id, 2);
406
1.29M
}
407
408
int sc_concatenate_path(sc_path_t *d, const sc_path_t *p1, const sc_path_t *p2)
409
0
{
410
0
  sc_path_t tpath;
411
412
0
  if (d == NULL || p1 == NULL || p2 == NULL)
413
0
    return SC_ERROR_INVALID_ARGUMENTS;
414
415
0
  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
0
  if (p1->len + p2->len > SC_MAX_PATH_SIZE)
420
0
    return SC_ERROR_INVALID_ARGUMENTS;
421
422
0
  memset(&tpath, 0, sizeof(sc_path_t));
423
0
  memcpy(tpath.value, p1->value, p1->len);
424
0
  memcpy(tpath.value + p1->len, p2->value, p2->len);
425
0
  tpath.len  = p1->len + p2->len;
426
0
  tpath.type = SC_PATH_TYPE_PATH;
427
  /* use 'index' and 'count' entry of the second path object */
428
0
  tpath.index = p2->index;
429
0
  tpath.count = p2->count;
430
  /* the result is currently always as path */
431
0
  tpath.type  = SC_PATH_TYPE_PATH;
432
433
0
  *d = tpath;
434
435
0
  return SC_SUCCESS;
436
0
}
437
438
const char *sc_print_path(const sc_path_t *path)
439
140k
{
440
140k
  static char buffer[SC_MAX_PATH_STRING_SIZE + SC_MAX_AID_STRING_SIZE];
441
442
140k
  if (sc_path_print(buffer, sizeof(buffer), path) != SC_SUCCESS)
443
0
    buffer[0] = '\0';
444
445
140k
  return buffer;
446
140k
}
447
448
int sc_path_print(char *buf, size_t buflen, const sc_path_t *path)
449
148k
{
450
148k
  size_t i;
451
452
148k
  if (buf == NULL || path == NULL)
453
0
    return SC_ERROR_INVALID_ARGUMENTS;
454
455
148k
  if (buflen < path->len * 2 + path->aid.len * 2 + 3)
456
0
    return SC_ERROR_BUFFER_TOO_SMALL;
457
458
148k
  buf[0] = '\0';
459
148k
  if (path->aid.len)   {
460
1.08M
    for (i = 0; i < path->aid.len; i++)
461
953k
      snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->aid.value[i]);
462
136k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
463
136k
  }
464
465
233k
  for (i = 0; i < path->len; i++)
466
84.4k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->value[i]);
467
148k
  if (!path->aid.len && path->type == SC_PATH_TYPE_DF_NAME)
468
6.63k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
469
470
148k
  return SC_SUCCESS;
471
148k
}
472
473
int sc_compare_path(const sc_path_t *path1, const sc_path_t *path2)
474
0
{
475
0
  return path1->len == path2->len
476
0
    && !memcmp(path1->value, path2->value, path1->len);
477
0
}
478
479
int sc_compare_path_prefix(const sc_path_t *prefix, const sc_path_t *path)
480
0
{
481
0
  sc_path_t tpath;
482
483
0
  if (prefix->len > path->len)
484
0
    return 0;
485
486
0
  tpath     = *path;
487
0
  tpath.len = prefix->len;
488
489
0
  return sc_compare_path(&tpath, prefix);
490
0
}
491
492
const sc_path_t *sc_get_mf_path(void)
493
3.17k
{
494
3.17k
  static const sc_path_t mf_path = {
495
3.17k
    {0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,
496
3.17k
    0,
497
3.17k
    0,
498
3.17k
    SC_PATH_TYPE_PATH,
499
3.17k
    {{0},0}
500
3.17k
  };
501
3.17k
  return &mf_path;
502
3.17k
}
503
504
int sc_file_add_acl_entry(sc_file_t *file, unsigned int operation,
505
                          unsigned int method, unsigned long key_ref)
506
3.05M
{
507
3.05M
  sc_acl_entry_t *p, *_new;
508
509
3.05M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
510
0
    return SC_ERROR_INVALID_ARGUMENTS;
511
0
  }
512
513
3.05M
  switch (method) {
514
2.75M
  case SC_AC_NEVER:
515
2.75M
    sc_file_clear_acl_entries(file, operation);
516
2.75M
    file->acl[operation] = (sc_acl_entry_t *) 1;
517
2.75M
    return SC_SUCCESS;
518
345
  case SC_AC_NONE:
519
345
    sc_file_clear_acl_entries(file, operation);
520
345
    file->acl[operation] = (sc_acl_entry_t *) 2;
521
345
    return SC_SUCCESS;
522
0
  case SC_AC_UNKNOWN:
523
0
    sc_file_clear_acl_entries(file, operation);
524
0
    file->acl[operation] = (sc_acl_entry_t *) 3;
525
0
    return SC_SUCCESS;
526
299k
  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
299k
    if (file->acl[operation] == (sc_acl_entry_t *) 1)
531
0
      return SC_SUCCESS;
532
299k
    if (file->acl[operation] == (sc_acl_entry_t *) 2
533
299k
     || file->acl[operation] == (sc_acl_entry_t *) 3)
534
0
      file->acl[operation] = NULL;
535
3.05M
  }
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
299k
  for (p = file->acl[operation]; p != NULL; p = p->next) {
540
0
    if ((p->method == method) && (p->key_ref == key_ref))
541
0
      return SC_SUCCESS;
542
0
  }
543
544
299k
  _new = malloc(sizeof(sc_acl_entry_t));
545
299k
  if (_new == NULL)
546
0
    return SC_ERROR_OUT_OF_MEMORY;
547
299k
  _new->method = method;
548
299k
  _new->key_ref = (unsigned)key_ref;
549
299k
  _new->next = NULL;
550
551
299k
  p = file->acl[operation];
552
299k
  if (p == NULL) {
553
299k
    file->acl[operation] = _new;
554
299k
    return SC_SUCCESS;
555
299k
  }
556
0
  while (p->next != NULL)
557
0
    p = p->next;
558
0
  p->next = _new;
559
560
0
  return SC_SUCCESS;
561
299k
}
562
563
const sc_acl_entry_t * sc_file_get_acl_entry(const sc_file_t *file,
564
              unsigned int operation)
565
18.8k
{
566
18.8k
  sc_acl_entry_t *p;
567
18.8k
  static const sc_acl_entry_t e_never = {
568
18.8k
    SC_AC_NEVER, SC_AC_KEY_REF_NONE, NULL
569
18.8k
  };
570
18.8k
  static const sc_acl_entry_t e_none = {
571
18.8k
    SC_AC_NONE, SC_AC_KEY_REF_NONE, NULL
572
18.8k
  };
573
18.8k
  static const sc_acl_entry_t e_unknown = {
574
18.8k
    SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE, NULL
575
18.8k
  };
576
577
18.8k
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
578
0
    return NULL;
579
0
  }
580
581
18.8k
  p = file->acl[operation];
582
18.8k
  if (p == (sc_acl_entry_t *) 1)
583
106
    return &e_never;
584
18.7k
  if (p == (sc_acl_entry_t *) 2)
585
157
    return &e_none;
586
18.5k
  if (p == (sc_acl_entry_t *) 3)
587
0
    return &e_unknown;
588
589
18.5k
  return file->acl[operation];
590
18.5k
}
591
592
void sc_file_clear_acl_entries(sc_file_t *file, unsigned int operation)
593
43.0M
{
594
43.0M
  sc_acl_entry_t *e;
595
596
43.0M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
597
0
    return;
598
0
  }
599
600
43.0M
  e = file->acl[operation];
601
43.0M
  if (e == (sc_acl_entry_t *) 1 ||
602
43.0M
      e == (sc_acl_entry_t *) 2 ||
603
43.0M
      e == (sc_acl_entry_t *) 3) {
604
2.75M
    file->acl[operation] = NULL;
605
2.75M
    return;
606
2.75M
  }
607
608
40.6M
  while (e != NULL) {
609
299k
    sc_acl_entry_t *tmp = e->next;
610
299k
    free(e);
611
299k
    e = tmp;
612
299k
  }
613
40.3M
  file->acl[operation] = NULL;
614
40.3M
}
615
616
sc_file_t * sc_file_new(void)
617
1.30M
{
618
1.30M
  sc_file_t *file = (sc_file_t *)calloc(1, sizeof(sc_file_t));
619
1.30M
  if (file == NULL)
620
0
    return NULL;
621
622
1.30M
  file->magic = SC_FILE_MAGIC;
623
1.30M
  return file;
624
1.30M
}
625
626
void sc_file_free(sc_file_t *file)
627
1.30M
{
628
1.30M
  unsigned int i;
629
1.30M
  if (file == NULL || !sc_file_valid(file))
630
2.57k
    return;
631
1.30M
  file->magic = 0;
632
41.6M
  for (i = 0; i < SC_MAX_AC_OPS; i++)
633
40.3M
    sc_file_clear_acl_entries(file, i);
634
1.30M
  if (file->sec_attr)
635
63
    free(file->sec_attr);
636
1.30M
  if (file->prop_attr)
637
40
    free(file->prop_attr);
638
1.30M
  if (file->type_attr)
639
107
    free(file->type_attr);
640
1.30M
  if (file->encoded_content)
641
0
    free(file->encoded_content);
642
1.30M
  free(file);
643
1.30M
}
644
645
void sc_file_dup(sc_file_t **dest, const sc_file_t *src)
646
607
{
647
607
  sc_file_t *newf;
648
607
  const sc_acl_entry_t *e;
649
607
  unsigned int op;
650
651
607
  *dest = NULL;
652
607
  if (!sc_file_valid(src))
653
0
    return;
654
607
  newf = sc_file_new();
655
607
  if (newf == NULL)
656
0
    return;
657
607
  *dest = newf;
658
659
607
  memcpy(&newf->path, &src->path, sizeof(struct sc_path));
660
607
  memcpy(&newf->name, &src->name, sizeof(src->name));
661
607
  newf->namelen = src->namelen;
662
607
  newf->type    = src->type;
663
607
  newf->shareable    = src->shareable;
664
607
  newf->ef_structure = src->ef_structure;
665
607
  newf->size    = src->size;
666
607
  newf->id      = src->id;
667
607
  newf->status  = src->status;
668
19.4k
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
669
18.8k
    newf->acl[op] = NULL;
670
18.8k
    e = sc_file_get_acl_entry(src, op);
671
18.8k
    if (e != NULL) {
672
452
      if (sc_file_add_acl_entry(newf, op, e->method, e->key_ref) < 0)
673
0
        goto err;
674
452
    }
675
18.8k
  }
676
607
  newf->record_length = src->record_length;
677
607
  newf->record_count  = src->record_count;
678
679
607
  if (sc_file_set_sec_attr(newf, src->sec_attr, src->sec_attr_len) < 0)
680
0
    goto err;
681
607
  if (sc_file_set_prop_attr(newf, src->prop_attr, src->prop_attr_len) < 0)
682
0
    goto err;
683
607
  if (sc_file_set_type_attr(newf, src->type_attr, src->type_attr_len) < 0)
684
0
    goto err;
685
607
  if (sc_file_set_content(newf, src->encoded_content, src->encoded_content_len) < 0)
686
0
    goto err;
687
607
  return;
688
607
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
789
{
696
789
  u8 *tmp;
697
789
  if (!sc_file_valid(file)) {
698
0
    return SC_ERROR_INVALID_ARGUMENTS;
699
0
  }
700
701
789
  if (sec_attr == NULL || sec_attr_len == 0) {
702
687
    if (file->sec_attr != NULL)
703
10
      free(file->sec_attr);
704
687
    file->sec_attr = NULL;
705
687
    file->sec_attr_len = 0;
706
687
    return 0;
707
687
   }
708
102
  tmp = (u8 *) realloc(file->sec_attr, sec_attr_len);
709
102
  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
102
  file->sec_attr = tmp;
717
102
  memcpy(file->sec_attr, sec_attr, sec_attr_len);
718
102
  file->sec_attr_len = sec_attr_len;
719
720
102
  return 0;
721
102
}
722
723
int sc_file_set_prop_attr(sc_file_t *file, const u8 *prop_attr,
724
       size_t prop_attr_len)
725
911
{
726
911
  u8 *tmp;
727
911
  if (!sc_file_valid(file)) {
728
0
    return SC_ERROR_INVALID_ARGUMENTS;
729
0
  }
730
731
911
  if (prop_attr == NULL || prop_attr_len == 0) {
732
816
    if (file->prop_attr != NULL)
733
44
      free(file->prop_attr);
734
816
    file->prop_attr = NULL;
735
816
    file->prop_attr_len = 0;
736
816
    return SC_SUCCESS;
737
816
   }
738
95
  tmp = (u8 *) realloc(file->prop_attr, prop_attr_len);
739
95
  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
95
  file->prop_attr = tmp;
747
95
  memcpy(file->prop_attr, prop_attr, prop_attr_len);
748
95
  file->prop_attr_len = prop_attr_len;
749
750
95
  return SC_SUCCESS;
751
95
}
752
753
int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr,
754
       size_t type_attr_len)
755
949
{
756
949
  u8 *tmp;
757
949
  if (!sc_file_valid(file)) {
758
0
    return SC_ERROR_INVALID_ARGUMENTS;
759
0
  }
760
761
949
  if (type_attr == NULL || type_attr_len == 0) {
762
594
    if (file->type_attr != NULL)
763
0
      free(file->type_attr);
764
594
    file->type_attr = NULL;
765
594
    file->type_attr_len = 0;
766
594
    return SC_SUCCESS;
767
594
   }
768
355
  tmp = (u8 *) realloc(file->type_attr, type_attr_len);
769
355
  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
355
  file->type_attr = tmp;
777
355
  memcpy(file->type_attr, type_attr, type_attr_len);
778
355
  file->type_attr_len = type_attr_len;
779
780
355
  return SC_SUCCESS;
781
355
}
782
783
784
int sc_file_set_content(sc_file_t *file, const u8 *content,
785
       size_t content_len)
786
607
{
787
607
  u8 *tmp;
788
607
  if (!sc_file_valid(file)) {
789
0
    return SC_ERROR_INVALID_ARGUMENTS;
790
0
  }
791
792
607
  if (content == NULL || content_len == 0) {
793
607
    if (file->encoded_content != NULL)
794
0
      free(file->encoded_content);
795
607
    file->encoded_content = NULL;
796
607
    file->encoded_content_len = 0;
797
607
    return SC_SUCCESS;
798
607
  }
799
800
0
  tmp = (u8 *) realloc(file->encoded_content, content_len);
801
0
  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
0
  file->encoded_content = tmp;
810
0
  memcpy(file->encoded_content, content, content_len);
811
0
  file->encoded_content_len = content_len;
812
813
0
  return SC_SUCCESS;
814
0
}
815
816
817
1.30M
int sc_file_valid(const sc_file_t *file) {
818
1.30M
  if (file == NULL)
819
0
    return 0;
820
1.30M
  return file->magic == SC_FILE_MAGIC;
821
1.30M
}
822
823
int _sc_parse_atr(sc_reader_t *reader)
824
9.35k
{
825
9.35k
  u8 *p = reader->atr.value;
826
9.35k
  int atr_len = (int) reader->atr.len;
827
9.35k
  int n_hist, x;
828
9.35k
  int tx[4] = {-1, -1, -1, -1};
829
9.35k
  int i, FI, DI;
830
9.35k
  const int Fi_table[] = {
831
9.35k
    372, 372, 558, 744, 1116, 1488, 1860, -1,
832
9.35k
    -1, 512, 768, 1024, 1536, 2048, -1, -1 };
833
9.35k
  const int f_table[] = {
834
9.35k
    40, 50, 60, 80, 120, 160, 200, -1,
835
9.35k
    -1, 50, 75, 100, 150, 200, -1, -1 };
836
9.35k
  const int Di_table[] = {
837
9.35k
    -1, 1, 2, 4, 8, 16, 32, -1,
838
9.35k
    12, 20, -1, -1, -1, -1, -1, -1 };
839
840
9.35k
  reader->atr_info.hist_bytes_len = 0;
841
9.35k
  reader->atr_info.hist_bytes = NULL;
842
843
9.35k
  if (atr_len == 0) {
844
4.31k
    sc_log(reader->ctx, "empty ATR - card not present?\n");
845
4.31k
    return SC_ERROR_INTERNAL;
846
4.31k
  }
847
848
5.03k
  if (p[0] != 0x3B && p[0] != 0x3F) {
849
298
    sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
850
298
    return SC_ERROR_INTERNAL;
851
298
  }
852
4.73k
  n_hist = p[1] & 0x0F;
853
4.73k
  x = p[1] >> 4;
854
4.73k
  p += 2;
855
4.73k
  atr_len -= 2;
856
23.5k
  for (i = 0; i < 4 && atr_len > 0; i++) {
857
18.8k
                if (x & (1 << i)) {
858
11.2k
                        tx[i] = *p;
859
11.2k
                        p++;
860
11.2k
                        atr_len--;
861
11.2k
                } else
862
7.55k
                        tx[i] = -1;
863
18.8k
        }
864
4.73k
  if (tx[0] >= 0) {
865
3.73k
    reader->atr_info.FI = FI = tx[0] >> 4;
866
3.73k
    reader->atr_info.DI = DI = tx[0] & 0x0F;
867
3.73k
    reader->atr_info.Fi = Fi_table[FI];
868
3.73k
    reader->atr_info.f = f_table[FI];
869
3.73k
    reader->atr_info.Di = Di_table[DI];
870
3.73k
  } else {
871
1.00k
    reader->atr_info.Fi = -1;
872
1.00k
    reader->atr_info.f = -1;
873
1.00k
    reader->atr_info.Di = -1;
874
1.00k
  }
875
4.73k
  if (tx[2] >= 0)
876
3.05k
    reader->atr_info.N = tx[3];
877
1.67k
  else
878
1.67k
    reader->atr_info.N = -1;
879
10.5k
  while (tx[3] > 0 && tx[3] & 0xF0 && atr_len > 0) {
880
5.77k
    x = tx[3] >> 4;
881
28.7k
    for (i = 0; i < 4 && atr_len > 0; i++) {
882
23.0k
                  if (x & (1 << i)) {
883
8.98k
                          tx[i] = *p;
884
8.98k
                          p++;
885
8.98k
                          atr_len--;
886
8.98k
                  } else
887
14.0k
                          tx[i] = -1;
888
23.0k
    }
889
5.77k
  }
890
4.73k
  if (atr_len <= 0)
891
91
    return SC_SUCCESS;
892
4.64k
  if (n_hist > atr_len)
893
424
    n_hist = atr_len;
894
4.64k
  reader->atr_info.hist_bytes_len = n_hist;
895
4.64k
  reader->atr_info.hist_bytes = p;
896
4.64k
  return SC_SUCCESS;
897
4.73k
}
898
899
void *sc_mem_secure_alloc(size_t len)
900
0
{
901
0
  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
0
  p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
910
0
  if (p != NULL) {
911
0
    mlock(p, len);
912
0
  }
913
0
#endif
914
915
0
  return p;
916
0
}
917
918
void sc_mem_secure_free(void *ptr, size_t len)
919
0
{
920
#ifdef _WIN32
921
  VirtualUnlock(ptr, len);
922
  VirtualFree(ptr, 0, MEM_RELEASE);
923
#else
924
0
  munlock(ptr, len);
925
0
  munmap(ptr, len);
926
0
#endif
927
0
}
928
929
void sc_mem_clear(void *ptr, size_t len)
930
22.3k
{
931
22.3k
  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
22.3k
  }
944
22.3k
}
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
1.16k
{
1059
1.16k
  if (buf != NULL) {
1060
1.16k
    size_t idx;
1061
1.16k
    u8 plain_tag = tag & 0xF0;
1062
1.16k
    size_t expected_len = tag & 0x0F;
1063
1064
13.6k
          for (idx = 0; idx < len; idx++) {
1065
12.7k
      if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len &&
1066
12.7k
          (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) {
1067
301
        if (outlen != NULL)
1068
126
          *outlen = buf[idx] & 0x0F;
1069
301
        return buf + (idx + 1);
1070
301
      }
1071
12.4k
      idx += (buf[idx] & 0x0F);
1072
12.4k
                }
1073
1.16k
        }
1074
860
  return NULL;
1075
1.16k
}
1076
1077
/**************************** mutex functions ************************/
1078
1079
int sc_mutex_create(const sc_context_t *ctx, void **mutex)
1080
18.7k
{
1081
18.7k
  if (ctx == NULL)
1082
0
    return SC_ERROR_INVALID_ARGUMENTS;
1083
18.7k
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->create_mutex != NULL)
1084
0
    return ctx->thread_ctx->create_mutex(mutex);
1085
18.7k
  else
1086
18.7k
    return SC_SUCCESS;
1087
18.7k
}
1088
1089
int sc_mutex_lock(const sc_context_t *ctx, void *mutex)
1090
2.03M
{
1091
2.03M
  if (ctx == NULL)
1092
0
    return SC_ERROR_INVALID_ARGUMENTS;
1093
2.03M
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->lock_mutex != NULL)
1094
0
    return ctx->thread_ctx->lock_mutex(mutex);
1095
2.03M
  else
1096
2.03M
    return SC_SUCCESS;
1097
2.03M
}
1098
1099
int sc_mutex_unlock(const sc_context_t *ctx, void *mutex)
1100
2.03M
{
1101
2.03M
  if (ctx == NULL)
1102
0
    return SC_ERROR_INVALID_ARGUMENTS;
1103
2.03M
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->unlock_mutex != NULL)
1104
0
    return ctx->thread_ctx->unlock_mutex(mutex);
1105
2.03M
  else
1106
2.03M
    return SC_SUCCESS;
1107
2.03M
}
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
}