static int load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts) { int err = 0; const scconf_list *list; const char *val, *s_internal = "internal"; int debug; int reopen; #ifdef _WIN32 char expanded_val[PATH_MAX]; DWORD expanded_len; #endif reopen = scconf_get_bool(block, "reopen_debug_file", 1); debug = scconf_get_int(block, "debug", ctx->debug); if (debug > ctx->debug) ctx->debug = debug; val = scconf_get_str(block, "debug_file", NULL); if (val) { #ifdef _WIN32 expanded_len = PATH_MAX; expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len); if (expanded_len > 0) val = expanded_val; #endif if (reopen) ctx->debug_filename = strdup(val); sc_ctx_log_to_file(ctx, val); } ctx->paranoid_memory = scconf_get_bool (block, "paranoid-memory", ctx->paranoid_memory); ctx->enable_default_driver = scconf_get_bool (block, "enable_default_driver", ctx->enable_default_driver); val = scconf_get_str(block, "force_card_driver", NULL); if (val) { if (opts->forced_card_driver) free(opts->forced_card_driver); opts->forced_card_driver = strdup(val); } list = scconf_find_list(block, "card_drivers"); if (list != NULL) del_drvs(opts); while (list != NULL) { if (strcmp(list->data, s_internal) == 0) add_internal_drvs(opts); else add_drv(opts, list->data); list = list->next; } return err; }
static int npa_load_options(sc_context_t *ctx, struct npa_drv_data *drv_data) { int r; size_t i, j; scconf_block **found_blocks, *block; const char *file; if (!ctx || !drv_data) { r = SC_ERROR_INTERNAL; goto err; } for (i = 0; ctx->conf_blocks[i]; i++) { found_blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", "npa"); if (!found_blocks) continue; for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) { if (!drv_data->can) drv_data->can = scconf_get_str(block, "can", NULL); if (!drv_data->st_dv_certificate || !drv_data->st_dv_certificate_len) { file = scconf_get_str(block, "st_dv_certificate", NULL); if (!fread_to_eof(file, (unsigned char **) &drv_data->st_dv_certificate, &drv_data->st_dv_certificate_len)) sc_log(ctx, "Warning: Could not read %s.\n", file); } if (!drv_data->st_certificate || !drv_data->st_certificate_len) { file = scconf_get_str(block, "st_certificate", NULL); if (!fread_to_eof(file, (unsigned char **) &drv_data->st_certificate, &drv_data->st_certificate_len)) sc_log(ctx, "Warning: Could not read %s.\n", file); } if (!drv_data->st_key || !drv_data->st_key_len) { file = scconf_get_str(block, "st_key", NULL); if (!fread_to_eof(file, (unsigned char **) &drv_data->st_key, &drv_data->st_key_len)) sc_log(ctx, "Warning: Could not read %s.\n", file); } } free(found_blocks); } r = SC_SUCCESS; err: return r; }
static int get_conf_aid(sc_card_t *card, u8 *aid, size_t *len) { sc_context_t *ctx = card->ctx; scconf_block *conf_block, **blocks; int i; const char *str_aid; SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE); conf_block = NULL; for (i = 0; ctx->conf_blocks[i] != NULL; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card", "gemsafeV1"); if (blocks[0] != NULL) conf_block = blocks[0]; free(blocks); } if (!conf_block) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no card specific options configured, trying default AID\n"); return SC_ERROR_INTERNAL; } str_aid = scconf_get_str(conf_block, "aid", NULL); if (!str_aid) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no aid configured, trying default AID\n"); return SC_ERROR_INTERNAL; } return sc_hex_to_bin(str_aid, aid, len); }
static int print_default_module(void) { const scconf_block *pam_pkcs11; scconf_context *ctx = NULL; int result = 1; /* * read the base pam_pkcs11.conf */ ctx = scconf_new(PAM_PKCS11_CONF); if (ctx == NULL) { goto bail; } if (scconf_parse(ctx) <= 0) { goto bail; } pam_pkcs11 = scconf_find_block(ctx, NULL, "pam_pkcs11"); if (!pam_pkcs11) { goto bail; } printf("%s\n", scconf_get_str(pam_pkcs11, "use_pkcs11_module", "")); result = 0; bail: if (ctx) { scconf_free(ctx); } ctx = NULL; return result; }
/** * find library module for provided driver in configuration file * if not found assume library name equals to module name */ static const char *find_library(sc_context_t *ctx, const char *name) { int i; const char *libname = NULL; scconf_block **blocks, *blk; for (i = 0; ctx->conf_blocks[i]; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", name); if (!blocks) continue; blk = blocks[0]; free(blocks); if (blk == NULL) continue; libname = scconf_get_str(blk, "module", name); #ifdef _WIN32 if (libname && libname[0] != '\\' ) #else if (libname && libname[0] != '/' ) #endif sc_log(ctx, "warning: relative path to driver '%s' used", libname); break; } return libname; }
static int list_modules(void) { const scconf_block *pam_pkcs11; scconf_block **pkcs11_blocks; scconf_context *ctx = NULL; int i; int result = 1; /* * loop through looking for smart card entries */ ctx = scconf_new(PAM_PKCS11_CONF); if (ctx == NULL) { goto bail; } if (scconf_parse(ctx) <= 0 ) { goto bail; } pam_pkcs11 = scconf_find_block(ctx, NULL, "pam_pkcs11"); if (!pam_pkcs11) { goto bail; } pkcs11_blocks = scconf_find_blocks(ctx, pam_pkcs11, "pkcs11_module", NULL); if (!pkcs11_blocks) { goto bail; } /* list only those smart cards which are actually installed */ for (i=0; pkcs11_blocks[i]; i++) { void *libhandle; const char *path = scconf_get_str(pkcs11_blocks[i], "module", NULL); /* check to see if the module exists on the system */ if (!path || *path == 0) { continue; } /* verify the module exists */ if ((libhandle=dlopen(path, RTLD_LAZY)) != NULL) { dlclose(libhandle); if (pkcs11_blocks[i] && pkcs11_blocks[i]->name && pkcs11_blocks[i]->name->data) { printf("%s\n", pkcs11_blocks[i]->name->data); } } } result = 0; bail: if (ctx) { scconf_free(ctx); } return result; }
int sc_profile_load(struct sc_profile *profile, const char *filename) { struct sc_context *ctx = profile->card->ctx; scconf_context *conf; const char *profile_dir = NULL; char path[PATH_MAX]; int res = 0, i; for (i = 0; ctx->conf_blocks[i]; i++) { profile_dir = scconf_get_str(ctx->conf_blocks[i], "profile_dir", NULL); if (profile_dir) break; } if (!profile_dir) { profile_dir = SC_PKCS15_PROFILE_DIRECTORY; } sc_debug(ctx, "Using profile directory '%s'.", profile_dir); #ifdef _WIN32 snprintf(path, sizeof(path), "%s\\%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX); #else /* _WIN32 */ snprintf(path, sizeof(path), "%s/%s.%s", profile_dir, filename, SC_PKCS15_PROFILE_SUFFIX); #endif /* _WIN32 */ if (profile->card->ctx->debug >= 2) { sc_debug(profile->card->ctx, "Trying profile file %s", path); } conf = scconf_new(path); res = scconf_parse(conf); if (res > 0 && profile->card->ctx->debug >= 2) { sc_debug(profile->card->ctx, "profile %s loaded ok", path); } if (res < 0) return SC_ERROR_FILE_NOT_FOUND; if (res == 0) { /* FIXME - we may want to display conf->errmsg here. */ return SC_ERROR_SYNTAX_ERROR; } res = process_conf(profile, conf); scconf_free(conf); return res; }
static const char *ui_get_config_str(struct sc_context *ctx, struct sc_atr *atr, const char *flag_name, const char *ret_default) { const char *ret = ret_default; scconf_block *atrblock = _sc_match_atr_block(ctx, NULL, atr); if (atrblock) ret = scconf_get_str(atrblock, flag_name, ret_default); return ret; }
/** * Parse configuration file to extract user consent flags */ static int get_user_consent_env(sc_context_t *ctx) { int i; scconf_block **blocks, *blk; for (i = 0; ctx->conf_blocks[i]; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],"card_driver","dnie"); if (!blocks) continue; blk=blocks[0]; free(blocks); if (blk==NULL) continue; user_consent_app = scconf_get_str(blk,"user_consent_app",PIN_ENTRY); user_consent_enabled = scconf_get_bool(blk,"user_consent_enabled",1); } return SC_SUCCESS; }
static int load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts) { int err = 0; const scconf_list *list; const char *val, *s_internal = "internal"; const char *debug = NULL; ctx->debug = scconf_get_int(block, "debug", ctx->debug); debug = getenv("OPENSC_DEBUG"); if (debug) ctx->debug = atoi(debug); val = scconf_get_str(block, "debug_file", NULL); if (val) sc_ctx_log_to_file(ctx, val); val = scconf_get_str(block, "force_card_driver", NULL); if (val) { if (opts->forced_card_driver) free(opts->forced_card_driver); opts->forced_card_driver = strdup(val); } list = scconf_find_list(block, "card_drivers"); if (list != NULL) del_drvs(opts); while (list != NULL) { if (strcmp(list->data, s_internal) == 0) add_internal_drvs(opts); else add_drv(opts, list->data); list = list->next; } return err; }
static int belpic_detect_pin_pad(sc_card_t *card, struct belpic_priv_data *priv_data) { int i = 0; char *reader_name = card->reader->name, *conf_reader, *conf_lib; scconf_block *conf_block = NULL; char *reader_i = "reader ", *lib_i = "lib "; int rn_len = strlen(reader_name); /* Hardcoded readers */ for (i = 0; pp_reader_names[i] != NULL; i++) { int pp_rn_len = strlen(pp_reader_names[i]); if (rn_len >= pp_rn_len && strncmp(reader_name, pp_reader_names[i], pp_rn_len) == 0) { return belpic_load_pin_pad_lib(card, priv_data, reader_name, pp_reader_libs[i]); } } /* From the config file */ conf_block = get_belpic_conf(card->ctx, "belpic_pin_pad"); if (conf_block == NULL) return 0; for (i = 0; i < 10; i++) { reader_i[6] = (char) (0x30 + i); conf_reader = (char *) scconf_get_str(conf_block, reader_i, NULL); if (conf_reader != NULL && rn_len >= strlen(conf_reader) && strncmp(reader_name, conf_reader, strlen(conf_reader)) == 0) { lib_i[3] = (char) (0x30 + i); conf_lib = (char *) scconf_get_str(conf_block, lib_i, NULL); if (conf_lib != NULL) return belpic_load_pin_pad_lib(card, priv_data, reader_name, conf_lib); } } return 0; }
static int load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts) { int err = 0; const scconf_list *list; const char *val; int debug; #ifdef _WIN32 char expanded_val[PATH_MAX]; DWORD expanded_len; #endif debug = scconf_get_int(block, "debug", ctx->debug); if (debug > ctx->debug) ctx->debug = debug; val = scconf_get_str(block, "debug_file", NULL); if (val) { #ifdef _WIN32 expanded_len = PATH_MAX; expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len); if (0 < expanded_len && expanded_len < sizeof expanded_val) val = expanded_val; #endif sc_ctx_log_to_file(ctx, val); } else if (ctx->debug) { sc_ctx_log_to_file(ctx, NULL); } if (scconf_get_bool (block, "disable_popups", ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS)) ctx->flags |= SC_CTX_FLAG_DISABLE_POPUPS; if (scconf_get_bool (block, "disable_colors", ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)) ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS; if (scconf_get_bool (block, "enable_default_driver", ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER)) ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER; list = scconf_find_list(block, "card_drivers"); set_drivers(opts, list); return err; }
void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) { scconf_block *conf_block = NULL; char *unblock_style = NULL; /* Set defaults */ conf->plug_and_play = 1; conf->max_virtual_slots = 16; conf->slots_per_card = 4; conf->hide_empty_tokens = 1; conf->lock_login = 0; conf->soft_keygen_allowed = 0; conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED; conf->create_puk_slot = 0; conf->zero_ckaid_for_ca_certs = 0; conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1); if (!conf_block) return; /* contains the defaults, if there is a "pkcs11" config block */ conf->plug_and_play = scconf_get_bool(conf_block, "plug_and_play", conf->plug_and_play); conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots); conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card); conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens); conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login); conf->soft_keygen_allowed = scconf_get_bool(conf_block, "soft_keygen_allowed", conf->soft_keygen_allowed); unblock_style = (char *)scconf_get_str(conf_block, "user_pin_unblock_style", NULL); if (unblock_style && !strcmp(unblock_style, "set_pin_in_unlogged_session")) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN; else if (unblock_style && !strcmp(unblock_style, "set_pin_in_specific_context")) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN; else if (unblock_style && !strcmp(unblock_style, "init_pin_in_so_session")) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN; conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot); conf->zero_ckaid_for_ca_certs = scconf_get_bool(conf_block, "zero_ckaid_for_ca_certs", conf->zero_ckaid_for_ca_certs); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d " "hide_empty_tokens=%d lock_login=%d pin_unblock_style=%d zero_ckaid_for_ca_certs=%d", conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card, conf->hide_empty_tokens, conf->lock_login, conf->pin_unblock_style, conf->zero_ckaid_for_ca_certs); }
mapper_module * mapper_module_init(scconf_block *blk,const char *mapper_name) { #else mapper_module * uid_mapper_module_init(scconf_block *blk,const char *mapper_name) { #endif mapper_module *pt; if (blk) { debug= scconf_get_bool(blk,"debug",0); mapfile = scconf_get_str(blk,"mapfile",mapfile); ignorecase = scconf_get_bool(blk,"ignorecase",ignorecase); } else { DBG1("No block declaration for mapper '%s'", mapper_name); } set_debug_level(debug); pt= init_mapper_st(blk,mapper_name); if(pt) DBG3("UniqueID mapper started. debug: %d, mapfile: %s, icase: %d",debug,mapfile,ignorecase); else DBG("UniqueID mapper initialization failed"); return pt; }
mapper_module * mapper_module_init(scconf_block *ctx,const char *mapper_name) { #else mapper_module * null_mapper_module_init(scconf_block *ctx,const char *mapper_name) { #endif mapper_module *pt= NULL; if (ctx) { default_user = scconf_get_str( ctx,"default_user",default_user); match = scconf_get_bool( ctx,"default_match",0); debug = scconf_get_bool( ctx,"debug",0); } else { DBG1("No block declaration for mapper '%s'", mapper_name); } set_debug_level(debug); pt = init_mapper_st(ctx,mapper_name); if (pt) DBG1("Null mapper match set to '%s'",match?"always":"never"); else DBG("Null mapper initialization failed"); return pt; }
static int sm_gp_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) { scconf_block *sm_conf_block = NULL, **blocks; struct sm_gp_keyset *gp_keyset = &sm_info->session.gp.gp_keyset; const char *kmc = NULL; unsigned char hex[48]; size_t hex_len = sizeof(hex); int rv, ii; sc_log(ctx, "SM get KMC from config section '%s'", sm_info->config_section); for (ii = 0; ctx->conf_blocks[ii]; ii++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section); if (blocks) { sm_conf_block = blocks[0]; free(blocks); } if (sm_conf_block) break; } kmc = scconf_get_str(sm_conf_block, "kmc", NULL); if (!kmc) return SC_ERROR_SM_KEYSET_NOT_FOUND; rv = sc_hex_to_bin(kmc, hex, &hex_len); if (rv) { sc_log(ctx, "SM get KMC: hex to bin failed for '%s'; error %i", kmc, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } sc_log(ctx, "SM type:%X, KMC(%i) %s", sm_info->sm_type, hex_len, sc_dump_hex(hex, hex_len)); if (hex_len != 16 && hex_len != 48 ) return SC_ERROR_INVALID_DATA; memcpy(gp_keyset->kmc, hex, hex_len); gp_keyset->kmc_len = hex_len; return SC_SUCCESS; }
/* * Get the named functions from the user interface * library. If no library is configured, or if the * libray doesn't define the named symbol, fall back * to the default function */ static int sc_ui_get_func(sc_context_t *ctx, const char *name, void **ret) { *ret = NULL; if (!sc_ui_lib_handle && !sc_ui_lib_loaded) { const char *lib_name = NULL; scconf_block *blk; int i; /* Prevent recursion */ sc_ui_lib_loaded = 1; for (i = 0; (blk = ctx->conf_blocks[i]); i++) { lib_name = scconf_get_str(blk, "user_interface", NULL); if (lib_name) break; } if (!lib_name) return 0; sc_ui_lib_handle = lt_dlopen(lib_name); if (!sc_ui_lib_handle) { sc_error(ctx, "Unable to open user interface library '%s': %s\n", lib_name, lt_dlerror()); return SC_ERROR_INTERNAL; } } if (sc_ui_lib_handle == NULL) return 0; *ret = lt_dlsym(sc_ui_lib_handle, name); return *ret ? SC_SUCCESS : SC_ERROR_UNKNOWN; }
int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize) { char *homedir; const char *cache_dir; scconf_block *conf_block = NULL; #ifdef _WIN32 char temp_path[PATH_MAX]; #endif conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); cache_dir = scconf_get_str(conf_block, "file_cache_dir", NULL); if (cache_dir != NULL) { if (bufsize <= strlen(cache_dir)) return SC_ERROR_BUFFER_TOO_SMALL; strcpy(buf, cache_dir); return SC_SUCCESS; } #ifndef _WIN32 cache_dir = ".eid/cache"; homedir = getenv("HOME"); #else cache_dir = "eid-cache"; homedir = getenv("USERPROFILE"); /* If USERPROFILE isn't defined, assume it's a single-user OS * and put the cache dir in the Windows dir (usually C:\\WINDOWS) */ if (homedir == NULL || homedir[0] == '\0') { GetWindowsDirectoryA(temp_path, sizeof(temp_path)); homedir = temp_path; } #endif if (homedir == NULL) return SC_ERROR_INTERNAL; if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0) return SC_ERROR_BUFFER_TOO_SMALL; return SC_SUCCESS; }
static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf) { sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; sc_pkcs15emu_opt_t opts; void *handle = NULL; int (*init_func)(sc_pkcs15_card_t *); int (*init_func_ex)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); int r, force = 0; const char *driver, *module_name; driver = conf->name->data; init_func = NULL; init_func_ex = NULL; memset(&opts, 0, sizeof(opts)); opts.blk = conf; if (force != 0) opts.flags = SC_PKCS15EMU_FLAGS_NO_CHECK; module_name = scconf_get_str(conf, "module", builtin_name); if (!strcmp(module_name, "builtin")) { int i; /* This function is built into libopensc itself. * Look it up in the table of emulators */ module_name = driver; for (i = 0; builtin_emulators[i].name; i++) { if (!strcmp(builtin_emulators[i].name, module_name)) { init_func_ex = builtin_emulators[i].handler; break; } } } else { const char *(*get_version)(void); const char *name = NULL; void *address; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Loading %s\n", module_name); /* try to open dynamic library */ handle = sc_dlopen(module_name); if (!handle) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to open dynamic library '%s': %s\n", module_name, sc_dlerror()); return SC_ERROR_INTERNAL; } /* try to get version of the driver/api */ get_version = (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version"); if (!get_version || strcmp(get_version(), "0.9.3") < 0) { /* no sc_driver_version function => assume old style * init function (note: this should later give an error */ /* get the init function name */ name = scconf_get_str(conf, "function", func_name); address = sc_dlsym(handle, name); if (address) init_func = (int (*)(sc_pkcs15_card_t *)) address; } else { name = scconf_get_str(conf, "function", exfunc_name); address = sc_dlsym(handle, name); if (address) init_func_ex = (int (*)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *)) address; } } /* try to initialize the pkcs15 structures */ if (init_func_ex) r = init_func_ex(p15card, &opts); else if (init_func) r = init_func(p15card); else r = SC_ERROR_WRONG_CARD; if (r >= 0) { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s succeeded, card bound\n", module_name); p15card->dll_handle = handle; } else { sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s failed: %s\n", module_name, sc_strerror(r)); /* clear pkcs15 card */ sc_pkcs15_card_clear(p15card); if (handle) sc_dlclose(handle); } return r; }
/* get SM related configuration settings and initialize SM session, SM module, ... */ static int sc_card_sm_check(struct sc_card *card) { const char *sm = NULL, *module_name = NULL, *module_path = NULL, *module_data = NULL, *sm_mode = NULL; struct sc_context *ctx = card->ctx; scconf_block *atrblock = NULL, *sm_conf_block = NULL; int rv, ii; LOG_FUNC_CALLED(ctx); /* get the name of card specific SM configuration section */ atrblock = _sc_match_atr_block(ctx, card->driver, &card->atr); if (atrblock == NULL) LOG_FUNC_RETURN(ctx, SC_SUCCESS); sm = scconf_get_str(atrblock, "secure_messaging", NULL); if (!sm) LOG_FUNC_RETURN(ctx, SC_SUCCESS); /* get SM configuration section by the name */ sc_log(ctx, "secure_messaging configuration block '%s'", sm); for (ii = 0; ctx->conf_blocks[ii]; ii++) { scconf_block **blocks; blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm); if (blocks) { sm_conf_block = blocks[0]; free(blocks); } if (sm_conf_block != NULL) break; } if (!sm_conf_block) LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "SM configuration block not preset"); /* check if an external SM module has to be used */ module_path = scconf_get_str(sm_conf_block, "module_path", DEFAULT_SM_MODULE_PATH); module_name = scconf_get_str(sm_conf_block, "module_name", DEFAULT_SM_MODULE); sc_log(ctx, "SM module '%s' in '%s'", module_name, module_path); if (!module_name) LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "Invalid SM configuration: module not defined"); rv = sc_card_sm_load(card, module_path, module_name); LOG_TEST_RET(ctx, rv, "Failed to load SM module"); strlcpy(card->sm_ctx.module.filename, module_name, sizeof(card->sm_ctx.module.filename)); strlcpy(card->sm_ctx.config_section, sm, sizeof(card->sm_ctx.config_section)); /* allocate resources for the external SM module */ if (card->sm_ctx.module.ops.module_init) { module_data = scconf_get_str(sm_conf_block, "module_data", NULL); rv = card->sm_ctx.module.ops.module_init(ctx, module_data); LOG_TEST_RET(ctx, rv, "Cannot initialize SM module"); } /* initialize SM session in the case of 'APDU TRANSMIT' SM mode */ sm_mode = scconf_get_str(sm_conf_block, "mode", NULL); if (sm_mode && !strcasecmp("Transmit", sm_mode)) { if (!card->sm_ctx.ops.open || !card->sm_ctx.ops.get_sm_apdu || !card->sm_ctx.ops.free_sm_apdu) LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "'Transmit' SM asked but not supported by card driver"); card->sm_ctx.sm_mode = SM_MODE_TRANSMIT; rv = card->sm_ctx.ops.open(card); LOG_TEST_RET(ctx, rv, "Cannot initialize SM"); } sc_log(ctx, "SM mode:%X", card->sm_ctx.sm_mode); SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv); }
static int read_config(scconf_block *blk) { int debug = scconf_get_bool(blk,"debug",0); const char *ssltls; ldaphost = scconf_get_str(blk,"ldaphost",ldaphost); ldapport = scconf_get_int(blk,"ldapport",ldapport); ldapURI = scconf_get_str(blk,"uri",ldapURI); scope = scconf_get_int(blk,"scope",scope); binddn = scconf_get_str(blk,"binddn",binddn); passwd = scconf_get_str(blk,"passwd",passwd); base = scconf_get_str(blk,"base",base); attribute = scconf_get_str(blk,"attribute",attribute); filter = scconf_get_str(blk,"filter",filter); ignorecase = scconf_get_bool(blk,"ignorecase",ignorecase); searchtimeout = scconf_get_int(blk,"searchtimeout",searchtimeout); ssltls = scconf_get_str(blk,"ssl","off"); if (! strncasecmp (ssltls, "tls", 3)) ssl_on = SSL_START_TLS; else if( ! strncasecmp (ssltls, "on", 2)) ssl_on = SSL_LDAPS; else if( ! strncasecmp (ssltls, "ssl", 3)) ssl_on = SSL_LDAPS; #if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) /* TLS specific options */ tls_randfile = scconf_get_str(blk,"tls_randfile",tls_randfile); tls_cacertfile = scconf_get_str(blk,"tls_cacertfile",tls_cacertfile); tls_cacertdir = scconf_get_str(blk,"tls_cacertdir",tls_cacertdir); tls_checkpeer=scconf_get_int(blk,"tls_checkpeer",tls_checkpeer); tls_ciphers = scconf_get_str(blk,"tls_ciphers",tls_ciphers); tls_cert = scconf_get_str(blk,"tls_cert",tls_cert); tls_key = scconf_get_str(blk,"tls_key",tls_key); #endif set_debug_level(debug); DBG1("test ssltls = %s", ssltls); DBG("LDAP mapper started."); DBG1("debug = %d", debug); DBG1("ignorecase = %d", ignorecase); DBG1("ldaphost = %s", ldaphost); DBG1("ldapport = %d", ldapport); DBG1("ldapURI = %s", ldapURI); DBG1("scope = %d", scope); DBG1("binddn = %s", binddn); DBG1("passwd = %s", passwd); DBG1("base = %s", base); DBG1("attribute = %s", attribute); DBG1("filter = %s", filter); DBG1("searchtimeout = %d", searchtimeout); DBG1("ssl_on = %d", ssl_on); #if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)) DBG1("tls_randfile = %s", tls_randfile); DBG1("tls_cacertfile= %s", tls_cacertfile); DBG1("tls_cacertdir = %s", tls_cacertdir); DBG1("tls_checkpeer = %d", tls_checkpeer); DBG1("tls_ciphers = %s", tls_ciphers); DBG1("tls_cert = %s", tls_cert); DBG1("tls_key = %s", tls_key); #endif return 1; }
static int pcsc_init(sc_context_t *ctx, void **reader_data) { struct pcsc_global_private_data *gpriv; scconf_block *conf_block = NULL; int ret = SC_ERROR_INTERNAL; *reader_data = NULL; gpriv = (struct pcsc_global_private_data *) calloc(1, sizeof(struct pcsc_global_private_data)); if (gpriv == NULL) { ret = SC_ERROR_OUT_OF_MEMORY; goto out; } /* Defaults */ gpriv->connect_reset = 1; gpriv->connect_exclusive = 0; gpriv->transaction_reset = 0; gpriv->enable_pinpad = 0; gpriv->provider_library = DEFAULT_PCSC_PROVIDER; gpriv->pcsc_ctx = -1; conf_block = sc_get_conf_block(ctx, "reader_driver", "pcsc", 1); if (conf_block) { gpriv->connect_reset = scconf_get_bool(conf_block, "connect_reset", gpriv->connect_reset); gpriv->connect_exclusive = scconf_get_bool(conf_block, "connect_exclusive", gpriv->connect_exclusive); gpriv->transaction_reset = scconf_get_bool(conf_block, "transaction_reset", gpriv->transaction_reset); gpriv->enable_pinpad = scconf_get_bool(conf_block, "enable_pinpad", gpriv->enable_pinpad); gpriv->provider_library = scconf_get_str(conf_block, "provider_library", gpriv->provider_library); } gpriv->dlhandle = lt_dlopen(gpriv->provider_library); if (gpriv->dlhandle == NULL) { ret = SC_ERROR_CANNOT_LOAD_MODULE; goto out; } gpriv->SCardEstablishContext = (SCardEstablishContext_t)lt_dlsym(gpriv->dlhandle, "SCardEstablishContext"); gpriv->SCardReleaseContext = (SCardReleaseContext_t)lt_dlsym(gpriv->dlhandle, "SCardReleaseContext"); gpriv->SCardConnect = (SCardConnect_t)lt_dlsym(gpriv->dlhandle, "SCardConnect"); gpriv->SCardReconnect = (SCardReconnect_t)lt_dlsym(gpriv->dlhandle, "SCardReconnect"); gpriv->SCardDisconnect = (SCardDisconnect_t)lt_dlsym(gpriv->dlhandle, "SCardDisconnect"); gpriv->SCardBeginTransaction = (SCardBeginTransaction_t)lt_dlsym(gpriv->dlhandle, "SCardBeginTransaction"); gpriv->SCardEndTransaction = (SCardEndTransaction_t)lt_dlsym(gpriv->dlhandle, "SCardEndTransaction"); gpriv->SCardStatus = (SCardStatus_t)lt_dlsym(gpriv->dlhandle, "SCardStatus"); gpriv->SCardGetStatusChange = (SCardGetStatusChange_t)lt_dlsym(gpriv->dlhandle, "SCardGetStatusChange"); gpriv->SCardTransmit = (SCardTransmit_t)lt_dlsym(gpriv->dlhandle, "SCardTransmit"); gpriv->SCardListReaders = (SCardListReaders_t)lt_dlsym(gpriv->dlhandle, "SCardListReaders"); if (gpriv->SCardConnect == NULL) gpriv->SCardConnect = (SCardConnect_t)lt_dlsym(gpriv->dlhandle, "SCardConnectA"); if (gpriv->SCardStatus == NULL) gpriv->SCardStatus = (SCardStatus_t)lt_dlsym(gpriv->dlhandle, "SCardStatusA"); if (gpriv->SCardGetStatusChange == NULL) gpriv->SCardGetStatusChange = (SCardGetStatusChange_t)lt_dlsym(gpriv->dlhandle, "SCardGetStatusChangeA"); if (gpriv->SCardListReaders == NULL) gpriv->SCardListReaders = (SCardListReaders_t)lt_dlsym(gpriv->dlhandle, "SCardListReadersA"); /* If we have SCardGetAttrib it is correct API */ if (lt_dlsym(gpriv->dlhandle, "SCardGetAttrib") != NULL) { #ifdef __APPLE__ gpriv->SCardControl = (SCardControl_t)lt_dlsym(gpriv->dlhandle, "SCardControl132"); #endif if (gpriv->SCardControl == NULL) { gpriv->SCardControl = (SCardControl_t)lt_dlsym(gpriv->dlhandle, "SCardControl"); } } else { gpriv->SCardControlOLD = (SCardControlOLD_t)lt_dlsym(gpriv->dlhandle, "SCardControl"); } if ( gpriv->SCardReleaseContext == NULL || gpriv->SCardConnect == NULL || gpriv->SCardReconnect == NULL || gpriv->SCardDisconnect == NULL || gpriv->SCardBeginTransaction == NULL || gpriv->SCardEndTransaction == NULL || gpriv->SCardStatus == NULL || gpriv->SCardGetStatusChange == NULL || (gpriv->SCardControl == NULL && gpriv->SCardControlOLD == NULL) || gpriv->SCardTransmit == NULL || gpriv->SCardListReaders == NULL ) { ret = SC_ERROR_CANNOT_LOAD_MODULE; goto out; } *reader_data = gpriv; gpriv = NULL; ret = SC_SUCCESS; out: if (gpriv != NULL) { if (gpriv->dlhandle != NULL) lt_dlclose(gpriv->dlhandle); free(gpriv); } return ret; }
static int load_card_atrs(sc_context_t *ctx) { struct sc_card_driver *driver; scconf_block **blocks; int i, j, k; for (i = 0; ctx->conf_blocks[i] != NULL; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_atr", NULL); if (!blocks) continue; for (j = 0; blocks[j] != NULL; j++) { scconf_block *b = blocks[j]; char *atr = b->name->data; const scconf_list *list; struct sc_atr_table t; const char *dname; driver = NULL; if (strlen(atr) < 4) continue; /* The interesting part. If there's no card * driver assigned for the ATR, add it to * the default driver. This will reduce the * amount of code required to process things * related to card_atr blocks in situations, * where the code is not exactly related to * card driver settings, but for example * forcing a protocol at the reader driver. */ dname = scconf_get_str(b, "driver", "default"); /* Find the card driver structure according to dname */ for (k = 0; ctx->card_drivers[k] != NULL; k++) { driver = ctx->card_drivers[k]; if (!strcmp(dname, driver->short_name)) break; driver = NULL; } if (!driver) continue; memset(&t, 0, sizeof(struct sc_atr_table)); t.atr = atr; t.atrmask = (char *) scconf_get_str(b, "atrmask", NULL); t.name = (char *) scconf_get_str(b, "name", NULL); t.type = scconf_get_int(b, "type", SC_CARD_TYPE_UNKNOWN); list = scconf_find_list(b, "flags"); while (list != NULL) { unsigned int flags; if (!list->data) { list = list->next; continue; } flags = 0; if (!strcmp(list->data, "rng")) { flags = SC_CARD_FLAG_RNG; } else { if (sscanf(list->data, "%x", &flags) != 1) flags = 0; } t.flags |= flags; list = list->next; } t.card_atr = b; _sc_add_atr(ctx, driver, &t); } free(blocks); } return SC_SUCCESS; }
/** * find library module for provided driver in configuration file * if not found assume library name equals to module name */ static const char *find_library(sc_context_t *ctx, const char *name) { int i; const char *libname = NULL; scconf_block **blocks, *blk; for (i = 0; ctx->conf_blocks[i]; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", name); if (!blocks) continue; blk = blocks[0]; free(blocks); if (blk == NULL) continue; libname = scconf_get_str(blk, "module", name); #ifdef _WIN32 if (libname && libname[0] != '\\' ) { #else if (libname && libname[0] != '/' ) { #endif sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "warning: relative path to driver '%s' used", libname); } break; } return libname; } /** * load card/reader driver modules * Every module should contain a function " void * sc_module_init(char *) " * that returns a pointer to the function _sc_get_xxxx_driver() * used to initialize static modules * Also, an exported "char *sc_module_version" variable should exist in module */ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name) { const char *version, *libname; void *handle; void *(*modinit)(const char *) = NULL; void *(**tmodi)(const char *) = &modinit; const char *(*modversion)(void) = NULL; const char *(**tmodv)(void) = &modversion; if (name == NULL) { /* should not occurr, but... */ sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"No module specified",name); return NULL; } libname = find_library(ctx, name); if (libname == NULL) return NULL; handle = sc_dlopen(libname); if (handle == NULL) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Module %s: cannot load %s library: %s", name, libname, sc_dlerror()); return NULL; } /* verify correctness of module */ *(void **)tmodi = sc_dlsym(handle, "sc_module_init"); *(void **)tmodv = sc_dlsym(handle, "sc_driver_version"); if (modinit == NULL || modversion == NULL) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "dynamic library '%s' is not a OpenSC module",libname); sc_dlclose(handle); return NULL; } /* verify module version */ version = modversion(); /* XXX: We really need to have ABI version for each interface */ if (version == NULL || strncmp(version, PACKAGE_VERSION, strlen(PACKAGE_VERSION)) != 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL,"dynamic library '%s': invalid module version",libname); sc_dlclose(handle); return NULL; } *dll = handle; sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "successfully loaded card driver '%s'", name); return modinit(name); } static int load_card_driver_options(sc_context_t *ctx, struct sc_card_driver *driver) { scconf_block **blocks, *blk; int i; for (i = 0; ctx->conf_blocks[i]; i++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", driver->short_name); if (!blocks) continue; blk = blocks[0]; free(blocks); if (blk == NULL) continue; /* no options at the moment */ } return SC_SUCCESS; }
static int parse_type(const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth) { void *parm = entry->parm; size_t *len = (size_t *) entry->arg; int (*callback_func) (const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth) = (int (*)(const scconf_context *, const scconf_block *, scconf_entry *, int)) parm; int r = 0; if (config->debug) { fprintf(stderr, "decoding '%s'\n", entry->name); } switch (entry->type) { case SCCONF_CALLBACK: if (parm) { r = callback_func(config, block, entry, depth); } break; case SCCONF_BLOCK: if (parm) { r = parse_entries(config, block, (scconf_entry *) parm, depth + 1); } break; case SCCONF_LIST: { const scconf_list *val = scconf_find_list(block, entry->name); if (!val) { r = 1; break; } if (parm) { if (entry->flags & SCCONF_ALLOC) { scconf_list *dest = NULL; for (; val != NULL; val = val->next) { if (!scconf_list_add(&dest, val->data)) { r = 1; break; } } *((scconf_list **) parm) = dest; } else { *((const scconf_list **) parm) = val; } } if (entry->flags & SCCONF_VERBOSE) { char *buf = scconf_list_strdup(val, ", "); printf("%s = %s\n", entry->name, buf); free(buf); } } break; case SCCONF_BOOLEAN: { int val = scconf_get_bool(block, entry->name, 0); if (parm) { *((int *) parm) = val; } if (entry->flags & SCCONF_VERBOSE) { printf("%s = %s\n", entry->name, val == 0 ? "false" : "true"); } } break; case SCCONF_INTEGER: { int val = scconf_get_int(block, entry->name, 0); if (parm) { *((int *) parm) = val; } if (entry->flags & SCCONF_VERBOSE) { printf("%s = %i\n", entry->name, val); } } break; case SCCONF_STRING: { const char *val = scconf_get_str(block, entry->name, NULL); int vallen = val ? strlen(val) : 0; if (!vallen) { r = 1; break; } if (parm) { if (entry->flags & SCCONF_ALLOC) { char **buf = (char **) parm; *buf = malloc(vallen + 1); if (*buf == NULL) { r = 1; break; } memset(*buf, 0, vallen + 1); if (len) { *len = vallen; } parm = *buf; } memcpy((char *) parm, val, vallen); } if (entry->flags & SCCONF_VERBOSE) { printf("%s = %s\n", entry->name, val); } } break; default: fprintf(stderr, "invalid configuration type: %d\n", entry->type); } if (r) { fprintf(stderr, "decoding of configuration entry '%s' failed.\n", entry->name); return r; } entry->flags |= SCCONF_PRESENT; return 0; }
static int parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen, int rec_nr) { struct sc_context *ctx = card->ctx; struct sc_asn1_entry asn1_dirrecord[5], asn1_dir[2]; scconf_block *conf_block = NULL; sc_app_info_t *app = NULL; struct sc_aid aid; u8 label[128], path[128], ddo[128]; size_t label_len = sizeof(label) - 1, path_len = sizeof(path), ddo_len = sizeof(ddo); int r; LOG_FUNC_CALLED(ctx); aid.len = sizeof(aid.value); memset(label, 0, sizeof(label)); sc_copy_asn1_entry(c_asn1_dirrecord, asn1_dirrecord); sc_copy_asn1_entry(c_asn1_dir, asn1_dir); sc_format_asn1_entry(asn1_dir + 0, asn1_dirrecord, NULL, 0); sc_format_asn1_entry(asn1_dirrecord + 0, aid.value, &aid.len, 0); sc_format_asn1_entry(asn1_dirrecord + 1, label, &label_len, 0); sc_format_asn1_entry(asn1_dirrecord + 2, path, &path_len, 0); sc_format_asn1_entry(asn1_dirrecord + 3, ddo, &ddo_len, 0); r = sc_asn1_decode(ctx, asn1_dir, *buf, *buflen, (const u8 **) buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) LOG_FUNC_RETURN(ctx, r); LOG_TEST_RET(ctx, r, "EF(DIR) parsing failed"); conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); if (conf_block) { scconf_block **blocks = NULL; char aid_str[SC_MAX_AID_STRING_SIZE]; int ignore_app = 0; sc_bin_to_hex(aid.value, aid.len, aid_str, sizeof(aid_str), 0); blocks = scconf_find_blocks(card->ctx->conf, conf_block, "application", aid_str); if (blocks) { ignore_app = (blocks[0] && scconf_get_str(blocks[0], "disable", 0)); free(blocks); } if (ignore_app) { sc_log(ctx, "Application '%s' ignored", aid_str); LOG_FUNC_RETURN(ctx, SC_SUCCESS); } } app = calloc(1, sizeof(struct sc_app_info)); if (app == NULL) LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY); memcpy(&app->aid, &aid, sizeof(struct sc_aid)); if (asn1_dirrecord[1].flags & SC_ASN1_PRESENT) app->label = strdup((char *) label); else app->label = NULL; if (asn1_dirrecord[2].flags & SC_ASN1_PRESENT && path_len > 0) { /* application path present: ignore AID */ if (path_len > SC_MAX_PATH_SIZE) { free(app); LOG_TEST_RET(ctx, SC_ERROR_INVALID_ASN1_OBJECT, "Application path is too long."); } memcpy(app->path.value, path, path_len); app->path.len = path_len; app->path.type = SC_PATH_TYPE_PATH; } else { /* application path not present: use AID as application path */ memcpy(app->path.value, aid.value, aid.len); app->path.len = aid.len; app->path.type = SC_PATH_TYPE_DF_NAME; } if (asn1_dirrecord[3].flags & SC_ASN1_PRESENT) { app->ddo.value = malloc(ddo_len); if (app->ddo.value == NULL) { free(app); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate DDO value"); } memcpy(app->ddo.value, ddo, ddo_len); app->ddo.len = ddo_len; } else { app->ddo.value = NULL; app->ddo.len = 0; } app->rec_nr = rec_nr; card->app[card->app_count] = app; card->app_count++; LOG_FUNC_RETURN(ctx, SC_SUCCESS); }
static int sm_cwa_config_get_keyset(struct sc_context *ctx, struct sm_info *sm_info) { struct sm_cwa_session *cwa_session = &sm_info->session.cwa; struct sm_cwa_keyset *cwa_keyset = &sm_info->session.cwa.cwa_keyset; scconf_block *sm_conf_block = NULL, **blocks; struct sc_crt *crt_at = &sm_info->session.cwa.params.crt_at; const char *value = NULL; char name[128]; unsigned char hex[48]; size_t hex_len = sizeof(hex); int rv, ii, ref = crt_at->refs[0] & IASECC_OBJECT_REF_MAX; for (ii = 0; ctx->conf_blocks[ii]; ii++) { blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm_info->config_section); if (blocks) { sm_conf_block = blocks[0]; free(blocks); } if (sm_conf_block) break; } sc_log(ctx, "CRT(algo:%X,ref:%X)", crt_at->algo, crt_at->refs[0]); /* Keyset ENC */ if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL)) snprintf(name, sizeof(name), "keyset_%s_%02i_enc", sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref); else snprintf(name, sizeof(name), "keyset_%02i_enc", ref); value = scconf_get_str(sm_conf_block, name, NULL); if (!value) { sc_log(ctx, "No %s value in OpenSC config", name); return SC_ERROR_SM_KEYSET_NOT_FOUND; } sc_log(ctx, "keyset::enc(%i) %s", strlen(value), value); if (strlen(value) == 16) { memcpy(cwa_keyset->enc, value, 16); } else { hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { sc_log(ctx, "SM get %s: hex to bin failed for '%s'; error %i", name, value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } sc_log(ctx, "ENC(%i) %s", hex_len, sc_dump_hex(hex, hex_len)); if (hex_len != 16) return SC_ERROR_INVALID_DATA; memcpy(cwa_keyset->enc, hex, hex_len); } sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->enc, 16)); /* Keyset MAC */ if (sm_info->current_aid.len && (crt_at->refs[0] & IASECC_OBJECT_REF_LOCAL)) snprintf(name, sizeof(name), "keyset_%s_%02i_mac", sc_dump_hex(sm_info->current_aid.value, sm_info->current_aid.len), ref); else snprintf(name, sizeof(name), "keyset_%02i_mac", ref); value = scconf_get_str(sm_conf_block, name, NULL); if (!value) { sc_log(ctx, "No %s value in OpenSC config", name); return SC_ERROR_SM_KEYSET_NOT_FOUND; } sc_log(ctx, "keyset::mac(%i) %s", strlen(value), value); if (strlen(value) == 16) { memcpy(cwa_keyset->mac, value, 16); } else { hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { sc_log(ctx, "SM get '%s': hex to bin failed for '%s'; error %i", name, value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } sc_log(ctx, "MAC(%i) %s", hex_len, sc_dump_hex(hex, hex_len)); if (hex_len != 16) return SC_ERROR_INVALID_DATA; memcpy(cwa_keyset->mac, hex, hex_len); } sc_log(ctx, "%s %s", name, sc_dump_hex(cwa_keyset->mac, 16)); cwa_keyset->sdo_reference = crt_at->refs[0]; /* IFD parameters */ //memset(cwa_session, 0, sizeof(struct sm_cwa_session)); value = scconf_get_str(sm_conf_block, "ifd_serial", NULL); if (!value) return SC_ERROR_SM_IFD_DATA_MISSING; hex_len = sizeof(hex); rv = sc_hex_to_bin(value, hex, &hex_len); if (rv) { sc_log(ctx, "SM get 'ifd_serial': hex to bin failed for '%s'; error %i", value, rv); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } if (hex_len != sizeof(cwa_session->ifd.sn)) { sc_log(ctx, "SM get 'ifd_serial': invalid IFD serial length: %i", hex_len); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } memcpy(cwa_session->ifd.sn, hex, hex_len); rv = RAND_bytes(cwa_session->ifd.rnd, 8); if (!rv) { sc_log(ctx, "Generate random error: %i", rv); return SC_ERROR_SM_RAND_FAILED; } rv = RAND_bytes(cwa_session->ifd.k, 32); if (!rv) { sc_log(ctx, "Generate random error: %i", rv); return SC_ERROR_SM_RAND_FAILED; } sc_log(ctx, "IFD.Serial: %s", sc_dump_hex(cwa_session->ifd.sn, sizeof(cwa_session->ifd.sn))); sc_log(ctx, "IFD.Rnd: %s", sc_dump_hex(cwa_session->ifd.rnd, sizeof(cwa_session->ifd.rnd))); sc_log(ctx, "IFD.K: %s", sc_dump_hex(cwa_session->ifd.k, sizeof(cwa_session->ifd.k))); return SC_SUCCESS; }
static int belpic_init(sc_card_t *card) { struct belpic_priv_data *priv = NULL; scconf_block *conf_block; #ifdef BELPIC_PIN_PAD int r; #endif sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Belpic V%s", BELPIC_VERSION); #ifdef HAVE_GUI sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with GUI support"); #endif #ifdef BELPIC_PIN_PAD sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with support for pin pad reader libs"); #endif sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "\n"); if (card->type < 0) card->type = SC_CARD_TYPE_BELPIC_EID; /* Unknown card: assume it's the Belpic Card */ priv = calloc(1, sizeof(struct belpic_priv_data)); if (priv == NULL) return SC_ERROR_OUT_OF_MEMORY; card->drv_data = priv; card->cla = 0x00; if (card->type == SC_CARD_TYPE_BELPIC_EID) { _sc_card_add_rsa_alg(card, 1024, SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0); } /* V1 applets have a problem: if the card sends a 6C XX (only XX bytes available), * and we resend the command too soon (i.e. the reader is too fast), the card * doesn't respond. So we build in a delay. */ card->wait_resend_apdu = 40; /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG; /* State that we don't return FCI (no file type, no file size, ...) */ card->caps |= SC_CARD_CAP_NO_FCI; /* Language prefences */ priv->lang = -1; conf_block = get_belpic_conf(card->ctx, "belpic_general"); if (conf_block != NULL) { char *lang = (char *) scconf_get_str(conf_block, "force_language", NULL); if (lang != NULL && strlen(lang) == 2) priv->lang = str2lang(card->ctx, lang); } #ifdef GET_LANG_FROM_CARD if (priv->lang == -1) priv->lang = get_language(card); #endif card->max_pin_len = BELPIC_MAX_USER_PIN_LEN; #ifdef HAVE_GUI r = scgui_init(); if (r != 0) sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_init() returned error %d\n", i); #endif #ifdef BELPIC_PIN_PAD r = belpic_detect_pin_pad(card, priv); if (r == 1) card->reader->capabilities |= SC_READER_CAP_PIN_PAD; else if (r < 0) return r; /* error loading/initing pin pad lib */ conf_block = get_belpic_conf(card->ctx, "belpic_pin_pad"); if (conf_block != NULL) { if (scconf_get_bool(conf_block, "msg_auth_pin", 1)) priv->options |= PP_MSG_AUTH_PIN; if (scconf_get_bool(conf_block, "msg_wrong_pin", 1)) priv->options |= PP_MSG_WRONG_PIN; if (scconf_get_bool(conf_block, "msg_changepin_mismatch", 1)) priv->options |= PP_MSG_CHANGEPIN_MISMATCH; if (scconf_get_bool(conf_block, "msg_pin_blocked", 1)) priv->options |= PP_MSG_PIN_BLOCKED; } #endif return 0; }
void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx) { scconf_block *conf_block = NULL; char *unblock_style = NULL; char *create_slots_for_pins = NULL, *op, *tmp; /* Set defaults */ conf->plug_and_play = 1; conf->max_virtual_slots = 16; if (strcmp(ctx->app_name, "onepin-opensc-pkcs11") == 0) { conf->slots_per_card = 1; } else { conf->slots_per_card = 4; } conf->hide_empty_tokens = 1; conf->lock_login = 0; conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED; conf->create_puk_slot = 0; conf->zero_ckaid_for_ca_certs = 0; conf->create_slots_flags = SC_PKCS11_SLOT_CREATE_ALL; conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1); if (!conf_block) return; /* contains the defaults, if there is a "pkcs11" config block */ conf->plug_and_play = scconf_get_bool(conf_block, "plug_and_play", conf->plug_and_play); conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots); conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card); conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens); conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login); unblock_style = (char *)scconf_get_str(conf_block, "user_pin_unblock_style", NULL); if (unblock_style && !strcmp(unblock_style, "set_pin_in_unlogged_session")) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN; else if (unblock_style && !strcmp(unblock_style, "set_pin_in_specific_context")) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN; else if (unblock_style && !strcmp(unblock_style, "init_pin_in_so_session")) conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN; conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot); conf->zero_ckaid_for_ca_certs = scconf_get_bool(conf_block, "zero_ckaid_for_ca_certs", conf->zero_ckaid_for_ca_certs); create_slots_for_pins = (char *)scconf_get_str(conf_block, "create_slots_for_pins", "all"); conf->create_slots_flags = 0; tmp = strdup(create_slots_for_pins); op = strtok(tmp, " ,"); while (op) { if (!strcmp(op, "user")) conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_PIN_USER; else if (!strcmp(op, "sign")) conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_PIN_SIGN; else if (!strcmp(op, "application")) conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_APPLICATION; else if (!strcmp(op, "all")) conf->create_slots_flags |= SC_PKCS11_SLOT_CREATE_ALL; op = strtok(NULL, " ,"); } free(tmp); sc_log(ctx, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d " "hide_empty_tokens=%d lock_login=%d pin_unblock_style=%d " "zero_ckaid_for_ca_certs=%d create_slots_flags=0x%X", conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card, conf->hide_empty_tokens, conf->lock_login, conf->pin_unblock_style, conf->zero_ckaid_for_ca_certs, conf->create_slots_flags); }
static int set_default_module(const char *mod) { scconf_block *pam_pkcs11, *pkcs11_eventmgr; scconf_block **modules = NULL; scconf_context *ctx = NULL; scconf_context *ectx = NULL; const char *lib = NULL; int result = 1; /* * write out pam_pkcs11.conf */ ctx = scconf_new(PAM_PKCS11_CONF); if (ctx == NULL) { goto bail; } if (scconf_parse(ctx) <= 0) { goto bail; } pam_pkcs11 = (scconf_block *)scconf_find_block(ctx, NULL, "pam_pkcs11"); if (!pam_pkcs11) { goto bail; } scconf_replace_str(pam_pkcs11, "use_pkcs11_module", mod); modules = scconf_find_blocks(ctx, pam_pkcs11, "pkcs11_module", mod); if (!modules || !modules[0]) { goto bail; } lib = scconf_get_str(modules[0], "module", NULL); if (!lib) { goto bail; } result = scconf_write(ctx, NULL); if (result != 0) { goto bail; } ectx = scconf_new(EVENTMGR_CONF); if (ectx == NULL) { goto bail; } if (scconf_parse(ectx) <= 0) { goto bail; } pkcs11_eventmgr = (scconf_block *) scconf_find_block(ectx, NULL, "pkcs11_eventmgr"); if (!pkcs11_eventmgr) { goto bail; } scconf_replace_str(pkcs11_eventmgr, "pkcs11_module", lib); result = scconf_write(ectx, NULL); bail: if (modules) { free(modules); } if (ctx) { scconf_free(ctx); } if (ectx) { scconf_free(ectx); } return result; }