Ejemplo n.º 1
0
static int ctapi_init(sc_context_t *ctx)
{
	int i;
	struct ctapi_global_private_data *gpriv;
	scconf_block **blocks = NULL, *conf_block = NULL;

	gpriv = calloc(1, sizeof(struct ctapi_global_private_data));
	if (gpriv == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	ctx->reader_drv_data = gpriv;
	
	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
					    "reader_driver", "ctapi");
		if (blocks && blocks[0])
			conf_block = blocks[0];
		free(blocks);
		if (conf_block != NULL)
			break;
	}
	if (conf_block == NULL)
		return 0;
	blocks = scconf_find_blocks(ctx->conf, conf_block, "module", NULL);
	for (i = 0; blocks != NULL && blocks[i] != NULL; i++)
		ctapi_load_module(ctx, gpriv, blocks[i]);
	free(blocks);
	
	return 0;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
Archivo: ctx.c Proyecto: velter/OpenSC
/**
 * 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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
static int print_card_remove_action(void)
{
    const scconf_block *pkcs11_eventmgr;
    scconf_block **event_blocks = NULL;
    scconf_context *ctx = NULL;
    const scconf_list *actionList = NULL;
    int result = 1;

    /*
     * read the pkcs11_eventmgr.conf to get our action
     */
    ctx = scconf_new(EVENTMGR_CONF);
    if (ctx == NULL) {
        goto bail;
    }
    if (scconf_parse(ctx) <= 0) {
        goto bail;
    }
    pkcs11_eventmgr = scconf_find_block(ctx, NULL, "pkcs11_eventmgr");
    if (!pkcs11_eventmgr) {
        goto bail;
    }
    event_blocks = scconf_find_blocks(ctx, pkcs11_eventmgr, "event",
                                      "card_remove");
    if (!event_blocks || !event_blocks[0]) {
        goto bail;
    }
    actionList = scconf_find_list(event_blocks[0],"action");
    if (actionList) {
        char *lst = scconf_list_strdup(actionList, "\n");
        if (lst != NULL) {
            printf("%s\n", lst);
            free(lst);
        }
    }
    result = 0;

bail:
    if (event_blocks) {
        free(event_blocks);
    }
    if (ctx) {
        scconf_free(ctx);
    }

    return result;
}
Ejemplo n.º 8
0
static scconf_block *get_belpic_conf(sc_context_t *ctx, const char *name)
{
	scconf_block *conf_block = NULL, **blocks;
	int i;

	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], name, NULL);
		if (!blocks)
			return NULL;
		conf_block = blocks[0];
		free(blocks);
		if (conf_block != NULL)
			break;
	}

	return conf_block;
}
Ejemplo n.º 9
0
scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char *name2, int priority)
{
	int i;
	scconf_block *conf_block = NULL;

	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
		scconf_block **blocks;

		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], name1, name2);
		if (blocks != NULL) {
			conf_block = blocks[0];
			free(blocks);
		}
		if (conf_block != NULL && priority)
			break;
	}
	return conf_block;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
static int set_card_remove_action(const char *act)
{
    scconf_block *pkcs11_eventmgr;
    scconf_block **insert_blocks = NULL;
    scconf_context *ctx = NULL;
    int result = 1;

    /*
     * write out pkcs11_eventmgr.conf
     */
    ctx = scconf_new(EVENTMGR_CONF);
    if (ctx == NULL) {
        goto bail;
    }
    if (scconf_parse(ctx) <= 0) {
        goto bail;
    }
    pkcs11_eventmgr = (scconf_block *)
                      scconf_find_block(ctx, NULL, "pkcs11_eventmgr");
    if (!pkcs11_eventmgr) {
        goto bail;
    }
    insert_blocks = scconf_find_blocks(ctx, pkcs11_eventmgr,
                                       "event", "card_remove");
    if (!insert_blocks || !insert_blocks[0]) {
        goto bail;
    }

    scconf_replace_str_list(insert_blocks[0], "action", act);

    result = scconf_write(ctx, NULL);

bail:
    if (insert_blocks) {
        free(insert_blocks);
    }
    if (ctx) {
        scconf_free(ctx);
    }
    return result;
}
Ejemplo n.º 12
0
Archivo: ctx.c Proyecto: velter/OpenSC
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;
}
Ejemplo n.º 13
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);
}
Ejemplo n.º 14
0
static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
{
	int i, r, count = 0;
	scconf_block **blocks;
	const char *conf_path = NULL;
#ifdef _WIN32
	char temp_path[PATH_MAX];
	DWORD temp_len;
	long rc;
	HKEY hKey;
#endif

	memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks));
#ifdef _WIN32
	conf_path = getenv("OPENSC_CONF");
	if (!conf_path) {
		rc = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey);
		if (rc == ERROR_SUCCESS) {
			temp_len = PATH_MAX;
			rc = RegQueryValueEx( hKey, "ConfigFile", NULL, NULL, (LPBYTE) temp_path, &temp_len);
			if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
				conf_path = temp_path;
			RegCloseKey(hKey);
		}
	}

	if (!conf_path) {
		rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey );
		if (rc == ERROR_SUCCESS) {
			temp_len = PATH_MAX;
			rc = RegQueryValueEx( hKey, "ConfigFile", NULL, NULL, (LPBYTE) temp_path, &temp_len);
			if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
				conf_path = temp_path;
			RegCloseKey(hKey);
		}
	}

	if (!conf_path) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "process_config_file doesn't find opensc config file. Please set the registry key.");
		return;
	}

#else
	conf_path = getenv("OPENSC_CONF");
	if (!conf_path)
		conf_path = OPENSC_CONF_PATH;
#endif
	ctx->conf = scconf_new(conf_path);
	if (ctx->conf == NULL)
		return;
	r = scconf_parse(ctx->conf);
#ifdef OPENSC_CONFIG_STRING
	/* Parse the string if config file didn't exist */
	if (r < 0)
		r = scconf_parse_string(ctx->conf, OPENSC_CONFIG_STRING);
#endif
	if (r < 1) {
		/* A negative return value means the config file isn't
		 * there, which is not an error. Nevertheless log this
		 * fact. */
		if (r < 0)
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "scconf_parse failed: %s", ctx->conf->errmsg);
		else
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "scconf_parse failed: %s", ctx->conf->errmsg);
		scconf_free(ctx->conf);
		ctx->conf = NULL;
		return;
	}
	blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->app_name);
	if (blocks[0])
	    	ctx->conf_blocks[count++] = blocks[0];
	free(blocks);
	if (strcmp(ctx->app_name, "default") != 0) {
		blocks = scconf_find_blocks(ctx->conf, NULL, "app", "default");
		if (blocks[0])
		    	ctx->conf_blocks[count] = blocks[0];
		free(blocks);
	}
	/* Above we add 2 blocks at most, but conf_blocks has 3 elements,
	 * so at least one is NULL */
	for (i = 0; ctx->conf_blocks[i]; i++)
		load_parameters(ctx, ctx->conf_blocks[i], opts);
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
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;
}
Ejemplo n.º 17
0
int sc_pkcs15_bind(sc_card_t *card,
		   struct sc_pkcs15_card **p15card_out)
{
	struct sc_pkcs15_card *p15card = NULL;
	sc_context_t *ctx;
	scconf_block *conf_block = NULL, **blocks;
	int    i, r, emu_first, enable_emu;

	assert(sc_card_valid(card) && p15card_out != NULL);
	ctx = card->ctx;
	SC_FUNC_CALLED(ctx, 1);
	p15card = sc_pkcs15_card_new();
	if (p15card == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	p15card->card = card;

	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
			"framework", "pkcs15");
		if (blocks && blocks[0] != NULL)
			conf_block = blocks[0];
		free(blocks);
	}

	if (conf_block) {
		p15card->opts.use_cache = scconf_get_bool(conf_block, "use_caching", 0);
	}

	r = sc_lock(card);
	if (r) {
		sc_error(ctx, "sc_lock() failed: %s\n", sc_strerror(r));
		sc_pkcs15_card_free(p15card);
		SC_FUNC_RETURN(ctx, 1, r);
	}

	enable_emu = scconf_get_bool(conf_block, "enable_pkcs15_emulation", 1);
	if (enable_emu) {
		emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
		if (emu_first || sc_pkcs15_is_emulation_only(card)) {
			r = sc_pkcs15_bind_synthetic(p15card);
			if (r == SC_SUCCESS)
				goto done;
			r = sc_pkcs15_bind_internal(p15card);
			if (r < 0)
				goto error;
		} else {
			r = sc_pkcs15_bind_internal(p15card);
			if (r == SC_SUCCESS)
				goto done;
			r = sc_pkcs15_bind_synthetic(p15card);
			if (r < 0)
				goto error;
		}
	} else {
		r = sc_pkcs15_bind_internal(p15card);
		if (r < 0)
			goto error;
	}
done:
	*p15card_out = p15card;
	sc_unlock(card);
	return 0;
error:
	sc_unlock(card);
	sc_pkcs15_card_free(p15card);
	SC_FUNC_RETURN(ctx, 1, r);
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
int
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
{
	sc_context_t		*ctx = p15card->card->ctx;
	scconf_block		*conf_block, **blocks, *blk;
	sc_pkcs15emu_opt_t	opts;
	int			i, r = SC_ERROR_WRONG_CARD;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	memset(&opts, 0, sizeof(opts));
	conf_block = NULL;

	conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);

	if (!conf_block) {
		/* no conf file found => try bultin drivers  */
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no conf file (or section), trying all builtin emulators\n");
		for (i = 0; builtin_emulators[i].name; i++) {
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", builtin_emulators[i].name);
			r = builtin_emulators[i].handler(p15card, &opts);
			if (r == SC_SUCCESS)
				/* we got a hit */
				goto out;
		}
	} else {
		/* we have a conf file => let's use it */
		int builtin_enabled; 
		const scconf_list *list, *item;

		builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
		list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */

		if (builtin_enabled && list) {
			/* get the list of enabled emulation drivers */
			for (item = list; item; item = item->next) {
				/* go through the list of builtin drivers */
				const char *name = item->data;

				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", name);
				for (i = 0; builtin_emulators[i].name; i++)
					if (!strcmp(builtin_emulators[i].name, name)) {
						r = builtin_emulators[i].handler(p15card, &opts);
						if (r == SC_SUCCESS)
							/* we got a hit */
							goto out;
					}
			}	
		}
		else if (builtin_enabled) {
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no emulator list in config file, trying all builtin emulators\n");
			for (i = 0; builtin_emulators[i].name; i++) {
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", builtin_emulators[i].name);
				r = builtin_emulators[i].handler(p15card, &opts);
				if (r == SC_SUCCESS)
					/* we got a hit */
					goto out;
			}
		}

		/* search for 'emulate foo { ... }' entries in the conf file */
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "searching for 'emulate foo { ... }' blocks\n");
		blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
		for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
			const char *name = blk->name->data;
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", name);
			r = parse_emu_block(p15card, blk);
			if (r == SC_SUCCESS) {
				free(blocks);
				goto out;
			}
		}
		if (blocks)
			free(blocks);
	}
		
	/* Total failure */
	return SC_ERROR_WRONG_CARD;

out:	if (r == SC_SUCCESS) {
		p15card->magic  = SC_PKCS15_CARD_MAGIC;
		p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
	} else if (r != SC_ERROR_WRONG_CARD) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to load card emulator: %s\n",
				sc_strerror(r));
	}

	return r;
}
Ejemplo n.º 20
0
Archivo: ctx.c Proyecto: AktivCo/OpenSC
static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
{
	int i, r, count = 0;
	scconf_block **blocks;
	const char *conf_path = NULL;
	const char *debug = NULL;
#ifdef _WIN32
	char temp_path[PATH_MAX];
	size_t temp_len;
#endif

	/* Takes effect even when no config around */
	debug = getenv("OPENSC_DEBUG");
	if (debug)
		ctx->debug = atoi(debug);

	memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks));
#ifdef _WIN32
	temp_len = PATH_MAX-1;
	r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\OpenSC Project\\OpenSC",
		temp_path, &temp_len);
	if (r)   {
		sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key.");
		return;
	}
	temp_path[temp_len] = '\0';
	conf_path = temp_path;
#else
	conf_path = getenv("OPENSC_CONF");
	if (!conf_path)
		conf_path = OPENSC_CONF_PATH;
#endif
	ctx->conf = scconf_new(conf_path);
	if (ctx->conf == NULL)
		return;
	r = scconf_parse(ctx->conf);
#ifdef OPENSC_CONFIG_STRING
	/* Parse the string if config file didn't exist */
	if (r < 0)
		r = scconf_parse_string(ctx->conf, OPENSC_CONFIG_STRING);
#endif
	if (r < 1) {
		/* A negative return value means the config file isn't
		 * there, which is not an error. Nevertheless log this
		 * fact. */
		if (r < 0)
			sc_log(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
		else
			sc_log(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
		scconf_free(ctx->conf);
		ctx->conf = NULL;
		return;
	}
	/* needs to be after the log file is known */
	sc_log(ctx, "Used configuration file '%s'", conf_path);
	blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->app_name);
	if (blocks && blocks[0])
		ctx->conf_blocks[count++] = blocks[0];
	free(blocks);
	if (strcmp(ctx->app_name, "default") != 0) {
		blocks = scconf_find_blocks(ctx->conf, NULL, "app", "default");
		if (blocks && blocks[0])
			ctx->conf_blocks[count] = blocks[0];
		free(blocks);
	}
	/* Above we add 2 blocks at most, but conf_blocks has 3 elements,
	 * so at least one is NULL */
	for (i = 0; ctx->conf_blocks[i]; i++)
		load_parameters(ctx, ctx->conf_blocks[i], opts);
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
0
Archivo: dir.c Proyecto: AktivCo/OpenSC
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);
}