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