Coverage Report

Created: 2025-11-16 06:12

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