📄 profile.c
字号:
struct file_info *fi; if ((fi = sc_profile_find_file_by_path(profile, path)) == NULL) return SC_ERROR_FILE_NOT_FOUND; sc_file_dup(ret, fi->file); return 0;}/* * Configuration file parser */static voidinit_state(struct state *cur, struct state *new_state){ memset(new_state, 0, sizeof(*new_state)); new_state->filename = cur->filename; new_state->profile = cur->profile; new_state->frame = cur;}static intdo_card_driver(struct state *cur, int argc, char **argv){ cur->profile->driver = strdup(argv[0]); return 0;}static intdo_maxpinlength(struct state *cur, int argc, char **argv){ return get_uint(cur, argv[0], &cur->profile->pin_maxlen);}static intdo_minpinlength(struct state *cur, int argc, char **argv){ return get_uint(cur, argv[0], &cur->profile->pin_minlen);}static intdo_default_pin_type(struct state *cur, int argc, char **argv){ return map_str2int(cur, argv[0], &cur->profile->pin_encoding, pinTypeNames);}static intdo_pin_pad_char(struct state *cur, int argc, char **argv){ return get_uint(cur, argv[0], &cur->profile->pin_pad_char);}static intdo_card_label(struct state *cur, int argc, char **argv){ struct sc_pkcs15_card *p15card = cur->profile->p15_card; return setstr(&p15card->label, argv[0]);}static intdo_card_manufacturer(struct state *cur, int argc, char **argv){ struct sc_pkcs15_card *p15card = cur->profile->p15_card; return setstr(&p15card->manufacturer_id, argv[0]);}/* * Process a key block */static intprocess_key(struct state *cur, struct block *info, const char *name, scconf_block *blk){ unsigned int type, id; struct state state; if (get_authid(cur, name, &type, &id)) return 1; init_state(cur, &state); state.key = new_key(cur->profile, type, id); return process_block(&state, info, name, blk);}static struct auth_info *new_key(struct sc_profile *profile, unsigned int type, unsigned int ref){ struct auth_info *ai, **aip; for (aip = &profile->auth_list; (ai = *aip); aip = &ai->next) { if (ai->type == type && ai->ref == ref) return ai; } ai = (struct auth_info *) calloc(1, sizeof(*ai)); ai->type = type; ai->ref = ref; *aip = ai; return ai;}intdo_key_value(struct state *cur, int argc, char **argv){ struct auth_info *ai = cur->key; const char *key = argv[0]; size_t key_len; unsigned char keybuf[32]; if (key[0] == '=') { ++key; key_len = strlen(key); memcpy(keybuf, key, key_len); } else { key_len = sizeof(keybuf); if (sc_hex_to_bin(key, keybuf, &key_len)) { parse_error(cur, "Error parsing PIN/key \"%s\"\n", key); return 1; } } memcpy(ai->key, keybuf, key_len); ai->key_len = key_len; return 0;}/* * This function is called when the parser finds a block with an unknown * name in the filesystem block. This will create a new filesystem * object as the child of the current object. */static intprocess_df(struct state *cur, struct block *info, const char *name, scconf_block *blk){ struct state state; init_state(cur, &state); if (name == NULL) { parse_error(cur, "No name given for DF object."); return 1; } if (!(state.file = new_file(cur, name, SC_FILE_TYPE_DF))) return 1; return process_block(&state, info, name, blk);}static intprocess_ef(struct state *cur, struct block *info, const char *name, scconf_block *blk){ struct state state; init_state(cur, &state); if (name == NULL) { parse_error(cur, "No name given for EF object."); return 1; } if (!(state.file = new_file(cur, name, SC_FILE_TYPE_WORKING_EF))) return 1; return process_block(&state, info, name, blk);}static struct file_info *new_file(struct state *cur, const char *name, unsigned int type){ struct sc_profile *profile = cur->profile; struct file_info *info; struct sc_file *file; unsigned int df_type = 0, dont_free = 0; if ((info = sc_profile_find_file(profile, name)) != NULL) return info; info = (struct file_info *) calloc(1, sizeof(*info)); info->ident = strdup(name); /* Special cases for those EFs handled separately * by the PKCS15 logic */ if (strncasecmp(name, "PKCS15-", 7)) { file = init_file(type); } else if (!strcasecmp(name+7, "TokenInfo")) { file = profile->p15_card->file_tokeninfo; dont_free = 1; } else if (!strcasecmp(name+7, "ODF")) { file = profile->p15_card->file_odf; dont_free = 1; } else if (!strcasecmp(name+7, "AppDF")) { file = init_file(SC_FILE_TYPE_DF); } else { if (map_str2int(cur, name+7, &df_type, pkcs15DfNames)) return NULL; file = init_file(SC_FILE_TYPE_WORKING_EF); profile->df[df_type] = file; } assert(file); if (file->type != type) { parse_error(cur, "inconsistent file type (should be %s)", (file->type == SC_FILE_TYPE_DF)? "DF" : "EF"); return NULL; } info->parent = cur->file; info->file = file; info->dont_free = dont_free; info->next = profile->ef_list; profile->ef_list = info; return info;}static intdo_file_type(struct state *cur, int argc, char **argv){ unsigned int type; if (map_str2int(cur, argv[0], &type, fileTypeNames)) return 1; cur->file->file->type = type; return 0;}static intdo_file_path(struct state *cur, int argc, char **argv){ struct sc_file *file = cur->file->file; struct sc_path *path = &file->path; /* sc_format_path doesn't return an error indication * when it's unable to parse the path */ sc_format_path(argv[0], path); if (!path->len || (path->len & 1)) { parse_error(cur, "Invalid path length\n"); return 1; } file->id = (path->value[path->len-2] << 8) | path->value[path->len-1]; return 0;}static intdo_fileid(struct state *cur, int argc, char **argv){ struct file_info *fi; struct sc_file *df, *file = cur->file->file; struct sc_path temp, *path = &file->path; /* sc_format_path doesn't return an error indication * when it's unable to parse the path */ sc_format_path(argv[0], &temp); if (temp.len != 2) { parse_error(cur, "Invalid file ID length\n"); return 1; } /* Get the DF, if any */ if ((fi = cur->file->parent) && (df = fi->file)) { if (df->path.len == 0) { parse_error(cur, "No path/fileid set for parent DF\n"); return 1; } if (df->path.len + 2 > sizeof(df->path)) { parse_error(cur, "File path too long\n"); return 1; } *path = df->path; } memcpy(path->value + path->len, temp.value, 2); path->len += 2; file->id = (temp.value[0] << 8) | temp.value[1]; return 0;}static intdo_structure(struct state *cur, int argc, char **argv){ unsigned int ef_structure; if (map_str2int(cur, argv[0], &ef_structure, fileStructureNames)) return 1; cur->file->file->ef_structure = ef_structure; return 0;}static intdo_size(struct state *cur, int argc, char **argv){ unsigned int size; if (get_uint(cur, argv[0], &size)) return 1; cur->file->file->size = size; return 0;}static intdo_reclength(struct state *cur, int argc, char **argv){ unsigned int reclength; if (get_uint(cur, argv[0], &reclength)) return 1; cur->file->file->record_length = reclength; return 0;}static intdo_aid(struct state *cur, int argc, char **argv){ struct sc_file *file = cur->file->file; const char *name = argv[0]; unsigned int len; int res = 0; if (*name == '=') { len = strlen(++name); if (len > sizeof(file->name)) { parse_error(cur, "AID \"%s\" too long\n", name); return 1; } memcpy(file->name, name, len); file->namelen = len; } else { file->namelen = sizeof(file->name); res = sc_hex_to_bin(name, file->name, &file->namelen); } return res;}/* * Parse ACL list. * The way we do this is we first split things like CHV1 * into a method (SC_AC_CHV) and a reference (1). * When we're finished parsing the profile, the fake references * are replaced by the real references given in KEY or PIN * commands */static intdo_acl(struct state *cur, int argc, char **argv){ struct sc_file *file = cur->file->file; char *oper = 0, *what = 0; while (argc--) { unsigned int op, method, id; oper = *argv++; if ((what = strchr(oper, '=')) == NULL) goto bad; *what++ = '\0'; if (*what == '$') { method = SC_AC_SYMBOLIC; if (map_str2int(cur, what+1, &id, pinIdNames)) return 1; } else if (get_authid(cur, what, &method, &id)) goto bad; if (!strcmp(oper, "*")) { for (op = 0; op < SC_MAX_AC_OPS; op++) { sc_file_clear_acl_entries(file, op); sc_file_add_acl_entry(file, op, method, id); } } else { const struct sc_acl_entry *acl; if (map_str2int(cur, oper, &op, fileOpNames)) goto bad; acl = sc_file_get_acl_entry(file, op); if (acl->method == SC_AC_NEVER || acl->method == SC_AC_NONE || acl->method == SC_AC_UNKNOWN) sc_file_clear_acl_entries(file, op); sc_file_add_acl_entry(file, op, method, id); } } return 0;bad: parse_error(cur, "Invalid ACL \"%s%s%s\"\n", oper, what? "=" : "", what? what : ""); return 1;}static intprocess_pin(struct state *cur, struct block *info, const char *name, scconf_block *blk){ struct state state; unsigned int id; if (map_str2int(cur, name, &id, pinIdNames)) return 1; init_state(cur, &state); state.pin = new_pin(cur->profile, id); return process_block(&state, info, name, blk);}static struct pin_info *new_pin(struct sc_profile *profile, unsigned int id){ struct pin_info *pi, **tail; for (tail = &profile->pin_list; (pi = *tail); tail = &pi->next) { if (pi->id == id) return pi; } /* Create pin info object. Most values are * set to their defaults in set_pin_defaults later * We can't do this here because these pin info objects * are usually created before we've read the card specific * profile */ pi = (struct pin_info *) calloc(1, sizeof(*pi)); pi->id = id; pi->pin.type = -1; pi->pin.flags = 0x32; pi->pin.max_length = 0; pi->pin.min_length = 0; pi->pin.stored_length = 0; pi->pin.pad_char = 0xA5; pi->pin.magic = SC_PKCS15_PIN_MAGIC; pi->pin.reference = -1; pi->pin.tries_left = 3; *tail = pi; return pi;}voidset_pin_defaults(struct sc_profile *profile, struct pin_info *pi){ struct sc_pkcs15_pin_info *info = &pi->pin; if (info->type < 0) info->type = profile->pin_encoding; if (info->max_length == 0) info->max_length = profile->pin_maxlen; if (info->min_length == 0) info->min_length = profile->pin_minlen; if (info->stored_length == 0) { info->stored_length = profile->pin_maxlen; /* BCD encoded PIN takes half the space */ if (info->type == SC_PKCS15_PIN_TYPE_BCD) info->stored_length = (info->stored_length + 1) / 2; } if (info->pad_char == 0xA5) info->pad_char = profile->pin_pad_char;}static intdo_pin_file(struct state *cur, int argc, char **argv){ cur->pin->file_name = strdup(argv[0]); return 0;}static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -