Beispiel #1
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, *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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
/**
 * 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;
}
Beispiel #6
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
/**
 * 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;
}
Beispiel #10
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, *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;
}
Beispiel #11
0
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;
}
Beispiel #12
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;
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
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;
}
Beispiel #17
0
/*
 * 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;
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
/* 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);
}
Beispiel #21
0
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
/**
 * 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;
}
Beispiel #25
0
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;
}
Beispiel #26
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);
}
Beispiel #27
0
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;
}
Beispiel #28
0
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;
}
Beispiel #29
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);
}
Beispiel #30
0
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;
}