Coverage Report

Created: 2025-11-23 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/sc.c
Line
Count
Source
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
8.46k
{
60
8.46k
    return sc_version;
61
8.46k
}
62
63
int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen)
64
69.8k
{
65
69.8k
  const char *sc_hex_to_bin_separators = " :";
66
69.8k
  if (in == NULL || out == NULL || outlen == NULL) {
67
0
    return SC_ERROR_INVALID_ARGUMENTS;
68
0
  }
69
70
69.8k
  int byte_needs_nibble = 0;
71
69.8k
  int r = SC_SUCCESS;
72
69.8k
  size_t left = *outlen;
73
69.8k
  u8 byte = 0;
74
2.53M
  while (*in != '\0' && 0 != left) {
75
2.46M
    char c = *in++;
76
2.46M
    u8 nibble;
77
2.46M
    if      ('0' <= c && c <= '9')
78
1.15M
      nibble = c - '0';
79
1.31M
    else if ('a' <= c && c <= 'f')
80
282k
      nibble = c - 'a' + 10;
81
1.03M
    else if ('A' <= c && c <= 'F')
82
290k
      nibble = c - 'A' + 10;
83
741k
    else {
84
741k
      if (strchr(sc_hex_to_bin_separators, (int) c)) {
85
741k
        if (byte_needs_nibble) {
86
0
          r = SC_ERROR_INVALID_ARGUMENTS;
87
0
          goto err;
88
0
        }
89
741k
        continue;
90
741k
      }
91
0
      r = SC_ERROR_INVALID_ARGUMENTS;
92
0
      goto err;
93
741k
    }
94
95
1.72M
    if (byte_needs_nibble) {
96
862k
      byte |= nibble;
97
862k
      *out++ = (u8) byte;
98
862k
      left--;
99
862k
      byte_needs_nibble = 0;
100
862k
    } else {
101
862k
      byte  = nibble << 4;
102
862k
      byte_needs_nibble = 1;
103
862k
    }
104
1.72M
  }
105
106
69.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
69.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
69.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
69.8k
  if (*in != '\0') {
127
0
    r = SC_ERROR_BUFFER_TOO_SMALL;
128
0
    goto err;
129
0
  }
130
131
69.8k
err:
132
69.8k
  *outlen -= left;
133
69.8k
  return r;
134
69.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
203k
{
139
203k
  if (in == NULL || out == NULL) {
140
0
    return SC_ERROR_INVALID_ARGUMENTS;
141
0
  }
142
143
203k
  if (in_sep > 0) {
144
203k
    if (out_len < in_len*3 || out_len < 1)
145
0
      return SC_ERROR_BUFFER_TOO_SMALL;
146
203k
  } else {
147
0
    if (out_len < in_len*2 + 1)
148
0
      return SC_ERROR_BUFFER_TOO_SMALL;
149
0
  }
150
151
203k
  const char hex[] = "0123456789abcdef";
152
1.52M
  while (in_len) {
153
1.31M
    unsigned char value = *in++;
154
1.31M
    *out++ = hex[(value >> 4) & 0xF];
155
1.31M
    *out++ = hex[ value       & 0xF];
156
1.31M
    in_len--;
157
1.31M
    if (in_len && in_sep > 0)
158
1.23M
      *out++ = (char)in_sep;
159
1.31M
  }
160
203k
  *out = '\0';
161
162
203k
  return SC_SUCCESS;
163
203k
}
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
4.72k
{
190
4.72k
  if (buf != NULL) {
191
4.72k
    buf[3] = (u8) (x & 0xff);
192
4.72k
    buf[2] = (u8) ((x >> 8) & 0xff);
193
4.72k
    buf[1] = (u8) ((x >> 16) & 0xff);
194
4.72k
    buf[0] = (u8) ((x >> 24) & 0xff);
195
4.72k
  }
196
4.72k
  return buf;
197
4.72k
}
198
199
u8 *ushort2bebytes(u8 *buf, unsigned short x)
200
21.1k
{
201
21.1k
  if (buf != NULL) {
202
21.1k
    buf[1] = (u8) (x & 0xff);
203
21.1k
    buf[0] = (u8) ((x >> 8) & 0xff);
204
21.1k
  }
205
21.1k
  return buf;
206
21.1k
}
207
208
unsigned long bebytes2ulong(const u8 *buf)
209
60.1k
{
210
60.1k
  if (buf == NULL)
211
0
    return 0UL;
212
60.1k
  return (unsigned long)buf[0] << 24
213
60.1k
    | (unsigned long)buf[1] << 16
214
60.1k
    | (unsigned long)buf[2] << 8
215
60.1k
    | (unsigned long)buf[3];
216
60.1k
}
217
218
unsigned short bebytes2ushort(const u8 *buf)
219
173k
{
220
173k
  if (buf == NULL)
221
0
    return 0U;
222
173k
  return (unsigned short)buf[0] << 8
223
173k
    | (unsigned short)buf[1];
224
173k
}
225
226
unsigned short lebytes2ushort(const u8 *buf)
227
1.85k
{
228
1.85k
  if (buf == NULL)
229
0
    return 0U;
230
1.85k
  return (unsigned short)buf[1] << 8
231
1.85k
    | (unsigned short)buf[0];
232
1.85k
}
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
20.4k
{
256
20.4k
  int ii;
257
258
20.4k
  if (!oid)
259
0
    return;
260
347k
  for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
261
326k
    oid->value[ii] = -1;
262
20.4k
}
263
264
int sc_format_oid(struct sc_object_id *oid, const char *in)
265
3.51k
{
266
3.51k
  int        ii, ret = SC_ERROR_INVALID_ARGUMENTS;
267
3.51k
  const char *p;
268
3.51k
  char       *q;
269
270
3.51k
  if (oid == NULL || in == NULL)
271
0
    return SC_ERROR_INVALID_ARGUMENTS;
272
273
3.51k
  sc_init_oid(oid);
274
275
3.51k
  p = in;
276
23.8k
  for (ii=0; ii < SC_MAX_OBJECT_ID_OCTETS; ii++)   {
277
23.8k
    oid->value[ii] = (int)strtol(p, &q, 10);
278
23.8k
    if (!*q)
279
3.51k
      break;
280
281
20.3k
    if (!(q[0] == '.' && isdigit((unsigned char)q[1])))
282
0
      goto out;
283
284
20.3k
    p = q + 1;
285
20.3k
  }
286
287
3.51k
  if (!sc_valid_oid(oid))
288
0
    goto out;
289
290
3.51k
  ret = SC_SUCCESS;
291
3.51k
out:
292
3.51k
  if (ret)
293
0
    sc_init_oid(oid);
294
295
3.51k
  return ret;
296
3.51k
}
297
298
int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2)
299
28.1k
{
300
28.1k
  int i;
301
302
28.1k
  if (oid1 == NULL || oid2 == NULL) {
303
0
    return SC_ERROR_INVALID_ARGUMENTS;
304
0
  }
305
306
65.6k
  for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++)   {
307
65.6k
    if (oid1->value[i] != oid2->value[i])
308
25.7k
      return 0;
309
39.8k
    if (oid1->value[i] == -1)
310
2.40k
      break;
311
39.8k
  }
312
313
2.40k
  return 1;
314
28.1k
}
315
316
317
int sc_valid_oid(const struct sc_object_id *oid)
318
3.51k
{
319
3.51k
  int ii;
320
321
3.51k
  if (!oid)
322
0
    return 0;
323
3.51k
  if (oid->value[0] == -1 || oid->value[1] == -1)
324
0
    return 0;
325
3.51k
  if (oid->value[0] > 2 || oid->value[1] > 39)
326
0
    return 0;
327
3.51k
  for (ii=0;ii<SC_MAX_OBJECT_ID_OCTETS;ii++)
328
3.51k
    if (oid->value[ii])
329
3.51k
      break;
330
3.51k
  if (ii==SC_MAX_OBJECT_ID_OCTETS)
331
0
    return 0;
332
3.51k
  return 1;
333
3.51k
}
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.19k
{
356
5.19k
  if (path == NULL || id == NULL || id_len == 0 || id_len > SC_MAX_PATH_SIZE)
357
0
    return SC_ERROR_INVALID_ARGUMENTS;
358
359
5.19k
  memset(path, 0, sizeof(*path));
360
5.19k
  memcpy(path->value, id, id_len);
361
5.19k
  path->len   = id_len;
362
5.19k
  path->type  = type;
363
5.19k
  path->index = idx;
364
5.19k
  path->count = count;
365
366
5.19k
  return SC_SUCCESS;
367
5.19k
}
368
369
void sc_format_path(const char *str, sc_path_t *path)
370
13.4k
{
371
13.4k
  int type = SC_PATH_TYPE_PATH;
372
373
13.4k
  if (path) {
374
13.4k
    memset(path, 0, sizeof(*path));
375
13.4k
    if (*str == 'i' || *str == 'I') {
376
0
      type = SC_PATH_TYPE_FILE_ID;
377
0
      str++;
378
0
    }
379
13.4k
    path->len = sizeof(path->value);
380
13.4k
    if (sc_hex_to_bin(str, path->value, &path->len) >= 0) {
381
13.4k
      path->type = type;
382
13.4k
    }
383
13.4k
    path->count = -1;
384
13.4k
  }
385
13.4k
}
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.49M
{
394
1.49M
  if (dest->len + idlen > SC_MAX_PATH_SIZE)
395
1.44M
    return SC_ERROR_INVALID_ARGUMENTS;
396
50.6k
  memcpy(dest->value + dest->len, id, idlen);
397
50.6k
  dest->len += idlen;
398
50.6k
  return SC_SUCCESS;
399
1.49M
}
400
401
int sc_append_file_id(sc_path_t *dest, unsigned int fid)
402
1.49M
{
403
1.49M
  u8 id[2] = { fid >> 8, fid & 0xff };
404
405
1.49M
  return sc_append_path_id(dest, id, 2);
406
1.49M
}
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
129k
{
440
129k
  static char buffer[SC_MAX_PATH_STRING_SIZE + SC_MAX_AID_STRING_SIZE];
441
442
129k
  if (sc_path_print(buffer, sizeof(buffer), path) != SC_SUCCESS)
443
0
    buffer[0] = '\0';
444
445
129k
  return buffer;
446
129k
}
447
448
int sc_path_print(char *buf, size_t buflen, const sc_path_t *path)
449
137k
{
450
137k
  size_t i;
451
452
137k
  if (buf == NULL || path == NULL)
453
0
    return SC_ERROR_INVALID_ARGUMENTS;
454
455
137k
  if (buflen < path->len * 2 + path->aid.len * 2 + 3)
456
16
    return SC_ERROR_BUFFER_TOO_SMALL;
457
458
137k
  buf[0] = '\0';
459
137k
  if (path->aid.len)   {
460
1.00M
    for (i = 0; i < path->aid.len; i++)
461
882k
      snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->aid.value[i]);
462
126k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
463
126k
  }
464
465
216k
  for (i = 0; i < path->len; i++)
466
78.4k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->value[i]);
467
137k
  if (!path->aid.len && path->type == SC_PATH_TYPE_DF_NAME)
468
6.16k
    snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
469
470
137k
  return SC_SUCCESS;
471
137k
}
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.06k
{
494
3.06k
  static const sc_path_t mf_path = {
495
3.06k
    {0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,
496
3.06k
    0,
497
3.06k
    0,
498
3.06k
    SC_PATH_TYPE_PATH,
499
3.06k
    {{0},0}
500
3.06k
  };
501
3.06k
  return &mf_path;
502
3.06k
}
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.51M
{
507
3.51M
  sc_acl_entry_t *p, *_new;
508
509
3.51M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
510
0
    return SC_ERROR_INVALID_ARGUMENTS;
511
0
  }
512
513
3.51M
  switch (method) {
514
3.17M
  case SC_AC_NEVER:
515
3.17M
    sc_file_clear_acl_entries(file, operation);
516
3.17M
    file->acl[operation] = (sc_acl_entry_t *) 1;
517
3.17M
    return SC_SUCCESS;
518
227
  case SC_AC_NONE:
519
227
    sc_file_clear_acl_entries(file, operation);
520
227
    file->acl[operation] = (sc_acl_entry_t *) 2;
521
227
    return SC_SUCCESS;
522
90
  case SC_AC_UNKNOWN:
523
90
    sc_file_clear_acl_entries(file, operation);
524
90
    file->acl[operation] = (sc_acl_entry_t *) 3;
525
90
    return SC_SUCCESS;
526
340k
  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
340k
    if (file->acl[operation] == (sc_acl_entry_t *) 1)
531
0
      return SC_SUCCESS;
532
340k
    if (file->acl[operation] == (sc_acl_entry_t *) 2
533
340k
     || file->acl[operation] == (sc_acl_entry_t *) 3)
534
0
      file->acl[operation] = NULL;
535
3.51M
  }
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
340k
  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
340k
  _new = malloc(sizeof(sc_acl_entry_t));
545
340k
  if (_new == NULL)
546
0
    return SC_ERROR_OUT_OF_MEMORY;
547
340k
  _new->method = method;
548
340k
  _new->key_ref = (unsigned)key_ref;
549
340k
  _new->next = NULL;
550
551
340k
  p = file->acl[operation];
552
340k
  if (p == NULL) {
553
340k
    file->acl[operation] = _new;
554
340k
    return SC_SUCCESS;
555
340k
  }
556
0
  while (p->next != NULL)
557
0
    p = p->next;
558
0
  p->next = _new;
559
560
0
  return SC_SUCCESS;
561
340k
}
562
563
const sc_acl_entry_t * sc_file_get_acl_entry(const sc_file_t *file,
564
              unsigned int operation)
565
15.9k
{
566
15.9k
  sc_acl_entry_t *p;
567
15.9k
  static const sc_acl_entry_t e_never = {
568
15.9k
    SC_AC_NEVER, SC_AC_KEY_REF_NONE, NULL
569
15.9k
  };
570
15.9k
  static const sc_acl_entry_t e_none = {
571
15.9k
    SC_AC_NONE, SC_AC_KEY_REF_NONE, NULL
572
15.9k
  };
573
15.9k
  static const sc_acl_entry_t e_unknown = {
574
15.9k
    SC_AC_UNKNOWN, SC_AC_KEY_REF_NONE, NULL
575
15.9k
  };
576
577
15.9k
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
578
0
    return NULL;
579
0
  }
580
581
15.9k
  p = file->acl[operation];
582
15.9k
  if (p == (sc_acl_entry_t *) 1)
583
124
    return &e_never;
584
15.8k
  if (p == (sc_acl_entry_t *) 2)
585
100
    return &e_none;
586
15.7k
  if (p == (sc_acl_entry_t *) 3)
587
45
    return &e_unknown;
588
589
15.7k
  return file->acl[operation];
590
15.7k
}
591
592
void sc_file_clear_acl_entries(sc_file_t *file, unsigned int operation)
593
49.8M
{
594
49.8M
  sc_acl_entry_t *e;
595
596
49.8M
  if (file == NULL || operation >= SC_MAX_AC_OPS) {
597
0
    return;
598
0
  }
599
600
49.8M
  e = file->acl[operation];
601
49.8M
  if (e == (sc_acl_entry_t *) 1 ||
602
46.6M
      e == (sc_acl_entry_t *) 2 ||
603
46.6M
      e == (sc_acl_entry_t *) 3) {
604
3.17M
    file->acl[operation] = NULL;
605
3.17M
    return;
606
3.17M
  }
607
608
46.9M
  while (e != NULL) {
609
340k
    sc_acl_entry_t *tmp = e->next;
610
340k
    free(e);
611
340k
    e = tmp;
612
340k
  }
613
46.6M
  file->acl[operation] = NULL;
614
46.6M
}
615
616
sc_file_t * sc_file_new(void)
617
1.50M
{
618
1.50M
  sc_file_t *file = (sc_file_t *)calloc(1, sizeof(sc_file_t));
619
1.50M
  if (file == NULL)
620
0
    return NULL;
621
622
1.50M
  file->magic = SC_FILE_MAGIC;
623
1.50M
  return file;
624
1.50M
}
625
626
void sc_file_free(sc_file_t *file)
627
1.50M
{
628
1.50M
  unsigned int i;
629
1.50M
  if (file == NULL || !sc_file_valid(file))
630
2.19k
    return;
631
1.50M
  file->magic = 0;
632
48.1M
  for (i = 0; i < SC_MAX_AC_OPS; i++)
633
46.6M
    sc_file_clear_acl_entries(file, i);
634
1.50M
  if (file->sec_attr)
635
54
    free(file->sec_attr);
636
1.50M
  if (file->prop_attr)
637
41
    free(file->prop_attr);
638
1.50M
  if (file->type_attr)
639
90
    free(file->type_attr);
640
1.50M
  if (file->encoded_content)
641
0
    free(file->encoded_content);
642
1.50M
  free(file);
643
1.50M
}
644
645
void sc_file_dup(sc_file_t **dest, const sc_file_t *src)
646
516
{
647
516
  sc_file_t *newf;
648
516
  const sc_acl_entry_t *e;
649
516
  unsigned int op;
650
651
516
  *dest = NULL;
652
516
  if (!sc_file_valid(src))
653
0
    return;
654
516
  newf = sc_file_new();
655
516
  if (newf == NULL)
656
0
    return;
657
516
  *dest = newf;
658
659
516
  memcpy(&newf->path, &src->path, sizeof(struct sc_path));
660
516
  memcpy(&newf->name, &src->name, sizeof(src->name));
661
516
  newf->namelen = src->namelen;
662
516
  newf->type    = src->type;
663
516
  newf->shareable    = src->shareable;
664
516
  newf->ef_structure = src->ef_structure;
665
516
  newf->size    = src->size;
666
516
  newf->id      = src->id;
667
516
  newf->status  = src->status;
668
16.5k
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
669
15.9k
    newf->acl[op] = NULL;
670
15.9k
    e = sc_file_get_acl_entry(src, op);
671
15.9k
    if (e != NULL) {
672
499
      if (sc_file_add_acl_entry(newf, op, e->method, e->key_ref) < 0)
673
0
        goto err;
674
499
    }
675
15.9k
  }
676
516
  newf->record_length = src->record_length;
677
516
  newf->record_count  = src->record_count;
678
679
516
  if (sc_file_set_sec_attr(newf, src->sec_attr, src->sec_attr_len) < 0)
680
0
    goto err;
681
516
  if (sc_file_set_prop_attr(newf, src->prop_attr, src->prop_attr_len) < 0)
682
0
    goto err;
683
516
  if (sc_file_set_type_attr(newf, src->type_attr, src->type_attr_len) < 0)
684
0
    goto err;
685
516
  if (sc_file_set_content(newf, src->encoded_content, src->encoded_content_len) < 0)
686
0
    goto err;
687
516
  return;
688
516
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
692
{
696
692
  u8 *tmp;
697
692
  if (!sc_file_valid(file)) {
698
0
    return SC_ERROR_INVALID_ARGUMENTS;
699
0
  }
700
701
692
  if (sec_attr == NULL || sec_attr_len == 0) {
702
596
    if (file->sec_attr != NULL)
703
10
      free(file->sec_attr);
704
596
    file->sec_attr = NULL;
705
596
    file->sec_attr_len = 0;
706
596
    return 0;
707
596
   }
708
96
  tmp = (u8 *) realloc(file->sec_attr, sec_attr_len);
709
96
  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
96
  file->sec_attr = tmp;
717
96
  memcpy(file->sec_attr, sec_attr, sec_attr_len);
718
96
  file->sec_attr_len = sec_attr_len;
719
720
96
  return 0;
721
96
}
722
723
int sc_file_set_prop_attr(sc_file_t *file, const u8 *prop_attr,
724
       size_t prop_attr_len)
725
815
{
726
815
  u8 *tmp;
727
815
  if (!sc_file_valid(file)) {
728
0
    return SC_ERROR_INVALID_ARGUMENTS;
729
0
  }
730
731
815
  if (prop_attr == NULL || prop_attr_len == 0) {
732
713
    if (file->prop_attr != NULL)
733
41
      free(file->prop_attr);
734
713
    file->prop_attr = NULL;
735
713
    file->prop_attr_len = 0;
736
713
    return SC_SUCCESS;
737
713
   }
738
102
  tmp = (u8 *) realloc(file->prop_attr, prop_attr_len);
739
102
  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
102
  file->prop_attr = tmp;
747
102
  memcpy(file->prop_attr, prop_attr, prop_attr_len);
748
102
  file->prop_attr_len = prop_attr_len;
749
750
102
  return SC_SUCCESS;
751
102
}
752
753
int sc_file_set_type_attr(sc_file_t *file, const u8 *type_attr,
754
       size_t type_attr_len)
755
765
{
756
765
  u8 *tmp;
757
765
  if (!sc_file_valid(file)) {
758
0
    return SC_ERROR_INVALID_ARGUMENTS;
759
0
  }
760
761
765
  if (type_attr == NULL || type_attr_len == 0) {
762
504
    if (file->type_attr != NULL)
763
0
      free(file->type_attr);
764
504
    file->type_attr = NULL;
765
504
    file->type_attr_len = 0;
766
504
    return SC_SUCCESS;
767
504
   }
768
261
  tmp = (u8 *) realloc(file->type_attr, type_attr_len);
769
261
  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
261
  file->type_attr = tmp;
777
261
  memcpy(file->type_attr, type_attr, type_attr_len);
778
261
  file->type_attr_len = type_attr_len;
779
780
261
  return SC_SUCCESS;
781
261
}
782
783
784
int sc_file_set_content(sc_file_t *file, const u8 *content,
785
       size_t content_len)
786
516
{
787
516
  u8 *tmp;
788
516
  if (!sc_file_valid(file)) {
789
0
    return SC_ERROR_INVALID_ARGUMENTS;
790
0
  }
791
792
516
  if (content == NULL || content_len == 0) {
793
516
    if (file->encoded_content != NULL)
794
0
      free(file->encoded_content);
795
516
    file->encoded_content = NULL;
796
516
    file->encoded_content_len = 0;
797
516
    return SC_SUCCESS;
798
516
  }
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.50M
int sc_file_valid(const sc_file_t *file) {
818
1.50M
  if (file == NULL)
819
0
    return 0;
820
1.50M
  return file->magic == SC_FILE_MAGIC;
821
1.50M
}
822
823
int _sc_parse_atr(sc_reader_t *reader)
824
8.46k
{
825
8.46k
  u8 *p = reader->atr.value;
826
8.46k
  int atr_len = (int) reader->atr.len;
827
8.46k
  int n_hist, x;
828
8.46k
  int tx[4] = {-1, -1, -1, -1};
829
8.46k
  int i, FI, DI;
830
8.46k
  const int Fi_table[] = {
831
8.46k
    372, 372, 558, 744, 1116, 1488, 1860, -1,
832
8.46k
    -1, 512, 768, 1024, 1536, 2048, -1, -1 };
833
8.46k
  const int f_table[] = {
834
8.46k
    40, 50, 60, 80, 120, 160, 200, -1,
835
8.46k
    -1, 50, 75, 100, 150, 200, -1, -1 };
836
8.46k
  const int Di_table[] = {
837
8.46k
    -1, 1, 2, 4, 8, 16, 32, -1,
838
8.46k
    12, 20, -1, -1, -1, -1, -1, -1 };
839
840
8.46k
  reader->atr_info.hist_bytes_len = 0;
841
8.46k
  reader->atr_info.hist_bytes = NULL;
842
843
8.46k
  if (atr_len == 0) {
844
3.87k
    sc_log(reader->ctx, "empty ATR - card not present?\n");
845
3.87k
    return SC_ERROR_INTERNAL;
846
3.87k
  }
847
848
4.59k
  if (p[0] != 0x3B && p[0] != 0x3F) {
849
261
    sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
850
261
    return SC_ERROR_INTERNAL;
851
261
  }
852
4.33k
  n_hist = p[1] & 0x0F;
853
4.33k
  x = p[1] >> 4;
854
4.33k
  p += 2;
855
4.33k
  atr_len -= 2;
856
21.5k
  for (i = 0; i < 4 && atr_len > 0; i++) {
857
17.2k
                if (x & (1 << i)) {
858
10.5k
                        tx[i] = *p;
859
10.5k
                        p++;
860
10.5k
                        atr_len--;
861
10.5k
                } else
862
6.72k
                        tx[i] = -1;
863
17.2k
        }
864
4.33k
  if (tx[0] >= 0) {
865
3.48k
    reader->atr_info.FI = FI = tx[0] >> 4;
866
3.48k
    reader->atr_info.DI = DI = tx[0] & 0x0F;
867
3.48k
    reader->atr_info.Fi = Fi_table[FI];
868
3.48k
    reader->atr_info.f = f_table[FI];
869
3.48k
    reader->atr_info.Di = Di_table[DI];
870
3.48k
  } else {
871
847
    reader->atr_info.Fi = -1;
872
847
    reader->atr_info.f = -1;
873
847
    reader->atr_info.Di = -1;
874
847
  }
875
4.33k
  if (tx[2] >= 0)
876
2.83k
    reader->atr_info.N = tx[3];
877
1.50k
  else
878
1.50k
    reader->atr_info.N = -1;
879
9.61k
  while (tx[3] > 0 && tx[3] & 0xF0 && atr_len > 0) {
880
5.28k
    x = tx[3] >> 4;
881
26.3k
    for (i = 0; i < 4 && atr_len > 0; i++) {
882
21.0k
                  if (x & (1 << i)) {
883
8.21k
                          tx[i] = *p;
884
8.21k
                          p++;
885
8.21k
                          atr_len--;
886
8.21k
                  } else
887
12.8k
                          tx[i] = -1;
888
21.0k
    }
889
5.28k
  }
890
4.33k
  if (atr_len <= 0)
891
78
    return SC_SUCCESS;
892
4.25k
  if (n_hist > atr_len)
893
422
    n_hist = atr_len;
894
4.25k
  reader->atr_info.hist_bytes_len = n_hist;
895
4.25k
  reader->atr_info.hist_bytes = p;
896
4.25k
  return SC_SUCCESS;
897
4.33k
}
898
899
void *sc_mem_secure_alloc(size_t len)
900
2
{
901
2
  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
2
  p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
910
2
  if (p != NULL) {
911
2
    mlock(p, len);
912
2
  }
913
2
#endif
914
915
2
  return p;
916
2
}
917
918
void sc_mem_secure_free(void *ptr, size_t len)
919
2
{
920
#ifdef _WIN32
921
  VirtualUnlock(ptr, len);
922
  VirtualFree(ptr, 0, MEM_RELEASE);
923
#else
924
2
  munlock(ptr, len);
925
2
  munmap(ptr, len);
926
2
#endif
927
2
}
928
929
void sc_mem_clear(void *ptr, size_t len)
930
20.2k
{
931
20.2k
  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
20.2k
  }
944
20.2k
}
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.04k
{
1059
1.04k
  if (buf != NULL) {
1060
1.04k
    size_t idx;
1061
1.04k
    u8 plain_tag = tag & 0xF0;
1062
1.04k
    size_t expected_len = tag & 0x0F;
1063
1064
16.1k
          for (idx = 0; idx < len; idx++) {
1065
15.3k
      if ((buf[idx] & 0xF0) == plain_tag && idx + expected_len < len &&
1066
966
          (expected_len == 0 || expected_len == (buf[idx] & 0x0F))) {
1067
240
        if (outlen != NULL)
1068
103
          *outlen = buf[idx] & 0x0F;
1069
240
        return buf + (idx + 1);
1070
240
      }
1071
15.0k
      idx += (buf[idx] & 0x0F);
1072
15.0k
                }
1073
1.04k
        }
1074
801
  return NULL;
1075
1.04k
}
1076
1077
/**************************** mutex functions ************************/
1078
1079
int sc_mutex_create(const sc_context_t *ctx, void **mutex)
1080
16.9k
{
1081
16.9k
  if (ctx == NULL)
1082
0
    return SC_ERROR_INVALID_ARGUMENTS;
1083
16.9k
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->create_mutex != NULL)
1084
0
    return ctx->thread_ctx->create_mutex(mutex);
1085
16.9k
  else
1086
16.9k
    return SC_SUCCESS;
1087
16.9k
}
1088
1089
int sc_mutex_lock(const sc_context_t *ctx, void *mutex)
1090
2.08M
{
1091
2.08M
  if (ctx == NULL)
1092
0
    return SC_ERROR_INVALID_ARGUMENTS;
1093
2.08M
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->lock_mutex != NULL)
1094
0
    return ctx->thread_ctx->lock_mutex(mutex);
1095
2.08M
  else
1096
2.08M
    return SC_SUCCESS;
1097
2.08M
}
1098
1099
int sc_mutex_unlock(const sc_context_t *ctx, void *mutex)
1100
2.08M
{
1101
2.08M
  if (ctx == NULL)
1102
0
    return SC_ERROR_INVALID_ARGUMENTS;
1103
2.08M
  if (ctx->thread_ctx != NULL && ctx->thread_ctx->unlock_mutex != NULL)
1104
0
    return ctx->thread_ctx->unlock_mutex(mutex);
1105
2.08M
  else
1106
2.08M
    return SC_SUCCESS;
1107
2.08M
}
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
}