Coverage Report

Created: 2025-11-16 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/pkcs15init/profile.c
Line
Count
Source
1
/*
2
 * Initialize Cards according to PKCS#15
3
 *
4
 * Copyright (C) 2002 Olaf Kirch <okir@suse.de>
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
 * Random notes
21
 *  - the "key" command should go away, it's obsolete
22
 */
23
24
#include "config.h"
25
26
#include <stdio.h>
27
#include <ctype.h>
28
#include <stdarg.h>
29
#include <string.h>
30
#include <limits.h>
31
#ifdef HAVE_STRINGS_H
32
#include <strings.h>
33
#endif
34
#ifdef HAVE_UNISTD_H
35
#include <unistd.h>
36
#endif
37
#include <assert.h>
38
#include <stdlib.h>
39
40
#ifdef _WIN32
41
#include <windows.h>
42
#include <winreg.h>
43
#endif
44
45
#include "common/compat_strlcpy.h"
46
#include "scconf/scconf.h"
47
#include "libopensc/log.h"
48
#include "libopensc/pkcs15.h"
49
#include "pkcs15-init.h"
50
#include "profile.h"
51
52
13.2k
#define DEF_PRKEY_RSA_ACCESS  0x1D
53
#define DEF_PUBKEY_ACCESS 0x12
54
55
13.1k
#define TEMPLATE_FILEID_MIN_DIFF  0x20
56
57
8.40k
#define WORD_SIZE 64
58
59
/*
60
#define DEBUG_PROFILE
61
*/
62
63
/*
64
 * Parser state
65
 */
66
struct state {
67
  struct state *    frame;
68
  const char *    filename;
69
  struct sc_profile * profile;
70
  struct file_info *  file;
71
  struct pin_info * pin;
72
  struct auth_info *  key;
73
};
74
75
76
struct command {
77
  const char *    name;
78
  int     min_args, max_args;
79
  int     (*func)(struct state *, int, char **);
80
};
81
82
struct block {
83
  const char *    name;
84
  int     (*handler)(struct state *,
85
          struct block *,
86
          const char *,
87
          scconf_block *);
88
  struct command *  cmd_info;
89
  struct block *    blk_info;
90
};
91
92
struct map {
93
  const char *    name;
94
  unsigned int    val;
95
};
96
97
static struct map   aclNames[] = {
98
  { "NONE", SC_AC_NONE  },
99
  { "NEVER",  SC_AC_NEVER },
100
  { "CHV",  SC_AC_CHV },
101
  { "TERM", SC_AC_TERM  },
102
  { "PRO",  SC_AC_PRO },
103
  { "AUT",  SC_AC_AUT },
104
  { "KEY",  SC_AC_AUT },
105
  { "SEN",  SC_AC_SEN },
106
  { "IDA",  SC_AC_IDA },
107
  { "SCB",  SC_AC_SCB },
108
  { NULL, 0 }
109
};
110
static struct map   fileOpNames[] = {
111
  { "SELECT", SC_AC_OP_SELECT },
112
  { "LOCK", SC_AC_OP_LOCK },
113
  { "DELETE", SC_AC_OP_DELETE },
114
  { "DELETE-SELF",SC_AC_OP_DELETE_SELF },
115
  { "CREATE", SC_AC_OP_CREATE },
116
  { "CREATE-EF",  SC_AC_OP_CREATE_EF  },
117
  { "CREATE-DF",  SC_AC_OP_CREATE_DF  },
118
  { "REHABILITATE",SC_AC_OP_REHABILITATE  },
119
  { "INVALIDATE", SC_AC_OP_INVALIDATE },
120
  { "FILES",  SC_AC_OP_LIST_FILES },
121
  { "READ", SC_AC_OP_READ },
122
  { "UPDATE", SC_AC_OP_UPDATE },
123
  { "WRITE",  SC_AC_OP_WRITE  },
124
  { "ERASE",  SC_AC_OP_ERASE  },
125
  { "CRYPTO",     SC_AC_OP_CRYPTO },
126
        { "PIN-DEFINE", SC_AC_OP_PIN_DEFINE },
127
        { "PIN-CHANGE", SC_AC_OP_PIN_CHANGE },
128
        { "PIN-RESET",  SC_AC_OP_PIN_RESET },
129
        { "PIN-USE",  SC_AC_OP_PIN_USE },
130
  { "GENERATE", SC_AC_OP_GENERATE },
131
  { "PSO-COMPUTE-SIGNATURE",  SC_AC_OP_PSO_COMPUTE_SIGNATURE },
132
  { "INTERNAL-AUTHENTICATE",  SC_AC_OP_INTERNAL_AUTHENTICATE },
133
  { "PSO-DECRYPT",    SC_AC_OP_PSO_DECRYPT },
134
  { "RESIZE", SC_AC_OP_RESIZE },
135
  { "ADMIN",  SC_AC_OP_ADMIN  },
136
  { "ACTIVATE", SC_AC_OP_ACTIVATE },
137
  { "DEACTIVATE", SC_AC_OP_DEACTIVATE },
138
  { NULL, 0 }
139
};
140
static struct map   fileTypeNames[] = {
141
  { "EF",   SC_FILE_TYPE_WORKING_EF   },
142
  { "INTERNAL-EF",SC_FILE_TYPE_INTERNAL_EF  },
143
  { "DF",   SC_FILE_TYPE_DF     },
144
  { "BSO",  SC_FILE_TYPE_BSO    },
145
  { NULL, 0 }
146
};
147
static struct map   fileStructureNames[] = {
148
  { "TRANSPARENT",  SC_FILE_EF_TRANSPARENT  },
149
  { "LINEAR-FIXED", SC_FILE_EF_LINEAR_FIXED },
150
  { "LINEAR-FIXED-TLV", SC_FILE_EF_LINEAR_FIXED_TLV },
151
  { "LINEAR-VARIABLE",  SC_FILE_EF_LINEAR_VARIABLE  },
152
  { "LINEAR-VARIABLE-TLV",SC_FILE_EF_LINEAR_VARIABLE_TLV  },
153
  { "CYCLIC",   SC_FILE_EF_CYCLIC },
154
  { "CYCLIC-TLV",   SC_FILE_EF_CYCLIC_TLV },
155
  { NULL, 0 }
156
};
157
static struct map   pkcs15DfNames[] = {
158
  { "PRKDF",    SC_PKCS15_PRKDF   },
159
  { "PUKDF",    SC_PKCS15_PUKDF   },
160
  { "PUKDF-TRUSTED",  SC_PKCS15_PUKDF_TRUSTED },
161
  { "SKDF",   SC_PKCS15_SKDF    },
162
  { "CDF",    SC_PKCS15_CDF   },
163
  { "CDF-TRUSTED",  SC_PKCS15_CDF_TRUSTED },
164
  { "CDF-USEFUL",   SC_PKCS15_CDF_USEFUL  },
165
  { "DODF",   SC_PKCS15_DODF    },
166
  { "AODF",   SC_PKCS15_AODF    },
167
  { NULL, 0 }
168
};
169
static struct map   pinTypeNames[] = {
170
  { "BCD",    SC_PKCS15_PIN_TYPE_BCD  },
171
  { "ascii-numeric",  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC  },
172
  { "utf8",   SC_PKCS15_PIN_TYPE_UTF8 },
173
  { "half-nibble-bcd",  SC_PKCS15_PIN_TYPE_HALFNIBBLE_BCD },
174
  { "iso9564-1",    SC_PKCS15_PIN_TYPE_ISO9564_1  },
175
  { NULL, 0 }
176
};
177
static struct map   pinIdNames[] = {
178
  { "pin",    SC_PKCS15INIT_USER_PIN  },
179
  { "puk",    SC_PKCS15INIT_USER_PUK  },
180
  { "user-pin",   SC_PKCS15INIT_USER_PIN  },
181
  { "user-puk",   SC_PKCS15INIT_USER_PUK  },
182
  { "sopin",    SC_PKCS15INIT_SO_PIN  },
183
  { "sopuk",    SC_PKCS15INIT_SO_PUK  },
184
  { "so-pin",   SC_PKCS15INIT_SO_PIN  },
185
  { "so-puk",   SC_PKCS15INIT_SO_PUK  },
186
  { NULL, 0 }
187
};
188
static struct map   pinFlagNames[] = {
189
  { "case-sensitive",   SC_PKCS15_PIN_FLAG_CASE_SENSITIVE   },
190
  { "local",      SC_PKCS15_PIN_FLAG_LOCAL      },
191
  { "change-disabled",    SC_PKCS15_PIN_FLAG_CHANGE_DISABLED    },
192
  { "unblock-disabled",   SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED   },
193
  { "initialized",    SC_PKCS15_PIN_FLAG_INITIALIZED      },
194
  { "needs-padding",    SC_PKCS15_PIN_FLAG_NEEDS_PADDING    },
195
  { "unblockingPin",    SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN   },
196
  { "soPin",      SC_PKCS15_PIN_FLAG_SO_PIN     },
197
  { "disable-allowed",    SC_PKCS15_PIN_FLAG_DISABLE_ALLOW    },
198
  { "integrity-protected",  SC_PKCS15_PIN_FLAG_INTEGRITY_PROTECTED    },
199
  { "confidentiality-protected",  SC_PKCS15_PIN_FLAG_CONFIDENTIALITY_PROTECTED  },
200
  { "exchangeRefData",    SC_PKCS15_PIN_FLAG_EXCHANGE_REF_DATA    },
201
  { NULL, 0 }
202
};
203
static struct map   idStyleNames[] = {
204
  { "native",   SC_PKCS15INIT_ID_STYLE_NATIVE },
205
  { "mozilla",    SC_PKCS15INIT_ID_STYLE_MOZILLA },
206
  { "rfc2459",    SC_PKCS15INIT_ID_STYLE_RFC2459 },
207
  { NULL, 0 }
208
};
209
static struct map              mdStyleNames[] = {
210
  { "none",               SC_PKCS15INIT_MD_STYLE_NONE },
211
  { "gemalto",            SC_PKCS15INIT_MD_STYLE_GEMALTO },
212
  { NULL, 0 }
213
};
214
static struct {
215
  const char *    name;
216
  struct map *    addr;
217
} mapNames[] = {
218
  { "file ACL",   aclNames  },
219
  { "file operation", fileOpNames },
220
  { "file type",    fileTypeNames },
221
  { "file structure", fileStructureNames},
222
  { "PKCS#15 file name",  pkcs15DfNames },
223
  { "pin encoding", pinTypeNames  },
224
  { "pin name",   pinIdNames  },
225
  { "pin flag",   pinFlagNames  },
226
  { NULL, NULL }
227
};
228
229
static int    process_conf(struct sc_profile *, scconf_context *);
230
static int    process_block(struct state *, struct block *,
231
        const char *, scconf_block *);
232
static void   init_state(struct state *, struct state *);
233
static int    get_authid(struct state *, const char *,
234
        unsigned int *, unsigned int *);
235
static int    get_uint(struct state *, const char *, unsigned int *);
236
static int    get_bool(struct state *, const char *, unsigned int *);
237
static int    get_uint_eval(struct state *, int, char **,
238
        unsigned int *);
239
static int    map_str2int(struct state *, const char *,
240
        unsigned int *, struct map *);
241
static int    setstr(char **strp, const char *value);
242
static void   parse_error(struct state *, const char *, ...);
243
244
static struct file_info * sc_profile_instantiate_file(sc_profile_t *,
245
        struct file_info *, struct file_info *,
246
        unsigned int);
247
static struct file_info * sc_profile_find_file(struct sc_profile *,
248
        const sc_path_t *, const char *);
249
static struct file_info * sc_profile_find_file_by_path(
250
        struct sc_profile *,
251
        const sc_path_t *);
252
253
static struct pin_info *  new_pin(struct sc_profile *, int);
254
static struct file_info * new_file(struct state *, const char *,
255
        unsigned int);
256
static struct file_info * add_file(sc_profile_t *, const char *,
257
        sc_file_t *, struct file_info *);
258
static void   free_file_list(struct file_info **);
259
static void   append_file(sc_profile_t *, struct file_info *);
260
static struct auth_info * new_key(struct sc_profile *,
261
        unsigned int, unsigned int);
262
static void   set_pin_defaults(struct sc_profile *,
263
        struct pin_info *);
264
static int    new_macro(sc_profile_t *, const char *, scconf_list *);
265
static sc_macro_t * find_macro(sc_profile_t *, const char *);
266
static int    is_macro_character(char c);
267
268
static sc_file_t *
269
init_file(unsigned int type)
270
63.8k
{
271
63.8k
  struct sc_file  *file;
272
63.8k
  unsigned int  op;
273
274
63.8k
  file = sc_file_new();
275
2.04M
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
276
1.97M
    sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);
277
1.97M
  }
278
63.8k
  file->type = type;
279
63.8k
  file->status = SC_FILE_STATUS_ACTIVATED;
280
63.8k
  if (file->type != SC_FILE_TYPE_DF && file->type != SC_FILE_TYPE_BSO)
281
46.2k
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
282
63.8k
  return file;
283
63.8k
}
profile.c:init_file
Line
Count
Source
270
615
{
271
615
  struct sc_file  *file;
272
615
  unsigned int  op;
273
274
615
  file = sc_file_new();
275
19.6k
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
276
19.0k
    sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);
277
19.0k
  }
278
615
  file->type = type;
279
615
  file->status = SC_FILE_STATUS_ACTIVATED;
280
615
  if (file->type != SC_FILE_TYPE_DF && file->type != SC_FILE_TYPE_BSO)
281
615
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
282
615
  return file;
283
615
}
fuzz_pkcs15init.c:init_file
Line
Count
Source
270
63.2k
{
271
63.2k
  struct sc_file  *file;
272
63.2k
  unsigned int  op;
273
274
63.2k
  file = sc_file_new();
275
2.02M
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
276
1.96M
    sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);
277
1.96M
  }
278
63.2k
  file->type = type;
279
63.2k
  file->status = SC_FILE_STATUS_ACTIVATED;
280
63.2k
  if (file->type != SC_FILE_TYPE_DF && file->type != SC_FILE_TYPE_BSO)
281
45.6k
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
282
63.2k
  return file;
283
63.2k
}
284
285
/*
286
 * Initialize profile
287
 */
288
struct sc_profile *
289
sc_profile_new(void)
290
13.2k
{
291
13.2k
  struct sc_pkcs15_card *p15card;
292
13.2k
  struct sc_profile *pro;
293
294
13.2k
  pro = calloc(1, sizeof(*pro));
295
13.2k
  if (pro == NULL)
296
0
    return NULL;
297
13.2k
  pro->p15_spec = p15card = sc_pkcs15_card_new();
298
299
13.2k
  pro->pkcs15.do_last_update = 1;
300
301
13.2k
  if (p15card) {
302
13.2k
    p15card->tokeninfo->label = strdup("OpenSC Card");
303
13.2k
    p15card->tokeninfo->manufacturer_id = strdup("OpenSC Project");
304
13.2k
    p15card->tokeninfo->serial_number = strdup("0000");
305
13.2k
    p15card->tokeninfo->flags = SC_PKCS15_TOKEN_EID_COMPLIANT;
306
13.2k
    p15card->tokeninfo->version = 0;
307
308
    /* Set up EF(TokenInfo) and EF(ODF) */
309
13.2k
    p15card->file_tokeninfo = init_file(SC_FILE_TYPE_WORKING_EF);
310
13.2k
    p15card->file_odf = init_file(SC_FILE_TYPE_WORKING_EF);
311
13.2k
    p15card->file_unusedspace = init_file(SC_FILE_TYPE_WORKING_EF);
312
13.2k
  }
313
314
  /* Assume card does RSA natively */
315
13.2k
  pro->rsa_access_flags = DEF_PRKEY_RSA_ACCESS;
316
13.2k
  pro->pin_encoding = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
317
13.2k
  pro->pin_minlen = 4;
318
13.2k
  pro->pin_maxlen = 8;
319
13.2k
  pro->id_style = SC_PKCS15INIT_ID_STYLE_NATIVE;
320
321
13.2k
  return pro;
322
13.2k
}
323
324
int
325
sc_profile_load(struct sc_profile *profile, const char *filename)
326
137
{
327
137
  struct sc_context *ctx = profile->card->ctx;
328
137
  scconf_context  *conf;
329
137
  const char *profile_dir = NULL;
330
137
  char path[PATH_MAX];
331
137
  int res = 0, i;
332
#ifdef _WIN32
333
  char temp_path[PATH_MAX];
334
  size_t temp_len;
335
#endif
336
337
137
  LOG_FUNC_CALLED(ctx);
338
274
  for (i = 0; ctx->conf_blocks[i]; i++) {
339
137
    profile_dir = scconf_get_str(ctx->conf_blocks[i], "profile_dir", NULL);
340
137
    if (profile_dir)
341
0
      break;
342
137
  }
343
344
137
  if (!profile_dir) {
345
#ifdef _WIN32
346
    temp_len = PATH_MAX - 1;
347
    res = sc_ctx_win32_get_config_value(NULL, "ProfileDir", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX,
348
        temp_path, &temp_len);
349
    if (res)
350
      LOG_FUNC_RETURN(ctx, res);
351
    temp_path[temp_len] = '\0';
352
    profile_dir = temp_path;
353
#else
354
137
    profile_dir = SC_PKCS15_PROFILE_DIRECTORY;
355
137
#endif
356
137
  }
357
137
  sc_log(ctx, "Using profile directory '%s'.", profile_dir);
358
359
#ifdef _WIN32
360
  snprintf(path, sizeof(path), "%s\\%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX);
361
#else /* _WIN32 */
362
137
  snprintf(path, sizeof(path), "%s/%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX);
363
137
#endif /* _WIN32 */
364
365
137
  sc_log(ctx, "Trying profile file %s", path);
366
367
137
  conf = scconf_new(path);
368
137
  res = scconf_parse(conf);
369
370
137
  sc_log(ctx, "profile %s loaded ok", path);
371
372
137
  if (res < 0) {
373
137
    scconf_free(conf);
374
137
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
375
137
  }
376
377
0
  if (res == 0) {
378
0
    scconf_free(conf);
379
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SYNTAX_ERROR);
380
0
  }
381
382
0
  res = process_conf(profile, conf);
383
0
  scconf_free(conf);
384
0
  LOG_FUNC_RETURN(ctx, res);
385
0
}
386
387
388
int
389
sc_profile_finish(struct sc_profile *profile, const struct sc_app_info *app_info)
390
10.2k
{
391
10.2k
  struct sc_context *ctx = profile->card->ctx;
392
10.2k
  struct file_info *fi;
393
10.2k
  struct pin_info *pi;
394
10.2k
  char    reason[64];
395
396
10.2k
  LOG_FUNC_CALLED(ctx);
397
10.2k
  profile->mf_info = sc_profile_find_file(profile, NULL, "MF");
398
10.2k
  if (!profile->mf_info)
399
10.2k
    LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Profile doesn't define a MF");
400
401
6.94k
  if (app_info && app_info->aid.len)   {
402
0
    struct sc_path path;
403
404
0
    sc_log(ctx, "finish profile with '%s' application profile", app_info->label);
405
0
    memset(&path, 0, sizeof(struct sc_path));
406
0
    path.type = SC_PATH_TYPE_DF_NAME;
407
0
    path.aid = app_info->aid;
408
409
0
    sc_log(ctx, "Look for file by path '%s'", sc_print_path(&path));
410
0
    profile->df_info = sc_profile_find_file_by_path(profile, &path);
411
0
    sc_log(ctx, "returned DF info %p", profile->df_info);
412
0
    if (profile->df_info && profile->df_info->profile_extension)   {
413
0
      sc_log(ctx, "application profile extension '%s'", profile->df_info->profile_extension);
414
0
      if (sc_profile_load(profile, profile->df_info->profile_extension))
415
0
        LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Cannot load application profile extension");
416
0
    }
417
0
  }
418
419
6.94k
  profile->df_info = sc_profile_find_file(profile, NULL, "PKCS15-AppDF");
420
6.94k
  if (!profile->df_info)
421
6.94k
    LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Profile doesn't define a PKCS15-AppDF");
422
423
6.88k
  profile->p15_spec->file_app = profile->df_info->file;
424
6.88k
  profile->df_info->dont_free = 1;
425
426
10.5k
  for (pi = profile->pin_list; pi; pi = pi->next) {
427
3.62k
    const char  *name;
428
429
3.62k
    set_pin_defaults(profile, pi);
430
3.62k
    if (!(name = pi->file_name))
431
3.62k
      continue;
432
1
    if (!(fi = sc_profile_find_file(profile, NULL, name))) {
433
1
      snprintf(reason, sizeof(reason), "unknown PIN file \"%s\"\n", name);
434
1
      goto whine;
435
1
    }
436
437
0
    pi->file = fi;
438
0
  }
439
6.87k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
440
441
1
whine:
442
1
  sc_log(ctx, "%s", reason);
443
1
  LOG_FUNC_RETURN(ctx, SC_ERROR_INCONSISTENT_PROFILE);
444
1
}
445
446
void
447
sc_profile_free(struct sc_profile *profile)
448
15.1k
{
449
15.1k
  struct auth_info *ai;
450
15.1k
  struct pin_info *pi;
451
15.1k
  sc_macro_t  *mi;
452
15.1k
  sc_template_t *ti;
453
454
15.1k
  if (profile->name)
455
12.3k
    free(profile->name);
456
15.1k
  if (profile->driver)
457
9
    free(profile->driver);
458
459
15.1k
  free_file_list(&profile->ef_list);
460
461
15.1k
  while ((ai = profile->auth_list) != NULL) {
462
4
    profile->auth_list = ai->next;
463
4
    free(ai);
464
4
  }
465
466
17.0k
  while ((ti = profile->template_list) != NULL) {
467
1.92k
    profile->template_list = ti->next;
468
1.92k
    if (ti->data)
469
1.92k
      sc_profile_free(ti->data);
470
1.92k
    if (ti->name)
471
1.92k
      free(ti->name);
472
1.92k
    free(ti);
473
1.92k
  }
474
475
17.9k
  while ((mi = profile->macro_list) != NULL) {
476
2.82k
    profile->macro_list = mi->next;
477
2.82k
    if (mi->name)
478
2.82k
      free(mi->name);
479
2.82k
    free(mi);
480
2.82k
  }
481
482
34.9k
  while ((pi = profile->pin_list) != NULL) {
483
19.8k
    profile->pin_list = pi->next;
484
19.8k
    if (pi->file_name)
485
26
      free(pi->file_name);
486
19.8k
    free(pi);
487
19.8k
  }
488
489
15.3k
  for (int i = 0; profile->options[i]; i++) {
490
202
    free(profile->options[i]);
491
202
  }
492
493
15.1k
  if (profile->p15_spec)
494
13.2k
    sc_pkcs15_card_free(profile->p15_spec);
495
496
15.1k
  if (profile->dll)
497
0
    sc_dlclose(profile->dll);
498
499
15.1k
  free(profile);
500
15.1k
}
501
502
void
503
sc_profile_get_pin_info(struct sc_profile *profile,
504
    int id, struct sc_pkcs15_auth_info *info)
505
28.8k
{
506
28.8k
  struct pin_info *pi;
507
508
28.8k
  pi = new_pin(profile, id);
509
28.8k
  if (pi == NULL)
510
0
    return;
511
512
28.8k
  pi->pin.max_tries = pi->pin.tries_left;
513
28.8k
  *info = pi->pin;
514
28.8k
}
515
516
int
517
sc_profile_get_pin_retries(sc_profile_t *profile, int id)
518
49
{
519
49
  struct pin_info *pi;
520
521
49
  pi = new_pin(profile, id);
522
49
  if (pi == NULL)
523
0
    return SC_ERROR_OUT_OF_MEMORY;
524
49
  return pi->pin.tries_left;
525
49
}
526
527
int
528
sc_profile_get_pin_id(struct sc_profile *profile,
529
    unsigned int reference, int *id)
530
31
{
531
31
  struct pin_info *pi;
532
533
173
  for (pi = profile->pin_list; pi; pi = pi->next) {
534
161
    if (pi->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
535
0
      continue;
536
161
    if (pi->pin.attrs.pin.reference == (int)reference) {
537
19
      *id = pi->id;
538
19
      return 0;
539
19
    }
540
541
161
  }
542
12
  return SC_ERROR_OBJECT_NOT_FOUND;
543
31
}
544
545
int
546
sc_profile_get_file_in(sc_profile_t *profile,
547
    const sc_path_t *path, const char *name, sc_file_t **ret)
548
19
{
549
19
  struct file_info *fi;
550
551
19
  if ((fi = sc_profile_find_file(profile, path, name)) == NULL)
552
14
    return SC_ERROR_FILE_NOT_FOUND;
553
5
  sc_file_dup(ret, fi->file);
554
5
  if (*ret == NULL)
555
0
    return SC_ERROR_OUT_OF_MEMORY;
556
5
  return 0;
557
5
}
558
559
int
560
sc_profile_get_file(struct sc_profile *profile,
561
    const char *name, sc_file_t **ret)
562
8.37k
{
563
8.37k
  struct file_info *fi;
564
565
8.37k
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
566
5.17k
    return SC_ERROR_FILE_NOT_FOUND;
567
3.20k
  sc_file_dup(ret, fi->file);
568
3.20k
  if (*ret == NULL)
569
0
    return SC_ERROR_OUT_OF_MEMORY;
570
3.20k
  return 0;
571
3.20k
}
572
573
int
574
sc_profile_get_file_instance(struct sc_profile *profile, const char *name,
575
    int index, sc_file_t **ret)
576
25.7k
{
577
25.7k
  struct sc_context *ctx = profile->card->ctx;
578
25.7k
  struct file_info *fi;
579
25.7k
  struct sc_file *file;
580
25.7k
  int r;
581
582
25.7k
  LOG_FUNC_CALLED(ctx);
583
25.7k
  sc_log(ctx, "try to get '%s' file instance", name);
584
585
25.7k
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
586
25.7k
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
587
4.24k
  sc_file_dup(&file, fi->file);
588
4.24k
  sc_log(ctx, "ident '%s'; parent '%s'", fi->ident, fi->parent ? fi->parent->ident : "(null)");
589
4.24k
  if (file == NULL)
590
4.24k
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
591
4.24k
  sc_log(ctx, "file (type:%X, path:'%s')", file->type, sc_print_path(&file->path));
592
593
4.24k
  file->id += index;
594
4.24k
        if(file->type == SC_FILE_TYPE_BSO) {
595
9
    r = sc_profile_add_file(profile, name, file);
596
9
    if (r < 0)
597
6
      sc_file_free(file);
598
9
    LOG_TEST_RET(ctx, r, "Profile error: cannot add BSO file");
599
9
  }
600
4.23k
  else if (file->path.len)   {
601
576
    file->path.value[file->path.len - 2] = (file->id >> 8) & 0xFF;
602
576
    file->path.value[file->path.len - 1] = file->id & 0xFF;
603
604
576
    r = sc_profile_add_file(profile, name, file);
605
576
    if (r < 0)
606
45
      sc_file_free(file);
607
576
    LOG_TEST_RET(ctx, r, "Profile error: cannot add file");
608
576
  }
609
610
4.19k
  if (ret)
611
4.19k
    *ret = file;
612
0
  else
613
0
    sc_file_free(file);
614
615
4.19k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
616
4.19k
}
617
618
int
619
sc_profile_get_path(struct sc_profile *profile,
620
    const char *name, sc_path_t *ret)
621
0
{
622
0
  struct file_info *fi;
623
624
0
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
625
0
    return SC_ERROR_FILE_NOT_FOUND;
626
0
  *ret = fi->file->path;
627
0
  return 0;
628
0
}
629
630
int
631
sc_profile_get_file_by_path(struct sc_profile *profile,
632
    const sc_path_t *path, sc_file_t **ret)
633
6.35k
{
634
6.35k
  struct sc_context *ctx = profile->card->ctx;
635
6.35k
  struct file_info *fi;
636
637
6.35k
  LOG_FUNC_CALLED(ctx);
638
6.35k
  if ((fi = sc_profile_find_file_by_path(profile, path)) == NULL)
639
6.35k
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
640
3.49k
  sc_file_dup(ret, fi->file);
641
3.49k
  LOG_FUNC_RETURN(ctx, *ret ? SC_SUCCESS : SC_ERROR_OUT_OF_MEMORY);
642
3.49k
}
643
644
int
645
sc_profile_add_file(sc_profile_t *profile, const char *name, sc_file_t *file)
646
590
{
647
590
  struct sc_context *ctx = profile->card->ctx;
648
590
  sc_path_t path = file->path;
649
590
  struct file_info  *parent;
650
651
590
  LOG_FUNC_CALLED(ctx);
652
590
  if (!path.len)   {
653
3
    parent = profile->df_info;
654
587
  } else {
655
587
    path.len -= 2;
656
587
    parent = sc_profile_find_file_by_path(profile, &path);
657
587
  }
658
590
  if (!parent)
659
590
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
660
534
  sc_log(ctx, "Parent path:%s", sc_print_path(&parent->file->path));
661
662
534
  sc_file_dup(&file, file);
663
534
  if (file == NULL)
664
534
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
665
666
534
  add_file(profile, name, file, parent);
667
534
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
668
534
}
669
670
/*
671
 * Instantiate template
672
 */
673
int
674
sc_profile_instantiate_template(sc_profile_t *profile,
675
    const char *template_name, const sc_path_t *base_path,
676
    const char *file_name, const sc_pkcs15_id_t *id,
677
    sc_file_t **ret)
678
27.4k
{
679
27.4k
  struct sc_context *ctx = profile->card->ctx;
680
27.4k
  struct sc_profile *tmpl;
681
27.4k
  struct sc_template  *info;
682
27.4k
  unsigned int  idx;
683
27.4k
  struct file_info *fi, *base_file, *match = NULL;
684
685
#ifdef DEBUG_PROFILE
686
  printf("Instantiate %s in template %s\n", file_name, template_name);
687
  sc_profile_find_file_by_path(profile, base_path);
688
#endif
689
28.1k
  for (info = profile->template_list; info; info = info->next)
690
2.22k
    if (!strcmp(info->name, template_name))
691
1.59k
      break;
692
27.4k
  if (info == NULL)   {
693
25.8k
    sc_log(ctx, "Template %s not found", template_name);
694
25.8k
    return SC_ERROR_TEMPLATE_NOT_FOUND;
695
25.8k
  }
696
697
1.59k
  tmpl = info->data;
698
1.59k
  idx = id->value[id->len-1];
699
106k
  for (fi = profile->ef_list; fi; fi = fi->next) {
700
105k
    if (fi->base_template == tmpl
701
100k
     && fi->inst_index == idx
702
1.86k
     && sc_compare_path(&fi->inst_path, base_path)
703
1.85k
     && !strcmp(fi->ident, file_name)) {
704
307
      sc_file_dup(ret, fi->file);
705
307
      if (*ret == NULL)
706
0
        return SC_ERROR_OUT_OF_MEMORY;
707
307
      return 0;
708
307
    }
709
105k
  }
710
711
1.28k
  sc_log(ctx, "Instantiating template %s at %s", template_name, sc_print_path(base_path));
712
713
1.28k
  base_file = sc_profile_find_file_by_path(profile, base_path);
714
1.28k
  if (base_file == NULL) {
715
18
    sc_log(ctx, "Directory %s not defined in profile", sc_print_path(base_path));
716
18
    return SC_ERROR_OBJECT_NOT_FOUND;
717
18
  }
718
719
  /* This loop relies on the fact that new files are always
720
   * appended to the list, after the parent files they refer to
721
   */
722
1.28k
  assert(base_file->instance);
723
2.57k
  for (fi = tmpl->ef_list; fi; fi = fi->next) {
724
1.30k
    struct file_info  *parent, *instance;
725
1.30k
    unsigned int  skew = 0;
726
727
1.30k
    fi->instance = NULL;
728
1.30k
    if ((parent = fi->parent) == NULL) {
729
1.20k
      parent = base_file;
730
1.20k
      skew = idx;
731
1.20k
    }
732
1.30k
    parent = parent->instance;
733
734
1.30k
    instance = sc_profile_instantiate_file(profile, fi, parent, skew);
735
1.30k
    if (instance == NULL)
736
0
      return SC_ERROR_OUT_OF_MEMORY;
737
1.30k
    instance->base_template = tmpl;
738
1.30k
    instance->inst_index = idx;
739
1.30k
    instance->inst_path = *base_path;
740
741
1.30k
    if (!strcmp(instance->ident, file_name))
742
510
      match = instance;
743
1.30k
  }
744
745
1.27k
  if (match == NULL) {
746
760
    sc_log(ctx, "No file named \"%s\" in template \"%s\"",
747
760
        file_name, template_name);
748
760
    return SC_ERROR_OBJECT_NOT_FOUND;
749
760
  }
750
510
  sc_file_dup(ret, match->file);
751
510
  if (*ret == NULL)
752
0
    return SC_ERROR_OUT_OF_MEMORY;
753
#ifdef DEBUG_PROFILE
754
  printf("Template instantiated\n");
755
#endif
756
510
  return 0;
757
510
}
758
759
static struct file_info *
760
sc_profile_instantiate_file(sc_profile_t *profile, struct file_info *ft,
761
    struct file_info *parent, unsigned int skew)
762
1.30k
{
763
1.30k
  struct sc_context *ctx = profile->card->ctx;
764
1.30k
  struct file_info *fi;
765
766
1.30k
  fi = calloc(1, sizeof(*fi));
767
1.30k
  if (fi == NULL)
768
0
    return NULL;
769
1.30k
  fi->instance = fi;
770
1.30k
  fi->parent = parent;
771
1.30k
  fi->ident = strdup(ft->ident);
772
1.30k
  if (fi->ident == NULL) {
773
0
    free(fi);
774
0
    return NULL;
775
0
  }
776
1.30k
  sc_file_dup(&fi->file, ft->file);
777
1.30k
  if (fi->file == NULL) {
778
0
    free(fi->ident);
779
0
    free(fi);
780
0
    return NULL;
781
0
  }
782
1.30k
  fi->file->path = parent->file->path;
783
1.30k
  fi->file->id += skew;
784
785
1.30k
  if (fi->file->type == SC_FILE_TYPE_INTERNAL_EF
786
1.27k
      || fi->file->type == SC_FILE_TYPE_WORKING_EF
787
1.14k
      || (fi->file->type == SC_FILE_TYPE_DF && fi->file->id))
788
247
    sc_append_file_id(&fi->file->path, fi->file->id);
789
790
1.30k
  append_file(profile, fi);
791
792
1.30k
  ft->instance = fi;
793
794
1.30k
  sc_log(ctx, "Instantiated %s at %s", ft->ident, sc_print_path(&fi->file->path));
795
1.30k
  sc_log(ctx, "  parent=%s@%s", parent->ident, sc_print_path(&parent->file->path));
796
797
1.30k
  return fi;
798
1.30k
}
Unexecuted instantiation: profile.c:sc_profile_instantiate_file
fuzz_pkcs15init.c:sc_profile_instantiate_file
Line
Count
Source
762
1.30k
{
763
1.30k
  struct sc_context *ctx = profile->card->ctx;
764
1.30k
  struct file_info *fi;
765
766
1.30k
  fi = calloc(1, sizeof(*fi));
767
1.30k
  if (fi == NULL)
768
0
    return NULL;
769
1.30k
  fi->instance = fi;
770
1.30k
  fi->parent = parent;
771
1.30k
  fi->ident = strdup(ft->ident);
772
1.30k
  if (fi->ident == NULL) {
773
0
    free(fi);
774
0
    return NULL;
775
0
  }
776
1.30k
  sc_file_dup(&fi->file, ft->file);
777
1.30k
  if (fi->file == NULL) {
778
0
    free(fi->ident);
779
0
    free(fi);
780
0
    return NULL;
781
0
  }
782
1.30k
  fi->file->path = parent->file->path;
783
1.30k
  fi->file->id += skew;
784
785
1.30k
  if (fi->file->type == SC_FILE_TYPE_INTERNAL_EF
786
1.27k
      || fi->file->type == SC_FILE_TYPE_WORKING_EF
787
1.14k
      || (fi->file->type == SC_FILE_TYPE_DF && fi->file->id))
788
247
    sc_append_file_id(&fi->file->path, fi->file->id);
789
790
1.30k
  append_file(profile, fi);
791
792
1.30k
  ft->instance = fi;
793
794
1.30k
  sc_log(ctx, "Instantiated %s at %s", ft->ident, sc_print_path(&fi->file->path));
795
1.30k
  sc_log(ctx, "  parent=%s@%s", parent->ident, sc_print_path(&parent->file->path));
796
797
1.30k
  return fi;
798
1.30k
}
799
800
int
801
sc_profile_get_pin_id_by_reference(struct sc_profile *profile,
802
    unsigned auth_method, int reference,
803
    struct sc_pkcs15_auth_info *auth_info)
804
2.90k
{
805
2.90k
  struct pin_info *pinfo;
806
807
7.51k
  for (pinfo = profile->pin_list; pinfo; pinfo = pinfo->next)  {
808
6.22k
    if (auth_method == SC_AC_SYMBOLIC)   {
809
3.05k
      if (pinfo->id != reference)
810
1.46k
        continue;
811
3.05k
    }
812
3.16k
    else   {
813
3.16k
      if (pinfo->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
814
0
        continue;
815
3.16k
      if (pinfo->pin.auth_method != auth_method)
816
376
        continue;
817
2.78k
      if (pinfo->pin.attrs.pin.reference != reference)
818
2.76k
        continue;
819
2.78k
    }
820
821
1.61k
    if (auth_info)
822
1.61k
      *auth_info = pinfo->pin;
823
1.61k
    return pinfo->id;
824
6.22k
  }
825
826
1.29k
  return -1;
827
2.90k
}
828
829
/*
830
 * Configuration file parser
831
 */
832
static void
833
init_state(struct state *cur_state, struct state *new_state)
834
37.8k
{
835
37.8k
  memset(new_state, 0, sizeof(*new_state));
836
37.8k
  new_state->filename = cur_state->filename;
837
37.8k
  new_state->profile = cur_state->profile;
838
37.8k
  new_state->frame = cur_state;
839
37.8k
}
Unexecuted instantiation: profile.c:init_state
fuzz_pkcs15init.c:init_state
Line
Count
Source
834
37.8k
{
835
37.8k
  memset(new_state, 0, sizeof(*new_state));
836
37.8k
  new_state->filename = cur_state->filename;
837
37.8k
  new_state->profile = cur_state->profile;
838
37.8k
  new_state->frame = cur_state;
839
37.8k
}
840
841
static int
842
do_card_driver(struct state *cur, int argc, char **argv)
843
69
{
844
69
  free(cur->profile->driver);
845
69
  cur->profile->driver = strdup(argv[0]);
846
69
  return 0;
847
69
}
Unexecuted instantiation: profile.c:do_card_driver
fuzz_pkcs15init.c:do_card_driver
Line
Count
Source
843
69
{
844
69
  free(cur->profile->driver);
845
69
  cur->profile->driver = strdup(argv[0]);
846
69
  return 0;
847
69
}
848
849
static int
850
do_maxpinlength(struct state *cur, int argc, char **argv)
851
128
{
852
128
  return get_uint(cur, argv[0], &cur->profile->pin_maxlen);
853
128
}
Unexecuted instantiation: profile.c:do_maxpinlength
fuzz_pkcs15init.c:do_maxpinlength
Line
Count
Source
851
128
{
852
128
  return get_uint(cur, argv[0], &cur->profile->pin_maxlen);
853
128
}
854
855
static int
856
do_minpinlength(struct state *cur, int argc, char **argv)
857
269
{
858
269
  return get_uint(cur, argv[0], &cur->profile->pin_minlen);
859
269
}
Unexecuted instantiation: profile.c:do_minpinlength
fuzz_pkcs15init.c:do_minpinlength
Line
Count
Source
857
269
{
858
269
  return get_uint(cur, argv[0], &cur->profile->pin_minlen);
859
269
}
860
861
static int
862
do_default_pin_type(struct state *cur, int argc, char **argv)
863
334
{
864
334
  return map_str2int(cur, argv[0],
865
334
            &cur->profile->pin_encoding, pinTypeNames);
866
334
}
Unexecuted instantiation: profile.c:do_default_pin_type
fuzz_pkcs15init.c:do_default_pin_type
Line
Count
Source
863
334
{
864
334
  return map_str2int(cur, argv[0],
865
334
            &cur->profile->pin_encoding, pinTypeNames);
866
334
}
867
868
static int
869
do_pin_pad_char(struct state *cur, int argc, char **argv)
870
305
{
871
305
  return get_uint(cur, argv[0], &cur->profile->pin_pad_char);
872
305
}
Unexecuted instantiation: profile.c:do_pin_pad_char
fuzz_pkcs15init.c:do_pin_pad_char
Line
Count
Source
870
305
{
871
305
  return get_uint(cur, argv[0], &cur->profile->pin_pad_char);
872
305
}
873
874
static int
875
do_pin_domains(struct state *cur, int argc, char **argv)
876
188
{
877
188
  return get_bool(cur, argv[0], &cur->profile->pin_domains);
878
188
}
Unexecuted instantiation: profile.c:do_pin_domains
fuzz_pkcs15init.c:do_pin_domains
Line
Count
Source
876
188
{
877
188
  return get_bool(cur, argv[0], &cur->profile->pin_domains);
878
188
}
879
880
static int
881
do_card_label(struct state *cur, int argc, char **argv)
882
454
{
883
454
  struct sc_pkcs15_card *p15card = cur->profile->p15_spec;
884
885
454
  return setstr(&p15card->tokeninfo->label, argv[0]);
886
454
}
Unexecuted instantiation: profile.c:do_card_label
fuzz_pkcs15init.c:do_card_label
Line
Count
Source
882
454
{
883
454
  struct sc_pkcs15_card *p15card = cur->profile->p15_spec;
884
885
454
  return setstr(&p15card->tokeninfo->label, argv[0]);
886
454
}
887
888
static int
889
do_card_manufacturer(struct state *cur, int argc, char **argv)
890
143
{
891
143
  struct sc_pkcs15_card *p15card = cur->profile->p15_spec;
892
893
143
  return setstr(&p15card->tokeninfo->manufacturer_id, argv[0]);
894
143
}
Unexecuted instantiation: profile.c:do_card_manufacturer
fuzz_pkcs15init.c:do_card_manufacturer
Line
Count
Source
890
143
{
891
143
  struct sc_pkcs15_card *p15card = cur->profile->p15_spec;
892
893
143
  return setstr(&p15card->tokeninfo->manufacturer_id, argv[0]);
894
143
}
895
896
/*
897
 * Command related to the pkcs15 we generate
898
 */
899
static int
900
do_direct_certificates(struct state *cur, int argc, char **argv)
901
1.39k
{
902
1.39k
  return get_bool(cur, argv[0], &cur->profile->pkcs15.direct_certificates);
903
1.39k
}
Unexecuted instantiation: profile.c:do_direct_certificates
fuzz_pkcs15init.c:do_direct_certificates
Line
Count
Source
901
1.39k
{
902
1.39k
  return get_bool(cur, argv[0], &cur->profile->pkcs15.direct_certificates);
903
1.39k
}
904
905
static int
906
do_encode_df_length(struct state *cur, int argc, char **argv)
907
1.02k
{
908
1.02k
  return get_bool(cur, argv[0], &cur->profile->pkcs15.encode_df_length);
909
1.02k
}
Unexecuted instantiation: profile.c:do_encode_df_length
fuzz_pkcs15init.c:do_encode_df_length
Line
Count
Source
907
1.02k
{
908
1.02k
  return get_bool(cur, argv[0], &cur->profile->pkcs15.encode_df_length);
909
1.02k
}
910
911
static int
912
do_encode_update_field(struct state *cur, int argc, char **argv)
913
1.07k
{
914
1.07k
  return get_bool(cur, argv[0], &cur->profile->pkcs15.do_last_update);
915
1.07k
}
Unexecuted instantiation: profile.c:do_encode_update_field
fuzz_pkcs15init.c:do_encode_update_field
Line
Count
Source
913
1.07k
{
914
1.07k
  return get_bool(cur, argv[0], &cur->profile->pkcs15.do_last_update);
915
1.07k
}
916
917
static int
918
do_pkcs15_id_style(struct state *cur, int argc, char **argv)
919
736
{
920
736
  return map_str2int(cur, argv[0], &cur->profile->id_style, idStyleNames);
921
736
}
Unexecuted instantiation: profile.c:do_pkcs15_id_style
fuzz_pkcs15init.c:do_pkcs15_id_style
Line
Count
Source
919
736
{
920
736
  return map_str2int(cur, argv[0], &cur->profile->id_style, idStyleNames);
921
736
}
922
923
static int
924
do_minidriver_support_style(struct state *cur, int argc, char **argv)
925
1
{
926
1
  return map_str2int(cur, argv[0], &cur->profile->md_style, mdStyleNames);
927
1
}
Unexecuted instantiation: profile.c:do_minidriver_support_style
fuzz_pkcs15init.c:do_minidriver_support_style
Line
Count
Source
925
1
{
926
1
  return map_str2int(cur, argv[0], &cur->profile->md_style, mdStyleNames);
927
1
}
928
929
/*
930
 * Process an option block
931
 */
932
static int
933
process_option(struct state *cur, struct block *info,
934
    const char *name, scconf_block *blk)
935
1.15k
{
936
1.15k
  sc_profile_t  *profile = cur->profile;
937
1.15k
  int   match = 0, i;
938
939
1.55k
  for (i = 0; profile->options[i]; i++)
940
404
    match |= !strcmp(profile->options[i], name);
941
1.15k
  if (!match && strcmp("default", name))
942
568
    return 0;
943
585
  return process_block(cur, info, name, blk);
944
1.15k
}
Unexecuted instantiation: profile.c:process_option
fuzz_pkcs15init.c:process_option
Line
Count
Source
935
1.15k
{
936
1.15k
  sc_profile_t  *profile = cur->profile;
937
1.15k
  int   match = 0, i;
938
939
1.55k
  for (i = 0; profile->options[i]; i++)
940
404
    match |= !strcmp(profile->options[i], name);
941
1.15k
  if (!match && strcmp("default", name))
942
568
    return 0;
943
585
  return process_block(cur, info, name, blk);
944
1.15k
}
945
946
/*
947
 * Process a key block
948
 */
949
static int
950
process_key(struct state *cur, struct block *info,
951
    const char *name, scconf_block *blk)
952
19
{
953
19
  unsigned int  type, id;
954
19
  struct state  state;
955
956
19
  if (get_authid(cur, name, &type, &id))
957
15
    return 1;
958
959
4
  init_state(cur, &state);
960
4
  state.key = new_key(cur->profile, type, id);
961
4
  return process_block(&state, info, name, blk);
962
19
}
Unexecuted instantiation: profile.c:process_key
fuzz_pkcs15init.c:process_key
Line
Count
Source
952
19
{
953
19
  unsigned int  type, id;
954
19
  struct state  state;
955
956
19
  if (get_authid(cur, name, &type, &id))
957
15
    return 1;
958
959
4
  init_state(cur, &state);
960
4
  state.key = new_key(cur->profile, type, id);
961
4
  return process_block(&state, info, name, blk);
962
19
}
963
964
static struct auth_info *
965
new_key(struct sc_profile *profile, unsigned int type, unsigned int ref)
966
4
{
967
4
  struct auth_info *ai, **aip;
968
969
4
  for (aip = &profile->auth_list; (ai = *aip); aip = &ai->next) {
970
0
    if (ai->type == type && ai->ref == ref)
971
0
      return ai;
972
0
  }
973
974
4
  ai = calloc(1, sizeof(*ai));
975
4
  if (ai == NULL)
976
0
    return NULL;
977
4
  ai->type = type;
978
4
  ai->ref = ref;
979
4
  *aip = ai;
980
4
  return ai;
981
4
}
Unexecuted instantiation: profile.c:new_key
fuzz_pkcs15init.c:new_key
Line
Count
Source
966
4
{
967
4
  struct auth_info *ai, **aip;
968
969
4
  for (aip = &profile->auth_list; (ai = *aip); aip = &ai->next) {
970
0
    if (ai->type == type && ai->ref == ref)
971
0
      return ai;
972
0
  }
973
974
4
  ai = calloc(1, sizeof(*ai));
975
4
  if (ai == NULL)
976
0
    return NULL;
977
4
  ai->type = type;
978
4
  ai->ref = ref;
979
4
  *aip = ai;
980
4
  return ai;
981
4
}
982
983
static int
984
do_key_value(struct state *cur, int argc, char **argv)
985
0
{
986
0
  struct auth_info *ai = cur->key;
987
0
  const char  *key = argv[0];
988
0
  size_t    key_len;
989
0
  unsigned char keybuf[32];
990
991
0
  if (key[0] == '=') {
992
0
    ++key;
993
0
    key_len = strlen(key);
994
0
    memcpy(keybuf, key, key_len);
995
0
  } else {
996
0
    key_len = sizeof(keybuf);
997
0
    if (sc_hex_to_bin(key, keybuf, &key_len)) {
998
0
      parse_error(cur, "Error parsing PIN/key \"%s\"\n", key);
999
0
      return 1;
1000
0
    }
1001
0
  }
1002
1003
0
  memcpy(ai->key, keybuf, key_len);
1004
0
  ai->key_len = key_len;
1005
0
  return 0;
1006
0
}
Unexecuted instantiation: profile.c:do_key_value
Unexecuted instantiation: fuzz_pkcs15init.c:do_key_value
1007
1008
/*
1009
 * This function is called when the parser finds a block with an unknown
1010
 * name in the filesystem block. This will create a new filesystem
1011
 * object as the child of the current object.
1012
 */
1013
static int
1014
process_df(struct state *cur, struct block *info,
1015
    const char *name, scconf_block *blk)
1016
20.9k
{
1017
20.9k
  struct state  state;
1018
1019
20.9k
  init_state(cur, &state);
1020
20.9k
  if (name == NULL) {
1021
0
    parse_error(cur, "No name given for DF object.");
1022
0
    return 1;
1023
0
  }
1024
20.9k
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_DF)))
1025
164
    return 1;
1026
20.8k
  return process_block(&state, info, name, blk);
1027
20.9k
}
Unexecuted instantiation: profile.c:process_df
fuzz_pkcs15init.c:process_df
Line
Count
Source
1016
20.9k
{
1017
20.9k
  struct state  state;
1018
1019
20.9k
  init_state(cur, &state);
1020
20.9k
  if (name == NULL) {
1021
0
    parse_error(cur, "No name given for DF object.");
1022
0
    return 1;
1023
0
  }
1024
20.9k
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_DF)))
1025
164
    return 1;
1026
20.8k
  return process_block(&state, info, name, blk);
1027
20.9k
}
1028
1029
static int
1030
process_ef(struct state *cur, struct block *info,
1031
    const char *name, scconf_block *blk)
1032
8.30k
{
1033
8.30k
  struct state  state;
1034
1035
8.30k
  init_state(cur, &state);
1036
8.30k
  if (name == NULL) {
1037
0
    parse_error(cur, "No name given for EF object.");
1038
0
    return 1;
1039
0
  }
1040
8.30k
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_WORKING_EF)))
1041
37
    return 1;
1042
8.26k
  return process_block(&state, info, name, blk);
1043
8.30k
}
Unexecuted instantiation: profile.c:process_ef
fuzz_pkcs15init.c:process_ef
Line
Count
Source
1032
8.30k
{
1033
8.30k
  struct state  state;
1034
1035
8.30k
  init_state(cur, &state);
1036
8.30k
  if (name == NULL) {
1037
0
    parse_error(cur, "No name given for EF object.");
1038
0
    return 1;
1039
0
  }
1040
8.30k
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_WORKING_EF)))
1041
37
    return 1;
1042
8.26k
  return process_block(&state, info, name, blk);
1043
8.30k
}
1044
1045
1046
static int
1047
process_bso(struct state *cur, struct block *info,
1048
    const char *name, scconf_block *blk)
1049
150
{
1050
150
  struct state  state;
1051
1052
150
  init_state(cur, &state);
1053
150
  if (name == NULL) {
1054
0
    parse_error(cur, "No name given for BSO object.");
1055
0
    return 1;
1056
0
  }
1057
150
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_BSO)))
1058
1
    return 1;
1059
149
  return process_block(&state, info, name, blk);
1060
150
}
Unexecuted instantiation: profile.c:process_bso
fuzz_pkcs15init.c:process_bso
Line
Count
Source
1049
150
{
1050
150
  struct state  state;
1051
1052
150
  init_state(cur, &state);
1053
150
  if (name == NULL) {
1054
0
    parse_error(cur, "No name given for BSO object.");
1055
0
    return 1;
1056
0
  }
1057
150
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_BSO)))
1058
1
    return 1;
1059
149
  return process_block(&state, info, name, blk);
1060
150
}
1061
1062
/*
1063
 * In the template the difference between any two file-ids
1064
 * should be greater then TEMPLATE_FILEID_MIN_DIFF.
1065
 */
1066
static int
1067
template_sanity_check(struct state *cur, struct sc_profile *templ)
1068
1.77k
{
1069
1.77k
  struct file_info *fi, *ffi;
1070
1071
6.23k
  for (fi = templ->ef_list; fi; fi = fi->next) {
1072
4.50k
    struct sc_path fi_path =  fi->file->path;
1073
4.50k
    int fi_id;
1074
1075
4.50k
    if (fi->file->type == SC_FILE_TYPE_BSO)
1076
122
      continue;
1077
1078
4.37k
    if (fi_path.len < 2) {
1079
21
      parse_error(cur, "Template insane: file-path length should not be less than 2 bytes");
1080
21
      return 1;
1081
21
    }
1082
1083
4.35k
    fi_id = fi_path.value[fi_path.len - 2] * 0x100
1084
4.35k
        + fi_path.value[fi_path.len - 1];
1085
1086
21.8k
    for (ffi = templ->ef_list; ffi; ffi = ffi->next) {
1087
17.5k
      struct sc_path ffi_path =  ffi->file->path;
1088
17.5k
      int dlt, ffi_id;
1089
1090
17.5k
      if (ffi->file->type == SC_FILE_TYPE_BSO)
1091
22
        continue;
1092
1093
17.5k
      if (ffi_path.len < 2) {
1094
9
        parse_error(cur, "Template insane: file-path length should not be less than 2 bytes");
1095
9
        return 1;
1096
9
      }
1097
1098
17.5k
      ffi_id = ffi_path.value[ffi_path.len - 2] * 0x100
1099
17.5k
          + ffi_path.value[ffi_path.len - 1];
1100
1101
17.5k
      dlt = fi_id > ffi_id ? fi_id - ffi_id : ffi_id - fi_id;
1102
17.5k
      if (strcmp(ffi->ident, fi->ident))   {
1103
13.1k
        if (dlt >= TEMPLATE_FILEID_MIN_DIFF)
1104
13.1k
          continue;
1105
1106
14
        parse_error(cur, "Template insane: file-ids should be substantially different");
1107
14
        return 1;
1108
13.1k
      }
1109
17.5k
    }
1110
4.35k
  }
1111
1112
1.73k
  return SC_SUCCESS;
1113
1.77k
}
Unexecuted instantiation: profile.c:template_sanity_check
fuzz_pkcs15init.c:template_sanity_check
Line
Count
Source
1068
1.77k
{
1069
1.77k
  struct file_info *fi, *ffi;
1070
1071
6.23k
  for (fi = templ->ef_list; fi; fi = fi->next) {
1072
4.50k
    struct sc_path fi_path =  fi->file->path;
1073
4.50k
    int fi_id;
1074
1075
4.50k
    if (fi->file->type == SC_FILE_TYPE_BSO)
1076
122
      continue;
1077
1078
4.37k
    if (fi_path.len < 2) {
1079
21
      parse_error(cur, "Template insane: file-path length should not be less than 2 bytes");
1080
21
      return 1;
1081
21
    }
1082
1083
4.35k
    fi_id = fi_path.value[fi_path.len - 2] * 0x100
1084
4.35k
        + fi_path.value[fi_path.len - 1];
1085
1086
21.8k
    for (ffi = templ->ef_list; ffi; ffi = ffi->next) {
1087
17.5k
      struct sc_path ffi_path =  ffi->file->path;
1088
17.5k
      int dlt, ffi_id;
1089
1090
17.5k
      if (ffi->file->type == SC_FILE_TYPE_BSO)
1091
22
        continue;
1092
1093
17.5k
      if (ffi_path.len < 2) {
1094
9
        parse_error(cur, "Template insane: file-path length should not be less than 2 bytes");
1095
9
        return 1;
1096
9
      }
1097
1098
17.5k
      ffi_id = ffi_path.value[ffi_path.len - 2] * 0x100
1099
17.5k
          + ffi_path.value[ffi_path.len - 1];
1100
1101
17.5k
      dlt = fi_id > ffi_id ? fi_id - ffi_id : ffi_id - fi_id;
1102
17.5k
      if (strcmp(ffi->ident, fi->ident))   {
1103
13.1k
        if (dlt >= TEMPLATE_FILEID_MIN_DIFF)
1104
13.1k
          continue;
1105
1106
14
        parse_error(cur, "Template insane: file-ids should be substantially different");
1107
14
        return 1;
1108
13.1k
      }
1109
17.5k
    }
1110
4.35k
  }
1111
1112
1.73k
  return SC_SUCCESS;
1113
1.77k
}
1114
1115
1116
static int
1117
process_tmpl(struct state *cur, struct block *info,
1118
    const char *name, scconf_block *blk)
1119
1.92k
{
1120
1.92k
  struct state  state;
1121
1.92k
  sc_template_t *tinfo;
1122
1.92k
  sc_profile_t  *templ;
1123
1.92k
  int r;
1124
1125
#ifdef DEBUG_PROFILE
1126
  printf("Process template:%s; block:%s\n", name, info->name);
1127
#endif
1128
1.92k
  if (name == NULL) {
1129
0
    parse_error(cur, "No name given for template.");
1130
0
    return 1;
1131
0
  }
1132
1133
1.92k
  templ = calloc(1, sizeof(*templ));
1134
1.92k
  if (templ == NULL) {
1135
0
    parse_error(cur, "memory allocation failed");
1136
0
    return 1;
1137
0
  }
1138
1139
1.92k
  tinfo = calloc(1, sizeof(*tinfo));
1140
1.92k
  if (tinfo == NULL) {
1141
0
    parse_error(cur, "memory allocation failed");
1142
0
    free(templ);
1143
0
    return 1;
1144
0
  }
1145
1.92k
  tinfo->name = strdup(name);
1146
1.92k
  tinfo->data = templ;
1147
1148
1.92k
  tinfo->next = cur->profile->template_list;
1149
1.92k
  cur->profile->template_list = tinfo;
1150
1151
1.92k
  init_state(cur, &state);
1152
1.92k
  state.profile = tinfo->data;
1153
1.92k
  state.file = NULL;
1154
1155
1.92k
  r = process_block(&state, info, name, blk);
1156
1.92k
  if (!r)
1157
1.77k
    r = template_sanity_check(cur, templ);
1158
1159
#ifdef DEBUG_PROFILE
1160
  printf("Template %s processed; returns %i\n", name, r);
1161
#endif
1162
1.92k
  return r;
1163
1.92k
}
Unexecuted instantiation: profile.c:process_tmpl
fuzz_pkcs15init.c:process_tmpl
Line
Count
Source
1119
1.92k
{
1120
1.92k
  struct state  state;
1121
1.92k
  sc_template_t *tinfo;
1122
1.92k
  sc_profile_t  *templ;
1123
1.92k
  int r;
1124
1125
#ifdef DEBUG_PROFILE
1126
  printf("Process template:%s; block:%s\n", name, info->name);
1127
#endif
1128
1.92k
  if (name == NULL) {
1129
0
    parse_error(cur, "No name given for template.");
1130
0
    return 1;
1131
0
  }
1132
1133
1.92k
  templ = calloc(1, sizeof(*templ));
1134
1.92k
  if (templ == NULL) {
1135
0
    parse_error(cur, "memory allocation failed");
1136
0
    return 1;
1137
0
  }
1138
1139
1.92k
  tinfo = calloc(1, sizeof(*tinfo));
1140
1.92k
  if (tinfo == NULL) {
1141
0
    parse_error(cur, "memory allocation failed");
1142
0
    free(templ);
1143
0
    return 1;
1144
0
  }
1145
1.92k
  tinfo->name = strdup(name);
1146
1.92k
  tinfo->data = templ;
1147
1148
1.92k
  tinfo->next = cur->profile->template_list;
1149
1.92k
  cur->profile->template_list = tinfo;
1150
1151
1.92k
  init_state(cur, &state);
1152
1.92k
  state.profile = tinfo->data;
1153
1.92k
  state.file = NULL;
1154
1155
1.92k
  r = process_block(&state, info, name, blk);
1156
1.92k
  if (!r)
1157
1.77k
    r = template_sanity_check(cur, templ);
1158
1159
#ifdef DEBUG_PROFILE
1160
  printf("Template %s processed; returns %i\n", name, r);
1161
#endif
1162
1.92k
  return r;
1163
1.92k
}
1164
1165
/*
1166
 * Append new file at the end of the ef_list.
1167
 * This is crucial; the profile instantiation code relies on it
1168
 */
1169
static void append_file(sc_profile_t *profile, struct file_info *nfile)
1170
26.3k
{
1171
26.3k
  struct file_info  **list, *fi;
1172
1173
26.3k
  list = &profile->ef_list;
1174
139k
  while ((fi = *list) != NULL)
1175
112k
    list = &fi->next;
1176
26.3k
  *list = nfile;
1177
26.3k
}
Unexecuted instantiation: profile.c:append_file
fuzz_pkcs15init.c:append_file
Line
Count
Source
1170
26.3k
{
1171
26.3k
  struct file_info  **list, *fi;
1172
1173
26.3k
  list = &profile->ef_list;
1174
139k
  while ((fi = *list) != NULL)
1175
112k
    list = &fi->next;
1176
26.3k
  *list = nfile;
1177
26.3k
}
1178
1179
/*
1180
 * Add a new file to the profile.
1181
 * This function is called by sc_profile_add_file.
1182
 */
1183
static struct file_info *
1184
add_file(sc_profile_t *profile, const char *name,
1185
    sc_file_t *file, struct file_info *parent)
1186
25.0k
{
1187
25.0k
  struct file_info  *info;
1188
1189
25.0k
  info = calloc(1, sizeof(*info));
1190
25.0k
  if (info == NULL)
1191
0
    return NULL;
1192
25.0k
  info->instance = info;
1193
25.0k
  info->ident = strdup(name);
1194
1195
25.0k
  info->parent = parent;
1196
25.0k
  info->file = file;
1197
1198
25.0k
  append_file(profile, info);
1199
25.0k
  return info;
1200
25.0k
}
Unexecuted instantiation: profile.c:add_file
fuzz_pkcs15init.c:add_file
Line
Count
Source
1186
25.0k
{
1187
25.0k
  struct file_info  *info;
1188
1189
25.0k
  info = calloc(1, sizeof(*info));
1190
25.0k
  if (info == NULL)
1191
0
    return NULL;
1192
25.0k
  info->instance = info;
1193
25.0k
  info->ident = strdup(name);
1194
1195
25.0k
  info->parent = parent;
1196
25.0k
  info->file = file;
1197
1198
25.0k
  append_file(profile, info);
1199
25.0k
  return info;
1200
25.0k
}
1201
1202
/*
1203
 * Free file_info list
1204
 */
1205
static void
1206
free_file_list(struct file_info **list)
1207
15.1k
{
1208
15.1k
  struct file_info  *fi;
1209
1210
41.5k
  while ((fi = *list) != NULL) {
1211
26.3k
    *list = fi->next;
1212
1213
26.3k
    if (fi->dont_free == 0)
1214
19.0k
      sc_file_free(fi->file);
1215
26.3k
    free(fi->profile_extension);
1216
26.3k
    free(fi->ident);
1217
26.3k
    free(fi);
1218
26.3k
  }
1219
15.1k
}
profile.c:free_file_list
Line
Count
Source
1207
205
{
1208
205
  struct file_info  *fi;
1209
1210
205
  while ((fi = *list) != NULL) {
1211
0
    *list = fi->next;
1212
1213
0
    if (fi->dont_free == 0)
1214
0
      sc_file_free(fi->file);
1215
0
    free(fi->profile_extension);
1216
0
    free(fi->ident);
1217
0
    free(fi);
1218
0
  }
1219
205
}
fuzz_pkcs15init.c:free_file_list
Line
Count
Source
1207
14.9k
{
1208
14.9k
  struct file_info  *fi;
1209
1210
41.3k
  while ((fi = *list) != NULL) {
1211
26.3k
    *list = fi->next;
1212
1213
26.3k
    if (fi->dont_free == 0)
1214
19.0k
      sc_file_free(fi->file);
1215
26.3k
    free(fi->profile_extension);
1216
26.3k
    free(fi->ident);
1217
26.3k
    free(fi);
1218
26.3k
  }
1219
14.9k
}
1220
1221
/*
1222
 * Create a new file info object.
1223
 * This function is called by the profile parser.
1224
 */
1225
static struct file_info *
1226
new_file(struct state *cur, const char *name, unsigned int type)
1227
29.4k
{
1228
29.4k
  sc_profile_t  *profile = cur->profile;
1229
29.4k
  struct file_info  *info;
1230
29.4k
  sc_file_t *file;
1231
29.4k
  unsigned int  df_type = 0, dont_free = 0;
1232
29.4k
  int free_file = 0;
1233
1234
29.4k
  if ((info = sc_profile_find_file(profile, NULL, name)) != NULL)
1235
4.74k
    return info;
1236
1237
  /* Special cases for those EFs handled separately
1238
   * by the PKCS15 logic */
1239
24.7k
  if (strncasecmp(name, "PKCS15-", 7)) {
1240
14.9k
    file = init_file(type);
1241
14.9k
    free_file = 1;
1242
14.9k
  } else if (!strcasecmp(name+7, "TokenInfo")) {
1243
96
    if (!profile->p15_spec) {
1244
1
      parse_error(cur, "no pkcs15 spec in profile");
1245
1
      return NULL;
1246
1
    }
1247
95
    file = profile->p15_spec->file_tokeninfo;
1248
95
    dont_free = 1;
1249
9.66k
  } else if (!strcasecmp(name+7, "ODF")) {
1250
204
    if (!profile->p15_spec) {
1251
1
      parse_error(cur, "no pkcs15 spec in profile");
1252
1
      return NULL;
1253
1
    }
1254
203
    file = profile->p15_spec->file_odf;
1255
203
    dont_free = 1;
1256
9.46k
  } else if (!strcasecmp(name+7, "UnusedSpace")) {
1257
75
    if (!profile->p15_spec) {
1258
0
      parse_error(cur, "no pkcs15 spec in profile");
1259
0
      return NULL;
1260
0
    }
1261
75
    file = profile->p15_spec->file_unusedspace;
1262
75
    dont_free = 1;
1263
9.38k
  } else if (!strcasecmp(name+7, "AppDF")) {
1264
7.96k
    file = init_file(SC_FILE_TYPE_DF);
1265
7.96k
    free_file = 1;
1266
7.96k
  } else {
1267
1.42k
    if (map_str2int(cur, name+7, &df_type, pkcs15DfNames)
1268
1.24k
        || df_type >= SC_PKCS15_DF_TYPE_COUNT)
1269
192
      return NULL;
1270
1271
1.23k
    file = init_file(SC_FILE_TYPE_WORKING_EF);
1272
1.23k
    profile->df[df_type] = file;
1273
1.23k
    free_file = 1;
1274
1.23k
  }
1275
24.7k
  assert(file);
1276
24.5k
  if (file->type != type) {
1277
8
    parse_error(cur, "inconsistent file type (should be %s)",
1278
8
      file->type == SC_FILE_TYPE_DF
1279
8
        ? "DF" : file->type == SC_FILE_TYPE_BSO
1280
7
          ? "BS0" : "EF");
1281
8
    if (free_file)
1282
6
      sc_file_free(file);
1283
8
    return NULL;
1284
8
  }
1285
1286
24.5k
  info = add_file(profile, name, file, cur->file);
1287
24.5k
  if (info == NULL) {
1288
0
    parse_error(cur, "memory allocation failed");
1289
0
    return NULL;
1290
0
  }
1291
24.5k
  info->dont_free = dont_free;
1292
24.5k
  return info;
1293
24.5k
}
Unexecuted instantiation: profile.c:new_file
fuzz_pkcs15init.c:new_file
Line
Count
Source
1227
29.4k
{
1228
29.4k
  sc_profile_t  *profile = cur->profile;
1229
29.4k
  struct file_info  *info;
1230
29.4k
  sc_file_t *file;
1231
29.4k
  unsigned int  df_type = 0, dont_free = 0;
1232
29.4k
  int free_file = 0;
1233
1234
29.4k
  if ((info = sc_profile_find_file(profile, NULL, name)) != NULL)
1235
4.74k
    return info;
1236
1237
  /* Special cases for those EFs handled separately
1238
   * by the PKCS15 logic */
1239
24.7k
  if (strncasecmp(name, "PKCS15-", 7)) {
1240
14.9k
    file = init_file(type);
1241
14.9k
    free_file = 1;
1242
14.9k
  } else if (!strcasecmp(name+7, "TokenInfo")) {
1243
96
    if (!profile->p15_spec) {
1244
1
      parse_error(cur, "no pkcs15 spec in profile");
1245
1
      return NULL;
1246
1
    }
1247
95
    file = profile->p15_spec->file_tokeninfo;
1248
95
    dont_free = 1;
1249
9.66k
  } else if (!strcasecmp(name+7, "ODF")) {
1250
204
    if (!profile->p15_spec) {
1251
1
      parse_error(cur, "no pkcs15 spec in profile");
1252
1
      return NULL;
1253
1
    }
1254
203
    file = profile->p15_spec->file_odf;
1255
203
    dont_free = 1;
1256
9.46k
  } else if (!strcasecmp(name+7, "UnusedSpace")) {
1257
75
    if (!profile->p15_spec) {
1258
0
      parse_error(cur, "no pkcs15 spec in profile");
1259
0
      return NULL;
1260
0
    }
1261
75
    file = profile->p15_spec->file_unusedspace;
1262
75
    dont_free = 1;
1263
9.38k
  } else if (!strcasecmp(name+7, "AppDF")) {
1264
7.96k
    file = init_file(SC_FILE_TYPE_DF);
1265
7.96k
    free_file = 1;
1266
7.96k
  } else {
1267
1.42k
    if (map_str2int(cur, name+7, &df_type, pkcs15DfNames)
1268
1.24k
        || df_type >= SC_PKCS15_DF_TYPE_COUNT)
1269
192
      return NULL;
1270
1271
1.23k
    file = init_file(SC_FILE_TYPE_WORKING_EF);
1272
1.23k
    profile->df[df_type] = file;
1273
1.23k
    free_file = 1;
1274
1.23k
  }
1275
24.7k
  assert(file);
1276
24.5k
  if (file->type != type) {
1277
8
    parse_error(cur, "inconsistent file type (should be %s)",
1278
8
      file->type == SC_FILE_TYPE_DF
1279
8
        ? "DF" : file->type == SC_FILE_TYPE_BSO
1280
7
          ? "BS0" : "EF");
1281
8
    if (free_file)
1282
6
      sc_file_free(file);
1283
8
    return NULL;
1284
8
  }
1285
1286
24.5k
  info = add_file(profile, name, file, cur->file);
1287
24.5k
  if (info == NULL) {
1288
0
    parse_error(cur, "memory allocation failed");
1289
0
    return NULL;
1290
0
  }
1291
24.5k
  info->dont_free = dont_free;
1292
24.5k
  return info;
1293
24.5k
}
1294
1295
static int
1296
do_file_type(struct state *cur, int argc, char **argv)
1297
4.36k
{
1298
4.36k
  unsigned int  type;
1299
1300
4.36k
  if (!cur->file) {
1301
1
    parse_error(cur, "Invalid state\n");
1302
1
    return 1;
1303
1
  }
1304
1305
4.36k
  if (map_str2int(cur, argv[0], &type, fileTypeNames))
1306
3
    return 1;
1307
4.36k
  cur->file->file->type = type;
1308
4.36k
  return 0;
1309
4.36k
}
Unexecuted instantiation: profile.c:do_file_type
fuzz_pkcs15init.c:do_file_type
Line
Count
Source
1297
4.36k
{
1298
4.36k
  unsigned int  type;
1299
1300
4.36k
  if (!cur->file) {
1301
1
    parse_error(cur, "Invalid state\n");
1302
1
    return 1;
1303
1
  }
1304
1305
4.36k
  if (map_str2int(cur, argv[0], &type, fileTypeNames))
1306
3
    return 1;
1307
4.36k
  cur->file->file->type = type;
1308
4.36k
  return 0;
1309
4.36k
}
1310
1311
static int
1312
do_file_path(struct state *cur, int argc, char **argv)
1313
4.38k
{
1314
4.38k
  struct sc_file  *file = NULL;
1315
4.38k
  struct sc_path  *path = NULL;
1316
1317
4.38k
  if (!cur->file) {
1318
1
    parse_error(cur, "Invalid state\n");
1319
1
    return 1;
1320
1
  }
1321
4.38k
  file = cur->file->file;
1322
4.38k
  path = &file->path;
1323
1324
  /* sc_format_path doesn't return an error indication
1325
   * when it's unable to parse the path */
1326
4.38k
  sc_format_path(argv[0], path);
1327
4.38k
  if (!path->len || (path->len & 1)) {
1328
33
    parse_error(cur, "Invalid path length\n");
1329
33
    return 1;
1330
33
  }
1331
4.35k
  file->id = (path->value[path->len-2] << 8) | path->value[path->len-1];
1332
4.35k
  return 0;
1333
4.38k
}
Unexecuted instantiation: profile.c:do_file_path
fuzz_pkcs15init.c:do_file_path
Line
Count
Source
1313
4.38k
{
1314
4.38k
  struct sc_file  *file = NULL;
1315
4.38k
  struct sc_path  *path = NULL;
1316
1317
4.38k
  if (!cur->file) {
1318
1
    parse_error(cur, "Invalid state\n");
1319
1
    return 1;
1320
1
  }
1321
4.38k
  file = cur->file->file;
1322
4.38k
  path = &file->path;
1323
1324
  /* sc_format_path doesn't return an error indication
1325
   * when it's unable to parse the path */
1326
4.38k
  sc_format_path(argv[0], path);
1327
4.38k
  if (!path->len || (path->len & 1)) {
1328
33
    parse_error(cur, "Invalid path length\n");
1329
33
    return 1;
1330
33
  }
1331
4.35k
  file->id = (path->value[path->len-2] << 8) | path->value[path->len-1];
1332
4.35k
  return 0;
1333
4.38k
}
1334
1335
static int
1336
do_fileid(struct state *cur, int argc, char **argv)
1337
8.26k
{
1338
8.26k
  struct file_info *fi;
1339
8.26k
  struct sc_file  *df, *file = NULL;
1340
8.26k
  struct sc_path  temp, *path = NULL;
1341
1342
8.26k
  if (!cur->file) {
1343
1
    parse_error(cur, "Invalid state\n");
1344
1
    return 1;
1345
1
  }
1346
8.26k
  file = cur->file->file;
1347
8.26k
  path = &file->path;
1348
1349
  /* sc_format_path doesn't return an error indication
1350
   * when it's unable to parse the path */
1351
8.26k
  sc_format_path(argv[0], &temp);
1352
8.26k
  if (temp.len != 2) {
1353
11
    parse_error(cur, "Invalid file ID length\n");
1354
11
    return 1;
1355
11
  }
1356
1357
  /* Get the DF, if any */
1358
8.25k
  if ((fi = cur->file->parent) && (df = fi->file)) {
1359
6.07k
    if (!df->path.len && !df->path.aid.len) {
1360
2
      parse_error(cur, "No path/fileid set for parent DF\n");
1361
2
      return 1;
1362
2
    }
1363
6.07k
    if (df->path.len + 2 > sizeof(df->path.value)) {
1364
1
      parse_error(cur, "File path too long\n");
1365
1
      return 1;
1366
1
    }
1367
6.07k
    *path = df->path;
1368
6.07k
  }
1369
8.24k
  if (path->len + 2 > sizeof(path->value)) {
1370
4
    parse_error(cur, "File path too long\n");
1371
4
    return 1;
1372
4
  }
1373
8.24k
  memcpy(path->value + path->len, temp.value, 2);
1374
8.24k
  path->len += 2;
1375
1376
8.24k
  file->id = (temp.value[0] << 8) | temp.value[1];
1377
8.24k
  return 0;
1378
8.24k
}
Unexecuted instantiation: profile.c:do_fileid
fuzz_pkcs15init.c:do_fileid
Line
Count
Source
1337
8.26k
{
1338
8.26k
  struct file_info *fi;
1339
8.26k
  struct sc_file  *df, *file = NULL;
1340
8.26k
  struct sc_path  temp, *path = NULL;
1341
1342
8.26k
  if (!cur->file) {
1343
1
    parse_error(cur, "Invalid state\n");
1344
1
    return 1;
1345
1
  }
1346
8.26k
  file = cur->file->file;
1347
8.26k
  path = &file->path;
1348
1349
  /* sc_format_path doesn't return an error indication
1350
   * when it's unable to parse the path */
1351
8.26k
  sc_format_path(argv[0], &temp);
1352
8.26k
  if (temp.len != 2) {
1353
11
    parse_error(cur, "Invalid file ID length\n");
1354
11
    return 1;
1355
11
  }
1356
1357
  /* Get the DF, if any */
1358
8.25k
  if ((fi = cur->file->parent) && (df = fi->file)) {
1359
6.07k
    if (!df->path.len && !df->path.aid.len) {
1360
2
      parse_error(cur, "No path/fileid set for parent DF\n");
1361
2
      return 1;
1362
2
    }
1363
6.07k
    if (df->path.len + 2 > sizeof(df->path.value)) {
1364
1
      parse_error(cur, "File path too long\n");
1365
1
      return 1;
1366
1
    }
1367
6.07k
    *path = df->path;
1368
6.07k
  }
1369
8.24k
  if (path->len + 2 > sizeof(path->value)) {
1370
4
    parse_error(cur, "File path too long\n");
1371
4
    return 1;
1372
4
  }
1373
8.24k
  memcpy(path->value + path->len, temp.value, 2);
1374
8.24k
  path->len += 2;
1375
1376
8.24k
  file->id = (temp.value[0] << 8) | temp.value[1];
1377
8.24k
  return 0;
1378
8.24k
}
1379
1380
static int
1381
do_structure(struct state *cur, int argc, char **argv)
1382
1.44k
{
1383
1.44k
  unsigned int  ef_structure;
1384
1385
1.44k
  if (!cur->file) {
1386
1
    parse_error(cur, "Invalid state\n");
1387
1
    return 1;
1388
1
  }
1389
1390
1.44k
  if (map_str2int(cur, argv[0], &ef_structure, fileStructureNames))
1391
4
    return 1;
1392
1.44k
  cur->file->file->ef_structure = ef_structure;
1393
1.44k
  return 0;
1394
1.44k
}
Unexecuted instantiation: profile.c:do_structure
fuzz_pkcs15init.c:do_structure
Line
Count
Source
1382
1.44k
{
1383
1.44k
  unsigned int  ef_structure;
1384
1385
1.44k
  if (!cur->file) {
1386
1
    parse_error(cur, "Invalid state\n");
1387
1
    return 1;
1388
1
  }
1389
1390
1.44k
  if (map_str2int(cur, argv[0], &ef_structure, fileStructureNames))
1391
4
    return 1;
1392
1.44k
  cur->file->file->ef_structure = ef_structure;
1393
1.44k
  return 0;
1394
1.44k
}
1395
1396
static int
1397
do_size(struct state *cur, int argc, char **argv)
1398
2.13k
{
1399
2.13k
  unsigned int  size;
1400
1401
2.13k
  if (!cur->file) {
1402
1
    parse_error(cur, "Invalid state\n");
1403
1
    return 1;
1404
1
  }
1405
1406
2.13k
  if (get_uint_eval(cur, argc, argv, &size))
1407
216
    return 1;
1408
1.92k
  cur->file->file->size = size;
1409
1.92k
  return 0;
1410
2.13k
}
Unexecuted instantiation: profile.c:do_size
fuzz_pkcs15init.c:do_size
Line
Count
Source
1398
2.13k
{
1399
2.13k
  unsigned int  size;
1400
1401
2.13k
  if (!cur->file) {
1402
1
    parse_error(cur, "Invalid state\n");
1403
1
    return 1;
1404
1
  }
1405
1406
2.13k
  if (get_uint_eval(cur, argc, argv, &size))
1407
216
    return 1;
1408
1.92k
  cur->file->file->size = size;
1409
1.92k
  return 0;
1410
2.13k
}
1411
1412
static int
1413
do_reclength(struct state *cur, int argc, char **argv)
1414
20
{
1415
20
  unsigned int  reclength;
1416
1417
20
  if (!cur->file) {
1418
1
    parse_error(cur, "Invalid state\n");
1419
1
    return 1;
1420
1
  }
1421
1422
19
  if (get_uint(cur, argv[0], &reclength))
1423
1
    return 1;
1424
18
  cur->file->file->record_length = reclength;
1425
18
  return 0;
1426
19
}
Unexecuted instantiation: profile.c:do_reclength
fuzz_pkcs15init.c:do_reclength
Line
Count
Source
1414
20
{
1415
20
  unsigned int  reclength;
1416
1417
20
  if (!cur->file) {
1418
1
    parse_error(cur, "Invalid state\n");
1419
1
    return 1;
1420
1
  }
1421
1422
19
  if (get_uint(cur, argv[0], &reclength))
1423
1
    return 1;
1424
18
  cur->file->file->record_length = reclength;
1425
18
  return 0;
1426
19
}
1427
1428
static int
1429
do_content(struct state *cur, int argc, char **argv)
1430
32
{
1431
32
  struct sc_file *file = NULL;
1432
32
  size_t len = (strlen(argv[0]) + 1) / 2;
1433
32
  int rv = 0;
1434
1435
32
  if (!cur->file) {
1436
1
    parse_error(cur, "Invalid state\n");
1437
1
    return 1;
1438
1
  }
1439
31
  file = cur->file->file;
1440
1441
31
  free(file->encoded_content);
1442
1443
31
  file->encoded_content = malloc(len);
1444
31
  if (!file->encoded_content)
1445
0
    return 1;
1446
31
  rv = sc_hex_to_bin(argv[0], file->encoded_content, &len);
1447
31
  file->encoded_content_len = len;
1448
31
  return rv;
1449
31
}
Unexecuted instantiation: profile.c:do_content
fuzz_pkcs15init.c:do_content
Line
Count
Source
1430
32
{
1431
32
  struct sc_file *file = NULL;
1432
32
  size_t len = (strlen(argv[0]) + 1) / 2;
1433
32
  int rv = 0;
1434
1435
32
  if (!cur->file) {
1436
1
    parse_error(cur, "Invalid state\n");
1437
1
    return 1;
1438
1
  }
1439
31
  file = cur->file->file;
1440
1441
31
  free(file->encoded_content);
1442
1443
31
  file->encoded_content = malloc(len);
1444
31
  if (!file->encoded_content)
1445
0
    return 1;
1446
31
  rv = sc_hex_to_bin(argv[0], file->encoded_content, &len);
1447
31
  file->encoded_content_len = len;
1448
31
  return rv;
1449
31
}
1450
1451
static int
1452
do_prop_attr(struct state *cur, int argc, char **argv)
1453
51
{
1454
51
  struct sc_file *file = NULL;
1455
51
  size_t len = (strlen(argv[0]) + 1) / 2;
1456
51
  int rv = 0;
1457
1458
51
  if (!cur->file) {
1459
1
    parse_error(cur, "Invalid state\n");
1460
1
    return 1;
1461
1
  }
1462
50
  file = cur->file->file;
1463
1464
50
  free(file->prop_attr);
1465
50
  file->prop_attr = malloc(len);
1466
50
  if (!file->prop_attr)
1467
0
    return 1;
1468
50
  rv = sc_hex_to_bin(argv[0], file->prop_attr, &len);
1469
50
  file->prop_attr_len = len;
1470
50
  return rv;
1471
50
}
Unexecuted instantiation: profile.c:do_prop_attr
fuzz_pkcs15init.c:do_prop_attr
Line
Count
Source
1453
51
{
1454
51
  struct sc_file *file = NULL;
1455
51
  size_t len = (strlen(argv[0]) + 1) / 2;
1456
51
  int rv = 0;
1457
1458
51
  if (!cur->file) {
1459
1
    parse_error(cur, "Invalid state\n");
1460
1
    return 1;
1461
1
  }
1462
50
  file = cur->file->file;
1463
1464
50
  free(file->prop_attr);
1465
50
  file->prop_attr = malloc(len);
1466
50
  if (!file->prop_attr)
1467
0
    return 1;
1468
50
  rv = sc_hex_to_bin(argv[0], file->prop_attr, &len);
1469
50
  file->prop_attr_len = len;
1470
50
  return rv;
1471
50
}
1472
1473
static int
1474
do_aid(struct state *cur, int argc, char **argv)
1475
509
{
1476
509
  struct sc_file  *file = NULL;
1477
509
  const char  *name = argv[0];
1478
509
  size_t len;
1479
509
  int   res = 0;
1480
1481
509
  if (!cur->file) {
1482
1
    parse_error(cur, "Invalid state\n");
1483
1
    return 1;
1484
1
  }
1485
508
  file = cur->file->file;
1486
1487
508
  if (*name == '=') {
1488
22
    len = strlen(++name);
1489
22
    if (len > sizeof(file->name)) {
1490
1
      parse_error(cur, "AID \"%s\" too long\n", name);
1491
1
      return 1;
1492
1
    }
1493
21
    memcpy(file->name, name, len);
1494
21
    file->namelen = len;
1495
21
  }
1496
486
  else {
1497
486
    file->namelen = sizeof(file->name);
1498
486
    res = sc_hex_to_bin(name, file->name, &file->namelen);
1499
486
  }
1500
507
  return res;
1501
508
}
Unexecuted instantiation: profile.c:do_aid
fuzz_pkcs15init.c:do_aid
Line
Count
Source
1475
509
{
1476
509
  struct sc_file  *file = NULL;
1477
509
  const char  *name = argv[0];
1478
509
  size_t len;
1479
509
  int   res = 0;
1480
1481
509
  if (!cur->file) {
1482
1
    parse_error(cur, "Invalid state\n");
1483
1
    return 1;
1484
1
  }
1485
508
  file = cur->file->file;
1486
1487
508
  if (*name == '=') {
1488
22
    len = strlen(++name);
1489
22
    if (len > sizeof(file->name)) {
1490
1
      parse_error(cur, "AID \"%s\" too long\n", name);
1491
1
      return 1;
1492
1
    }
1493
21
    memcpy(file->name, name, len);
1494
21
    file->namelen = len;
1495
21
  }
1496
486
  else {
1497
486
    file->namelen = sizeof(file->name);
1498
486
    res = sc_hex_to_bin(name, file->name, &file->namelen);
1499
486
  }
1500
507
  return res;
1501
508
}
1502
1503
static int
1504
do_exclusive_aid(struct state *cur, int argc, char **argv)
1505
904
{
1506
904
  struct sc_file  *file = NULL;
1507
904
  const char  *name = argv[0];
1508
904
  size_t len;
1509
904
  int   res = 0;
1510
1511
904
  if (!cur->file) {
1512
1
    parse_error(cur, "Invalid state\n");
1513
1
    return 1;
1514
1
  }
1515
903
  file = cur->file->file;
1516
1517
#ifdef DEBUG_PROFILE
1518
  printf("do_exclusive_aid(): exclusive-aid '%s'\n", name);
1519
  printf("do_exclusive_aid(): current file '%s' (path:%s)\n", cur->file->ident, sc_print_path(&file->path));
1520
#endif
1521
903
  sc_format_path(name, &file->path);
1522
903
  if (file->path.len > SC_MAX_AID_SIZE)   {
1523
0
    parse_error(cur, "Path length is too big\n");
1524
0
    return 1;
1525
0
  }
1526
1527
903
  memcpy(file->path.aid.value, file->path.value, file->path.len);
1528
903
  file->path.aid.len = file->path.len;
1529
1530
903
  file->path.len = 0;
1531
903
  file->path.type = SC_PATH_TYPE_DF_NAME;
1532
1533
#ifdef DEBUG_PROFILE
1534
  printf("do_exclusive_aid(): '%s' exclusive-aid path %s\n", cur->file->ident, sc_print_path(&file->path));
1535
#endif
1536
903
  if (*name == '=') {
1537
23
    len = strlen(++name);
1538
23
    if (len > sizeof(file->name)) {
1539
1
      parse_error(cur, "AID \"%s\" too long\n", name);
1540
1
      return 1;
1541
1
    }
1542
22
    memcpy(file->name, name, len);
1543
22
    file->namelen = len;
1544
22
  }
1545
880
  else {
1546
880
    file->namelen = sizeof(file->name);
1547
880
    res = sc_hex_to_bin(name, file->name, &file->namelen);
1548
880
  }
1549
902
  return res;
1550
903
}
Unexecuted instantiation: profile.c:do_exclusive_aid
fuzz_pkcs15init.c:do_exclusive_aid
Line
Count
Source
1505
904
{
1506
904
  struct sc_file  *file = NULL;
1507
904
  const char  *name = argv[0];
1508
904
  size_t len;
1509
904
  int   res = 0;
1510
1511
904
  if (!cur->file) {
1512
1
    parse_error(cur, "Invalid state\n");
1513
1
    return 1;
1514
1
  }
1515
903
  file = cur->file->file;
1516
1517
#ifdef DEBUG_PROFILE
1518
  printf("do_exclusive_aid(): exclusive-aid '%s'\n", name);
1519
  printf("do_exclusive_aid(): current file '%s' (path:%s)\n", cur->file->ident, sc_print_path(&file->path));
1520
#endif
1521
903
  sc_format_path(name, &file->path);
1522
903
  if (file->path.len > SC_MAX_AID_SIZE)   {
1523
0
    parse_error(cur, "Path length is too big\n");
1524
0
    return 1;
1525
0
  }
1526
1527
903
  memcpy(file->path.aid.value, file->path.value, file->path.len);
1528
903
  file->path.aid.len = file->path.len;
1529
1530
903
  file->path.len = 0;
1531
903
  file->path.type = SC_PATH_TYPE_DF_NAME;
1532
1533
#ifdef DEBUG_PROFILE
1534
  printf("do_exclusive_aid(): '%s' exclusive-aid path %s\n", cur->file->ident, sc_print_path(&file->path));
1535
#endif
1536
903
  if (*name == '=') {
1537
23
    len = strlen(++name);
1538
23
    if (len > sizeof(file->name)) {
1539
1
      parse_error(cur, "AID \"%s\" too long\n", name);
1540
1
      return 1;
1541
1
    }
1542
22
    memcpy(file->name, name, len);
1543
22
    file->namelen = len;
1544
22
  }
1545
880
  else {
1546
880
    file->namelen = sizeof(file->name);
1547
880
    res = sc_hex_to_bin(name, file->name, &file->namelen);
1548
880
  }
1549
902
  return res;
1550
903
}
1551
1552
static int
1553
do_profile_extension(struct state *cur, int argc, char **argv)
1554
24
{
1555
24
  if (!cur->file) {
1556
2
    parse_error(cur, "Invalid state\n");
1557
2
    return 1;
1558
2
  }
1559
22
  return setstr(&cur->file->profile_extension, argv[0]);
1560
24
}
Unexecuted instantiation: profile.c:do_profile_extension
fuzz_pkcs15init.c:do_profile_extension
Line
Count
Source
1554
24
{
1555
24
  if (!cur->file) {
1556
2
    parse_error(cur, "Invalid state\n");
1557
2
    return 1;
1558
2
  }
1559
22
  return setstr(&cur->file->profile_extension, argv[0]);
1560
24
}
1561
1562
/*
1563
 * Parse ACL list.
1564
 * The way we do this is we first split things like CHV1
1565
 * into a method (SC_AC_CHV) and a reference (1).
1566
 * When we're finished parsing the profile, the fake references
1567
 * are replaced by the real references given in KEY or PIN
1568
 * commands
1569
 */
1570
static int
1571
do_acl(struct state *cur, int argc, char **argv)
1572
3.74k
{
1573
3.74k
  struct sc_file  *file = NULL;
1574
3.74k
  char    oper[64], *what = NULL;
1575
3.74k
  memset(oper, 0, sizeof(oper));
1576
1577
3.74k
  if (!cur->file)
1578
2
    goto bad;
1579
3.74k
  file = cur->file->file;
1580
1581
15.8k
  while (argc--) {
1582
12.1k
    unsigned int  op, method, id;
1583
1584
12.1k
    if (strlen(*argv) >= sizeof(oper))
1585
8
      goto bad;
1586
12.1k
    strlcpy(oper, *argv++, sizeof(oper));
1587
1588
12.1k
    if ((what = strchr(oper, '=')) == NULL)
1589
17
      goto bad;
1590
12.1k
    *what++ = '\0';
1591
1592
12.1k
    if (*what == '$') {
1593
5.86k
      method = SC_AC_SYMBOLIC;
1594
5.86k
      if (map_str2int(cur, what+1, &id, pinIdNames))
1595
4
        return 1;
1596
5.86k
    }
1597
6.29k
    else if (get_authid(cur, what, &method, &id))
1598
26
      goto bad;
1599
1600
1601
12.1k
    if (!strcmp(oper, "*")) {
1602
73.7k
      for (op = 0; op < SC_MAX_AC_OPS; op++) {
1603
71.4k
        sc_file_clear_acl_entries(file, op);
1604
71.4k
        sc_file_add_acl_entry(file, op, method, id);
1605
71.4k
      }
1606
9.82k
    } else {
1607
9.82k
      const sc_acl_entry_t *acl;
1608
1609
9.82k
      if (map_str2int(cur, oper, &op, fileOpNames))
1610
5
        goto bad;
1611
9.81k
      if (!(acl = sc_file_get_acl_entry(file, op)))
1612
17
        goto bad;
1613
9.80k
      if (acl->method == SC_AC_NEVER
1614
6.33k
       || acl->method == SC_AC_NONE
1615
1.13k
       || acl->method == SC_AC_UNKNOWN)
1616
8.66k
        sc_file_clear_acl_entries(file, op);
1617
1618
9.80k
      sc_file_add_acl_entry(file, op, method, id);
1619
9.80k
    }
1620
12.1k
  }
1621
3.67k
  return 0;
1622
1623
75
bad:  parse_error(cur,
1624
75
    "Invalid ACL \"%s%s%s\"\n",
1625
75
    oper, what? "=" : "", what? what : "");
1626
75
  return 1;
1627
3.74k
}
Unexecuted instantiation: profile.c:do_acl
fuzz_pkcs15init.c:do_acl
Line
Count
Source
1572
3.74k
{
1573
3.74k
  struct sc_file  *file = NULL;
1574
3.74k
  char    oper[64], *what = NULL;
1575
3.74k
  memset(oper, 0, sizeof(oper));
1576
1577
3.74k
  if (!cur->file)
1578
2
    goto bad;
1579
3.74k
  file = cur->file->file;
1580
1581
15.8k
  while (argc--) {
1582
12.1k
    unsigned int  op, method, id;
1583
1584
12.1k
    if (strlen(*argv) >= sizeof(oper))
1585
8
      goto bad;
1586
12.1k
    strlcpy(oper, *argv++, sizeof(oper));
1587
1588
12.1k
    if ((what = strchr(oper, '=')) == NULL)
1589
17
      goto bad;
1590
12.1k
    *what++ = '\0';
1591
1592
12.1k
    if (*what == '$') {
1593
5.86k
      method = SC_AC_SYMBOLIC;
1594
5.86k
      if (map_str2int(cur, what+1, &id, pinIdNames))
1595
4
        return 1;
1596
5.86k
    }
1597
6.29k
    else if (get_authid(cur, what, &method, &id))
1598
26
      goto bad;
1599
1600
1601
12.1k
    if (!strcmp(oper, "*")) {
1602
73.7k
      for (op = 0; op < SC_MAX_AC_OPS; op++) {
1603
71.4k
        sc_file_clear_acl_entries(file, op);
1604
71.4k
        sc_file_add_acl_entry(file, op, method, id);
1605
71.4k
      }
1606
9.82k
    } else {
1607
9.82k
      const sc_acl_entry_t *acl;
1608
1609
9.82k
      if (map_str2int(cur, oper, &op, fileOpNames))
1610
5
        goto bad;
1611
9.81k
      if (!(acl = sc_file_get_acl_entry(file, op)))
1612
17
        goto bad;
1613
9.80k
      if (acl->method == SC_AC_NEVER
1614
6.33k
       || acl->method == SC_AC_NONE
1615
1.13k
       || acl->method == SC_AC_UNKNOWN)
1616
8.66k
        sc_file_clear_acl_entries(file, op);
1617
1618
9.80k
      sc_file_add_acl_entry(file, op, method, id);
1619
9.80k
    }
1620
12.1k
  }
1621
3.67k
  return 0;
1622
1623
75
bad:  parse_error(cur,
1624
75
    "Invalid ACL \"%s%s%s\"\n",
1625
75
    oper, what? "=" : "", what? what : "");
1626
75
  return 1;
1627
3.74k
}
1628
1629
static int
1630
process_pin(struct state *cur, struct block *info,
1631
    const char *name, scconf_block *blk)
1632
6.51k
{
1633
6.51k
  struct state  state;
1634
6.51k
  unsigned int  id;
1635
1636
6.51k
  if (map_str2int(cur, name, &id, pinIdNames))
1637
86
    return 1;
1638
1639
6.43k
  init_state(cur, &state);
1640
6.43k
  state.pin = new_pin(cur->profile, (int)id);
1641
1642
6.43k
  return process_block(&state, info, name, blk);
1643
6.51k
}
Unexecuted instantiation: profile.c:process_pin
fuzz_pkcs15init.c:process_pin
Line
Count
Source
1632
6.51k
{
1633
6.51k
  struct state  state;
1634
6.51k
  unsigned int  id;
1635
1636
6.51k
  if (map_str2int(cur, name, &id, pinIdNames))
1637
86
    return 1;
1638
1639
6.43k
  init_state(cur, &state);
1640
6.43k
  state.pin = new_pin(cur->profile, (int)id);
1641
1642
6.43k
  return process_block(&state, info, name, blk);
1643
6.51k
}
1644
1645
static struct pin_info *
1646
new_pin(struct sc_profile *profile, int id)
1647
35.3k
{
1648
35.3k
  struct pin_info *pi, **tail;
1649
1650
61.6k
  for (tail = &profile->pin_list; (pi = *tail); tail = &pi->next) {
1651
41.8k
    if (pi->id == id)
1652
15.5k
      return pi;
1653
41.8k
  }
1654
1655
  /* Create pin info object. Most values are
1656
   * set to their defaults in set_pin_defaults later
1657
   * We can't do this here because these pin info objects
1658
   * are usually created before we've read the card specific
1659
   * profile
1660
   */
1661
19.8k
  pi = calloc(1, sizeof(*pi));
1662
19.8k
  if (pi == NULL)
1663
0
    return NULL;
1664
19.8k
  pi->id = id;
1665
19.8k
  pi->pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1666
19.8k
  pi->pin.auth_method = SC_AC_CHV;
1667
19.8k
  pi->pin.attrs.pin.type = (unsigned int)-1;
1668
19.8k
  pi->pin.attrs.pin.flags = 0x32;
1669
19.8k
  pi->pin.attrs.pin.max_length = 0;
1670
19.8k
  pi->pin.attrs.pin.min_length = 0;
1671
19.8k
  pi->pin.attrs.pin.stored_length = 0;
1672
19.8k
  pi->pin.attrs.pin.pad_char = 0xA5;
1673
19.8k
  pi->pin.attrs.pin.reference = -1;
1674
19.8k
  pi->pin.tries_left = 3;
1675
1676
19.8k
  *tail = pi;
1677
19.8k
  return pi;
1678
19.8k
}
Unexecuted instantiation: profile.c:new_pin
fuzz_pkcs15init.c:new_pin
Line
Count
Source
1647
35.3k
{
1648
35.3k
  struct pin_info *pi, **tail;
1649
1650
61.6k
  for (tail = &profile->pin_list; (pi = *tail); tail = &pi->next) {
1651
41.8k
    if (pi->id == id)
1652
15.5k
      return pi;
1653
41.8k
  }
1654
1655
  /* Create pin info object. Most values are
1656
   * set to their defaults in set_pin_defaults later
1657
   * We can't do this here because these pin info objects
1658
   * are usually created before we've read the card specific
1659
   * profile
1660
   */
1661
19.8k
  pi = calloc(1, sizeof(*pi));
1662
19.8k
  if (pi == NULL)
1663
0
    return NULL;
1664
19.8k
  pi->id = id;
1665
19.8k
  pi->pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1666
19.8k
  pi->pin.auth_method = SC_AC_CHV;
1667
19.8k
  pi->pin.attrs.pin.type = (unsigned int)-1;
1668
19.8k
  pi->pin.attrs.pin.flags = 0x32;
1669
19.8k
  pi->pin.attrs.pin.max_length = 0;
1670
19.8k
  pi->pin.attrs.pin.min_length = 0;
1671
19.8k
  pi->pin.attrs.pin.stored_length = 0;
1672
19.8k
  pi->pin.attrs.pin.pad_char = 0xA5;
1673
19.8k
  pi->pin.attrs.pin.reference = -1;
1674
19.8k
  pi->pin.tries_left = 3;
1675
1676
19.8k
  *tail = pi;
1677
19.8k
  return pi;
1678
19.8k
}
1679
1680
static void set_pin_defaults(struct sc_profile *profile, struct pin_info *pi)
1681
3.62k
{
1682
3.62k
  struct sc_pkcs15_auth_info *info = &pi->pin;
1683
3.62k
  struct sc_pkcs15_pin_attributes *pin_attrs = &info->attrs.pin;
1684
1685
3.62k
  info->auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1686
1687
3.62k
  if (pin_attrs->type == (unsigned int) -1)
1688
3.60k
    pin_attrs->type = profile->pin_encoding;
1689
3.62k
  if (pin_attrs->max_length == 0)
1690
3.21k
    pin_attrs->max_length = profile->pin_maxlen;
1691
3.62k
  if (pin_attrs->min_length == 0)
1692
3.16k
    pin_attrs->min_length = profile->pin_minlen;
1693
3.62k
  if (pin_attrs->stored_length == 0) {
1694
3.59k
    pin_attrs->stored_length = profile->pin_maxlen;
1695
    /* BCD encoded PIN takes half the space */
1696
3.59k
    if (pin_attrs->type == SC_PKCS15_PIN_TYPE_BCD)
1697
8
      pin_attrs->stored_length = (pin_attrs->stored_length + 1) / 2;
1698
3.59k
  }
1699
3.62k
  if (pin_attrs->pad_char == 0xA5)
1700
3.62k
    pin_attrs->pad_char = profile->pin_pad_char;
1701
3.62k
}
Unexecuted instantiation: profile.c:set_pin_defaults
fuzz_pkcs15init.c:set_pin_defaults
Line
Count
Source
1681
3.62k
{
1682
3.62k
  struct sc_pkcs15_auth_info *info = &pi->pin;
1683
3.62k
  struct sc_pkcs15_pin_attributes *pin_attrs = &info->attrs.pin;
1684
1685
3.62k
  info->auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1686
1687
3.62k
  if (pin_attrs->type == (unsigned int) -1)
1688
3.60k
    pin_attrs->type = profile->pin_encoding;
1689
3.62k
  if (pin_attrs->max_length == 0)
1690
3.21k
    pin_attrs->max_length = profile->pin_maxlen;
1691
3.62k
  if (pin_attrs->min_length == 0)
1692
3.16k
    pin_attrs->min_length = profile->pin_minlen;
1693
3.62k
  if (pin_attrs->stored_length == 0) {
1694
3.59k
    pin_attrs->stored_length = profile->pin_maxlen;
1695
    /* BCD encoded PIN takes half the space */
1696
3.59k
    if (pin_attrs->type == SC_PKCS15_PIN_TYPE_BCD)
1697
8
      pin_attrs->stored_length = (pin_attrs->stored_length + 1) / 2;
1698
3.59k
  }
1699
3.62k
  if (pin_attrs->pad_char == 0xA5)
1700
3.62k
    pin_attrs->pad_char = profile->pin_pad_char;
1701
3.62k
}
1702
1703
static int
1704
do_pin_file(struct state *cur, int argc, char **argv)
1705
238
{
1706
238
  free(cur->pin->file_name);
1707
238
  cur->pin->file_name = strdup(argv[0]);
1708
238
  return 0;
1709
238
}
Unexecuted instantiation: profile.c:do_pin_file
fuzz_pkcs15init.c:do_pin_file
Line
Count
Source
1705
238
{
1706
238
  free(cur->pin->file_name);
1707
238
  cur->pin->file_name = strdup(argv[0]);
1708
238
  return 0;
1709
238
}
1710
1711
static int
1712
do_pin_offset(struct state *cur, int argc, char **argv)
1713
67
{
1714
67
  return get_uint(cur, argv[0], &cur->pin->file_offset);
1715
67
}
Unexecuted instantiation: profile.c:do_pin_offset
fuzz_pkcs15init.c:do_pin_offset
Line
Count
Source
1713
67
{
1714
67
  return get_uint(cur, argv[0], &cur->pin->file_offset);
1715
67
}
1716
1717
static int
1718
do_pin_attempts(struct state *cur, int argc, char **argv)
1719
927
{
1720
927
  struct pin_info *pi = cur->pin;
1721
927
  unsigned int  count;
1722
1723
927
  if (get_uint(cur, argv[0], &count))
1724
3
    return 1;
1725
924
  pi->pin.tries_left = count;
1726
924
  return 0;
1727
927
}
Unexecuted instantiation: profile.c:do_pin_attempts
fuzz_pkcs15init.c:do_pin_attempts
Line
Count
Source
1719
927
{
1720
927
  struct pin_info *pi = cur->pin;
1721
927
  unsigned int  count;
1722
1723
927
  if (get_uint(cur, argv[0], &count))
1724
3
    return 1;
1725
924
  pi->pin.tries_left = count;
1726
924
  return 0;
1727
927
}
1728
1729
static int
1730
do_pin_maxunlocks(struct state *cur, int argc, char **argv)
1731
195
{
1732
195
  struct pin_info *pi = cur->pin;
1733
195
  unsigned int  count;
1734
1735
195
  if (get_uint(cur, argv[0], &count))
1736
1
    return 1;
1737
194
  pi->pin.max_unlocks = count;
1738
194
  return 0;
1739
195
}
Unexecuted instantiation: profile.c:do_pin_maxunlocks
fuzz_pkcs15init.c:do_pin_maxunlocks
Line
Count
Source
1731
195
{
1732
195
  struct pin_info *pi = cur->pin;
1733
195
  unsigned int  count;
1734
1735
195
  if (get_uint(cur, argv[0], &count))
1736
1
    return 1;
1737
194
  pi->pin.max_unlocks = count;
1738
194
  return 0;
1739
195
}
1740
1741
static int
1742
do_pin_type(struct state *cur, int argc, char **argv)
1743
97
{
1744
97
  unsigned int  type;
1745
1746
97
  if (map_str2int(cur, argv[0], &type, pinTypeNames))
1747
2
    return 1;
1748
95
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1749
0
    return 1;
1750
95
  cur->pin->pin.attrs.pin.type = type;
1751
95
  return 0;
1752
95
}
Unexecuted instantiation: profile.c:do_pin_type
fuzz_pkcs15init.c:do_pin_type
Line
Count
Source
1743
97
{
1744
97
  unsigned int  type;
1745
1746
97
  if (map_str2int(cur, argv[0], &type, pinTypeNames))
1747
2
    return 1;
1748
95
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1749
0
    return 1;
1750
95
  cur->pin->pin.attrs.pin.type = type;
1751
95
  return 0;
1752
95
}
1753
1754
static int
1755
do_pin_reference(struct state *cur, int argc, char **argv)
1756
1.63k
{
1757
1.63k
  unsigned int  reference;
1758
1759
1.63k
  if (get_uint(cur, argv[0], &reference))
1760
1
    return 1;
1761
1.63k
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1762
0
    return 1;
1763
1.63k
  cur->pin->pin.attrs.pin.reference = reference;
1764
1.63k
  return 0;
1765
1.63k
}
Unexecuted instantiation: profile.c:do_pin_reference
fuzz_pkcs15init.c:do_pin_reference
Line
Count
Source
1756
1.63k
{
1757
1.63k
  unsigned int  reference;
1758
1759
1.63k
  if (get_uint(cur, argv[0], &reference))
1760
1
    return 1;
1761
1.63k
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1762
0
    return 1;
1763
1.63k
  cur->pin->pin.attrs.pin.reference = reference;
1764
1.63k
  return 0;
1765
1.63k
}
1766
1767
static int
1768
do_pin_authid(struct state *cur, int argc, char **argv)
1769
780
{
1770
780
  sc_pkcs15_format_id(argv[0], &cur->pin->pin.auth_id);
1771
780
  return 0;
1772
780
}
Unexecuted instantiation: profile.c:do_pin_authid
fuzz_pkcs15init.c:do_pin_authid
Line
Count
Source
1769
780
{
1770
780
  sc_pkcs15_format_id(argv[0], &cur->pin->pin.auth_id);
1771
780
  return 0;
1772
780
}
1773
1774
static int
1775
do_pin_minlength(struct state *cur, int argc, char **argv)
1776
1.08k
{
1777
1.08k
  unsigned int  len;
1778
1779
1.08k
  if (get_uint(cur, argv[0], &len))
1780
1
    return 1;
1781
1.07k
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1782
0
    return 1;
1783
1.07k
  cur->pin->pin.attrs.pin.min_length = len;
1784
1.07k
  return 0;
1785
1.07k
}
Unexecuted instantiation: profile.c:do_pin_minlength
fuzz_pkcs15init.c:do_pin_minlength
Line
Count
Source
1776
1.08k
{
1777
1.08k
  unsigned int  len;
1778
1779
1.08k
  if (get_uint(cur, argv[0], &len))
1780
1
    return 1;
1781
1.07k
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1782
0
    return 1;
1783
1.07k
  cur->pin->pin.attrs.pin.min_length = len;
1784
1.07k
  return 0;
1785
1.07k
}
1786
1787
static int
1788
do_pin_maxlength(struct state *cur, int argc, char **argv)
1789
923
{
1790
923
  unsigned int  len;
1791
1792
923
  if (get_uint(cur, argv[0], &len))
1793
2
    return 1;
1794
921
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1795
0
    return 1;
1796
921
  cur->pin->pin.attrs.pin.max_length = len;
1797
921
  return 0;
1798
921
}
Unexecuted instantiation: profile.c:do_pin_maxlength
fuzz_pkcs15init.c:do_pin_maxlength
Line
Count
Source
1789
923
{
1790
923
  unsigned int  len;
1791
1792
923
  if (get_uint(cur, argv[0], &len))
1793
2
    return 1;
1794
921
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1795
0
    return 1;
1796
921
  cur->pin->pin.attrs.pin.max_length = len;
1797
921
  return 0;
1798
921
}
1799
1800
static int
1801
do_pin_storedlength(struct state *cur, int argc, char **argv)
1802
157
{
1803
157
  unsigned int  len;
1804
1805
157
  if (get_uint(cur, argv[0], &len))
1806
1
    return 1;
1807
156
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1808
0
    return 1;
1809
156
  cur->pin->pin.attrs.pin.stored_length = len;
1810
156
  return 0;
1811
156
}
Unexecuted instantiation: profile.c:do_pin_storedlength
fuzz_pkcs15init.c:do_pin_storedlength
Line
Count
Source
1802
157
{
1803
157
  unsigned int  len;
1804
1805
157
  if (get_uint(cur, argv[0], &len))
1806
1
    return 1;
1807
156
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1808
0
    return 1;
1809
156
  cur->pin->pin.attrs.pin.stored_length = len;
1810
156
  return 0;
1811
156
}
1812
1813
static int
1814
do_pin_flags(struct state *cur, int argc, char **argv)
1815
1.43k
{
1816
1.43k
  unsigned int flags = 0;
1817
1.43k
  int   i, r;
1818
1819
1.43k
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1820
0
    return -1;
1821
1822
1.43k
  cur->pin->pin.attrs.pin.flags = 0;
1823
3.71k
  for (i = 0; i < argc; i++) {
1824
2.34k
    if ((r = map_str2int(cur, argv[i], &flags, pinFlagNames)) < 0)
1825
59
      return r;
1826
2.28k
    cur->pin->pin.attrs.pin.flags |= flags;
1827
2.28k
  }
1828
1829
1.37k
  return 0;
1830
1.43k
}
Unexecuted instantiation: profile.c:do_pin_flags
fuzz_pkcs15init.c:do_pin_flags
Line
Count
Source
1815
1.43k
{
1816
1.43k
  unsigned int flags = 0;
1817
1.43k
  int   i, r;
1818
1819
1.43k
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1820
0
    return -1;
1821
1822
1.43k
  cur->pin->pin.attrs.pin.flags = 0;
1823
3.71k
  for (i = 0; i < argc; i++) {
1824
2.34k
    if ((r = map_str2int(cur, argv[i], &flags, pinFlagNames)) < 0)
1825
59
      return r;
1826
2.28k
    cur->pin->pin.attrs.pin.flags |= flags;
1827
2.28k
  }
1828
1829
1.37k
  return 0;
1830
1.43k
}
1831
1832
static int
1833
process_macros(struct state *cur, struct block *info,
1834
    const char *dummy, scconf_block *blk)
1835
1.36k
{
1836
1.36k
  scconf_item *item;
1837
1.36k
  const char  *name;
1838
1.36k
  int    r;
1839
1840
6.91k
  for (item = blk->items; item; item = item->next) {
1841
5.59k
    char *s = item->key;
1842
5.59k
    name = item->key;
1843
5.59k
    if (item->type != SCCONF_ITEM_TYPE_VALUE || !name)
1844
488
      continue;
1845
1846
    /* make sure the macro name consist only of allowed characters.
1847
     * This is not guaranteed by the tokenizer */
1848
48.1k
    while (is_macro_character(*s)) {
1849
43.0k
      s++;
1850
43.0k
    }
1851
5.10k
    if (*s != '\0') {
1852
#ifdef DEBUG_PROFILE
1853
      printf("Invalid macro name %s\n", name);
1854
#endif
1855
21
      return SC_ERROR_SYNTAX_ERROR;
1856
21
    }
1857
#ifdef DEBUG_PROFILE
1858
    printf("Defining %s\n", name);
1859
#endif
1860
5.08k
    r = new_macro(cur->profile, name, item->value.list);
1861
5.08k
    if (r != SC_SUCCESS)
1862
21
      return r;
1863
5.08k
  }
1864
1865
1.32k
  return SC_SUCCESS;
1866
1.36k
}
Unexecuted instantiation: profile.c:process_macros
fuzz_pkcs15init.c:process_macros
Line
Count
Source
1835
1.36k
{
1836
1.36k
  scconf_item *item;
1837
1.36k
  const char  *name;
1838
1.36k
  int    r;
1839
1840
6.91k
  for (item = blk->items; item; item = item->next) {
1841
5.59k
    char *s = item->key;
1842
5.59k
    name = item->key;
1843
5.59k
    if (item->type != SCCONF_ITEM_TYPE_VALUE || !name)
1844
488
      continue;
1845
1846
    /* make sure the macro name consist only of allowed characters.
1847
     * This is not guaranteed by the tokenizer */
1848
48.1k
    while (is_macro_character(*s)) {
1849
43.0k
      s++;
1850
43.0k
    }
1851
5.10k
    if (*s != '\0') {
1852
#ifdef DEBUG_PROFILE
1853
      printf("Invalid macro name %s\n", name);
1854
#endif
1855
21
      return SC_ERROR_SYNTAX_ERROR;
1856
21
    }
1857
#ifdef DEBUG_PROFILE
1858
    printf("Defining %s\n", name);
1859
#endif
1860
5.08k
    r = new_macro(cur->profile, name, item->value.list);
1861
5.08k
    if (r != SC_SUCCESS)
1862
21
      return r;
1863
5.08k
  }
1864
1865
1.32k
  return SC_SUCCESS;
1866
1.36k
}
1867
1868
static int
1869
new_macro(sc_profile_t *profile, const char *name, scconf_list *value)
1870
5.08k
{
1871
5.08k
  sc_macro_t  *mac;
1872
1873
5.08k
  if (!profile || !name || !value)
1874
21
    return SC_ERROR_INVALID_ARGUMENTS;
1875
1876
5.06k
  if ((mac = find_macro(profile, name)) == NULL) {
1877
2.82k
    mac = calloc(1, sizeof(*mac));
1878
2.82k
    if (mac == NULL)
1879
0
      return SC_ERROR_OUT_OF_MEMORY;
1880
2.82k
    mac->name = strdup(name);
1881
2.82k
    mac->next = profile->macro_list;
1882
2.82k
    profile->macro_list = mac;
1883
2.82k
  }
1884
1885
5.06k
  mac->value = value;
1886
5.06k
  return SC_SUCCESS;
1887
5.06k
}
Unexecuted instantiation: profile.c:new_macro
fuzz_pkcs15init.c:new_macro
Line
Count
Source
1870
5.08k
{
1871
5.08k
  sc_macro_t  *mac;
1872
1873
5.08k
  if (!profile || !name || !value)
1874
21
    return SC_ERROR_INVALID_ARGUMENTS;
1875
1876
5.06k
  if ((mac = find_macro(profile, name)) == NULL) {
1877
2.82k
    mac = calloc(1, sizeof(*mac));
1878
2.82k
    if (mac == NULL)
1879
0
      return SC_ERROR_OUT_OF_MEMORY;
1880
2.82k
    mac->name = strdup(name);
1881
2.82k
    mac->next = profile->macro_list;
1882
2.82k
    profile->macro_list = mac;
1883
2.82k
  }
1884
1885
5.06k
  mac->value = value;
1886
5.06k
  return SC_SUCCESS;
1887
5.06k
}
1888
1889
static sc_macro_t *
1890
find_macro(sc_profile_t *profile, const char *name)
1891
14.8k
{
1892
14.8k
  sc_macro_t  *mac;
1893
1894
110k
  for (mac = profile->macro_list; mac; mac = mac->next) {
1895
100k
    if (!strcmp(mac->name, name))
1896
4.79k
      return mac;
1897
100k
  }
1898
10.0k
  return NULL;
1899
14.8k
}
Unexecuted instantiation: profile.c:find_macro
fuzz_pkcs15init.c:find_macro
Line
Count
Source
1891
14.8k
{
1892
14.8k
  sc_macro_t  *mac;
1893
1894
110k
  for (mac = profile->macro_list; mac; mac = mac->next) {
1895
100k
    if (!strcmp(mac->name, name))
1896
4.79k
      return mac;
1897
100k
  }
1898
10.0k
  return NULL;
1899
14.8k
}
1900
1901
/*
1902
 * Key section
1903
 */
1904
static struct command key_commands[] = {
1905
 { "value",   1,  1,  do_key_value  },
1906
 { NULL, 0, 0, NULL }
1907
};
1908
1909
/*
1910
 * Cardinfo section
1911
 */
1912
static struct command ci_commands[] = {
1913
 { "driver",    1,  1,  do_card_driver  },
1914
 { "max-pin-length",  1,  1,  do_maxpinlength },
1915
 { "min-pin-length",  1,  1,  do_minpinlength },
1916
 { "pin-encoding",  1,  1,  do_default_pin_type },
1917
 { "pin-pad-char",  1,  1,  do_pin_pad_char },
1918
 { "pin-domains", 1,  1,  do_pin_domains  },
1919
 { "label",   1,  1,  do_card_label },
1920
 { "manufacturer",  1,  1,  do_card_manufacturer},
1921
1922
 { NULL, 0, 0, NULL }
1923
};
1924
1925
static struct block ci_blocks[] = {
1926
 { "key",   process_key,  key_commands, NULL  },
1927
1928
 { NULL, NULL, NULL, NULL }
1929
};
1930
1931
/*
1932
 * Filesystem section
1933
 */
1934
static struct command fs_commands[] = {
1935
 { "type",    1,  1,  do_file_type  },
1936
 { "path",    1,  1,  do_file_path  },
1937
 { "file-id",   1,  1,  do_fileid },
1938
 { "structure",   1,  1,  do_structure  },
1939
 { "size",    1,  -1, do_size   },
1940
 { "record-length", 1,  1,  do_reclength  },
1941
 { "AID",   1,  1,  do_aid    },
1942
 { "ACL",   1,  -1, do_acl    },
1943
/* AID dependent sub-profile */
1944
 { "profile-extension", 1,  1,  do_profile_extension  },
1945
/* AID of the DFs without file-id */
1946
 { "exclusive-aid", 1,  1,  do_exclusive_aid  },
1947
 { "content",   1,  1,  do_content  },
1948
 { "prop-attr",   1,  1,  do_prop_attr  },
1949
1950
 { NULL, 0, 0, NULL }
1951
};
1952
1953
static struct block fs_blocks[] = {
1954
 { "DF",    process_df, fs_commands,  fs_blocks },
1955
 { "EF",    process_ef, fs_commands,  fs_blocks },
1956
 { "BSO",   process_bso,  fs_commands,  fs_blocks },
1957
 { "template",    process_tmpl, fs_commands,  fs_blocks },
1958
1959
 { NULL, NULL, NULL, NULL }
1960
};
1961
1962
/*
1963
 * Pin section
1964
 */
1965
static struct command pi_commands[] = {
1966
 { "file",    1,  1,  do_pin_file   },
1967
 { "offset",    1,  1,  do_pin_offset   },
1968
 { "attempts",    1,  2,  do_pin_attempts   },
1969
 { "encoding",    1,  1,  do_pin_type   },
1970
 { "reference",   1,  1,  do_pin_reference  },
1971
 { "auth-id",   1,  1,  do_pin_authid   },
1972
 { "max-length",  1,  1,  do_pin_maxlength  },
1973
 { "min-length",  1,  1,  do_pin_minlength  },
1974
 { "stored-length", 1,  1,  do_pin_storedlength },
1975
 { "max-unlocks", 1,  1,  do_pin_maxunlocks },
1976
 { "flags",   1,  -1, do_pin_flags    },
1977
 { NULL, 0, 0, NULL }
1978
};
1979
1980
/*
1981
 * pkcs15 dialect section
1982
 */
1983
static struct command p15_commands[] = {
1984
 { "direct-certificates", 1,  1,  do_direct_certificates },
1985
 { "encode-df-length",    1,  1,  do_encode_df_length },
1986
 { "do-last-update",    1,  1,  do_encode_update_field },
1987
 { "pkcs15-id-style",   1,  1,  do_pkcs15_id_style },
1988
 { "minidriver-support-style",  1,  1,  do_minidriver_support_style },
1989
 { NULL, 0, 0, NULL }
1990
};
1991
1992
static struct block root_blocks[] = {
1993
 { "filesystem",  process_block,  NULL,   fs_blocks },
1994
 { "cardinfo",    process_block,  ci_commands,  ci_blocks },
1995
 { "pin",   process_pin,  pi_commands,  NULL  },
1996
 { "option",    process_option, NULL,   root_blocks },
1997
 { "macros",    process_macros, NULL,   NULL  },
1998
 { "pkcs15",    process_block,  p15_commands, NULL  },
1999
2000
 { NULL, NULL, NULL, NULL }
2001
};
2002
2003
static struct block root_ops = {
2004
   "root",    process_block,  NULL,   root_blocks
2005
};
2006
2007
static int
2008
is_macro_character(char c)
2009
118k
{
2010
118k
  if (isalnum(c) || c == '-' || c == '_')
2011
105k
    return 1;
2012
13.5k
  return 0;
2013
118k
}
Unexecuted instantiation: profile.c:is_macro_character
fuzz_pkcs15init.c:is_macro_character
Line
Count
Source
2009
118k
{
2010
118k
  if (isalnum(c) || c == '-' || c == '_')
2011
105k
    return 1;
2012
13.5k
  return 0;
2013
118k
}
2014
2015
static int
2016
get_inner_word(char *str, char word[WORD_SIZE])
2017
8.40k
{
2018
8.40k
  char *inner = NULL;
2019
8.40k
  size_t len = 0;
2020
2021
8.40k
  inner = str;
2022
2023
69.5k
  while (is_macro_character(*inner)) {
2024
61.1k
    inner++;
2025
61.1k
    len++;
2026
61.1k
  }
2027
8.40k
  if (len >= WORD_SIZE)
2028
143
    return 1;
2029
8.26k
  memcpy(word, str, len);
2030
8.26k
  word[len] = '\0';
2031
8.26k
  return 0;
2032
8.40k
}
Unexecuted instantiation: profile.c:get_inner_word
fuzz_pkcs15init.c:get_inner_word
Line
Count
Source
2017
8.40k
{
2018
8.40k
  char *inner = NULL;
2019
8.40k
  size_t len = 0;
2020
2021
8.40k
  inner = str;
2022
2023
69.5k
  while (is_macro_character(*inner)) {
2024
61.1k
    inner++;
2025
61.1k
    len++;
2026
61.1k
  }
2027
8.40k
  if (len >= WORD_SIZE)
2028
143
    return 1;
2029
8.26k
  memcpy(word, str, len);
2030
8.26k
  word[len] = '\0';
2031
8.26k
  return 0;
2032
8.40k
}
2033
2034
/*
2035
 * Checks for a reference loop for macro named start_name in macro definitions.
2036
 * Function returns 1 if a reference loop is detected, 0 otherwise.
2037
 */
2038
static int
2039
check_macro_reference_loop(const char *start_name, sc_macro_t *macro, sc_profile_t *profile, int depth)
2040
2.50k
{
2041
2.50k
  scconf_list *value;
2042
2.50k
  char *name = NULL;
2043
2.50k
  sc_macro_t  *m;
2044
2.50k
  char word[WORD_SIZE];
2045
2046
2.50k
  if (!start_name || !macro || !profile || depth == 16)
2047
17
    return 1;
2048
2049
  /* For some reason, the macro value is a list where we need to check for references */
2050
5.94k
  for (value = macro->value; value != NULL; value = value->next) {
2051
    /* Find name in macro value */
2052
3.74k
    char *macro_value = value->data;
2053
3.74k
    if (!(name = strchr(macro_value, '$')))
2054
1.64k
      continue;
2055
    /* Extract the macro name from the string */
2056
2.10k
    if (get_inner_word(name + 1, word))
2057
2
      return 1;
2058
    /* Find whether name corresponds to some other macro */
2059
2.09k
    if (!(m = find_macro(profile, word)))
2060
990
      continue;
2061
    /* Check for loop */
2062
1.10k
    if (!strcmp(m->name, start_name))
2063
7
      return 1;
2064
    /* Reference loop was found to the original macro name */
2065
1.10k
    if (check_macro_reference_loop(start_name, m, profile, depth + 1) == 1) {
2066
277
      return 1;
2067
277
    }
2068
1.10k
  }
2069
2.19k
  return 0;
2070
2.48k
}
Unexecuted instantiation: profile.c:check_macro_reference_loop
fuzz_pkcs15init.c:check_macro_reference_loop
Line
Count
Source
2040
2.50k
{
2041
2.50k
  scconf_list *value;
2042
2.50k
  char *name = NULL;
2043
2.50k
  sc_macro_t  *m;
2044
2.50k
  char word[WORD_SIZE];
2045
2046
2.50k
  if (!start_name || !macro || !profile || depth == 16)
2047
17
    return 1;
2048
2049
  /* For some reason, the macro value is a list where we need to check for references */
2050
5.94k
  for (value = macro->value; value != NULL; value = value->next) {
2051
    /* Find name in macro value */
2052
3.74k
    char *macro_value = value->data;
2053
3.74k
    if (!(name = strchr(macro_value, '$')))
2054
1.64k
      continue;
2055
    /* Extract the macro name from the string */
2056
2.10k
    if (get_inner_word(name + 1, word))
2057
2
      return 1;
2058
    /* Find whether name corresponds to some other macro */
2059
2.09k
    if (!(m = find_macro(profile, word)))
2060
990
      continue;
2061
    /* Check for loop */
2062
1.10k
    if (!strcmp(m->name, start_name))
2063
7
      return 1;
2064
    /* Reference loop was found to the original macro name */
2065
1.10k
    if (check_macro_reference_loop(start_name, m, profile, depth + 1) == 1) {
2066
277
      return 1;
2067
277
    }
2068
1.10k
  }
2069
2.19k
  return 0;
2070
2.48k
}
2071
2072
static int
2073
build_argv(struct state *cur, const char *cmdname,
2074
    scconf_list *list, char **argv, unsigned int max)
2075
40.8k
{
2076
40.8k
  unsigned int  argc;
2077
40.8k
  const char  *str;
2078
40.8k
  sc_macro_t  *macro;
2079
40.8k
  int   r;
2080
2081
91.3k
  for (argc = 0; list; list = list->next) {
2082
50.5k
    if (argc >= max) {
2083
7
      parse_error(cur, "%s: too many arguments", cmdname);
2084
7
      return SC_ERROR_INVALID_ARGUMENTS;
2085
7
    }
2086
2087
50.5k
    str = list->data;
2088
50.5k
    if (str[0] != '$') {
2089
      /* When str contains macro inside, macro reference loop needs to be checked */
2090
49.2k
      char *macro_name = NULL;
2091
49.2k
      if ((macro_name = strchr(str, '$'))) {
2092
        /* Macro does not to start at the first position */
2093
6.30k
        char word[WORD_SIZE];
2094
6.30k
        get_inner_word(macro_name + 1, word);
2095
6.30k
        if ((macro = find_macro(cur->profile, word))
2096
126
            && check_macro_reference_loop(macro->name, macro, cur->profile, 0)) {
2097
2
          return SC_ERROR_SYNTAX_ERROR;
2098
2
        }
2099
6.30k
      }
2100
2101
49.2k
      argv[argc++] = list->data;
2102
49.2k
      continue;
2103
49.2k
    }
2104
2105
    /* Expand macro reference */
2106
1.29k
    if (!(macro = find_macro(cur->profile, str + 1))) {
2107
20
      parse_error(cur, "%s: unknown macro \"%s\"",
2108
20
          cmdname, str);
2109
20
      return SC_ERROR_SYNTAX_ERROR;
2110
20
    }
2111
2112
1.27k
    if (list == macro->value) {
2113
0
      return SC_ERROR_SYNTAX_ERROR;
2114
0
    }
2115
1.27k
    if (check_macro_reference_loop(macro->name, macro, cur->profile, 0)) {
2116
24
      return SC_ERROR_SYNTAX_ERROR;
2117
24
    }
2118
#ifdef DEBUG_PROFILE
2119
    {
2120
      scconf_list *list;
2121
2122
      printf("Expanding macro %s:", macro->name);
2123
      for (list = macro->value; list; list = list->next)
2124
        printf(" %s", list->data);
2125
      printf("\n");
2126
    }
2127
#endif
2128
1.24k
    r = build_argv(cur, cmdname, macro->value,
2129
1.24k
        argv + argc, max - argc);
2130
1.24k
    if (r < 0)
2131
36
      return r;
2132
2133
1.21k
    argc += r;
2134
1.21k
  }
2135
2136
40.8k
  return argc;
2137
40.8k
}
Unexecuted instantiation: profile.c:build_argv
fuzz_pkcs15init.c:build_argv
Line
Count
Source
2075
40.8k
{
2076
40.8k
  unsigned int  argc;
2077
40.8k
  const char  *str;
2078
40.8k
  sc_macro_t  *macro;
2079
40.8k
  int   r;
2080
2081
91.3k
  for (argc = 0; list; list = list->next) {
2082
50.5k
    if (argc >= max) {
2083
7
      parse_error(cur, "%s: too many arguments", cmdname);
2084
7
      return SC_ERROR_INVALID_ARGUMENTS;
2085
7
    }
2086
2087
50.5k
    str = list->data;
2088
50.5k
    if (str[0] != '$') {
2089
      /* When str contains macro inside, macro reference loop needs to be checked */
2090
49.2k
      char *macro_name = NULL;
2091
49.2k
      if ((macro_name = strchr(str, '$'))) {
2092
        /* Macro does not to start at the first position */
2093
6.30k
        char word[WORD_SIZE];
2094
6.30k
        get_inner_word(macro_name + 1, word);
2095
6.30k
        if ((macro = find_macro(cur->profile, word))
2096
126
            && check_macro_reference_loop(macro->name, macro, cur->profile, 0)) {
2097
2
          return SC_ERROR_SYNTAX_ERROR;
2098
2
        }
2099
6.30k
      }
2100
2101
49.2k
      argv[argc++] = list->data;
2102
49.2k
      continue;
2103
49.2k
    }
2104
2105
    /* Expand macro reference */
2106
1.29k
    if (!(macro = find_macro(cur->profile, str + 1))) {
2107
20
      parse_error(cur, "%s: unknown macro \"%s\"",
2108
20
          cmdname, str);
2109
20
      return SC_ERROR_SYNTAX_ERROR;
2110
20
    }
2111
2112
1.27k
    if (list == macro->value) {
2113
0
      return SC_ERROR_SYNTAX_ERROR;
2114
0
    }
2115
1.27k
    if (check_macro_reference_loop(macro->name, macro, cur->profile, 0)) {
2116
24
      return SC_ERROR_SYNTAX_ERROR;
2117
24
    }
2118
#ifdef DEBUG_PROFILE
2119
    {
2120
      scconf_list *list;
2121
2122
      printf("Expanding macro %s:", macro->name);
2123
      for (list = macro->value; list; list = list->next)
2124
        printf(" %s", list->data);
2125
      printf("\n");
2126
    }
2127
#endif
2128
1.24k
    r = build_argv(cur, cmdname, macro->value,
2129
1.24k
        argv + argc, max - argc);
2130
1.24k
    if (r < 0)
2131
36
      return r;
2132
2133
1.21k
    argc += r;
2134
1.21k
  }
2135
2136
40.8k
  return argc;
2137
40.8k
}
2138
2139
static int
2140
process_command(struct state *cur, struct command *cmd_info, scconf_list *list)
2141
39.5k
{
2142
39.5k
  const char  *cmd = cmd_info->name;
2143
39.5k
  char    *argv[32];
2144
39.5k
  int   argc, max = 32;
2145
2146
39.5k
  if (cmd_info->max_args >= 0 && max > cmd_info->max_args)
2147
32.2k
    max = cmd_info->max_args;
2148
2149
39.5k
  if ((argc = build_argv(cur, cmd, list, argv, max)) < 0)
2150
52
    return argc;
2151
2152
39.5k
  if (argc < cmd_info->min_args) {
2153
5
    parse_error(cur, "%s: not enough arguments\n", cmd);
2154
5
    return 1;
2155
5
  }
2156
39.5k
  return cmd_info->func(cur, argc, argv);
2157
39.5k
}
Unexecuted instantiation: profile.c:process_command
fuzz_pkcs15init.c:process_command
Line
Count
Source
2141
39.5k
{
2142
39.5k
  const char  *cmd = cmd_info->name;
2143
39.5k
  char    *argv[32];
2144
39.5k
  int   argc, max = 32;
2145
2146
39.5k
  if (cmd_info->max_args >= 0 && max > cmd_info->max_args)
2147
32.2k
    max = cmd_info->max_args;
2148
2149
39.5k
  if ((argc = build_argv(cur, cmd, list, argv, max)) < 0)
2150
52
    return argc;
2151
2152
39.5k
  if (argc < cmd_info->min_args) {
2153
5
    parse_error(cur, "%s: not enough arguments\n", cmd);
2154
5
    return 1;
2155
5
  }
2156
39.5k
  return cmd_info->func(cur, argc, argv);
2157
39.5k
}
2158
2159
static struct block *
2160
find_block_handler(struct block *bp, const char *name)
2161
52.7k
{
2162
52.7k
  if (bp == NULL)
2163
13
    return NULL;
2164
103k
  for (; bp->name; bp++) {
2165
103k
    if (!strcasecmp(bp->name, name))
2166
52.5k
      return bp;
2167
103k
  }
2168
178
  return NULL;
2169
52.7k
}
Unexecuted instantiation: profile.c:find_block_handler
fuzz_pkcs15init.c:find_block_handler
Line
Count
Source
2161
52.7k
{
2162
52.7k
  if (bp == NULL)
2163
13
    return NULL;
2164
103k
  for (; bp->name; bp++) {
2165
103k
    if (!strcasecmp(bp->name, name))
2166
52.5k
      return bp;
2167
103k
  }
2168
178
  return NULL;
2169
52.7k
}
2170
2171
static struct command *
2172
find_cmd_handler(struct command *cp, const char *name)
2173
39.9k
{
2174
39.9k
  if (cp == NULL)
2175
179
    return NULL;
2176
169k
  for (; cp->name; cp++) {
2177
169k
    if (!strcasecmp(cp->name, name))
2178
39.5k
      return cp;
2179
169k
  }
2180
152
  return NULL;
2181
39.7k
}
Unexecuted instantiation: profile.c:find_cmd_handler
fuzz_pkcs15init.c:find_cmd_handler
Line
Count
Source
2173
39.9k
{
2174
39.9k
  if (cp == NULL)
2175
179
    return NULL;
2176
169k
  for (; cp->name; cp++) {
2177
169k
    if (!strcasecmp(cp->name, name))
2178
39.5k
      return cp;
2179
169k
  }
2180
152
  return NULL;
2181
39.7k
}
2182
2183
static int
2184
process_block(struct state *cur, struct block *info,
2185
    const char *name, scconf_block *blk)
2186
62.2k
{
2187
62.2k
  scconf_item *item;
2188
62.2k
  struct command  *cp;
2189
62.2k
  struct block  *bp;
2190
62.2k
  const char  *cmd, *ident;
2191
62.2k
  int   res = 0;
2192
2193
198k
  for (item = blk->items; res == 0 && item; item = item->next) {
2194
136k
    cmd = item->key;
2195
136k
    if (item->type == SCCONF_ITEM_TYPE_COMMENT)
2196
43.5k
      continue;
2197
92.7k
    if (!cmd) {
2198
22
      parse_error(cur, "Command can not be processed.");
2199
22
      return SC_ERROR_SYNTAX_ERROR;
2200
22
    }
2201
92.7k
    if (item->type == SCCONF_ITEM_TYPE_BLOCK) {
2202
52.7k
      scconf_list *nlist;
2203
2204
52.7k
      ident = NULL;
2205
52.7k
      if ((nlist = item->value.block->name) != NULL) {
2206
52.7k
        if (nlist->next) {
2207
2
          parse_error(cur, "Too many name components in block name.");
2208
2
          return SC_ERROR_SYNTAX_ERROR;
2209
2
        }
2210
52.7k
        ident = nlist->data;
2211
52.7k
      }
2212
#ifdef DEBUG_PROFILE
2213
      printf("Processing %s %s\n", cmd, ident? ident : "");
2214
#endif
2215
52.7k
      if ((bp = find_block_handler(info->blk_info, cmd))) {
2216
52.5k
        res = bp->handler(cur, bp, ident, item->value.block);
2217
52.5k
        continue;
2218
52.5k
      }
2219
52.7k
    }
2220
39.9k
    else if (item->type == SCCONF_ITEM_TYPE_VALUE) {
2221
#ifdef DEBUG_PROFILE
2222
      printf("Processing %s\n", cmd);
2223
#endif
2224
39.9k
      if ((cp = find_cmd_handler(info->cmd_info, cmd))) {
2225
39.5k
        res = process_command(cur, cp, item->value.list);
2226
39.5k
        continue;
2227
39.5k
      }
2228
39.9k
    }
2229
522
    parse_error(cur, "Command \"%s\" not understood in this context.", cmd);
2230
522
    return SC_ERROR_SYNTAX_ERROR;
2231
92.7k
  }
2232
2233
61.7k
  if (res > 0)
2234
881
    res = SC_ERROR_SYNTAX_ERROR;
2235
61.7k
  return res;
2236
62.2k
}
Unexecuted instantiation: profile.c:process_block
fuzz_pkcs15init.c:process_block
Line
Count
Source
2186
62.2k
{
2187
62.2k
  scconf_item *item;
2188
62.2k
  struct command  *cp;
2189
62.2k
  struct block  *bp;
2190
62.2k
  const char  *cmd, *ident;
2191
62.2k
  int   res = 0;
2192
2193
198k
  for (item = blk->items; res == 0 && item; item = item->next) {
2194
136k
    cmd = item->key;
2195
136k
    if (item->type == SCCONF_ITEM_TYPE_COMMENT)
2196
43.5k
      continue;
2197
92.7k
    if (!cmd) {
2198
22
      parse_error(cur, "Command can not be processed.");
2199
22
      return SC_ERROR_SYNTAX_ERROR;
2200
22
    }
2201
92.7k
    if (item->type == SCCONF_ITEM_TYPE_BLOCK) {
2202
52.7k
      scconf_list *nlist;
2203
2204
52.7k
      ident = NULL;
2205
52.7k
      if ((nlist = item->value.block->name) != NULL) {
2206
52.7k
        if (nlist->next) {
2207
2
          parse_error(cur, "Too many name components in block name.");
2208
2
          return SC_ERROR_SYNTAX_ERROR;
2209
2
        }
2210
52.7k
        ident = nlist->data;
2211
52.7k
      }
2212
#ifdef DEBUG_PROFILE
2213
      printf("Processing %s %s\n", cmd, ident? ident : "");
2214
#endif
2215
52.7k
      if ((bp = find_block_handler(info->blk_info, cmd))) {
2216
52.5k
        res = bp->handler(cur, bp, ident, item->value.block);
2217
52.5k
        continue;
2218
52.5k
      }
2219
52.7k
    }
2220
39.9k
    else if (item->type == SCCONF_ITEM_TYPE_VALUE) {
2221
#ifdef DEBUG_PROFILE
2222
      printf("Processing %s\n", cmd);
2223
#endif
2224
39.9k
      if ((cp = find_cmd_handler(info->cmd_info, cmd))) {
2225
39.5k
        res = process_command(cur, cp, item->value.list);
2226
39.5k
        continue;
2227
39.5k
      }
2228
39.9k
    }
2229
522
    parse_error(cur, "Command \"%s\" not understood in this context.", cmd);
2230
522
    return SC_ERROR_SYNTAX_ERROR;
2231
92.7k
  }
2232
2233
61.7k
  if (res > 0)
2234
881
    res = SC_ERROR_SYNTAX_ERROR;
2235
61.7k
  return res;
2236
62.2k
}
2237
2238
static int
2239
process_conf(struct sc_profile *profile, scconf_context *conf)
2240
11.9k
{
2241
11.9k
  struct state  state;
2242
2243
11.9k
  memset(&state, 0, sizeof(state));
2244
11.9k
  state.filename = conf->filename;
2245
11.9k
  state.profile = profile;
2246
11.9k
  return process_block(&state, &root_ops, "root", conf->root);
2247
11.9k
}
Unexecuted instantiation: profile.c:process_conf
fuzz_pkcs15init.c:process_conf
Line
Count
Source
2240
11.9k
{
2241
11.9k
  struct state  state;
2242
2243
11.9k
  memset(&state, 0, sizeof(state));
2244
11.9k
  state.filename = conf->filename;
2245
11.9k
  state.profile = profile;
2246
11.9k
  return process_block(&state, &root_ops, "root", conf->root);
2247
11.9k
}
2248
2249
static struct file_info *
2250
sc_profile_find_file(struct sc_profile *pro,
2251
    const sc_path_t *path, const char *name)
2252
80.8k
{
2253
80.8k
  struct file_info  *fi;
2254
80.8k
  size_t        len;
2255
80.8k
  const u8      *value;
2256
2257
80.8k
  value = path ? path->value : (const u8*) "";
2258
80.8k
  len = path ? path->len : 0;
2259
235k
  for (fi = pro->ef_list; fi; fi = fi->next) {
2260
181k
    sc_path_t *fpath = &fi->file->path;
2261
2262
181k
    if (!strcasecmp(fi->ident, name) && fpath->len >= len && !memcmp(fpath->value, value, len))
2263
26.0k
      return fi;
2264
181k
  }
2265
54.8k
  return NULL;
2266
80.8k
}
Unexecuted instantiation: profile.c:sc_profile_find_file
fuzz_pkcs15init.c:sc_profile_find_file
Line
Count
Source
2252
80.8k
{
2253
80.8k
  struct file_info  *fi;
2254
80.8k
  size_t        len;
2255
80.8k
  const u8      *value;
2256
2257
80.8k
  value = path ? path->value : (const u8*) "";
2258
80.8k
  len = path ? path->len : 0;
2259
235k
  for (fi = pro->ef_list; fi; fi = fi->next) {
2260
181k
    sc_path_t *fpath = &fi->file->path;
2261
2262
181k
    if (!strcasecmp(fi->ident, name) && fpath->len >= len && !memcmp(fpath->value, value, len))
2263
26.0k
      return fi;
2264
181k
  }
2265
54.8k
  return NULL;
2266
80.8k
}
2267
2268
2269
static struct file_info *
2270
sc_profile_find_file_by_path(struct sc_profile *pro, const sc_path_t *path)
2271
8.22k
{
2272
8.22k
  struct file_info *fi, *out = NULL;
2273
8.22k
  struct sc_path *fp_path, *fpp_path;
2274
2275
#ifdef DEBUG_PROFILE
2276
  struct sc_context *ctx = pro->card->ctx;
2277
2278
  sc_log(ctx, "profile's EF list:");
2279
  for (fi = pro->ef_list; fi; fi = fi->next)   {
2280
    sc_log(ctx, "'%s' (path:%s)",  fi->ident, sc_print_path(&fi->file->path));
2281
    sc_log(ctx, "fi parent %p", fi->parent);
2282
    if (fi->parent && fi->parent->file)
2283
      sc_log(ctx, "fi parent path %s", sc_print_path(&fi->parent->file->path));
2284
  }
2285
  sc_log(ctx, "find profile file by path:%s", sc_print_path(path));
2286
#endif
2287
2288
8.22k
  if (!path || (!path->len && !path->aid.len))
2289
2.83k
    return NULL;
2290
2291
104k
  for (fi = pro->ef_list; fi; fi = fi->next) {
2292
99.3k
    fp_path = &fi->file->path;
2293
99.3k
    fpp_path = fi->parent ? &fi->parent->file->path : NULL;
2294
2295
99.3k
    if (fp_path->len != path->len)
2296
15.3k
      continue;
2297
84.0k
    if (fp_path->len && memcmp(fp_path->value, path->value, path->len))
2298
9.38k
      continue;
2299
2300
74.7k
    if (path->aid.len && fp_path->aid.len)   {
2301
34.4k
      if (memcmp(fp_path->aid.value, path->aid.value, path->aid.len))
2302
172
        continue;
2303
34.4k
    }
2304
40.2k
    else if (path->aid.len && !fp_path->aid.len && fpp_path)   {
2305
34.4k
      if (fpp_path->type == SC_PATH_TYPE_DF_NAME && fpp_path->len)   {
2306
178
        if (fpp_path->len != path->aid.len)
2307
81
          continue;
2308
97
        if (memcmp(fpp_path->value, path->aid.value, path->aid.len))
2309
77
          continue;
2310
97
      }
2311
34.3k
      else if (fpp_path->aid.len)   {
2312
680
        if (fpp_path->aid.len != path->aid.len)
2313
75
          continue;
2314
605
        if (memcmp(fpp_path->aid.value, path->aid.value, path->aid.len))
2315
142
          continue;
2316
605
      }
2317
34.4k
    }
2318
2319
74.1k
    out = fi;
2320
74.1k
  }
2321
2322
#ifdef DEBUG_PROFILE
2323
  sc_log(ctx, "returns (%s)", out ? out->ident: "<null>");
2324
#endif
2325
5.39k
  return out;
2326
8.22k
}
Unexecuted instantiation: profile.c:sc_profile_find_file_by_path
fuzz_pkcs15init.c:sc_profile_find_file_by_path
Line
Count
Source
2271
8.22k
{
2272
8.22k
  struct file_info *fi, *out = NULL;
2273
8.22k
  struct sc_path *fp_path, *fpp_path;
2274
2275
#ifdef DEBUG_PROFILE
2276
  struct sc_context *ctx = pro->card->ctx;
2277
2278
  sc_log(ctx, "profile's EF list:");
2279
  for (fi = pro->ef_list; fi; fi = fi->next)   {
2280
    sc_log(ctx, "'%s' (path:%s)",  fi->ident, sc_print_path(&fi->file->path));
2281
    sc_log(ctx, "fi parent %p", fi->parent);
2282
    if (fi->parent && fi->parent->file)
2283
      sc_log(ctx, "fi parent path %s", sc_print_path(&fi->parent->file->path));
2284
  }
2285
  sc_log(ctx, "find profile file by path:%s", sc_print_path(path));
2286
#endif
2287
2288
8.22k
  if (!path || (!path->len && !path->aid.len))
2289
2.83k
    return NULL;
2290
2291
104k
  for (fi = pro->ef_list; fi; fi = fi->next) {
2292
99.3k
    fp_path = &fi->file->path;
2293
99.3k
    fpp_path = fi->parent ? &fi->parent->file->path : NULL;
2294
2295
99.3k
    if (fp_path->len != path->len)
2296
15.3k
      continue;
2297
84.0k
    if (fp_path->len && memcmp(fp_path->value, path->value, path->len))
2298
9.38k
      continue;
2299
2300
74.7k
    if (path->aid.len && fp_path->aid.len)   {
2301
34.4k
      if (memcmp(fp_path->aid.value, path->aid.value, path->aid.len))
2302
172
        continue;
2303
34.4k
    }
2304
40.2k
    else if (path->aid.len && !fp_path->aid.len && fpp_path)   {
2305
34.4k
      if (fpp_path->type == SC_PATH_TYPE_DF_NAME && fpp_path->len)   {
2306
178
        if (fpp_path->len != path->aid.len)
2307
81
          continue;
2308
97
        if (memcmp(fpp_path->value, path->aid.value, path->aid.len))
2309
77
          continue;
2310
97
      }
2311
34.3k
      else if (fpp_path->aid.len)   {
2312
680
        if (fpp_path->aid.len != path->aid.len)
2313
75
          continue;
2314
605
        if (memcmp(fpp_path->aid.value, path->aid.value, path->aid.len))
2315
142
          continue;
2316
605
      }
2317
34.4k
    }
2318
2319
74.1k
    out = fi;
2320
74.1k
  }
2321
2322
#ifdef DEBUG_PROFILE
2323
  sc_log(ctx, "returns (%s)", out ? out->ident: "<null>");
2324
#endif
2325
5.39k
  return out;
2326
8.22k
}
2327
2328
int
2329
sc_profile_get_parent(struct sc_profile *profile,
2330
    const char *name, sc_file_t **ret)
2331
25
{
2332
25
  struct file_info *fi = NULL;
2333
2334
25
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
2335
0
    return SC_ERROR_FILE_NOT_FOUND;
2336
2337
25
  if (!fi->parent)
2338
1
    return SC_ERROR_FILE_NOT_FOUND;
2339
2340
24
  sc_file_dup(ret, fi->parent->file);
2341
24
  if (*ret == NULL)
2342
0
    return SC_ERROR_OUT_OF_MEMORY;
2343
24
  return 0;
2344
24
}
2345
2346
/*
2347
 * Split up KEY0 or CHV1 into SC_AC_XXX and a number
2348
 */
2349
static int
2350
get_authid(struct state *cur, const char *value,
2351
    unsigned int *type, unsigned int *num)
2352
6.31k
{
2353
6.31k
  char  temp[16];
2354
6.31k
  size_t  n;
2355
2356
6.31k
  if (isdigit((unsigned char) *value)) {
2357
1.44k
    *num = 0;
2358
1.44k
    return get_uint(cur, value, type);
2359
1.44k
  }
2360
2361
4.87k
  if (strlen(value) >= sizeof(temp))
2362
6
    return 1;
2363
2364
4.87k
  n = strcspn(value, "0123456789x");
2365
4.87k
  strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp));
2366
2367
4.87k
  if (map_str2int(cur, temp, type, aclNames))
2368
30
    return 1;
2369
4.84k
  if (value[n])
2370
835
    return get_uint(cur, value + n, num);
2371
4.00k
  *num = 0;
2372
4.00k
  return 0;
2373
4.84k
}
Unexecuted instantiation: profile.c:get_authid
fuzz_pkcs15init.c:get_authid
Line
Count
Source
2352
6.31k
{
2353
6.31k
  char  temp[16];
2354
6.31k
  size_t  n;
2355
2356
6.31k
  if (isdigit((unsigned char) *value)) {
2357
1.44k
    *num = 0;
2358
1.44k
    return get_uint(cur, value, type);
2359
1.44k
  }
2360
2361
4.87k
  if (strlen(value) >= sizeof(temp))
2362
6
    return 1;
2363
2364
4.87k
  n = strcspn(value, "0123456789x");
2365
4.87k
  strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp));
2366
2367
4.87k
  if (map_str2int(cur, temp, type, aclNames))
2368
30
    return 1;
2369
4.84k
  if (value[n])
2370
835
    return get_uint(cur, value + n, num);
2371
4.00k
  *num = 0;
2372
4.00k
  return 0;
2373
4.84k
}
2374
2375
static int
2376
get_uint(struct state *cur, const char *value, unsigned int *vp)
2377
11.2k
{
2378
11.2k
  char  *ep;
2379
11.2k
  unsigned long tmp;
2380
2381
11.2k
  if (strstr(value, "0x") == value)
2382
375
    tmp = strtoul(value + 2, &ep, 16);
2383
10.8k
  else if (strstr(value, "x") == value)
2384
257
    tmp = strtoul(value + 1, &ep, 16);
2385
10.6k
  else
2386
10.6k
    tmp = strtoul(value, &ep, 0);
2387
11.2k
  if (*ep != '\0') {
2388
356
    parse_error(cur, "invalid integer argument \"%s\"\n", value);
2389
356
    return 1;
2390
356
  }
2391
10.9k
  if (tmp > INT_MAX) {
2392
73
    parse_error(cur, "the number \"%s\" is too large\n", value);
2393
73
    return 1;
2394
73
  }
2395
10.8k
  *vp = (int)tmp;
2396
10.8k
  return 0;
2397
10.9k
}
Unexecuted instantiation: profile.c:get_uint
fuzz_pkcs15init.c:get_uint
Line
Count
Source
2377
11.2k
{
2378
11.2k
  char  *ep;
2379
11.2k
  unsigned long tmp;
2380
2381
11.2k
  if (strstr(value, "0x") == value)
2382
375
    tmp = strtoul(value + 2, &ep, 16);
2383
10.8k
  else if (strstr(value, "x") == value)
2384
257
    tmp = strtoul(value + 1, &ep, 16);
2385
10.6k
  else
2386
10.6k
    tmp = strtoul(value, &ep, 0);
2387
11.2k
  if (*ep != '\0') {
2388
356
    parse_error(cur, "invalid integer argument \"%s\"\n", value);
2389
356
    return 1;
2390
356
  }
2391
10.9k
  if (tmp > INT_MAX) {
2392
73
    parse_error(cur, "the number \"%s\" is too large\n", value);
2393
73
    return 1;
2394
73
  }
2395
10.8k
  *vp = (int)tmp;
2396
10.8k
  return 0;
2397
10.9k
}
2398
2399
static int
2400
get_bool(struct state *cur, const char *value, unsigned int *vp)
2401
3.67k
{
2402
3.67k
  if (!strcasecmp(value, "on")
2403
3.54k
   || !strcasecmp(value, "yes")
2404
3.26k
   || !strcasecmp(value, "true")) {
2405
1.17k
    *vp = 1;
2406
1.17k
  } else
2407
2.50k
  if (!strcasecmp(value, "off")
2408
2.18k
   || !strcasecmp(value, "no")
2409
2.37k
   || !strcasecmp(value, "false")) {
2410
2.37k
    *vp = 0;
2411
2.37k
  } else {
2412
135
    parse_error(cur, "invalid boolean argument \"%s\"\n", value);
2413
135
    return 1;
2414
135
  }
2415
3.54k
  return 0;
2416
3.67k
}
Unexecuted instantiation: profile.c:get_bool
fuzz_pkcs15init.c:get_bool
Line
Count
Source
2401
3.67k
{
2402
3.67k
  if (!strcasecmp(value, "on")
2403
3.54k
   || !strcasecmp(value, "yes")
2404
3.26k
   || !strcasecmp(value, "true")) {
2405
1.17k
    *vp = 1;
2406
1.17k
  } else
2407
2.50k
  if (!strcasecmp(value, "off")
2408
2.18k
   || !strcasecmp(value, "no")
2409
2.37k
   || !strcasecmp(value, "false")) {
2410
2.37k
    *vp = 0;
2411
2.37k
  } else {
2412
135
    parse_error(cur, "invalid boolean argument \"%s\"\n", value);
2413
135
    return 1;
2414
135
  }
2415
3.54k
  return 0;
2416
3.67k
}
2417
2418
static int
2419
map_str2int(struct state *cur, const char *value,
2420
    unsigned int *vp, struct map *map)
2421
37.8k
{
2422
37.8k
  unsigned int  n;
2423
37.8k
  const char  *what;
2424
2425
37.8k
  if (isdigit((unsigned char) *value))
2426
3.27k
    return get_uint(cur, value, vp);
2427
163k
  for (n = 0; map[n].name; n++) {
2428
163k
    if (!strcasecmp(value, map[n].name)) {
2429
34.2k
      *vp = map[n].val;
2430
34.2k
      return 0;
2431
34.2k
    }
2432
163k
  }
2433
2434
  /* Try to print a meaningful error message */
2435
333
  what = "argument";
2436
1.81k
  for (n = 0; mapNames[n].name; n++) {
2437
1.81k
    if (mapNames[n].addr == map) {
2438
329
      what = mapNames[n].name;
2439
329
      break;
2440
329
    }
2441
1.81k
  }
2442
2443
333
  parse_error(cur, "invalid %s \"%s\"\n", what, value);
2444
333
  return SC_ERROR_SYNTAX_ERROR;
2445
34.5k
}
Unexecuted instantiation: profile.c:map_str2int
fuzz_pkcs15init.c:map_str2int
Line
Count
Source
2421
37.8k
{
2422
37.8k
  unsigned int  n;
2423
37.8k
  const char  *what;
2424
2425
37.8k
  if (isdigit((unsigned char) *value))
2426
3.27k
    return get_uint(cur, value, vp);
2427
163k
  for (n = 0; map[n].name; n++) {
2428
163k
    if (!strcasecmp(value, map[n].name)) {
2429
34.2k
      *vp = map[n].val;
2430
34.2k
      return 0;
2431
34.2k
    }
2432
163k
  }
2433
2434
  /* Try to print a meaningful error message */
2435
333
  what = "argument";
2436
1.81k
  for (n = 0; mapNames[n].name; n++) {
2437
1.81k
    if (mapNames[n].addr == map) {
2438
329
      what = mapNames[n].name;
2439
329
      break;
2440
329
    }
2441
1.81k
  }
2442
2443
333
  parse_error(cur, "invalid %s \"%s\"\n", what, value);
2444
333
  return SC_ERROR_SYNTAX_ERROR;
2445
34.5k
}
2446
2447
static int
2448
setstr(char **strp, const char *value)
2449
619
{
2450
619
  if (*strp)
2451
608
    free(*strp);
2452
619
  *strp = strdup(value);
2453
619
  return 0;
2454
619
}
Unexecuted instantiation: profile.c:setstr
fuzz_pkcs15init.c:setstr
Line
Count
Source
2449
619
{
2450
619
  if (*strp)
2451
608
    free(*strp);
2452
619
  *strp = strdup(value);
2453
619
  return 0;
2454
619
}
2455
2456
/*
2457
 * Evaluate numeric expressions
2458
 */
2459
#include <setjmp.h>
2460
2461
struct num_exp_ctx {
2462
  struct state *  state;
2463
  jmp_buf   error;
2464
2465
  int   j;
2466
  char    word[WORD_SIZE];
2467
2468
  char *    unget;
2469
  char *    str;
2470
  int   argc;
2471
  char **   argv;
2472
};
2473
2474
static void expr_eval(struct num_exp_ctx *, unsigned int *, unsigned int, int);
2475
2476
static void
2477
expr_fail(struct num_exp_ctx *ctx)
2478
225
{
2479
225
  longjmp(ctx->error, 1);
2480
225
}
Unexecuted instantiation: profile.c:expr_fail
fuzz_pkcs15init.c:expr_fail
Line
Count
Source
2478
225
{
2479
225
  longjmp(ctx->error, 1);
2480
225
}
2481
2482
static void
2483
expr_put(struct num_exp_ctx *ctx, int c)
2484
23.0k
{
2485
23.0k
  if (ctx->j >= (int)sizeof(ctx->word))
2486
2
    expr_fail(ctx);
2487
23.0k
  ctx->word[ctx->j++] = (char)c;
2488
23.0k
}
Unexecuted instantiation: profile.c:expr_put
fuzz_pkcs15init.c:expr_put
Line
Count
Source
2484
23.0k
{
2485
23.0k
  if (ctx->j >= (int)sizeof(ctx->word))
2486
2
    expr_fail(ctx);
2487
23.0k
  ctx->word[ctx->j++] = (char)c;
2488
23.0k
}
2489
2490
static char *
2491
__expr_get(struct num_exp_ctx *ctx, int eof_okay)
2492
12.4k
{
2493
12.4k
  char  *s;
2494
2495
12.4k
  if ((s = ctx->unget) != NULL) {
2496
2.16k
    ctx->unget = NULL;
2497
2.16k
    return s;
2498
2.16k
  }
2499
2500
10.3k
  ctx->j = 0;
2501
10.3k
  s = ctx->str;
2502
10.3k
  do {
2503
10.3k
    if (s == NULL || *s == '\0') {
2504
4.58k
      if (ctx->argc == 0) {
2505
2.35k
        if (eof_okay)
2506
2.28k
          return NULL;
2507
65
        expr_fail(ctx);
2508
65
      }
2509
2.29k
      ctx->str = s = *(ctx->argv++);
2510
2.29k
      ctx->argc--;
2511
2.29k
    }
2512
2513
8.08k
    while (isspace((unsigned char)*s))
2514
310
      s++;
2515
8.08k
  } while (*s == '\0');
2516
2517
8.01k
  if (isdigit((unsigned char)*s)) {
2518
4.01k
    while (isdigit((unsigned char)*s))
2519
10.4k
      expr_put(ctx, *s++);
2520
4.01k
  }
2521
4.00k
  else if (*s == '$') {
2522
68
    expr_put(ctx, *s++);
2523
875
    while (is_macro_character(*s))
2524
807
      expr_put(ctx, *s++);
2525
68
  }
2526
3.93k
  else if (strchr("*/+-()|&", *s)) {
2527
3.82k
    expr_put(ctx, *s++);
2528
3.82k
  }
2529
113
  else {
2530
113
    expr_fail(ctx);
2531
113
  }
2532
8.01k
  ctx->str = s;
2533
2534
8.01k
  expr_put(ctx, '\0');
2535
8.01k
  return ctx->word;
2536
10.3k
}
Unexecuted instantiation: profile.c:__expr_get
fuzz_pkcs15init.c:__expr_get
Line
Count
Source
2492
12.4k
{
2493
12.4k
  char  *s;
2494
2495
12.4k
  if ((s = ctx->unget) != NULL) {
2496
2.16k
    ctx->unget = NULL;
2497
2.16k
    return s;
2498
2.16k
  }
2499
2500
10.3k
  ctx->j = 0;
2501
10.3k
  s = ctx->str;
2502
10.3k
  do {
2503
10.3k
    if (s == NULL || *s == '\0') {
2504
4.58k
      if (ctx->argc == 0) {
2505
2.35k
        if (eof_okay)
2506
2.28k
          return NULL;
2507
65
        expr_fail(ctx);
2508
65
      }
2509
2.29k
      ctx->str = s = *(ctx->argv++);
2510
2.29k
      ctx->argc--;
2511
2.29k
    }
2512
2513
8.08k
    while (isspace((unsigned char)*s))
2514
310
      s++;
2515
8.08k
  } while (*s == '\0');
2516
2517
8.01k
  if (isdigit((unsigned char)*s)) {
2518
4.01k
    while (isdigit((unsigned char)*s))
2519
10.4k
      expr_put(ctx, *s++);
2520
4.01k
  }
2521
4.00k
  else if (*s == '$') {
2522
68
    expr_put(ctx, *s++);
2523
875
    while (is_macro_character(*s))
2524
807
      expr_put(ctx, *s++);
2525
68
  }
2526
3.93k
  else if (strchr("*/+-()|&", *s)) {
2527
3.82k
    expr_put(ctx, *s++);
2528
3.82k
  }
2529
113
  else {
2530
113
    expr_fail(ctx);
2531
113
  }
2532
8.01k
  ctx->str = s;
2533
2534
8.01k
  expr_put(ctx, '\0');
2535
8.01k
  return ctx->word;
2536
10.3k
}
2537
2538
static char *
2539
expr_get(struct num_exp_ctx *ctx)
2540
5.99k
{
2541
5.99k
  return __expr_get(ctx, 0);
2542
5.99k
}
Unexecuted instantiation: profile.c:expr_get
fuzz_pkcs15init.c:expr_get
Line
Count
Source
2540
5.99k
{
2541
5.99k
  return __expr_get(ctx, 0);
2542
5.99k
}
2543
2544
static void
2545
expr_unget(struct num_exp_ctx *ctx, char *s)
2546
2.18k
{
2547
2.18k
  if (ctx->unget)
2548
0
    expr_fail(ctx);
2549
2.18k
  ctx->unget = s;
2550
2.18k
}
Unexecuted instantiation: profile.c:expr_unget
fuzz_pkcs15init.c:expr_unget
Line
Count
Source
2546
2.18k
{
2547
2.18k
  if (ctx->unget)
2548
0
    expr_fail(ctx);
2549
2.18k
  ctx->unget = s;
2550
2.18k
}
2551
2552
static void
2553
expr_expect(struct num_exp_ctx *ctx, int c)
2554
588
{
2555
588
  char  *tok;
2556
2557
588
  tok = expr_get(ctx);
2558
588
  if (tok[0] != (char)c || tok[1])
2559
2
    expr_fail(ctx);
2560
588
}
Unexecuted instantiation: profile.c:expr_expect
fuzz_pkcs15init.c:expr_expect
Line
Count
Source
2554
588
{
2555
588
  char  *tok;
2556
2557
588
  tok = expr_get(ctx);
2558
588
  if (tok[0] != (char)c || tok[1])
2559
2
    expr_fail(ctx);
2560
588
}
2561
2562
1.23k
#define MAX_BRACKETS 32
2563
static void
2564
expr_term(struct num_exp_ctx *ctx, unsigned int *vp, int opening_brackets)
2565
5.40k
{
2566
5.40k
  char  *tok;
2567
2568
5.40k
  tok = expr_get(ctx);
2569
5.40k
  if (*tok == '(') {
2570
1.23k
    if (opening_brackets + 1 > MAX_BRACKETS) {
2571
2
      parse_error(ctx->state, "Too many \"%s\" in expression", tok);
2572
2
      expr_fail(ctx);
2573
2
    }
2574
1.23k
    expr_eval(ctx, vp, 1, opening_brackets + 1);
2575
1.23k
    expr_expect(ctx, ')');
2576
1.23k
  }
2577
4.16k
  else if (isdigit((unsigned char)*tok)) {
2578
4.01k
    char  *ep;
2579
4.01k
    unsigned long tmp;
2580
2581
4.01k
    tmp = strtoul(tok, &ep, 0);
2582
4.01k
    if (*ep)
2583
1
      expr_fail(ctx);
2584
4.01k
    if (tmp > UINT_MAX)
2585
49
      expr_fail(ctx);
2586
4.01k
    *vp = (unsigned int)tmp;
2587
4.01k
  }
2588
157
  else if (*tok == '$') {
2589
59
    sc_macro_t  *mac;
2590
59
    char    *argv[32];
2591
59
    int   argc;
2592
2593
59
    if (!(mac = find_macro(ctx->state->profile, tok + 1)))
2594
6
      expr_fail(ctx);
2595
59
    argc = build_argv(ctx->state, "<expr>", mac->value, argv, 32);
2596
59
    if (argc < 0 || get_uint_eval(ctx->state, argc, argv, vp) < 0)
2597
10
      expr_fail(ctx);
2598
59
  }
2599
98
  else {
2600
98
    parse_error(ctx->state, "Unexpected token \"%s\" in expression", tok);
2601
98
    expr_fail(ctx);
2602
98
  }
2603
5.40k
}
Unexecuted instantiation: profile.c:expr_term
fuzz_pkcs15init.c:expr_term
Line
Count
Source
2565
5.40k
{
2566
5.40k
  char  *tok;
2567
2568
5.40k
  tok = expr_get(ctx);
2569
5.40k
  if (*tok == '(') {
2570
1.23k
    if (opening_brackets + 1 > MAX_BRACKETS) {
2571
2
      parse_error(ctx->state, "Too many \"%s\" in expression", tok);
2572
2
      expr_fail(ctx);
2573
2
    }
2574
1.23k
    expr_eval(ctx, vp, 1, opening_brackets + 1);
2575
1.23k
    expr_expect(ctx, ')');
2576
1.23k
  }
2577
4.16k
  else if (isdigit((unsigned char)*tok)) {
2578
4.01k
    char  *ep;
2579
4.01k
    unsigned long tmp;
2580
2581
4.01k
    tmp = strtoul(tok, &ep, 0);
2582
4.01k
    if (*ep)
2583
1
      expr_fail(ctx);
2584
4.01k
    if (tmp > UINT_MAX)
2585
49
      expr_fail(ctx);
2586
4.01k
    *vp = (unsigned int)tmp;
2587
4.01k
  }
2588
157
  else if (*tok == '$') {
2589
59
    sc_macro_t  *mac;
2590
59
    char    *argv[32];
2591
59
    int   argc;
2592
2593
59
    if (!(mac = find_macro(ctx->state->profile, tok + 1)))
2594
6
      expr_fail(ctx);
2595
59
    argc = build_argv(ctx->state, "<expr>", mac->value, argv, 32);
2596
59
    if (argc < 0 || get_uint_eval(ctx->state, argc, argv, vp) < 0)
2597
10
      expr_fail(ctx);
2598
59
  }
2599
98
  else {
2600
98
    parse_error(ctx->state, "Unexpected token \"%s\" in expression", tok);
2601
98
    expr_fail(ctx);
2602
98
  }
2603
5.40k
}
2604
2605
static void
2606
expr_eval(struct num_exp_ctx *ctx, unsigned int *vp, unsigned int pri, int opening_brackets)
2607
5.40k
{
2608
5.40k
  unsigned int  left, right, new_pri;
2609
5.40k
  char    *tok, op;
2610
2611
5.40k
  expr_term(ctx, &left, opening_brackets);
2612
2613
7.30k
  while (1) {
2614
6.47k
    tok = __expr_get(ctx, 1);
2615
6.47k
    if (tok == NULL)
2616
2.28k
      break;
2617
2618
4.18k
    op = tok[0];
2619
2620
4.18k
    new_pri = 0;
2621
4.18k
    switch (op) {
2622
522
    case '*':
2623
1.06k
    case '/':
2624
1.06k
      new_pri++;
2625
      /* fall through */
2626
1.84k
    case '+':
2627
2.55k
    case '-':
2628
2.55k
      new_pri++;
2629
      /* fall through */
2630
2.77k
    case '&':
2631
2.77k
      new_pri++;
2632
      /* fall through */
2633
3.51k
    case '|':
2634
3.51k
      new_pri++;
2635
      /* fall through */
2636
4.16k
    case ')':
2637
4.16k
      break;
2638
12
    default:
2639
12
      expr_fail(ctx);
2640
4.18k
    }
2641
2642
4.16k
    if (new_pri < pri) {
2643
2.18k
      expr_unget(ctx, tok);
2644
2.18k
      break;
2645
2.18k
    }
2646
1.98k
    pri = new_pri;
2647
2648
1.98k
    expr_eval(ctx, &right, new_pri + 1, opening_brackets);
2649
1.98k
    switch (op) {
2650
264
    case '*': left *= right; break;
2651
306
    case '/':
2652
306
      if (right == 0)
2653
5
        expr_fail(ctx);
2654
306
      left /= right; break;
2655
442
    case '+': left += right; break;
2656
408
    case '-': left -= right; break;
2657
107
    case '&': left &= right; break;
2658
373
    case '|': left |= right; break;
2659
2
    default: expr_fail(ctx);
2660
1.98k
    }
2661
1.98k
  }
2662
2663
5.29k
  *vp = left;
2664
5.29k
}
Unexecuted instantiation: profile.c:expr_eval
fuzz_pkcs15init.c:expr_eval
Line
Count
Source
2607
5.40k
{
2608
5.40k
  unsigned int  left, right, new_pri;
2609
5.40k
  char    *tok, op;
2610
2611
5.40k
  expr_term(ctx, &left, opening_brackets);
2612
2613
7.30k
  while (1) {
2614
6.47k
    tok = __expr_get(ctx, 1);
2615
6.47k
    if (tok == NULL)
2616
2.28k
      break;
2617
2618
4.18k
    op = tok[0];
2619
2620
4.18k
    new_pri = 0;
2621
4.18k
    switch (op) {
2622
522
    case '*':
2623
1.06k
    case '/':
2624
1.06k
      new_pri++;
2625
      /* fall through */
2626
1.84k
    case '+':
2627
2.55k
    case '-':
2628
2.55k
      new_pri++;
2629
      /* fall through */
2630
2.77k
    case '&':
2631
2.77k
      new_pri++;
2632
      /* fall through */
2633
3.51k
    case '|':
2634
3.51k
      new_pri++;
2635
      /* fall through */
2636
4.16k
    case ')':
2637
4.16k
      break;
2638
12
    default:
2639
12
      expr_fail(ctx);
2640
4.18k
    }
2641
2642
4.16k
    if (new_pri < pri) {
2643
2.18k
      expr_unget(ctx, tok);
2644
2.18k
      break;
2645
2.18k
    }
2646
1.98k
    pri = new_pri;
2647
2648
1.98k
    expr_eval(ctx, &right, new_pri + 1, opening_brackets);
2649
1.98k
    switch (op) {
2650
264
    case '*': left *= right; break;
2651
306
    case '/':
2652
306
      if (right == 0)
2653
5
        expr_fail(ctx);
2654
306
      left /= right; break;
2655
442
    case '+': left += right; break;
2656
408
    case '-': left -= right; break;
2657
107
    case '&': left &= right; break;
2658
373
    case '|': left |= right; break;
2659
2
    default: expr_fail(ctx);
2660
1.98k
    }
2661
1.98k
  }
2662
2663
5.29k
  *vp = left;
2664
5.29k
}
2665
2666
static int
2667
get_uint_eval(struct state *cur, int argc, char **argv, unsigned int *vp)
2668
2.18k
{
2669
2.18k
  struct num_exp_ctx  ctx;
2670
2671
2.18k
  memset(&ctx, 0, sizeof(ctx));
2672
2.18k
  ctx.state = cur;
2673
2.18k
  ctx.argc  = argc;
2674
2.18k
  ctx.argv  = argv;
2675
2676
2.18k
  if (setjmp(ctx.error)) {
2677
225
    parse_error(cur, "invalid numeric expression\n");
2678
225
    return SC_ERROR_SYNTAX_ERROR;
2679
225
  }
2680
2681
1.96k
  expr_eval(&ctx, vp, 0, 0);
2682
1.96k
  if (ctx.str[0] || ctx.argc)
2683
15
    expr_fail(&ctx);
2684
2685
1.96k
  return 0;
2686
2.18k
}
Unexecuted instantiation: profile.c:get_uint_eval
fuzz_pkcs15init.c:get_uint_eval
Line
Count
Source
2668
2.18k
{
2669
2.18k
  struct num_exp_ctx  ctx;
2670
2671
2.18k
  memset(&ctx, 0, sizeof(ctx));
2672
2.18k
  ctx.state = cur;
2673
2.18k
  ctx.argc  = argc;
2674
2.18k
  ctx.argv  = argv;
2675
2676
2.18k
  if (setjmp(ctx.error)) {
2677
225
    parse_error(cur, "invalid numeric expression\n");
2678
225
    return SC_ERROR_SYNTAX_ERROR;
2679
225
  }
2680
2681
1.96k
  expr_eval(&ctx, vp, 0, 0);
2682
1.96k
  if (ctx.str[0] || ctx.argc)
2683
15
    expr_fail(&ctx);
2684
2685
1.96k
  return 0;
2686
2.18k
}
2687
2688
static void
2689
parse_error(struct state *cur, const char *fmt, ...)
2690
1.90k
{
2691
1.90k
  char  buffer[1024], *sp;
2692
1.90k
  va_list ap;
2693
2694
1.90k
  va_start(ap, fmt);
2695
1.90k
  vsnprintf(buffer, sizeof(buffer), fmt, ap);
2696
1.90k
  va_end(ap);
2697
2698
1.90k
  if ((sp = strchr(buffer, '\n')) != NULL)
2699
1.23k
    *sp = '\0';
2700
2701
1.90k
  if (cur->profile->card && cur->profile->card->ctx)
2702
1.85k
    sc_log(cur->profile->card->ctx, "%s: %s", cur->filename, buffer);
2703
44
  else
2704
44
    fprintf(stdout, "%s: %s\n", cur->filename, buffer);
2705
1.90k
}
Unexecuted instantiation: profile.c:parse_error
fuzz_pkcs15init.c:parse_error
Line
Count
Source
2690
1.90k
{
2691
1.90k
  char  buffer[1024], *sp;
2692
1.90k
  va_list ap;
2693
2694
1.90k
  va_start(ap, fmt);
2695
1.90k
  vsnprintf(buffer, sizeof(buffer), fmt, ap);
2696
1.90k
  va_end(ap);
2697
2698
1.90k
  if ((sp = strchr(buffer, '\n')) != NULL)
2699
1.23k
    *sp = '\0';
2700
2701
1.90k
  if (cur->profile->card && cur->profile->card->ctx)
2702
1.85k
    sc_log(cur->profile->card->ctx, "%s: %s", cur->filename, buffer);
2703
44
  else
2704
44
    fprintf(stdout, "%s: %s\n", cur->filename, buffer);
2705
1.90k
}