Coverage Report

Created: 2026-07-24 06:06

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