Coverage Report

Created: 2025-11-06 06:35

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
0
#define DEF_PRKEY_RSA_ACCESS  0x1D
53
#define DEF_PUBKEY_ACCESS 0x12
54
55
0
#define TEMPLATE_FILEID_MIN_DIFF  0x20
56
57
0
#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
0
{
271
0
  struct sc_file  *file;
272
0
  unsigned int  op;
273
274
0
  file = sc_file_new();
275
0
  for (op = 0; op < SC_MAX_AC_OPS; op++) {
276
0
    sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);
277
0
  }
278
0
  file->type = type;
279
0
  file->status = SC_FILE_STATUS_ACTIVATED;
280
0
  if (file->type != SC_FILE_TYPE_DF && file->type != SC_FILE_TYPE_BSO)
281
0
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
282
0
  return file;
283
0
}
284
285
/*
286
 * Initialize profile
287
 */
288
struct sc_profile *
289
sc_profile_new(void)
290
0
{
291
0
  struct sc_pkcs15_card *p15card;
292
0
  struct sc_profile *pro;
293
294
0
  pro = calloc(1, sizeof(*pro));
295
0
  if (pro == NULL)
296
0
    return NULL;
297
0
  pro->p15_spec = p15card = sc_pkcs15_card_new();
298
299
0
  pro->pkcs15.do_last_update = 1;
300
301
0
  if (p15card) {
302
0
    p15card->tokeninfo->label = strdup("OpenSC Card");
303
0
    p15card->tokeninfo->manufacturer_id = strdup("OpenSC Project");
304
0
    p15card->tokeninfo->serial_number = strdup("0000");
305
0
    p15card->tokeninfo->flags = SC_PKCS15_TOKEN_EID_COMPLIANT;
306
0
    p15card->tokeninfo->version = 0;
307
308
    /* Set up EF(TokenInfo) and EF(ODF) */
309
0
    p15card->file_tokeninfo = init_file(SC_FILE_TYPE_WORKING_EF);
310
0
    p15card->file_odf = init_file(SC_FILE_TYPE_WORKING_EF);
311
0
    p15card->file_unusedspace = init_file(SC_FILE_TYPE_WORKING_EF);
312
0
  }
313
314
  /* Assume card does RSA natively */
315
0
  pro->rsa_access_flags = DEF_PRKEY_RSA_ACCESS;
316
0
  pro->pin_encoding = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
317
0
  pro->pin_minlen = 4;
318
0
  pro->pin_maxlen = 8;
319
0
  pro->id_style = SC_PKCS15INIT_ID_STYLE_NATIVE;
320
321
0
  return pro;
322
0
}
323
324
int
325
sc_profile_load(struct sc_profile *profile, const char *filename)
326
0
{
327
0
  struct sc_context *ctx = profile->card->ctx;
328
0
  scconf_context  *conf;
329
0
  const char *profile_dir = NULL;
330
0
  char path[PATH_MAX];
331
0
  int res = 0, i;
332
#ifdef _WIN32
333
  char temp_path[PATH_MAX];
334
  size_t temp_len;
335
#endif
336
337
0
  LOG_FUNC_CALLED(ctx);
338
0
  for (i = 0; ctx->conf_blocks[i]; i++) {
339
0
    profile_dir = scconf_get_str(ctx->conf_blocks[i], "profile_dir", NULL);
340
0
    if (profile_dir)
341
0
      break;
342
0
  }
343
344
0
  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
0
    profile_dir = SC_PKCS15_PROFILE_DIRECTORY;
355
0
#endif
356
0
  }
357
0
  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
0
  snprintf(path, sizeof(path), "%s/%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX);
363
0
#endif /* _WIN32 */
364
365
0
  sc_log(ctx, "Trying profile file %s", path);
366
367
0
  conf = scconf_new(path);
368
0
  res = scconf_parse(conf);
369
370
0
  sc_log(ctx, "profile %s loaded ok", path);
371
372
0
  if (res < 0) {
373
0
    scconf_free(conf);
374
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
375
0
  }
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
0
{
391
0
  struct sc_context *ctx = profile->card->ctx;
392
0
  struct file_info *fi;
393
0
  struct pin_info *pi;
394
0
  char    reason[64];
395
396
0
  LOG_FUNC_CALLED(ctx);
397
0
  profile->mf_info = sc_profile_find_file(profile, NULL, "MF");
398
0
  if (!profile->mf_info)
399
0
    LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Profile doesn't define a MF");
400
401
0
  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
0
  profile->df_info = sc_profile_find_file(profile, NULL, "PKCS15-AppDF");
420
0
  if (!profile->df_info)
421
0
    LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_PROFILE, "Profile doesn't define a PKCS15-AppDF");
422
423
0
  profile->p15_spec->file_app = profile->df_info->file;
424
0
  profile->df_info->dont_free = 1;
425
426
0
  for (pi = profile->pin_list; pi; pi = pi->next) {
427
0
    const char  *name;
428
429
0
    set_pin_defaults(profile, pi);
430
0
    if (!(name = pi->file_name))
431
0
      continue;
432
0
    if (!(fi = sc_profile_find_file(profile, NULL, name))) {
433
0
      snprintf(reason, sizeof(reason), "unknown PIN file \"%s\"\n", name);
434
0
      goto whine;
435
0
    }
436
437
0
    pi->file = fi;
438
0
  }
439
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
440
441
0
whine:
442
0
  sc_log(ctx, "%s", reason);
443
0
  LOG_FUNC_RETURN(ctx, SC_ERROR_INCONSISTENT_PROFILE);
444
0
}
445
446
void
447
sc_profile_free(struct sc_profile *profile)
448
0
{
449
0
  struct auth_info *ai;
450
0
  struct pin_info *pi;
451
0
  sc_macro_t  *mi;
452
0
  sc_template_t *ti;
453
454
0
  if (profile->name)
455
0
    free(profile->name);
456
0
  if (profile->driver)
457
0
    free(profile->driver);
458
459
0
  free_file_list(&profile->ef_list);
460
461
0
  while ((ai = profile->auth_list) != NULL) {
462
0
    profile->auth_list = ai->next;
463
0
    free(ai);
464
0
  }
465
466
0
  while ((ti = profile->template_list) != NULL) {
467
0
    profile->template_list = ti->next;
468
0
    if (ti->data)
469
0
      sc_profile_free(ti->data);
470
0
    if (ti->name)
471
0
      free(ti->name);
472
0
    free(ti);
473
0
  }
474
475
0
  while ((mi = profile->macro_list) != NULL) {
476
0
    profile->macro_list = mi->next;
477
0
    if (mi->name)
478
0
      free(mi->name);
479
0
    free(mi);
480
0
  }
481
482
0
  while ((pi = profile->pin_list) != NULL) {
483
0
    profile->pin_list = pi->next;
484
0
    if (pi->file_name)
485
0
      free(pi->file_name);
486
0
    free(pi);
487
0
  }
488
489
0
  for (int i = 0; profile->options[i]; i++) {
490
0
    free(profile->options[i]);
491
0
  }
492
493
0
  if (profile->p15_spec)
494
0
    sc_pkcs15_card_free(profile->p15_spec);
495
496
0
  if (profile->dll)
497
0
    sc_dlclose(profile->dll);
498
499
0
  free(profile);
500
0
}
501
502
void
503
sc_profile_get_pin_info(struct sc_profile *profile,
504
    int id, struct sc_pkcs15_auth_info *info)
505
0
{
506
0
  struct pin_info *pi;
507
508
0
  pi = new_pin(profile, id);
509
0
  if (pi == NULL)
510
0
    return;
511
512
0
  pi->pin.max_tries = pi->pin.tries_left;
513
0
  *info = pi->pin;
514
0
}
515
516
int
517
sc_profile_get_pin_retries(sc_profile_t *profile, int id)
518
0
{
519
0
  struct pin_info *pi;
520
521
0
  pi = new_pin(profile, id);
522
0
  if (pi == NULL)
523
0
    return SC_ERROR_OUT_OF_MEMORY;
524
0
  return pi->pin.tries_left;
525
0
}
526
527
int
528
sc_profile_get_pin_id(struct sc_profile *profile,
529
    unsigned int reference, int *id)
530
0
{
531
0
  struct pin_info *pi;
532
533
0
  for (pi = profile->pin_list; pi; pi = pi->next) {
534
0
    if (pi->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
535
0
      continue;
536
0
    if (pi->pin.attrs.pin.reference == (int)reference) {
537
0
      *id = pi->id;
538
0
      return 0;
539
0
    }
540
541
0
  }
542
0
  return SC_ERROR_OBJECT_NOT_FOUND;
543
0
}
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
0
{
549
0
  struct file_info *fi;
550
551
0
  if ((fi = sc_profile_find_file(profile, path, name)) == NULL)
552
0
    return SC_ERROR_FILE_NOT_FOUND;
553
0
  sc_file_dup(ret, fi->file);
554
0
  if (*ret == NULL)
555
0
    return SC_ERROR_OUT_OF_MEMORY;
556
0
  return 0;
557
0
}
558
559
int
560
sc_profile_get_file(struct sc_profile *profile,
561
    const char *name, sc_file_t **ret)
562
0
{
563
0
  struct file_info *fi;
564
565
0
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
566
0
    return SC_ERROR_FILE_NOT_FOUND;
567
0
  sc_file_dup(ret, fi->file);
568
0
  if (*ret == NULL)
569
0
    return SC_ERROR_OUT_OF_MEMORY;
570
0
  return 0;
571
0
}
572
573
int
574
sc_profile_get_file_instance(struct sc_profile *profile, const char *name,
575
    int index, sc_file_t **ret)
576
0
{
577
0
  struct sc_context *ctx = profile->card->ctx;
578
0
  struct file_info *fi;
579
0
  struct sc_file *file;
580
0
  int r;
581
582
0
  LOG_FUNC_CALLED(ctx);
583
0
  sc_log(ctx, "try to get '%s' file instance", name);
584
585
0
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
586
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
587
0
  sc_file_dup(&file, fi->file);
588
0
  sc_log(ctx, "ident '%s'; parent '%s'", fi->ident, fi->parent ? fi->parent->ident : "(null)");
589
0
  if (file == NULL)
590
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
591
0
  sc_log(ctx, "file (type:%X, path:'%s')", file->type, sc_print_path(&file->path));
592
593
0
  file->id += index;
594
0
        if(file->type == SC_FILE_TYPE_BSO) {
595
0
    r = sc_profile_add_file(profile, name, file);
596
0
    if (r < 0)
597
0
      sc_file_free(file);
598
0
    LOG_TEST_RET(ctx, r, "Profile error: cannot add BSO file");
599
0
  }
600
0
  else if (file->path.len)   {
601
0
    file->path.value[file->path.len - 2] = (file->id >> 8) & 0xFF;
602
0
    file->path.value[file->path.len - 1] = file->id & 0xFF;
603
604
0
    r = sc_profile_add_file(profile, name, file);
605
0
    if (r < 0)
606
0
      sc_file_free(file);
607
0
    LOG_TEST_RET(ctx, r, "Profile error: cannot add file");
608
0
  }
609
610
0
  if (ret)
611
0
    *ret = file;
612
0
  else
613
0
    sc_file_free(file);
614
615
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
616
0
}
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
0
{
634
0
  struct sc_context *ctx = profile->card->ctx;
635
0
  struct file_info *fi;
636
637
0
  LOG_FUNC_CALLED(ctx);
638
0
  if ((fi = sc_profile_find_file_by_path(profile, path)) == NULL)
639
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
640
0
  sc_file_dup(ret, fi->file);
641
0
  LOG_FUNC_RETURN(ctx, *ret ? SC_SUCCESS : SC_ERROR_OUT_OF_MEMORY);
642
0
}
643
644
int
645
sc_profile_add_file(sc_profile_t *profile, const char *name, sc_file_t *file)
646
0
{
647
0
  struct sc_context *ctx = profile->card->ctx;
648
0
  sc_path_t path = file->path;
649
0
  struct file_info  *parent;
650
651
0
  LOG_FUNC_CALLED(ctx);
652
0
  if (!path.len)   {
653
0
    parent = profile->df_info;
654
0
  } else {
655
0
    path.len -= 2;
656
0
    parent = sc_profile_find_file_by_path(profile, &path);
657
0
  }
658
0
  if (!parent)
659
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_FILE_NOT_FOUND);
660
0
  sc_log(ctx, "Parent path:%s", sc_print_path(&parent->file->path));
661
662
0
  sc_file_dup(&file, file);
663
0
  if (file == NULL)
664
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
665
666
0
  add_file(profile, name, file, parent);
667
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
668
0
}
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
0
{
679
0
  struct sc_context *ctx = profile->card->ctx;
680
0
  struct sc_profile *tmpl;
681
0
  struct sc_template  *info;
682
0
  unsigned int  idx;
683
0
  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
0
  for (info = profile->template_list; info; info = info->next)
690
0
    if (!strcmp(info->name, template_name))
691
0
      break;
692
0
  if (info == NULL)   {
693
0
    sc_log(ctx, "Template %s not found", template_name);
694
0
    return SC_ERROR_TEMPLATE_NOT_FOUND;
695
0
  }
696
697
0
  tmpl = info->data;
698
0
  idx = id->value[id->len-1];
699
0
  for (fi = profile->ef_list; fi; fi = fi->next) {
700
0
    if (fi->base_template == tmpl
701
0
     && fi->inst_index == idx
702
0
     && sc_compare_path(&fi->inst_path, base_path)
703
0
     && !strcmp(fi->ident, file_name)) {
704
0
      sc_file_dup(ret, fi->file);
705
0
      if (*ret == NULL)
706
0
        return SC_ERROR_OUT_OF_MEMORY;
707
0
      return 0;
708
0
    }
709
0
  }
710
711
0
  sc_log(ctx, "Instantiating template %s at %s", template_name, sc_print_path(base_path));
712
713
0
  base_file = sc_profile_find_file_by_path(profile, base_path);
714
0
  if (base_file == NULL) {
715
0
    sc_log(ctx, "Directory %s not defined in profile", sc_print_path(base_path));
716
0
    return SC_ERROR_OBJECT_NOT_FOUND;
717
0
  }
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
0
  assert(base_file->instance);
723
0
  for (fi = tmpl->ef_list; fi; fi = fi->next) {
724
0
    struct file_info  *parent, *instance;
725
0
    unsigned int  skew = 0;
726
727
0
    fi->instance = NULL;
728
0
    if ((parent = fi->parent) == NULL) {
729
0
      parent = base_file;
730
0
      skew = idx;
731
0
    }
732
0
    parent = parent->instance;
733
734
0
    instance = sc_profile_instantiate_file(profile, fi, parent, skew);
735
0
    if (instance == NULL)
736
0
      return SC_ERROR_OUT_OF_MEMORY;
737
0
    instance->base_template = tmpl;
738
0
    instance->inst_index = idx;
739
0
    instance->inst_path = *base_path;
740
741
0
    if (!strcmp(instance->ident, file_name))
742
0
      match = instance;
743
0
  }
744
745
0
  if (match == NULL) {
746
0
    sc_log(ctx, "No file named \"%s\" in template \"%s\"",
747
0
        file_name, template_name);
748
0
    return SC_ERROR_OBJECT_NOT_FOUND;
749
0
  }
750
0
  sc_file_dup(ret, match->file);
751
0
  if (*ret == NULL)
752
0
    return SC_ERROR_OUT_OF_MEMORY;
753
#ifdef DEBUG_PROFILE
754
  printf("Template instantiated\n");
755
#endif
756
0
  return 0;
757
0
}
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
0
{
763
0
  struct sc_context *ctx = profile->card->ctx;
764
0
  struct file_info *fi;
765
766
0
  fi = calloc(1, sizeof(*fi));
767
0
  if (fi == NULL)
768
0
    return NULL;
769
0
  fi->instance = fi;
770
0
  fi->parent = parent;
771
0
  fi->ident = strdup(ft->ident);
772
0
  if (fi->ident == NULL) {
773
0
    free(fi);
774
0
    return NULL;
775
0
  }
776
0
  sc_file_dup(&fi->file, ft->file);
777
0
  if (fi->file == NULL) {
778
0
    free(fi->ident);
779
0
    free(fi);
780
0
    return NULL;
781
0
  }
782
0
  fi->file->path = parent->file->path;
783
0
  fi->file->id += skew;
784
785
0
  if (fi->file->type == SC_FILE_TYPE_INTERNAL_EF
786
0
      || fi->file->type == SC_FILE_TYPE_WORKING_EF
787
0
      || (fi->file->type == SC_FILE_TYPE_DF && fi->file->id))
788
0
    sc_append_file_id(&fi->file->path, fi->file->id);
789
790
0
  append_file(profile, fi);
791
792
0
  ft->instance = fi;
793
794
0
  sc_log(ctx, "Instantiated %s at %s", ft->ident, sc_print_path(&fi->file->path));
795
0
  sc_log(ctx, "  parent=%s@%s", parent->ident, sc_print_path(&parent->file->path));
796
797
0
  return fi;
798
0
}
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
0
{
805
0
  struct pin_info *pinfo;
806
807
0
  for (pinfo = profile->pin_list; pinfo; pinfo = pinfo->next)  {
808
0
    if (auth_method == SC_AC_SYMBOLIC)   {
809
0
      if (pinfo->id != reference)
810
0
        continue;
811
0
    }
812
0
    else   {
813
0
      if (pinfo->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
814
0
        continue;
815
0
      if (pinfo->pin.auth_method != auth_method)
816
0
        continue;
817
0
      if (pinfo->pin.attrs.pin.reference != reference)
818
0
        continue;
819
0
    }
820
821
0
    if (auth_info)
822
0
      *auth_info = pinfo->pin;
823
0
    return pinfo->id;
824
0
  }
825
826
0
  return -1;
827
0
}
828
829
/*
830
 * Configuration file parser
831
 */
832
static void
833
init_state(struct state *cur_state, struct state *new_state)
834
0
{
835
0
  memset(new_state, 0, sizeof(*new_state));
836
0
  new_state->filename = cur_state->filename;
837
0
  new_state->profile = cur_state->profile;
838
0
  new_state->frame = cur_state;
839
0
}
840
841
static int
842
do_card_driver(struct state *cur, int argc, char **argv)
843
0
{
844
0
  free(cur->profile->driver);
845
0
  cur->profile->driver = strdup(argv[0]);
846
0
  return 0;
847
0
}
848
849
static int
850
do_maxpinlength(struct state *cur, int argc, char **argv)
851
0
{
852
0
  return get_uint(cur, argv[0], &cur->profile->pin_maxlen);
853
0
}
854
855
static int
856
do_minpinlength(struct state *cur, int argc, char **argv)
857
0
{
858
0
  return get_uint(cur, argv[0], &cur->profile->pin_minlen);
859
0
}
860
861
static int
862
do_default_pin_type(struct state *cur, int argc, char **argv)
863
0
{
864
0
  return map_str2int(cur, argv[0],
865
0
            &cur->profile->pin_encoding, pinTypeNames);
866
0
}
867
868
static int
869
do_pin_pad_char(struct state *cur, int argc, char **argv)
870
0
{
871
0
  return get_uint(cur, argv[0], &cur->profile->pin_pad_char);
872
0
}
873
874
static int
875
do_pin_domains(struct state *cur, int argc, char **argv)
876
0
{
877
0
  return get_bool(cur, argv[0], &cur->profile->pin_domains);
878
0
}
879
880
static int
881
do_card_label(struct state *cur, int argc, char **argv)
882
0
{
883
0
  struct sc_pkcs15_card *p15card = cur->profile->p15_spec;
884
885
0
  return setstr(&p15card->tokeninfo->label, argv[0]);
886
0
}
887
888
static int
889
do_card_manufacturer(struct state *cur, int argc, char **argv)
890
0
{
891
0
  struct sc_pkcs15_card *p15card = cur->profile->p15_spec;
892
893
0
  return setstr(&p15card->tokeninfo->manufacturer_id, argv[0]);
894
0
}
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
0
{
902
0
  return get_bool(cur, argv[0], &cur->profile->pkcs15.direct_certificates);
903
0
}
904
905
static int
906
do_encode_df_length(struct state *cur, int argc, char **argv)
907
0
{
908
0
  return get_bool(cur, argv[0], &cur->profile->pkcs15.encode_df_length);
909
0
}
910
911
static int
912
do_encode_update_field(struct state *cur, int argc, char **argv)
913
0
{
914
0
  return get_bool(cur, argv[0], &cur->profile->pkcs15.do_last_update);
915
0
}
916
917
static int
918
do_pkcs15_id_style(struct state *cur, int argc, char **argv)
919
0
{
920
0
  return map_str2int(cur, argv[0], &cur->profile->id_style, idStyleNames);
921
0
}
922
923
static int
924
do_minidriver_support_style(struct state *cur, int argc, char **argv)
925
0
{
926
0
  return map_str2int(cur, argv[0], &cur->profile->md_style, mdStyleNames);
927
0
}
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
0
{
936
0
  sc_profile_t  *profile = cur->profile;
937
0
  int   match = 0, i;
938
939
0
  for (i = 0; profile->options[i]; i++)
940
0
    match |= !strcmp(profile->options[i], name);
941
0
  if (!match && strcmp("default", name))
942
0
    return 0;
943
0
  return process_block(cur, info, name, blk);
944
0
}
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
0
{
953
0
  unsigned int  type, id;
954
0
  struct state  state;
955
956
0
  if (get_authid(cur, name, &type, &id))
957
0
    return 1;
958
959
0
  init_state(cur, &state);
960
0
  state.key = new_key(cur->profile, type, id);
961
0
  return process_block(&state, info, name, blk);
962
0
}
963
964
static struct auth_info *
965
new_key(struct sc_profile *profile, unsigned int type, unsigned int ref)
966
0
{
967
0
  struct auth_info *ai, **aip;
968
969
0
  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
0
  ai = calloc(1, sizeof(*ai));
975
0
  if (ai == NULL)
976
0
    return NULL;
977
0
  ai->type = type;
978
0
  ai->ref = ref;
979
0
  *aip = ai;
980
0
  return ai;
981
0
}
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
}
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
0
{
1017
0
  struct state  state;
1018
1019
0
  init_state(cur, &state);
1020
0
  if (name == NULL) {
1021
0
    parse_error(cur, "No name given for DF object.");
1022
0
    return 1;
1023
0
  }
1024
0
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_DF)))
1025
0
    return 1;
1026
0
  return process_block(&state, info, name, blk);
1027
0
}
1028
1029
static int
1030
process_ef(struct state *cur, struct block *info,
1031
    const char *name, scconf_block *blk)
1032
0
{
1033
0
  struct state  state;
1034
1035
0
  init_state(cur, &state);
1036
0
  if (name == NULL) {
1037
0
    parse_error(cur, "No name given for EF object.");
1038
0
    return 1;
1039
0
  }
1040
0
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_WORKING_EF)))
1041
0
    return 1;
1042
0
  return process_block(&state, info, name, blk);
1043
0
}
1044
1045
1046
static int
1047
process_bso(struct state *cur, struct block *info,
1048
    const char *name, scconf_block *blk)
1049
0
{
1050
0
  struct state  state;
1051
1052
0
  init_state(cur, &state);
1053
0
  if (name == NULL) {
1054
0
    parse_error(cur, "No name given for BSO object.");
1055
0
    return 1;
1056
0
  }
1057
0
  if (!(state.file = new_file(cur, name, SC_FILE_TYPE_BSO)))
1058
0
    return 1;
1059
0
  return process_block(&state, info, name, blk);
1060
0
}
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
0
{
1069
0
  struct file_info *fi, *ffi;
1070
1071
0
  for (fi = templ->ef_list; fi; fi = fi->next) {
1072
0
    struct sc_path fi_path =  fi->file->path;
1073
0
    int fi_id;
1074
1075
0
    if (fi->file->type == SC_FILE_TYPE_BSO)
1076
0
      continue;
1077
1078
0
    if (fi_path.len < 2) {
1079
0
      parse_error(cur, "Template insane: file-path length should not be less than 2 bytes");
1080
0
      return 1;
1081
0
    }
1082
1083
0
    fi_id = fi_path.value[fi_path.len - 2] * 0x100
1084
0
        + fi_path.value[fi_path.len - 1];
1085
1086
0
    for (ffi = templ->ef_list; ffi; ffi = ffi->next) {
1087
0
      struct sc_path ffi_path =  ffi->file->path;
1088
0
      int dlt, ffi_id;
1089
1090
0
      if (ffi->file->type == SC_FILE_TYPE_BSO)
1091
0
        continue;
1092
1093
0
      if (ffi_path.len < 2) {
1094
0
        parse_error(cur, "Template insane: file-path length should not be less than 2 bytes");
1095
0
        return 1;
1096
0
      }
1097
1098
0
      ffi_id = ffi_path.value[ffi_path.len - 2] * 0x100
1099
0
          + ffi_path.value[ffi_path.len - 1];
1100
1101
0
      dlt = fi_id > ffi_id ? fi_id - ffi_id : ffi_id - fi_id;
1102
0
      if (strcmp(ffi->ident, fi->ident))   {
1103
0
        if (dlt >= TEMPLATE_FILEID_MIN_DIFF)
1104
0
          continue;
1105
1106
0
        parse_error(cur, "Template insane: file-ids should be substantially different");
1107
0
        return 1;
1108
0
      }
1109
0
    }
1110
0
  }
1111
1112
0
  return SC_SUCCESS;
1113
0
}
1114
1115
1116
static int
1117
process_tmpl(struct state *cur, struct block *info,
1118
    const char *name, scconf_block *blk)
1119
0
{
1120
0
  struct state  state;
1121
0
  sc_template_t *tinfo;
1122
0
  sc_profile_t  *templ;
1123
0
  int r;
1124
1125
#ifdef DEBUG_PROFILE
1126
  printf("Process template:%s; block:%s\n", name, info->name);
1127
#endif
1128
0
  if (name == NULL) {
1129
0
    parse_error(cur, "No name given for template.");
1130
0
    return 1;
1131
0
  }
1132
1133
0
  templ = calloc(1, sizeof(*templ));
1134
0
  if (templ == NULL) {
1135
0
    parse_error(cur, "memory allocation failed");
1136
0
    return 1;
1137
0
  }
1138
1139
0
  tinfo = calloc(1, sizeof(*tinfo));
1140
0
  if (tinfo == NULL) {
1141
0
    parse_error(cur, "memory allocation failed");
1142
0
    free(templ);
1143
0
    return 1;
1144
0
  }
1145
0
  tinfo->name = strdup(name);
1146
0
  tinfo->data = templ;
1147
1148
0
  tinfo->next = cur->profile->template_list;
1149
0
  cur->profile->template_list = tinfo;
1150
1151
0
  init_state(cur, &state);
1152
0
  state.profile = tinfo->data;
1153
0
  state.file = NULL;
1154
1155
0
  r = process_block(&state, info, name, blk);
1156
0
  if (!r)
1157
0
    r = template_sanity_check(cur, templ);
1158
1159
#ifdef DEBUG_PROFILE
1160
  printf("Template %s processed; returns %i\n", name, r);
1161
#endif
1162
0
  return r;
1163
0
}
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
0
{
1171
0
  struct file_info  **list, *fi;
1172
1173
0
  list = &profile->ef_list;
1174
0
  while ((fi = *list) != NULL)
1175
0
    list = &fi->next;
1176
0
  *list = nfile;
1177
0
}
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
0
{
1187
0
  struct file_info  *info;
1188
1189
0
  info = calloc(1, sizeof(*info));
1190
0
  if (info == NULL)
1191
0
    return NULL;
1192
0
  info->instance = info;
1193
0
  info->ident = strdup(name);
1194
1195
0
  info->parent = parent;
1196
0
  info->file = file;
1197
1198
0
  append_file(profile, info);
1199
0
  return info;
1200
0
}
1201
1202
/*
1203
 * Free file_info list
1204
 */
1205
static void
1206
free_file_list(struct file_info **list)
1207
0
{
1208
0
  struct file_info  *fi;
1209
1210
0
  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
0
}
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
0
{
1228
0
  sc_profile_t  *profile = cur->profile;
1229
0
  struct file_info  *info;
1230
0
  sc_file_t *file;
1231
0
  unsigned int  df_type = 0, dont_free = 0;
1232
0
  int free_file = 0;
1233
1234
0
  if ((info = sc_profile_find_file(profile, NULL, name)) != NULL)
1235
0
    return info;
1236
1237
  /* Special cases for those EFs handled separately
1238
   * by the PKCS15 logic */
1239
0
  if (strncasecmp(name, "PKCS15-", 7)) {
1240
0
    file = init_file(type);
1241
0
    free_file = 1;
1242
0
  } else if (!strcasecmp(name+7, "TokenInfo")) {
1243
0
    if (!profile->p15_spec) {
1244
0
      parse_error(cur, "no pkcs15 spec in profile");
1245
0
      return NULL;
1246
0
    }
1247
0
    file = profile->p15_spec->file_tokeninfo;
1248
0
    dont_free = 1;
1249
0
  } else if (!strcasecmp(name+7, "ODF")) {
1250
0
    if (!profile->p15_spec) {
1251
0
      parse_error(cur, "no pkcs15 spec in profile");
1252
0
      return NULL;
1253
0
    }
1254
0
    file = profile->p15_spec->file_odf;
1255
0
    dont_free = 1;
1256
0
  } else if (!strcasecmp(name+7, "UnusedSpace")) {
1257
0
    if (!profile->p15_spec) {
1258
0
      parse_error(cur, "no pkcs15 spec in profile");
1259
0
      return NULL;
1260
0
    }
1261
0
    file = profile->p15_spec->file_unusedspace;
1262
0
    dont_free = 1;
1263
0
  } else if (!strcasecmp(name+7, "AppDF")) {
1264
0
    file = init_file(SC_FILE_TYPE_DF);
1265
0
    free_file = 1;
1266
0
  } else {
1267
0
    if (map_str2int(cur, name+7, &df_type, pkcs15DfNames)
1268
0
        || df_type >= SC_PKCS15_DF_TYPE_COUNT)
1269
0
      return NULL;
1270
1271
0
    file = init_file(SC_FILE_TYPE_WORKING_EF);
1272
0
    profile->df[df_type] = file;
1273
0
    free_file = 1;
1274
0
  }
1275
0
  assert(file);
1276
0
  if (file->type != type) {
1277
0
    parse_error(cur, "inconsistent file type (should be %s)",
1278
0
      file->type == SC_FILE_TYPE_DF
1279
0
        ? "DF" : file->type == SC_FILE_TYPE_BSO
1280
0
          ? "BS0" : "EF");
1281
0
    if (free_file)
1282
0
      sc_file_free(file);
1283
0
    return NULL;
1284
0
  }
1285
1286
0
  info = add_file(profile, name, file, cur->file);
1287
0
  if (info == NULL) {
1288
0
    parse_error(cur, "memory allocation failed");
1289
0
    return NULL;
1290
0
  }
1291
0
  info->dont_free = dont_free;
1292
0
  return info;
1293
0
}
1294
1295
static int
1296
do_file_type(struct state *cur, int argc, char **argv)
1297
0
{
1298
0
  unsigned int  type;
1299
1300
0
  if (!cur->file) {
1301
0
    parse_error(cur, "Invalid state\n");
1302
0
    return 1;
1303
0
  }
1304
1305
0
  if (map_str2int(cur, argv[0], &type, fileTypeNames))
1306
0
    return 1;
1307
0
  cur->file->file->type = type;
1308
0
  return 0;
1309
0
}
1310
1311
static int
1312
do_file_path(struct state *cur, int argc, char **argv)
1313
0
{
1314
0
  struct sc_file  *file = NULL;
1315
0
  struct sc_path  *path = NULL;
1316
1317
0
  if (!cur->file) {
1318
0
    parse_error(cur, "Invalid state\n");
1319
0
    return 1;
1320
0
  }
1321
0
  file = cur->file->file;
1322
0
  path = &file->path;
1323
1324
  /* sc_format_path doesn't return an error indication
1325
   * when it's unable to parse the path */
1326
0
  sc_format_path(argv[0], path);
1327
0
  if (!path->len || (path->len & 1)) {
1328
0
    parse_error(cur, "Invalid path length\n");
1329
0
    return 1;
1330
0
  }
1331
0
  file->id = (path->value[path->len-2] << 8) | path->value[path->len-1];
1332
0
  return 0;
1333
0
}
1334
1335
static int
1336
do_fileid(struct state *cur, int argc, char **argv)
1337
0
{
1338
0
  struct file_info *fi;
1339
0
  struct sc_file  *df, *file = NULL;
1340
0
  struct sc_path  temp, *path = NULL;
1341
1342
0
  if (!cur->file) {
1343
0
    parse_error(cur, "Invalid state\n");
1344
0
    return 1;
1345
0
  }
1346
0
  file = cur->file->file;
1347
0
  path = &file->path;
1348
1349
  /* sc_format_path doesn't return an error indication
1350
   * when it's unable to parse the path */
1351
0
  sc_format_path(argv[0], &temp);
1352
0
  if (temp.len != 2) {
1353
0
    parse_error(cur, "Invalid file ID length\n");
1354
0
    return 1;
1355
0
  }
1356
1357
  /* Get the DF, if any */
1358
0
  if ((fi = cur->file->parent) && (df = fi->file)) {
1359
0
    if (!df->path.len && !df->path.aid.len) {
1360
0
      parse_error(cur, "No path/fileid set for parent DF\n");
1361
0
      return 1;
1362
0
    }
1363
0
    if (df->path.len + 2 > sizeof(df->path.value)) {
1364
0
      parse_error(cur, "File path too long\n");
1365
0
      return 1;
1366
0
    }
1367
0
    *path = df->path;
1368
0
  }
1369
0
  if (path->len + 2 > sizeof(path->value)) {
1370
0
    parse_error(cur, "File path too long\n");
1371
0
    return 1;
1372
0
  }
1373
0
  memcpy(path->value + path->len, temp.value, 2);
1374
0
  path->len += 2;
1375
1376
0
  file->id = (temp.value[0] << 8) | temp.value[1];
1377
0
  return 0;
1378
0
}
1379
1380
static int
1381
do_structure(struct state *cur, int argc, char **argv)
1382
0
{
1383
0
  unsigned int  ef_structure;
1384
1385
0
  if (!cur->file) {
1386
0
    parse_error(cur, "Invalid state\n");
1387
0
    return 1;
1388
0
  }
1389
1390
0
  if (map_str2int(cur, argv[0], &ef_structure, fileStructureNames))
1391
0
    return 1;
1392
0
  cur->file->file->ef_structure = ef_structure;
1393
0
  return 0;
1394
0
}
1395
1396
static int
1397
do_size(struct state *cur, int argc, char **argv)
1398
0
{
1399
0
  unsigned int  size;
1400
1401
0
  if (!cur->file) {
1402
0
    parse_error(cur, "Invalid state\n");
1403
0
    return 1;
1404
0
  }
1405
1406
0
  if (get_uint_eval(cur, argc, argv, &size))
1407
0
    return 1;
1408
0
  cur->file->file->size = size;
1409
0
  return 0;
1410
0
}
1411
1412
static int
1413
do_reclength(struct state *cur, int argc, char **argv)
1414
0
{
1415
0
  unsigned int  reclength;
1416
1417
0
  if (!cur->file) {
1418
0
    parse_error(cur, "Invalid state\n");
1419
0
    return 1;
1420
0
  }
1421
1422
0
  if (get_uint(cur, argv[0], &reclength))
1423
0
    return 1;
1424
0
  cur->file->file->record_length = reclength;
1425
0
  return 0;
1426
0
}
1427
1428
static int
1429
do_content(struct state *cur, int argc, char **argv)
1430
0
{
1431
0
  struct sc_file *file = NULL;
1432
0
  size_t len = (strlen(argv[0]) + 1) / 2;
1433
0
  int rv = 0;
1434
1435
0
  if (!cur->file) {
1436
0
    parse_error(cur, "Invalid state\n");
1437
0
    return 1;
1438
0
  }
1439
0
  file = cur->file->file;
1440
1441
0
  free(file->encoded_content);
1442
1443
0
  file->encoded_content = malloc(len);
1444
0
  if (!file->encoded_content)
1445
0
    return 1;
1446
0
  rv = sc_hex_to_bin(argv[0], file->encoded_content, &len);
1447
0
  file->encoded_content_len = len;
1448
0
  return rv;
1449
0
}
1450
1451
static int
1452
do_prop_attr(struct state *cur, int argc, char **argv)
1453
0
{
1454
0
  struct sc_file *file = NULL;
1455
0
  size_t len = (strlen(argv[0]) + 1) / 2;
1456
0
  int rv = 0;
1457
1458
0
  if (!cur->file) {
1459
0
    parse_error(cur, "Invalid state\n");
1460
0
    return 1;
1461
0
  }
1462
0
  file = cur->file->file;
1463
1464
0
  free(file->prop_attr);
1465
0
  file->prop_attr = malloc(len);
1466
0
  if (!file->prop_attr)
1467
0
    return 1;
1468
0
  rv = sc_hex_to_bin(argv[0], file->prop_attr, &len);
1469
0
  file->prop_attr_len = len;
1470
0
  return rv;
1471
0
}
1472
1473
static int
1474
do_aid(struct state *cur, int argc, char **argv)
1475
0
{
1476
0
  struct sc_file  *file = NULL;
1477
0
  const char  *name = argv[0];
1478
0
  size_t len;
1479
0
  int   res = 0;
1480
1481
0
  if (!cur->file) {
1482
0
    parse_error(cur, "Invalid state\n");
1483
0
    return 1;
1484
0
  }
1485
0
  file = cur->file->file;
1486
1487
0
  if (*name == '=') {
1488
0
    len = strlen(++name);
1489
0
    if (len > sizeof(file->name)) {
1490
0
      parse_error(cur, "AID \"%s\" too long\n", name);
1491
0
      return 1;
1492
0
    }
1493
0
    memcpy(file->name, name, len);
1494
0
    file->namelen = len;
1495
0
  }
1496
0
  else {
1497
0
    file->namelen = sizeof(file->name);
1498
0
    res = sc_hex_to_bin(name, file->name, &file->namelen);
1499
0
  }
1500
0
  return res;
1501
0
}
1502
1503
static int
1504
do_exclusive_aid(struct state *cur, int argc, char **argv)
1505
0
{
1506
0
  struct sc_file  *file = NULL;
1507
0
  const char  *name = argv[0];
1508
0
  size_t len;
1509
0
  int   res = 0;
1510
1511
0
  if (!cur->file) {
1512
0
    parse_error(cur, "Invalid state\n");
1513
0
    return 1;
1514
0
  }
1515
0
  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
0
  sc_format_path(name, &file->path);
1522
0
  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
0
  memcpy(file->path.aid.value, file->path.value, file->path.len);
1528
0
  file->path.aid.len = file->path.len;
1529
1530
0
  file->path.len = 0;
1531
0
  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
0
  if (*name == '=') {
1537
0
    len = strlen(++name);
1538
0
    if (len > sizeof(file->name)) {
1539
0
      parse_error(cur, "AID \"%s\" too long\n", name);
1540
0
      return 1;
1541
0
    }
1542
0
    memcpy(file->name, name, len);
1543
0
    file->namelen = len;
1544
0
  }
1545
0
  else {
1546
0
    file->namelen = sizeof(file->name);
1547
0
    res = sc_hex_to_bin(name, file->name, &file->namelen);
1548
0
  }
1549
0
  return res;
1550
0
}
1551
1552
static int
1553
do_profile_extension(struct state *cur, int argc, char **argv)
1554
0
{
1555
0
  if (!cur->file) {
1556
0
    parse_error(cur, "Invalid state\n");
1557
0
    return 1;
1558
0
  }
1559
0
  return setstr(&cur->file->profile_extension, argv[0]);
1560
0
}
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
0
{
1573
0
  struct sc_file  *file = NULL;
1574
0
  char    oper[64], *what = NULL;
1575
0
  memset(oper, 0, sizeof(oper));
1576
1577
0
  if (!cur->file)
1578
0
    goto bad;
1579
0
  file = cur->file->file;
1580
1581
0
  while (argc--) {
1582
0
    unsigned int  op, method, id;
1583
1584
0
    if (strlen(*argv) >= sizeof(oper))
1585
0
      goto bad;
1586
0
    strlcpy(oper, *argv++, sizeof(oper));
1587
1588
0
    if ((what = strchr(oper, '=')) == NULL)
1589
0
      goto bad;
1590
0
    *what++ = '\0';
1591
1592
0
    if (*what == '$') {
1593
0
      method = SC_AC_SYMBOLIC;
1594
0
      if (map_str2int(cur, what+1, &id, pinIdNames))
1595
0
        return 1;
1596
0
    }
1597
0
    else if (get_authid(cur, what, &method, &id))
1598
0
      goto bad;
1599
1600
1601
0
    if (!strcmp(oper, "*")) {
1602
0
      for (op = 0; op < SC_MAX_AC_OPS; op++) {
1603
0
        sc_file_clear_acl_entries(file, op);
1604
0
        sc_file_add_acl_entry(file, op, method, id);
1605
0
      }
1606
0
    } else {
1607
0
      const sc_acl_entry_t *acl;
1608
1609
0
      if (map_str2int(cur, oper, &op, fileOpNames))
1610
0
        goto bad;
1611
0
      if (!(acl = sc_file_get_acl_entry(file, op)))
1612
0
        goto bad;
1613
0
      if (acl->method == SC_AC_NEVER
1614
0
       || acl->method == SC_AC_NONE
1615
0
       || acl->method == SC_AC_UNKNOWN)
1616
0
        sc_file_clear_acl_entries(file, op);
1617
1618
0
      sc_file_add_acl_entry(file, op, method, id);
1619
0
    }
1620
0
  }
1621
0
  return 0;
1622
1623
0
bad:  parse_error(cur,
1624
0
    "Invalid ACL \"%s%s%s\"\n",
1625
0
    oper, what? "=" : "", what? what : "");
1626
0
  return 1;
1627
0
}
1628
1629
static int
1630
process_pin(struct state *cur, struct block *info,
1631
    const char *name, scconf_block *blk)
1632
0
{
1633
0
  struct state  state;
1634
0
  unsigned int  id;
1635
1636
0
  if (map_str2int(cur, name, &id, pinIdNames))
1637
0
    return 1;
1638
1639
0
  init_state(cur, &state);
1640
0
  state.pin = new_pin(cur->profile, (int)id);
1641
1642
0
  return process_block(&state, info, name, blk);
1643
0
}
1644
1645
static struct pin_info *
1646
new_pin(struct sc_profile *profile, int id)
1647
0
{
1648
0
  struct pin_info *pi, **tail;
1649
1650
0
  for (tail = &profile->pin_list; (pi = *tail); tail = &pi->next) {
1651
0
    if (pi->id == id)
1652
0
      return pi;
1653
0
  }
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
0
  pi = calloc(1, sizeof(*pi));
1662
0
  if (pi == NULL)
1663
0
    return NULL;
1664
0
  pi->id = id;
1665
0
  pi->pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1666
0
  pi->pin.auth_method = SC_AC_CHV;
1667
0
  pi->pin.attrs.pin.type = (unsigned int)-1;
1668
0
  pi->pin.attrs.pin.flags = 0x32;
1669
0
  pi->pin.attrs.pin.max_length = 0;
1670
0
  pi->pin.attrs.pin.min_length = 0;
1671
0
  pi->pin.attrs.pin.stored_length = 0;
1672
0
  pi->pin.attrs.pin.pad_char = 0xA5;
1673
0
  pi->pin.attrs.pin.reference = -1;
1674
0
  pi->pin.tries_left = 3;
1675
1676
0
  *tail = pi;
1677
0
  return pi;
1678
0
}
1679
1680
static void set_pin_defaults(struct sc_profile *profile, struct pin_info *pi)
1681
0
{
1682
0
  struct sc_pkcs15_auth_info *info = &pi->pin;
1683
0
  struct sc_pkcs15_pin_attributes *pin_attrs = &info->attrs.pin;
1684
1685
0
  info->auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
1686
1687
0
  if (pin_attrs->type == (unsigned int) -1)
1688
0
    pin_attrs->type = profile->pin_encoding;
1689
0
  if (pin_attrs->max_length == 0)
1690
0
    pin_attrs->max_length = profile->pin_maxlen;
1691
0
  if (pin_attrs->min_length == 0)
1692
0
    pin_attrs->min_length = profile->pin_minlen;
1693
0
  if (pin_attrs->stored_length == 0) {
1694
0
    pin_attrs->stored_length = profile->pin_maxlen;
1695
    /* BCD encoded PIN takes half the space */
1696
0
    if (pin_attrs->type == SC_PKCS15_PIN_TYPE_BCD)
1697
0
      pin_attrs->stored_length = (pin_attrs->stored_length + 1) / 2;
1698
0
  }
1699
0
  if (pin_attrs->pad_char == 0xA5)
1700
0
    pin_attrs->pad_char = profile->pin_pad_char;
1701
0
}
1702
1703
static int
1704
do_pin_file(struct state *cur, int argc, char **argv)
1705
0
{
1706
0
  free(cur->pin->file_name);
1707
0
  cur->pin->file_name = strdup(argv[0]);
1708
0
  return 0;
1709
0
}
1710
1711
static int
1712
do_pin_offset(struct state *cur, int argc, char **argv)
1713
0
{
1714
0
  return get_uint(cur, argv[0], &cur->pin->file_offset);
1715
0
}
1716
1717
static int
1718
do_pin_attempts(struct state *cur, int argc, char **argv)
1719
0
{
1720
0
  struct pin_info *pi = cur->pin;
1721
0
  unsigned int  count;
1722
1723
0
  if (get_uint(cur, argv[0], &count))
1724
0
    return 1;
1725
0
  pi->pin.tries_left = count;
1726
0
  return 0;
1727
0
}
1728
1729
static int
1730
do_pin_maxunlocks(struct state *cur, int argc, char **argv)
1731
0
{
1732
0
  struct pin_info *pi = cur->pin;
1733
0
  unsigned int  count;
1734
1735
0
  if (get_uint(cur, argv[0], &count))
1736
0
    return 1;
1737
0
  pi->pin.max_unlocks = count;
1738
0
  return 0;
1739
0
}
1740
1741
static int
1742
do_pin_type(struct state *cur, int argc, char **argv)
1743
0
{
1744
0
  unsigned int  type;
1745
1746
0
  if (map_str2int(cur, argv[0], &type, pinTypeNames))
1747
0
    return 1;
1748
0
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1749
0
    return 1;
1750
0
  cur->pin->pin.attrs.pin.type = type;
1751
0
  return 0;
1752
0
}
1753
1754
static int
1755
do_pin_reference(struct state *cur, int argc, char **argv)
1756
0
{
1757
0
  unsigned int  reference;
1758
1759
0
  if (get_uint(cur, argv[0], &reference))
1760
0
    return 1;
1761
0
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1762
0
    return 1;
1763
0
  cur->pin->pin.attrs.pin.reference = reference;
1764
0
  return 0;
1765
0
}
1766
1767
static int
1768
do_pin_authid(struct state *cur, int argc, char **argv)
1769
0
{
1770
0
  sc_pkcs15_format_id(argv[0], &cur->pin->pin.auth_id);
1771
0
  return 0;
1772
0
}
1773
1774
static int
1775
do_pin_minlength(struct state *cur, int argc, char **argv)
1776
0
{
1777
0
  unsigned int  len;
1778
1779
0
  if (get_uint(cur, argv[0], &len))
1780
0
    return 1;
1781
0
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1782
0
    return 1;
1783
0
  cur->pin->pin.attrs.pin.min_length = len;
1784
0
  return 0;
1785
0
}
1786
1787
static int
1788
do_pin_maxlength(struct state *cur, int argc, char **argv)
1789
0
{
1790
0
  unsigned int  len;
1791
1792
0
  if (get_uint(cur, argv[0], &len))
1793
0
    return 1;
1794
0
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1795
0
    return 1;
1796
0
  cur->pin->pin.attrs.pin.max_length = len;
1797
0
  return 0;
1798
0
}
1799
1800
static int
1801
do_pin_storedlength(struct state *cur, int argc, char **argv)
1802
0
{
1803
0
  unsigned int  len;
1804
1805
0
  if (get_uint(cur, argv[0], &len))
1806
0
    return 1;
1807
0
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1808
0
    return 1;
1809
0
  cur->pin->pin.attrs.pin.stored_length = len;
1810
0
  return 0;
1811
0
}
1812
1813
static int
1814
do_pin_flags(struct state *cur, int argc, char **argv)
1815
0
{
1816
0
  unsigned int flags = 0;
1817
0
  int   i, r;
1818
1819
0
  if (cur->pin->pin.auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
1820
0
    return -1;
1821
1822
0
  cur->pin->pin.attrs.pin.flags = 0;
1823
0
  for (i = 0; i < argc; i++) {
1824
0
    if ((r = map_str2int(cur, argv[i], &flags, pinFlagNames)) < 0)
1825
0
      return r;
1826
0
    cur->pin->pin.attrs.pin.flags |= flags;
1827
0
  }
1828
1829
0
  return 0;
1830
0
}
1831
1832
static int
1833
process_macros(struct state *cur, struct block *info,
1834
    const char *dummy, scconf_block *blk)
1835
0
{
1836
0
  scconf_item *item;
1837
0
  const char  *name;
1838
0
  int    r;
1839
1840
0
  for (item = blk->items; item; item = item->next) {
1841
0
    char *s = item->key;
1842
0
    name = item->key;
1843
0
    if (item->type != SCCONF_ITEM_TYPE_VALUE || !name)
1844
0
      continue;
1845
1846
    /* make sure the macro name consist only of allowed characters.
1847
     * This is not guaranteed by the tokenizer */
1848
0
    while (is_macro_character(*s)) {
1849
0
      s++;
1850
0
    }
1851
0
    if (*s != '\0') {
1852
#ifdef DEBUG_PROFILE
1853
      printf("Invalid macro name %s\n", name);
1854
#endif
1855
0
      return SC_ERROR_SYNTAX_ERROR;
1856
0
    }
1857
#ifdef DEBUG_PROFILE
1858
    printf("Defining %s\n", name);
1859
#endif
1860
0
    r = new_macro(cur->profile, name, item->value.list);
1861
0
    if (r != SC_SUCCESS)
1862
0
      return r;
1863
0
  }
1864
1865
0
  return SC_SUCCESS;
1866
0
}
1867
1868
static int
1869
new_macro(sc_profile_t *profile, const char *name, scconf_list *value)
1870
0
{
1871
0
  sc_macro_t  *mac;
1872
1873
0
  if (!profile || !name || !value)
1874
0
    return SC_ERROR_INVALID_ARGUMENTS;
1875
1876
0
  if ((mac = find_macro(profile, name)) == NULL) {
1877
0
    mac = calloc(1, sizeof(*mac));
1878
0
    if (mac == NULL)
1879
0
      return SC_ERROR_OUT_OF_MEMORY;
1880
0
    mac->name = strdup(name);
1881
0
    mac->next = profile->macro_list;
1882
0
    profile->macro_list = mac;
1883
0
  }
1884
1885
0
  mac->value = value;
1886
0
  return SC_SUCCESS;
1887
0
}
1888
1889
static sc_macro_t *
1890
find_macro(sc_profile_t *profile, const char *name)
1891
0
{
1892
0
  sc_macro_t  *mac;
1893
1894
0
  for (mac = profile->macro_list; mac; mac = mac->next) {
1895
0
    if (!strcmp(mac->name, name))
1896
0
      return mac;
1897
0
  }
1898
0
  return NULL;
1899
0
}
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
0
{
2010
0
  if (isalnum(c) || c == '-' || c == '_')
2011
0
    return 1;
2012
0
  return 0;
2013
0
}
2014
2015
static int
2016
get_inner_word(char *str, char word[WORD_SIZE])
2017
0
{
2018
0
  char *inner = NULL;
2019
0
  size_t len = 0;
2020
2021
0
  inner = str;
2022
2023
0
  while (is_macro_character(*inner)) {
2024
0
    inner++;
2025
0
    len++;
2026
0
  }
2027
0
  if (len >= WORD_SIZE)
2028
0
    return 1;
2029
0
  memcpy(word, str, len);
2030
0
  word[len] = '\0';
2031
0
  return 0;
2032
0
}
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
0
{
2041
0
  scconf_list *value;
2042
0
  char *name = NULL;
2043
0
  sc_macro_t  *m;
2044
0
  char word[WORD_SIZE];
2045
2046
0
  if (!start_name || !macro || !profile || depth == 16)
2047
0
    return 1;
2048
2049
  /* For some reason, the macro value is a list where we need to check for references */
2050
0
  for (value = macro->value; value != NULL; value = value->next) {
2051
    /* Find name in macro value */
2052
0
    char *macro_value = value->data;
2053
0
    if (!(name = strchr(macro_value, '$')))
2054
0
      continue;
2055
    /* Extract the macro name from the string */
2056
0
    if (get_inner_word(name + 1, word))
2057
0
      return 1;
2058
    /* Find whether name corresponds to some other macro */
2059
0
    if (!(m = find_macro(profile, word)))
2060
0
      continue;
2061
    /* Check for loop */
2062
0
    if (!strcmp(m->name, start_name))
2063
0
      return 1;
2064
    /* Reference loop was found to the original macro name */
2065
0
    if (check_macro_reference_loop(start_name, m, profile, depth + 1) == 1) {
2066
0
      return 1;
2067
0
    }
2068
0
  }
2069
0
  return 0;
2070
0
}
2071
2072
static int
2073
build_argv(struct state *cur, const char *cmdname,
2074
    scconf_list *list, char **argv, unsigned int max)
2075
0
{
2076
0
  unsigned int  argc;
2077
0
  const char  *str;
2078
0
  sc_macro_t  *macro;
2079
0
  int   r;
2080
2081
0
  for (argc = 0; list; list = list->next) {
2082
0
    if (argc >= max) {
2083
0
      parse_error(cur, "%s: too many arguments", cmdname);
2084
0
      return SC_ERROR_INVALID_ARGUMENTS;
2085
0
    }
2086
2087
0
    str = list->data;
2088
0
    if (str[0] != '$') {
2089
      /* When str contains macro inside, macro reference loop needs to be checked */
2090
0
      char *macro_name = NULL;
2091
0
      if ((macro_name = strchr(str, '$'))) {
2092
        /* Macro does not to start at the first position */
2093
0
        char word[WORD_SIZE];
2094
0
        get_inner_word(macro_name + 1, word);
2095
0
        if ((macro = find_macro(cur->profile, word))
2096
0
            && check_macro_reference_loop(macro->name, macro, cur->profile, 0)) {
2097
0
          return SC_ERROR_SYNTAX_ERROR;
2098
0
        }
2099
0
      }
2100
2101
0
      argv[argc++] = list->data;
2102
0
      continue;
2103
0
    }
2104
2105
    /* Expand macro reference */
2106
0
    if (!(macro = find_macro(cur->profile, str + 1))) {
2107
0
      parse_error(cur, "%s: unknown macro \"%s\"",
2108
0
          cmdname, str);
2109
0
      return SC_ERROR_SYNTAX_ERROR;
2110
0
    }
2111
2112
0
    if (list == macro->value) {
2113
0
      return SC_ERROR_SYNTAX_ERROR;
2114
0
    }
2115
0
    if (check_macro_reference_loop(macro->name, macro, cur->profile, 0)) {
2116
0
      return SC_ERROR_SYNTAX_ERROR;
2117
0
    }
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
0
    r = build_argv(cur, cmdname, macro->value,
2129
0
        argv + argc, max - argc);
2130
0
    if (r < 0)
2131
0
      return r;
2132
2133
0
    argc += r;
2134
0
  }
2135
2136
0
  return argc;
2137
0
}
2138
2139
static int
2140
process_command(struct state *cur, struct command *cmd_info, scconf_list *list)
2141
0
{
2142
0
  const char  *cmd = cmd_info->name;
2143
0
  char    *argv[32];
2144
0
  int   argc, max = 32;
2145
2146
0
  if (cmd_info->max_args >= 0 && max > cmd_info->max_args)
2147
0
    max = cmd_info->max_args;
2148
2149
0
  if ((argc = build_argv(cur, cmd, list, argv, max)) < 0)
2150
0
    return argc;
2151
2152
0
  if (argc < cmd_info->min_args) {
2153
0
    parse_error(cur, "%s: not enough arguments\n", cmd);
2154
0
    return 1;
2155
0
  }
2156
0
  return cmd_info->func(cur, argc, argv);
2157
0
}
2158
2159
static struct block *
2160
find_block_handler(struct block *bp, const char *name)
2161
0
{
2162
0
  if (bp == NULL)
2163
0
    return NULL;
2164
0
  for (; bp->name; bp++) {
2165
0
    if (!strcasecmp(bp->name, name))
2166
0
      return bp;
2167
0
  }
2168
0
  return NULL;
2169
0
}
2170
2171
static struct command *
2172
find_cmd_handler(struct command *cp, const char *name)
2173
0
{
2174
0
  if (cp == NULL)
2175
0
    return NULL;
2176
0
  for (; cp->name; cp++) {
2177
0
    if (!strcasecmp(cp->name, name))
2178
0
      return cp;
2179
0
  }
2180
0
  return NULL;
2181
0
}
2182
2183
static int
2184
process_block(struct state *cur, struct block *info,
2185
    const char *name, scconf_block *blk)
2186
0
{
2187
0
  scconf_item *item;
2188
0
  struct command  *cp;
2189
0
  struct block  *bp;
2190
0
  const char  *cmd, *ident;
2191
0
  int   res = 0;
2192
2193
0
  for (item = blk->items; res == 0 && item; item = item->next) {
2194
0
    cmd = item->key;
2195
0
    if (item->type == SCCONF_ITEM_TYPE_COMMENT)
2196
0
      continue;
2197
0
    if (!cmd) {
2198
0
      parse_error(cur, "Command can not be processed.");
2199
0
      return SC_ERROR_SYNTAX_ERROR;
2200
0
    }
2201
0
    if (item->type == SCCONF_ITEM_TYPE_BLOCK) {
2202
0
      scconf_list *nlist;
2203
2204
0
      ident = NULL;
2205
0
      if ((nlist = item->value.block->name) != NULL) {
2206
0
        if (nlist->next) {
2207
0
          parse_error(cur, "Too many name components in block name.");
2208
0
          return SC_ERROR_SYNTAX_ERROR;
2209
0
        }
2210
0
        ident = nlist->data;
2211
0
      }
2212
#ifdef DEBUG_PROFILE
2213
      printf("Processing %s %s\n", cmd, ident? ident : "");
2214
#endif
2215
0
      if ((bp = find_block_handler(info->blk_info, cmd))) {
2216
0
        res = bp->handler(cur, bp, ident, item->value.block);
2217
0
        continue;
2218
0
      }
2219
0
    }
2220
0
    else if (item->type == SCCONF_ITEM_TYPE_VALUE) {
2221
#ifdef DEBUG_PROFILE
2222
      printf("Processing %s\n", cmd);
2223
#endif
2224
0
      if ((cp = find_cmd_handler(info->cmd_info, cmd))) {
2225
0
        res = process_command(cur, cp, item->value.list);
2226
0
        continue;
2227
0
      }
2228
0
    }
2229
0
    parse_error(cur, "Command \"%s\" not understood in this context.", cmd);
2230
0
    return SC_ERROR_SYNTAX_ERROR;
2231
0
  }
2232
2233
0
  if (res > 0)
2234
0
    res = SC_ERROR_SYNTAX_ERROR;
2235
0
  return res;
2236
0
}
2237
2238
static int
2239
process_conf(struct sc_profile *profile, scconf_context *conf)
2240
0
{
2241
0
  struct state  state;
2242
2243
0
  memset(&state, 0, sizeof(state));
2244
0
  state.filename = conf->filename;
2245
0
  state.profile = profile;
2246
0
  return process_block(&state, &root_ops, "root", conf->root);
2247
0
}
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
0
{
2253
0
  struct file_info  *fi;
2254
0
  size_t        len;
2255
0
  const u8      *value;
2256
2257
0
  value = path ? path->value : (const u8*) "";
2258
0
  len = path ? path->len : 0;
2259
0
  for (fi = pro->ef_list; fi; fi = fi->next) {
2260
0
    sc_path_t *fpath = &fi->file->path;
2261
2262
0
    if (!strcasecmp(fi->ident, name) && fpath->len >= len && !memcmp(fpath->value, value, len))
2263
0
      return fi;
2264
0
  }
2265
0
  return NULL;
2266
0
}
2267
2268
2269
static struct file_info *
2270
sc_profile_find_file_by_path(struct sc_profile *pro, const sc_path_t *path)
2271
0
{
2272
0
  struct file_info *fi, *out = NULL;
2273
0
  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
0
  if (!path || (!path->len && !path->aid.len))
2289
0
    return NULL;
2290
2291
0
  for (fi = pro->ef_list; fi; fi = fi->next) {
2292
0
    fp_path = &fi->file->path;
2293
0
    fpp_path = fi->parent ? &fi->parent->file->path : NULL;
2294
2295
0
    if (fp_path->len != path->len)
2296
0
      continue;
2297
0
    if (fp_path->len && memcmp(fp_path->value, path->value, path->len))
2298
0
      continue;
2299
2300
0
    if (path->aid.len && fp_path->aid.len)   {
2301
0
      if (memcmp(fp_path->aid.value, path->aid.value, path->aid.len))
2302
0
        continue;
2303
0
    }
2304
0
    else if (path->aid.len && !fp_path->aid.len && fpp_path)   {
2305
0
      if (fpp_path->type == SC_PATH_TYPE_DF_NAME && fpp_path->len)   {
2306
0
        if (fpp_path->len != path->aid.len)
2307
0
          continue;
2308
0
        if (memcmp(fpp_path->value, path->aid.value, path->aid.len))
2309
0
          continue;
2310
0
      }
2311
0
      else if (fpp_path->aid.len)   {
2312
0
        if (fpp_path->aid.len != path->aid.len)
2313
0
          continue;
2314
0
        if (memcmp(fpp_path->aid.value, path->aid.value, path->aid.len))
2315
0
          continue;
2316
0
      }
2317
0
    }
2318
2319
0
    out = fi;
2320
0
  }
2321
2322
#ifdef DEBUG_PROFILE
2323
  sc_log(ctx, "returns (%s)", out ? out->ident: "<null>");
2324
#endif
2325
0
  return out;
2326
0
}
2327
2328
int
2329
sc_profile_get_parent(struct sc_profile *profile,
2330
    const char *name, sc_file_t **ret)
2331
0
{
2332
0
  struct file_info *fi = NULL;
2333
2334
0
  if ((fi = sc_profile_find_file(profile, NULL, name)) == NULL)
2335
0
    return SC_ERROR_FILE_NOT_FOUND;
2336
2337
0
  if (!fi->parent)
2338
0
    return SC_ERROR_FILE_NOT_FOUND;
2339
2340
0
  sc_file_dup(ret, fi->parent->file);
2341
0
  if (*ret == NULL)
2342
0
    return SC_ERROR_OUT_OF_MEMORY;
2343
0
  return 0;
2344
0
}
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
0
{
2353
0
  char  temp[16];
2354
0
  size_t  n;
2355
2356
0
  if (isdigit((unsigned char) *value)) {
2357
0
    *num = 0;
2358
0
    return get_uint(cur, value, type);
2359
0
  }
2360
2361
0
  if (strlen(value) >= sizeof(temp))
2362
0
    return 1;
2363
2364
0
  n = strcspn(value, "0123456789x");
2365
0
  strlcpy(temp, value, (sizeof(temp) > n) ? n + 1 : sizeof(temp));
2366
2367
0
  if (map_str2int(cur, temp, type, aclNames))
2368
0
    return 1;
2369
0
  if (value[n])
2370
0
    return get_uint(cur, value + n, num);
2371
0
  *num = 0;
2372
0
  return 0;
2373
0
}
2374
2375
static int
2376
get_uint(struct state *cur, const char *value, unsigned int *vp)
2377
0
{
2378
0
  char  *ep;
2379
0
  unsigned long tmp;
2380
2381
0
  if (strstr(value, "0x") == value)
2382
0
    tmp = strtoul(value + 2, &ep, 16);
2383
0
  else if (strstr(value, "x") == value)
2384
0
    tmp = strtoul(value + 1, &ep, 16);
2385
0
  else
2386
0
    tmp = strtoul(value, &ep, 0);
2387
0
  if (*ep != '\0') {
2388
0
    parse_error(cur, "invalid integer argument \"%s\"\n", value);
2389
0
    return 1;
2390
0
  }
2391
0
  if (tmp > INT_MAX) {
2392
0
    parse_error(cur, "the number \"%s\" is too large\n", value);
2393
0
    return 1;
2394
0
  }
2395
0
  *vp = (int)tmp;
2396
0
  return 0;
2397
0
}
2398
2399
static int
2400
get_bool(struct state *cur, const char *value, unsigned int *vp)
2401
0
{
2402
0
  if (!strcasecmp(value, "on")
2403
0
   || !strcasecmp(value, "yes")
2404
0
   || !strcasecmp(value, "true")) {
2405
0
    *vp = 1;
2406
0
  } else
2407
0
  if (!strcasecmp(value, "off")
2408
0
   || !strcasecmp(value, "no")
2409
0
   || !strcasecmp(value, "false")) {
2410
0
    *vp = 0;
2411
0
  } else {
2412
0
    parse_error(cur, "invalid boolean argument \"%s\"\n", value);
2413
0
    return 1;
2414
0
  }
2415
0
  return 0;
2416
0
}
2417
2418
static int
2419
map_str2int(struct state *cur, const char *value,
2420
    unsigned int *vp, struct map *map)
2421
0
{
2422
0
  unsigned int  n;
2423
0
  const char  *what;
2424
2425
0
  if (isdigit((unsigned char) *value))
2426
0
    return get_uint(cur, value, vp);
2427
0
  for (n = 0; map[n].name; n++) {
2428
0
    if (!strcasecmp(value, map[n].name)) {
2429
0
      *vp = map[n].val;
2430
0
      return 0;
2431
0
    }
2432
0
  }
2433
2434
  /* Try to print a meaningful error message */
2435
0
  what = "argument";
2436
0
  for (n = 0; mapNames[n].name; n++) {
2437
0
    if (mapNames[n].addr == map) {
2438
0
      what = mapNames[n].name;
2439
0
      break;
2440
0
    }
2441
0
  }
2442
2443
0
  parse_error(cur, "invalid %s \"%s\"\n", what, value);
2444
0
  return SC_ERROR_SYNTAX_ERROR;
2445
0
}
2446
2447
static int
2448
setstr(char **strp, const char *value)
2449
0
{
2450
0
  if (*strp)
2451
0
    free(*strp);
2452
0
  *strp = strdup(value);
2453
0
  return 0;
2454
0
}
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
0
{
2479
0
  longjmp(ctx->error, 1);
2480
0
}
2481
2482
static void
2483
expr_put(struct num_exp_ctx *ctx, int c)
2484
0
{
2485
0
  if (ctx->j >= (int)sizeof(ctx->word))
2486
0
    expr_fail(ctx);
2487
0
  ctx->word[ctx->j++] = (char)c;
2488
0
}
2489
2490
static char *
2491
__expr_get(struct num_exp_ctx *ctx, int eof_okay)
2492
0
{
2493
0
  char  *s;
2494
2495
0
  if ((s = ctx->unget) != NULL) {
2496
0
    ctx->unget = NULL;
2497
0
    return s;
2498
0
  }
2499
2500
0
  ctx->j = 0;
2501
0
  s = ctx->str;
2502
0
  do {
2503
0
    if (s == NULL || *s == '\0') {
2504
0
      if (ctx->argc == 0) {
2505
0
        if (eof_okay)
2506
0
          return NULL;
2507
0
        expr_fail(ctx);
2508
0
      }
2509
0
      ctx->str = s = *(ctx->argv++);
2510
0
      ctx->argc--;
2511
0
    }
2512
2513
0
    while (isspace((unsigned char)*s))
2514
0
      s++;
2515
0
  } while (*s == '\0');
2516
2517
0
  if (isdigit((unsigned char)*s)) {
2518
0
    while (isdigit((unsigned char)*s))
2519
0
      expr_put(ctx, *s++);
2520
0
  }
2521
0
  else if (*s == '$') {
2522
0
    expr_put(ctx, *s++);
2523
0
    while (is_macro_character(*s))
2524
0
      expr_put(ctx, *s++);
2525
0
  }
2526
0
  else if (strchr("*/+-()|&", *s)) {
2527
0
    expr_put(ctx, *s++);
2528
0
  }
2529
0
  else {
2530
0
    expr_fail(ctx);
2531
0
  }
2532
0
  ctx->str = s;
2533
2534
0
  expr_put(ctx, '\0');
2535
0
  return ctx->word;
2536
0
}
2537
2538
static char *
2539
expr_get(struct num_exp_ctx *ctx)
2540
0
{
2541
0
  return __expr_get(ctx, 0);
2542
0
}
2543
2544
static void
2545
expr_unget(struct num_exp_ctx *ctx, char *s)
2546
0
{
2547
0
  if (ctx->unget)
2548
0
    expr_fail(ctx);
2549
0
  ctx->unget = s;
2550
0
}
2551
2552
static void
2553
expr_expect(struct num_exp_ctx *ctx, int c)
2554
0
{
2555
0
  char  *tok;
2556
2557
0
  tok = expr_get(ctx);
2558
0
  if (tok[0] != (char)c || tok[1])
2559
0
    expr_fail(ctx);
2560
0
}
2561
2562
0
#define MAX_BRACKETS 32
2563
static void
2564
expr_term(struct num_exp_ctx *ctx, unsigned int *vp, int opening_brackets)
2565
0
{
2566
0
  char  *tok;
2567
2568
0
  tok = expr_get(ctx);
2569
0
  if (*tok == '(') {
2570
0
    if (opening_brackets + 1 > MAX_BRACKETS) {
2571
0
      parse_error(ctx->state, "Too many \"%s\" in expression", tok);
2572
0
      expr_fail(ctx);
2573
0
    }
2574
0
    expr_eval(ctx, vp, 1, opening_brackets + 1);
2575
0
    expr_expect(ctx, ')');
2576
0
  }
2577
0
  else if (isdigit((unsigned char)*tok)) {
2578
0
    char  *ep;
2579
0
    unsigned long tmp;
2580
2581
0
    tmp = strtoul(tok, &ep, 0);
2582
0
    if (*ep)
2583
0
      expr_fail(ctx);
2584
0
    if (tmp > UINT_MAX)
2585
0
      expr_fail(ctx);
2586
0
    *vp = (unsigned int)tmp;
2587
0
  }
2588
0
  else if (*tok == '$') {
2589
0
    sc_macro_t  *mac;
2590
0
    char    *argv[32];
2591
0
    int   argc;
2592
2593
0
    if (!(mac = find_macro(ctx->state->profile, tok + 1)))
2594
0
      expr_fail(ctx);
2595
0
    argc = build_argv(ctx->state, "<expr>", mac->value, argv, 32);
2596
0
    if (argc < 0 || get_uint_eval(ctx->state, argc, argv, vp) < 0)
2597
0
      expr_fail(ctx);
2598
0
  }
2599
0
  else {
2600
0
    parse_error(ctx->state, "Unexpected token \"%s\" in expression", tok);
2601
0
    expr_fail(ctx);
2602
0
  }
2603
0
}
2604
2605
static void
2606
expr_eval(struct num_exp_ctx *ctx, unsigned int *vp, unsigned int pri, int opening_brackets)
2607
0
{
2608
0
  unsigned int  left, right, new_pri;
2609
0
  char    *tok, op;
2610
2611
0
  expr_term(ctx, &left, opening_brackets);
2612
2613
0
  while (1) {
2614
0
    tok = __expr_get(ctx, 1);
2615
0
    if (tok == NULL)
2616
0
      break;
2617
2618
0
    op = tok[0];
2619
2620
0
    new_pri = 0;
2621
0
    switch (op) {
2622
0
    case '*':
2623
0
    case '/':
2624
0
      new_pri++;
2625
      /* fall through */
2626
0
    case '+':
2627
0
    case '-':
2628
0
      new_pri++;
2629
      /* fall through */
2630
0
    case '&':
2631
0
      new_pri++;
2632
      /* fall through */
2633
0
    case '|':
2634
0
      new_pri++;
2635
      /* fall through */
2636
0
    case ')':
2637
0
      break;
2638
0
    default:
2639
0
      expr_fail(ctx);
2640
0
    }
2641
2642
0
    if (new_pri < pri) {
2643
0
      expr_unget(ctx, tok);
2644
0
      break;
2645
0
    }
2646
0
    pri = new_pri;
2647
2648
0
    expr_eval(ctx, &right, new_pri + 1, opening_brackets);
2649
0
    switch (op) {
2650
0
    case '*': left *= right; break;
2651
0
    case '/':
2652
0
      if (right == 0)
2653
0
        expr_fail(ctx);
2654
0
      left /= right; break;
2655
0
    case '+': left += right; break;
2656
0
    case '-': left -= right; break;
2657
0
    case '&': left &= right; break;
2658
0
    case '|': left |= right; break;
2659
0
    default: expr_fail(ctx);
2660
0
    }
2661
0
  }
2662
2663
0
  *vp = left;
2664
0
}
2665
2666
static int
2667
get_uint_eval(struct state *cur, int argc, char **argv, unsigned int *vp)
2668
0
{
2669
0
  struct num_exp_ctx  ctx;
2670
2671
0
  memset(&ctx, 0, sizeof(ctx));
2672
0
  ctx.state = cur;
2673
0
  ctx.argc  = argc;
2674
0
  ctx.argv  = argv;
2675
2676
0
  if (setjmp(ctx.error)) {
2677
0
    parse_error(cur, "invalid numeric expression\n");
2678
0
    return SC_ERROR_SYNTAX_ERROR;
2679
0
  }
2680
2681
0
  expr_eval(&ctx, vp, 0, 0);
2682
0
  if (ctx.str[0] || ctx.argc)
2683
0
    expr_fail(&ctx);
2684
2685
0
  return 0;
2686
0
}
2687
2688
static void
2689
parse_error(struct state *cur, const char *fmt, ...)
2690
0
{
2691
0
  char  buffer[1024], *sp;
2692
0
  va_list ap;
2693
2694
0
  va_start(ap, fmt);
2695
0
  vsnprintf(buffer, sizeof(buffer), fmt, ap);
2696
0
  va_end(ap);
2697
2698
0
  if ((sp = strchr(buffer, '\n')) != NULL)
2699
0
    *sp = '\0';
2700
2701
0
  if (cur->profile->card && cur->profile->card->ctx)
2702
0
    sc_log(cur->profile->card->ctx, "%s: %s", cur->filename, buffer);
2703
0
  else
2704
0
    fprintf(stdout, "%s: %s\n", cur->filename, buffer);
2705
0
}