Esempio n. 1
0
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
							   sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_entersafe_wkey_data data;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (key->algorithm != SC_ALGORITHM_RSA)
		 /* ignore DSA keys */
		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS);

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	data.key_id = (u8) kinfo->key_reference;
	data.usage=0x22;
	data.key_data.rsa=&key->u.rsa;
	return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
}
Esempio n. 2
0
static int create_sysdf(sc_profile_t *profile, sc_card_t *card, const char *name)
{
	sc_file_t *file;
	sc_path_t path;
	int r;

	assert(profile && card && card->ctx && name);
	r = sc_profile_get_file(profile, name, &file);
	if (r == SC_SUCCESS)
	{
		assert(file);
		path = file->path;
		assert(path.len > 2);
		if (path.len > 2)
			path.len -= 2;
		r = sc_select_file(card, &path, NULL);
		if (r == SC_SUCCESS)
			r = sc_file_add_acl_entry(file, SC_AC_OP_CREATE,
					SC_AC_CHV, RTECP_USER_PIN_REF);
		if (r == SC_SUCCESS)
			r = sc_file_add_acl_entry(file, SC_AC_OP_DELETE,
					SC_AC_NEVER, SC_AC_KEY_REF_NONE);
		if (r == SC_SUCCESS)
			r = sc_create_file(card, file);
		assert(file);
		sc_file_free(file);
	}
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		"Create %s failed: %s\n", name, sc_strerror(r));
	return r;
}
Esempio n. 3
0
/*
 * Create a new PIN inside a DF
 */
static int
cflex_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df,
		sc_pkcs15_object_t *pin_obj,
		const u8 *pin, size_t pin_len,
		const u8 *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
	struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin;
	sc_file_t	*dummies[2];
	int		ndummies, pin_type, puk_type, r;
	sc_file_t       *file;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

	/* If the profile doesn't specify a reference for this PIN, guess */
	if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
		pin_type = SC_PKCS15INIT_SO_PIN;
		puk_type = SC_PKCS15INIT_SO_PUK;
		if (pin_attrs->reference != 2)
			return SC_ERROR_INVALID_ARGUMENTS;
	} else {
		pin_type = SC_PKCS15INIT_USER_PIN;
		puk_type = SC_PKCS15INIT_USER_PUK;
		if (pin_attrs->reference != 1)
			return SC_ERROR_INVALID_ARGUMENTS;
	}

	/* Get file definition from the profile */
	if (sc_profile_get_file(profile, (pin_attrs->reference == 1)? "CHV1" : "CHV2", &file) < 0
			&& sc_profile_get_file(profile, "CHV", &file) < 0)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs");

	ndummies = cflex_create_dummy_chvs(profile, p15card, file, SC_AC_OP_CREATE, dummies);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, ndummies, "Unable to create dummy CHV file");

	r = cflex_create_pin_file(profile, p15card, &df->path, pin_attrs->reference,
			pin, pin_len, sc_profile_get_pin_retries(profile, pin_type),
			puk, puk_len, sc_profile_get_pin_retries(profile, puk_type),
			NULL, 0);

	cflex_delete_dummy_chvs(profile, p15card, ndummies, dummies);
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Esempio n. 4
0
/*
 * Erase the card via rm
 */
static int cflex_erase_card(struct sc_profile *profile, sc_pkcs15_card_t *p15card)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_file_t  *df = profile->df_info->file, *dir, *userpinfile = NULL;
	int             r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
	/* Delete EF(DIR). This may not be very nice
         * against other applications that use this file, but
         * extremely useful for testing :)
         * Note we need to delete if before the DF because we create
         * it *after* the DF.
         * */
        if (sc_profile_get_file(profile, "DIR", &dir) >= 0) {
                r = cflex_delete_file(profile, p15card, dir);
                sc_file_free(dir);
                if (r < 0 && r != SC_ERROR_FILE_NOT_FOUND)
                        goto out;
        }

	r=cflex_delete_file(profile, p15card, df);

	/* If the user pin file isn't in a sub-DF of the pkcs15 DF, delete it */
	if (sc_profile_get_file(profile, "pinfile-1", &userpinfile) >= 0 &&
	    userpinfile->path.len <= profile->df_info->file->path.len + 2 &&
	    memcmp(userpinfile->path.value, profile->df_info->file->path.value,
	           userpinfile->path.len) != 0) {
           	r = cflex_delete_file(profile, p15card, userpinfile);
		sc_file_free(userpinfile);
		userpinfile=NULL;
	}


out:	/* Forget all cached keys, the pin files on card are all gone. */
	if (userpinfile)
		sc_file_free(userpinfile);

        sc_free_apps(p15card->card);
        if (r == SC_ERROR_FILE_NOT_FOUND)
                r=0;

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Esempio n. 5
0
/*
 * Card-specific initialization of PKCS15 meta-information
 */
static int rtecp_init(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
{
	sc_card_t *card;
	sc_file_t *file;
	int r;

	if (!profile || !p15card || !p15card->card || !p15card->card->ctx)
		return SC_ERROR_INVALID_ARGUMENTS;

	card = p15card->card;

	r = sc_profile_get_file(profile, "MF", &file);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Get MF info failed");
	assert(file);
	r = sc_create_file(card, file);
	assert(file);
	sc_file_free(file);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Create MF failed");

	r = sc_profile_get_file(profile, "DIR", &file);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Get DIR file info failed");
	assert(file);
	r = sc_create_file(card, file);
	assert(file);
	sc_file_free(file);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Create DIR file failed");

	create_sysdf(profile, card, "Sys-DF");
	create_sysdf(profile, card, "SysKey-DF");
	create_sysdf(profile, card, "PuKey-DF");
	create_sysdf(profile, card, "PrKey-DF");
	create_sysdf(profile, card, "SKey-DF");
	create_sysdf(profile, card, "Cer-DF");
	create_sysdf(profile, card, "LCHV-DF");

	create_sysdf(profile, card, "Resrv1-DF");
	create_sysdf(profile, card, "Resrv2-DF");
	create_sysdf(profile, card, "Resrv3-DF");
	create_sysdf(profile, card, "Resrv4-DF");

	return sc_select_file(card, sc_get_mf_path(), NULL);
}
Esempio n. 6
0
/*
 * Setup file struct & path: get correct template from the profile, construct full path
 * num = number of objects of this type already on the card
 */
static int 
myeid_new_file(sc_profile_t *profile, sc_card_t *card,
		unsigned int type, unsigned int num, 
		sc_file_t **out)
{
	sc_file_t *file;
	sc_path_t *p;
	char name[64];
	const char *tag;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	if (type == SC_PKCS15_TYPE_PRKEY_RSA)
		tag = "private-key";
	else if (type  == SC_PKCS15_TYPE_PUBKEY_RSA)
		tag = "public-key";
	else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT)
		tag = "certificate";
	else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
		tag = "data";
	else 
	{
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unsupported file type");
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	/* Get template from profile  */
	snprintf(name, sizeof(name), "template-%s", tag);
	if (sc_profile_get_file(profile, name, &file) < 0) 
	{
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define %s", name);
		return SC_ERROR_NOT_SUPPORTED;
	}

	/* Auto-increment FID for next object */
	file->id += num;
	p = &file->path;
	*p = profile->df_info->file->path;
	p->value[p->len++] = (u8) (file->id / 256);
	p->value[p->len++] = (u8) (file->id % 256);

	/* Increment FID until there's no file with such path */
	r = sc_select_file(card, p, NULL);
	while(r == 0) 
	{
		file->id++;
		p->value[p->len - 2] = (u8) (file->id / 256);
		p->value[p->len - 1] = (u8) (file->id % 256);
		r = sc_select_file(card, p, NULL);
	}

	*out = file;
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 0);
}
Esempio n. 7
0
/*
 * Create a new PIN
 */
static int
setcos_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
	sc_file_t *df,
	sc_pkcs15_object_t *pin_obj,
	const u8 *pin, size_t pin_len,
	const u8 *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
	sc_file_t *pinfile = NULL;
	int r, ignore_ac = 0;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

        /* Create the global pin file if it doesn't exist yet */
	r = sc_profile_get_file(profile, "pinfile", &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No 'pinfile' template in profile");

	r = sc_select_file(p15card->card, &pinfile->path, &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select 'pinfile'");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "pinfile->status:%X", pinfile->status);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create PIN with reference:%X, flags:%X, path:%s",
			auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, sc_print_path(&auth_info->path));

	if (pinfile->status == SC_FILE_STATUS_CREATION)
		ignore_ac = 1;

	r = setcos_create_pin_internal(profile, p15card, ignore_ac, auth_info,
			pin, pin_len, puk, puk_len);

	/* If pinfile is in 'Creation' state and SOPIN has been created,
	 * change status of MF and 'pinfile' to 'Operational:Activated'
	 */
	if (ignore_ac && (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN))   {
		sc_file_t *mf = profile->mf_info->file;

		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set 'pinfile' into the activated state");

		r = sc_select_file(p15card->card, &mf->path, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

		r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_ACTIVATE_FILE, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot set MF into the activated state");
	}

	sc_file_free(pinfile);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 8
0
/*
 * Create a DF
 */
static int
myeid_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df) {
	struct sc_context *ctx = NULL;
	struct sc_file *file = NULL;
	int r = 0, ii;
	static const char *create_dfs[] = {
		"PKCS15-PrKDF",
		"PKCS15-PuKDF",
		"PKCS15-CDF",
		"PKCS15-CDF-TRUSTED",
		"PKCS15-DODF",
		NULL
	};

	static const int create_dfs_val[] = {
		SC_PKCS15_PRKDF,
		SC_PKCS15_PUKDF,
		SC_PKCS15_CDF,
		SC_PKCS15_CDF_TRUSTED,
		SC_PKCS15_DODF
	};

	if (!profile || !p15card || !p15card->card || !df)
		return SC_ERROR_INVALID_ARGUMENTS;

	ctx = p15card->card->ctx;
	LOG_FUNC_CALLED(ctx);
	sc_log(ctx, "id (%x)", df->id);

	if (df->id == 0x5015) {
		sc_log(ctx, "Select (%x)", df->id);
		r = sc_select_file(p15card->card, &df->path, NULL);

		for (ii = 0; create_dfs[ii]; ii++) {
			sc_log(ctx, "Create '%s'", create_dfs[ii]);

			r = sc_profile_get_file(profile, create_dfs[ii], &file);
			if (file)
				sc_file_free(file);
			if (r) {
				sc_log(ctx, "Inconsistent profile: cannot find %s", create_dfs[ii]);
				LOG_FUNC_RETURN(ctx, SC_ERROR_INCONSISTENT_PROFILE);
			}

			r = sc_pkcs15init_add_object(p15card, profile, create_dfs_val[ii], NULL);

			if (r != SC_ERROR_FILE_ALREADY_EXISTS)
				LOG_TEST_RET(ctx, r, "Failed to create MyEID xDF file");
		}
	}

	LOG_FUNC_RETURN(p15card->card->ctx, r);
}
Esempio n. 9
0
static int entersafe_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
								  sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey)
{
	int r;
	sc_entersafe_gen_key_data	gendat;
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA)
		return SC_ERROR_NOT_SUPPORTED;

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	/* generate key pair */
	gendat.key_id     = (u8) kinfo->key_reference;
	gendat.key_length = (size_t) kinfo->modulus_length;
	gendat.modulus    = NULL;
	r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_GENERATE_KEY, &gendat);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "EnterSafe generate RSA key pair failed");

	/* get the modulus via READ PUBLIC KEY */
	if (pubkey) {
		u8 *buf;
		struct sc_pkcs15_pubkey_rsa *rsa = &pubkey->u.rsa;
		/* set the modulus */
		rsa->modulus.data = gendat.modulus;
		rsa->modulus.len  = kinfo->modulus_length >> 3;
		/* set the exponent (always 0x10001) */
		buf = malloc(3);
		if (!buf)
			return SC_ERROR_OUT_OF_MEMORY;
		buf[0] = 0x01;
		buf[1] = 0x00;
		buf[2] = 0x01;
		rsa->exponent.data = buf;
		rsa->exponent.len  = 3;

		pubkey->algorithm = SC_ALGORITHM_RSA;
	} else
Esempio n. 10
0
/*
 * Create the MF and global pin file if they don't exist.
 */
static int
setcos_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_file_t *mf = profile->mf_info->file;
	sc_file_t *pinfile;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	/* Create the MF if it doesn't exist yet */
	r = sc_select_file(p15card->card, &mf->path, NULL);
	if (r == SC_ERROR_FILE_NOT_FOUND) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "MF doesn't exist, creating now");

		/* Fix up the file's ACLs */
		r = sc_pkcs15init_fixup_file(profile, p15card, mf);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "MF fixup failed");

		mf->status = SC_FILE_STATUS_CREATION;
		r = sc_create_file(p15card->card, mf);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "MF creation failed");
	}
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

	/* Create the global pin file if it doesn't exist yet */
	r = sc_profile_get_file(profile, "pinfile", &pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot get 'pinfile' from profile");

	r = sc_select_file(p15card->card, &pinfile->path, NULL);
	if (r == SC_ERROR_FILE_NOT_FOUND) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Global pin file doesn't exist, creating now");

		/* Fix up the file's ACLs */
		r = sc_pkcs15init_fixup_file(profile, p15card, pinfile);
		if (r < 0)
			sc_file_free(pinfile);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Pinfile fixup failed");

		/* Set life cycle state to SC_FILE_STATUS_CREATION,
		 * which means that all ACs are ignored. */
		pinfile->status = SC_FILE_STATUS_CREATION;
		r = sc_create_file(p15card->card, pinfile);
		if (r < 0)
			sc_file_free(pinfile);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Pinfile creation failed");
	}
	sc_file_free(pinfile);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Select pinfile failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 11
0
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
							   sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_entersafe_wkey_data data;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;
	int r;

	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)obj->data;
	size_t keybits = key_info->modulus_length;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if ( key->algorithm != SC_ALGORITHM_RSA )
	{
		 /* ignore DSA keys */
		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS);
	}

	/* Disable RSA:512bits */
	if ( ( keybits < 1024 ) ||
		 ( keybits > 2048 ) ||
		 ( keybits % 0x20 ) )
	{
		sc_debug(card->ctx,
			 SC_LOG_DEBUG_NORMAL,
			 "Unsupported key size %"SC_FORMAT_LEN_SIZE_T"u\n",
			 keybits);
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	data.key_id = (u8) kinfo->key_reference;
	data.usage=0x22;
	data.key_data.rsa=&key->u.rsa;
	return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
}
Esempio n. 12
0
/*
 * Create a new DF
 * This will usually be the application DF
 */
static int
gpk_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
{
	struct sc_file	*pinfile;
	int		r, locked;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0
			&& locked) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
			"This card is already personalized, unable to "
			"create PKCS#15 structure.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	/* Create the DF. */
	r = sc_pkcs15init_create_file(profile, p15card, df);
	if (r < 0)
		return r;

	/* See if there's a file called "pinfile" that resides within
	 * this DF. If so, create it */
	if (sc_profile_get_file(profile, "pinfile", &pinfile) >= 0) {
		/* Build the pin file's path from the DF path + its
		 * file ID */
		pinfile->path = df->path;
		sc_append_file_id(&pinfile->path, pinfile->id);

		r = gpk_init_pinfile(profile, p15card, pinfile);
		sc_file_free(pinfile);
		if (r < 0)
			return r;

		/* TODO: What for it was used ?
		for (i = 0; i < GPK_MAX_PINS; i++)
		*	sc_keycache_put_pin(&df->path, GPK_PIN_SCOPE|i, (const u8 *) "        ");
		*/
	}

	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 13
0
/*
 * Create a DF
 */
static int 
myeid_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_file *file = NULL;
	int	r=0, ii;
        static const char *create_dfs[] = {
		"PKCS15-PrKDF",
		"PKCS15-PuKDF",
		"PKCS15-CDF",
		"PKCS15-DODF",
		NULL
	};

	if (!profile || !p15card || !df)
		return SC_ERROR_INVALID_ARGUMENTS;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "id (%x)",df->id);

	if(df->id == 0x5015)
	{
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Select (%x)",df->id);
		r = sc_select_file(p15card->card, &df->path, NULL);

        	for (ii = 0; create_dfs[ii]; ii++)   {
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Create '%s'", create_dfs[ii]);
                	if (sc_profile_get_file(profile, create_dfs[ii], &file))   {
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Inconsistent profile: cannot find %s", create_dfs[ii]);
				SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INCONSISTENT_PROFILE);
			}
			r = sc_pkcs15init_create_file(profile, p15card, file);
			sc_file_free(file);
			if (r != SC_ERROR_FILE_ALREADY_EXISTS)
				SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to create MyEID xDF file");
		}
	}

	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 14
0
/*
 * Select a reference for a private key object
 */
static int rtecp_select_key_reference(sc_profile_t *profile,
		sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_info_t *key_info)
{
	sc_file_t *df;
	int r;

	if (!profile || !p15card || !p15card->card || !p15card->card->ctx || !key_info)
		return SC_ERROR_INVALID_ARGUMENTS;

	if (key_info->key_reference <= 0)
		key_info->key_reference = 1;
	else if (key_info->key_reference > 0xFF)
		return SC_ERROR_TOO_MANY_OBJECTS;

	r = sc_profile_get_file(profile, "PrKey-DF", &df);
	SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Get PrKey-DF info failed");
	assert(df);
	key_info->path = df->path;
	sc_file_free(df);
	r = sc_append_file_id(&key_info->path, key_info->key_reference);
	return r;
}
/*
 * Create a new DF
 * This will usually be the application DF
 */
static int
gpk_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df)
{
    struct sc_file	*pinfile;
    int		r, locked, i;

    if (sc_card_ctl(card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0
            && locked) {
        sc_error(card->ctx,
                 "This card is already personalized, unable to "
                 "create PKCS#15 structure.");
        return SC_ERROR_NOT_SUPPORTED;
    }

    /* Create the DF. */
    r = sc_pkcs15init_create_file(profile, card, df);
    if (r < 0)
        return r;

    /* See if there's a file called "pinfile" that resides within
     * this DF. If so, create it */
    if (sc_profile_get_file(profile, "pinfile", &pinfile) >= 0) {
        /* Build the pin file's path from the DF path + its
         * file ID */
        pinfile->path = df->path;
        sc_append_file_id(&pinfile->path, pinfile->id);

        r = gpk_init_pinfile(profile, card, pinfile);
        sc_file_free(pinfile);
        if (r < 0)
            return r;

        for (i = 0; i < GPK_MAX_PINS; i++)
            sc_keycache_put_pin(&df->path, GPK_PIN_SCOPE|i, (const u8 *) "        ");
    }

    return r;
}
Esempio n. 16
0
/*
 * Delete object
 * 
 * Applied to private key: used to delete public part internal file
 */
static int rtecp_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *obj, const struct sc_path *path)
{
	sc_context_t *ctx;
	sc_file_t *df;
	sc_path_t pubkey_path;
	int key_ref;
	int r;

	if (!profile || !p15card || !p15card->card || !p15card->card->ctx)
		return SC_ERROR_INVALID_ARGUMENTS;

	ctx = p15card->card->ctx;
	LOG_FUNC_CALLED(ctx);
	sc_log(ctx, "delete object: type %X, path %s", obj->type, sc_print_path(path));

	if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
		LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);

	key_ref = ((struct sc_pkcs15_prkey_info *)obj->data)->key_reference;
	sc_log(ctx, "key reference %04i", key_ref);

	r = sc_profile_get_file(profile, "PuKey-DF", &df);
	LOG_TEST_RET(ctx, r, "Get PuKey-DF info failed");
	pubkey_path = df->path;
	sc_file_free(df);

	r = sc_append_file_id(&pubkey_path, key_ref);
	LOG_TEST_RET(ctx, r, "Append ID to file failed");

	sc_log(ctx, "delete pubkey file %s", sc_print_path(&pubkey_path));
	r = sc_pkcs15init_delete_by_path(profile, p15card, &pubkey_path);
	if (r && r != SC_ERROR_FILE_NOT_FOUND)
		LOG_FUNC_RETURN(ctx, r);

	LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
}
Esempio n. 17
0
static int
cflex_create_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_path_t *df_path, int ref,
			const u8 *pin, size_t pin_len, int pin_tries,
			const u8 *puk, size_t puk_len, int puk_tries,
			sc_file_t **file_ret, int unprotected)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_object *pin_obj = NULL;
	unsigned char	buffer[23];
	sc_path_t	path;
	sc_file_t	*dummies[2], *file;
	int		r, ndummies;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
	if (file_ret)
		*file_ret = NULL;

	/* Build the CHV path */
	path = *df_path;
	path.value[path.len++] = ref - 1;
	path.value[path.len++] = 0;

	/* See if the CHV already exists */
	r = sc_select_file(p15card->card, &path, NULL);
	if (r >= 0)
		return SC_ERROR_FILE_ALREADY_EXISTS;

	/* Get the file definition from the profile */
	if (sc_profile_get_file_by_path(profile, &path, &file) < 0
			&& sc_profile_get_file(profile, (ref == 1)? "CHV1" : "CHV2", &file) < 0
			&& sc_profile_get_file(profile, "CHV", &file) < 0)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs");

	file->path = path;
	file->size = 23;
	file->id = (ref == 1)? 0x0000 : 0x0100;

	if (unprotected)   {
		sc_file_add_acl_entry(file, SC_AC_OP_UPDATE,
				SC_AC_NONE, SC_AC_KEY_REF_NONE);
	}

	/* Build the contents of the file */
	buffer[0] = buffer[1] = buffer[2] = 0xFF;
	put_pin(profile, buffer + 3, pin, pin_len, pin_tries);
	put_pin(profile, buffer + 13, puk, puk_len, puk_tries);

	/* For updating the file, create a dummy CHV files if
	 * necessary */
	ndummies = cflex_create_dummy_chvs(profile, p15card,
				file, SC_AC_OP_UPDATE, dummies);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, ndummies, "Unable to create dummy CHV file");

	if (!unprotected)   {
		struct sc_pin_cmd_data pin_cmd;

		memset(&pin_cmd, 0, sizeof(pin_cmd));
		pin_cmd.cmd = SC_PIN_CMD_VERIFY;
		pin_cmd.pin_type = SC_AC_CHV;
		pin_cmd.pin_reference = ref;
		pin_cmd.pin1.data = dummy_pin_value;
		pin_cmd.pin1.len = sizeof(dummy_pin_value);

		r = sc_pin_cmd(p15card->card, &pin_cmd, NULL);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot verify dummy PIN");

	};

	if (ref == 2)   {
		/* Cache dummy SOPIN value */
		r = sc_pkcs15_find_pin_by_type_and_reference(p15card, NULL, SC_AC_CHV, ref, &pin_obj);
		if (!r && pin_obj)
			sc_pkcs15_pincache_add(p15card, pin_obj, dummy_pin_value, sizeof(dummy_pin_value));
	}

	r = sc_pkcs15init_create_file(profile, p15card, file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to create PIN file");

	r = sc_update_binary(p15card->card, 0, buffer, 23, 0);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Failed to update PIN file");

	if (r < 0 || file_ret == NULL)
		sc_file_free(file);
	else
		*file_ret = file;

	/* Delete the dummy CHV files */
	cflex_delete_dummy_chvs(profile, p15card, ndummies, dummies);

	if (pin_obj)   {
		/* Cache new SOPIN value */
		sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len);
	}

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Esempio n. 18
0
/*
 * Store a key on the card
 */
static int rtecp_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_card_t *card;
	sc_pkcs15_prkey_info_t *key_info;
	sc_file_t *pukey_df;
	sc_path_t path;
	unsigned char *buf;
	size_t buf_len, key_len, len, i;
	int r;

	if (!profile || !p15card || !p15card->card || !p15card->card->ctx
			|| !obj || !obj->data || !key)
		return SC_ERROR_INVALID_ARGUMENTS;

	card = p15card->card;
	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if ((obj->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA)
			&& (obj->type != SC_PKCS15_TYPE_PRKEY_GOSTR3410
				|| key->algorithm != SC_ALGORITHM_GOSTR3410))
		return SC_ERROR_NOT_SUPPORTED;

	key_info = (sc_pkcs15_prkey_info_t *)obj->data;
	assert(key_info);

	if (key->algorithm == SC_ALGORITHM_RSA)
	{
		assert(key_info->modulus_length % 128 == 0);
		len = key_info->modulus_length / 8 / 2;
		key_len = len * 5 + 8;
		buf_len = key_len;
	}
	else
	{
		assert(key_info->modulus_length == SC_PKCS15_GOSTR3410_KEYSIZE);
		len = key_info->modulus_length / 8;
		key_len = len;
		buf_len = len;
	}
	if (key->algorithm == SC_ALGORITHM_RSA && (!key->u.rsa.p.data
			|| !key->u.rsa.q.data || !key->u.rsa.iqmp.data
			|| !key->u.rsa.dmp1.data || !key->u.rsa.dmq1.data
			|| !key->u.rsa.modulus.data || !key->u.rsa.exponent.data
			|| key->u.rsa.p.len != len || key->u.rsa.q.len != len
			|| key->u.rsa.iqmp.len != len || key->u.rsa.dmp1.len != len
			|| key->u.rsa.dmq1.len != len || key->u.rsa.modulus.len != 2*len
			|| key->u.rsa.exponent.len > len || key->u.rsa.exponent.len == 0))
		return SC_ERROR_INVALID_ARGUMENTS;
	if (key->algorithm == SC_ALGORITHM_GOSTR3410 && (!key->u.gostr3410.d.data
			|| key->u.gostr3410.d.len != len))
		return SC_ERROR_INVALID_ARGUMENTS;
	buf = calloc(1, buf_len);
	if (!buf)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	assert(key_len <= buf_len);
	if (key->algorithm == SC_ALGORITHM_RSA)
	{
		/* p */
		for (i = 0; i < len; ++i)
			buf[i] = key->u.rsa.p.data[len - 1 - i];
		/* q */
		for (i = 0; i < len; ++i)
			buf[len + 4 + i] = key->u.rsa.q.data[len - 1 - i];
		/* iqmp */
		for (i = 0; i < len; ++i)
			buf[len + 4 + len + 4 + i] = key->u.rsa.iqmp.data[len - 1 - i];
		/* dmp1 */
		for (i = 0; i < len; ++i)
			buf[len + 4 + len + 4 + len + i] =
				key->u.rsa.dmp1.data[len - 1 - i];
		/* dmq1 */
		for (i = 0; i < len; ++i)
			buf[len * 4 + 8 + i] = key->u.rsa.dmq1.data[len - 1 - i];
	}
	else
	{
		/* d */
		for (i = 0; i < len; ++i)
			buf[i] = key->u.gostr3410.d.data[len - 1 - i];
	}
	path = key_info->path;
	r = sc_select_file(card, &path, NULL);
	if (r == SC_SUCCESS)
		r = sc_change_reference_data(card, 0, 0, NULL, 0, buf, key_len, NULL);
	assert(buf);
	sc_mem_clear(buf, key_len);
	/* store public key */
	if (key->algorithm == SC_ALGORITHM_RSA)
		key_len = len * 3;
	else
		goto end;
	assert(key_len <= buf_len);
	if (key->algorithm == SC_ALGORITHM_RSA)
	{
		/* modulus */
		for (i = 0; i < 2*len; ++i)
			buf[i] = key->u.rsa.modulus.data[2*len - 1 - i];
		/* exponent */
		for (i = 0; i < key->u.rsa.exponent.len && i < len; ++i)
			buf[2 * len + i] = key->u.rsa.exponent.data[
				key->u.rsa.exponent.len - 1 - i];
	}
	if (r == SC_SUCCESS)
	{
		r = sc_profile_get_file(profile, "PuKey-DF", &pukey_df);
		if (r == SC_SUCCESS)
		{
			assert(pukey_df);
			path = pukey_df->path;
			r = sc_append_file_id(&path, key_info->key_reference);
			sc_file_free(pukey_df);
		}
		else if (card->ctx->debug >= 2)
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", "Get PuKey-DF info failed");
	}
	if (r == SC_SUCCESS)
	{
		r = sc_select_file(card, &path, NULL);
		if (r == SC_SUCCESS)
			r = sc_change_reference_data(card, 0, 0, NULL, 0,
					buf, key_len, NULL);
		if (r && card->ctx->debug >= 2)
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s\n", "Store public key failed");
	}
end:
	assert(buf);
	free(buf);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 19
0
/*
 * Create an empty key object
 */
static int rtecp_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_pkcs15_object_t *obj)
{
	sc_context_t *ctx;
	/*                              RSA_PRkey/ Adds Miller-
	 *                              RSA_PUBkey Rabin tests    Attempts Reserve */
	const unsigned char prkey_prop[]  = { 0x23,          0, 0,    0xAA, 0, 0 };
	const unsigned char pbkey_prop[]  = { 0x33,          0, 0,    0xAA, 0, 0 };
	/*                  GOSTR3410_PRkey/
	 *                  GOSTR3410_PUBkey  paramset    Attempts Reserve */
	unsigned char prgkey_prop[] = { 0x03,      '?', 0,    0xAA, 0, 0 };
	unsigned char pbgkey_prop[] = { 0x13,      '?', 0,    0xAA, 0, 0 };
	/*                        AccessMode  - Update  Use  -  -  - Delete */
	unsigned char prkey_sec[15] = { 0x46, 0,   '?', '?', 0, 0, 0,   '?' };
	unsigned char pbkey_sec[15] = { 0x46, 0,   '?',   0, 0, 0, 0,   '?' };
	unsigned char auth_id, paramset;
	sc_pkcs15_prkey_info_t *key_info;
	sc_file_t *file;
	int r;

	if (!profile || !p15card || !p15card->card || !p15card->card->ctx
			|| !obj || !obj->data)
		return SC_ERROR_INVALID_ARGUMENTS;

	ctx = p15card->card->ctx;
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA
			&& obj->type != SC_PKCS15_TYPE_PRKEY_GOSTR3410)
		return SC_ERROR_NOT_SUPPORTED;
	if (obj->auth_id.len != 1)
		return SC_ERROR_INVALID_ARGUMENTS;
	auth_id = obj->auth_id.value[0];

	key_info = (sc_pkcs15_prkey_info_t *)obj->data;
	assert(key_info);
	if ((obj->type == SC_PKCS15_TYPE_PRKEY_RSA
				&& key_info->modulus_length % 128 != 0)
			|| (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410
				&& key_info->modulus_length
				!= SC_PKCS15_GOSTR3410_KEYSIZE))
	{
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key size %u\n", key_info->modulus_length);
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410)
	{
		if (key_info->params.len < sizeof(int))
			return SC_ERROR_INVALID_ARGUMENTS;
		if (((int*)key_info->params.data)[0] < 1
				|| ((int*)key_info->params.data)[0] > 3)
			return SC_ERROR_INVALID_ARGUMENTS;
		paramset = ((unsigned int*)key_info->params.data)[0] & 0x03;
		assert(sizeof(prgkey_prop)/sizeof(prgkey_prop[0]) > 1);
		assert(sizeof(pbgkey_prop)/sizeof(pbgkey_prop[0]) > 1);
		prgkey_prop[1] = 0x10 + (paramset << 4);
		pbgkey_prop[1] = prgkey_prop[1];
	}

	r = sc_profile_get_file(profile, "PKCS15-AppDF", &file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Get PKCS15-AppDF info failed");
	r = sc_file_add_acl_entry(file, SC_AC_OP_CREATE, SC_AC_CHV, auth_id);
	if (r == SC_SUCCESS)
		r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE);
	assert(file);
	sc_file_free(file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Authenticate failed");

	file = sc_file_new();
	if (!file)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	file->id = key_info->key_reference;
	r = sc_file_set_type_attr(file, (const u8*)"\x10\x00", 2);

	/* private key file */
	if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)
		file->size = key_info->modulus_length / 8 / 2 * 5 + 8;
	else
		file->size = key_info->modulus_length / 8;
	if (r == SC_SUCCESS)
	{
		assert(sizeof(prkey_sec)/sizeof(prkey_sec[0]) > 7);
		prkey_sec[2] = auth_id;
		prkey_sec[3] = auth_id;
		prkey_sec[7] = auth_id;
		r = sc_file_set_sec_attr(file, prkey_sec, sizeof(prkey_sec));
	}
	if (r == SC_SUCCESS)
	{
		if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)
			r = sc_file_set_prop_attr(file, prkey_prop, sizeof(prkey_prop));
		else
			r = sc_file_set_prop_attr(file, prgkey_prop,sizeof(prgkey_prop));
	}
	if (r == SC_SUCCESS)  {
		sc_log(ctx, "create private key file id:%04i", file->id);
		r = sc_create_file(p15card->card, file);
	}
	/* public key file */
	if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)
		file->size = key_info->modulus_length / 8 / 2 * 3;
	else
		file->size = key_info->modulus_length / 8 * 2;
	if (r == SC_SUCCESS)
	{
		assert(sizeof(pbkey_sec)/sizeof(pbkey_sec[0]) > 7);
		pbkey_sec[2] = auth_id;
		pbkey_sec[7] = auth_id;
		r = sc_file_set_sec_attr(file, pbkey_sec, sizeof(pbkey_sec));
	}
	if (r == SC_SUCCESS)
	{
		if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA)
			r = sc_file_set_prop_attr(file, pbkey_prop, sizeof(pbkey_prop));
		else
			r = sc_file_set_prop_attr(file, pbgkey_prop,sizeof(pbgkey_prop));
	}
	if (r == SC_SUCCESS)   {
		sc_log(ctx, "create public key file id:%04i", file->id);
		r = sc_create_file(p15card->card, file);
	}
	assert(file);
	sc_file_free(file);
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 20
0
/*
 * Create a new PIN inside a DF
 */
static int westcos_pkcs15_create_pin(sc_profile_t *profile,
					sc_pkcs15_card_t *p15card,
					sc_file_t *df,
					sc_pkcs15_object_t *pin_obj,
					const u8 *pin, size_t pin_len,
					const u8 *puk, size_t puk_len)
{
	int r;
	sc_file_t *pinfile = NULL;

	if(pin_len>9 || puk_len>9)
		return SC_ERROR_INVALID_ARGUMENTS;

	r = sc_profile_get_file(profile, "PINFILE", &pinfile);
	if(r < 0) return r;

	r = sc_create_file(p15card->card, pinfile);
	if(r)
	{
		if(r != SC_ERROR_FILE_ALREADY_EXISTS)
			return (r);

		r = sc_select_file(p15card->card, &pinfile->path, NULL);
		if(r) return (r);
	}

	if(pinfile)
		sc_file_free(pinfile);

	if(pin != NULL)
	{
		sc_changekey_t ck;
		struct sc_pin_cmd_pin pin_cmd;
		int ret;

		memset(&pin_cmd, 0, sizeof(pin_cmd));
		memset(&ck, 0, sizeof(ck));

		memcpy(ck.key_template, "\x1e\x00\x00\x10", 4);

		pin_cmd.encoding = SC_PIN_ENCODING_GLP;
		pin_cmd.len = pin_len;
		pin_cmd.data = pin;
		pin_cmd.max_length = 8;

		ret = sc_build_pin(ck.new_key.key_value,
			sizeof(ck.new_key.key_value), &pin_cmd, 1);
		if(ret < 0)
			return SC_ERROR_CARD_CMD_FAILED;

		ck.new_key.key_len = ret;
		r = sc_card_ctl(p15card->card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck);
		if(r) return r;
	}

	if(puk != NULL)
	{
		sc_changekey_t ck;
		struct sc_pin_cmd_pin puk_cmd;
		int ret;

		memset(&puk_cmd, 0, sizeof(puk_cmd));
		memset(&ck, 0, sizeof(ck));

		memcpy(ck.key_template, "\x1e\x00\x00\x20", 4);

		puk_cmd.encoding = SC_PIN_ENCODING_GLP;
		puk_cmd.len = puk_len;
		puk_cmd.data = puk;
		puk_cmd.max_length = 8;

		ret = sc_build_pin(ck.new_key.key_value,
			sizeof(ck.new_key.key_value), &puk_cmd, 1);
		if(ret < 0)
			return SC_ERROR_CARD_CMD_FAILED;

		ck.new_key.key_len = ret;
		r = sc_card_ctl(p15card->card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck);
		if(r) return r;
	}

	return 0;
}
Esempio n. 21
0
/*
 * Create a PIN object within the given DF
 */
static int rtecp_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_file_t *df, sc_pkcs15_object_t *pin_obj,
		const unsigned char *pin, size_t pin_len,
		const unsigned char *puk, size_t puk_len)
{
	sc_context_t *ctx;
	sc_pkcs15_auth_info_t *auth_info;
	sc_file_t *file = NULL;
	/*                        GCHV min-length Flags Attempts  Reserve */
	unsigned char prop[]  = { 0x01,       '?', 0x01,     '?', 0, 0 };
	/*                  AccessMode Unblock Change             Delete */
	unsigned char sec[15] = { 0x43,    '?',   '?', 0, 0, 0, 0,  0xFF };
	char pin_sname[0x10];
	int r, reset_by_sopin = 0;

	(void)puk; /* no warning */
	if (!profile || !p15card || !p15card->card || !p15card->card->ctx || !df
			|| !pin_obj || !pin_obj->data || !pin || !pin_len)
		return SC_ERROR_INVALID_ARGUMENTS;

	ctx = p15card->card->ctx;
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	if (puk_len != 0)
	{
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Do not enter User unblocking PIN (PUK): %s\n",
				sc_strerror(SC_ERROR_NOT_SUPPORTED));
		return SC_ERROR_NOT_SUPPORTED;
	}

	auth_info = (sc_pkcs15_auth_info_t *)pin_obj->data;
	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

	if (auth_info->attrs.pin.reference != RTECP_SO_PIN_REF
			&& auth_info->attrs.pin.reference != RTECP_USER_PIN_REF)
	{
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN reference %i not found in standard"
				" (Rutoken ECP) PINs\n", auth_info->attrs.pin.reference);
		return SC_ERROR_NOT_SUPPORTED;
	}

	snprintf(pin_sname, sizeof(pin_sname), "CHV%i", auth_info->attrs.pin.reference);
	if (auth_info->attrs.pin.reference == RTECP_USER_PIN_REF)   {
		r = sc_profile_get_file(profile, pin_sname, &file);
		if (!r)   {
			const struct sc_acl_entry *acl = NULL;

			r = sc_pkcs15init_fixup_file(profile, p15card, file);
			if (r < 0)
				sc_file_free(file);
			SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot fixup the ACLs of PIN file");

			acl = sc_file_get_acl_entry(file, SC_AC_OP_PIN_RESET);
			if (acl && acl->method == SC_AC_CHV && acl->key_ref == RTECP_SO_PIN_REF)   {
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Allow reset of User PIN with SoPIN\n");
				reset_by_sopin = 1;
			}
			sc_file_free(file);
		}
	}

	file = sc_file_new();
	if (!file)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	file->id = auth_info->attrs.pin.reference;
	file->size = pin_len;
	assert(sizeof(sec)/sizeof(sec[0]) > 2);
	sec[1] = (auth_info->attrs.pin.reference == RTECP_SO_PIN_REF) ? 0xFF : RTECP_SO_PIN_REF;
	sec[2] = (unsigned char)auth_info->attrs.pin.reference | (reset_by_sopin ? RTECP_SO_PIN_REF : 0);
	r = sc_file_set_sec_attr(file, sec, sizeof(sec));
	if (r == SC_SUCCESS)
	{
		assert(sizeof(prop)/sizeof(prop[0]) > 3);
		prop[1] = (unsigned char)auth_info->attrs.pin.min_length;
		prop[3] = 0x11 * (unsigned char)(auth_info->tries_left & 0x0F);
		r = sc_file_set_prop_attr(file, prop, sizeof(prop));
	}
	if (r == SC_SUCCESS)
		r = sc_file_set_type_attr(file, (const u8*)"\x10\x00", 2);
	if (r == SC_SUCCESS)
		r = sc_create_file(p15card->card, file);
	sc_file_free(file);

	if (r == SC_SUCCESS)
		r = sc_change_reference_data(p15card->card, SC_AC_CHV,
				auth_info->attrs.pin.reference, NULL, 0, pin, pin_len, NULL);
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Esempio n. 22
0
/*
 * Allocate a file
 */
static int
miocos_new_file(struct sc_profile *profile, sc_card_t *card,
		unsigned int type, unsigned int num,
		sc_file_t **out)
{
	struct sc_file	*file;
	struct sc_path	*p;
	char		name[64];
	const char      *tag = NULL, *desc = NULL;

	while (1) {
		switch (type) {
		case SC_PKCS15_TYPE_PRKEY_RSA:
			desc = "RSA private key";
			tag = "private-key";
			break;
		case SC_PKCS15_TYPE_PUBKEY_RSA:
			desc = "RSA public key";
			tag = "public-key";
			break;
		case SC_PKCS15_TYPE_PRKEY:
			desc = "extractable private key";
			tag = "extractable-key";
			break;
		case SC_PKCS15_TYPE_CERT:
			desc = "certificate";
			tag = "certificate";
			break;
		case SC_PKCS15_TYPE_DATA_OBJECT:
			desc = "data object";
			tag = "data";
			break;
		}
		if (tag)
			break;
		/* If this is a specific type such as
		 * SC_PKCS15_TYPE_CERT_FOOBAR, fall back to
		 * the generic class (SC_PKCS15_TYPE_CERT)
		 */
		if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) {
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
				"File type not supported by card driver");
			return SC_ERROR_INVALID_ARGUMENTS;
		}
		type &= SC_PKCS15_TYPE_CLASS_MASK;
	}

	_snprintf(name, sizeof(name), "template-%s", tag);
	if (sc_profile_get_file(profile, name, &file) < 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define %s template (%s)",
				desc, name);
		return SC_ERROR_NOT_SUPPORTED;
	}

	/* Now construct file from template */
	file->id += num;

	p = &file->path;
	*p = profile->df_info->file->path;
	p->value[p->len++] = file->id >> 8;
	p->value[p->len++] = file->id;

	*out = file;
	return 0;
}
Esempio n. 23
0
/*
 * Key generation
 */
static int
cardos_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_pkcs15_object_t *obj,
		sc_pkcs15_pubkey_t *pubkey)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_prkey_info *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	struct sc_pkcs15_prkey_rsa key_obj;
	struct sc_cardctl_cardos_genkey_info args;
	struct sc_file	*temp;
	u8		abignum[256];
	int		algorithm = 0, r, delete_it = 0, use_ext_rsa = 0;
	size_t		keybits, rsa_max_size;
	int             pin_id = -1;

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA)
		return SC_ERROR_NOT_SUPPORTED;

	rsa_max_size = (p15card->card->caps & SC_CARD_CAP_RSA_2048) ? 2048 : 1024;
	keybits = key_info->modulus_length & ~7UL;
	if (keybits > rsa_max_size) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to generate key, max size is %lu",
			(unsigned long) rsa_max_size);
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	if (keybits > 1024)
		use_ext_rsa = 1;

	if (cardos_key_algorithm(key_info->usage, keybits, &algorithm) < 0) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CardOS does not support keys "
			       "that can both sign _and_ decrypt.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	if (sc_profile_get_file(profile, "tempfile", &temp) < 0) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define temporary file "
				"for key generation.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	pin_id = sc_pkcs15init_get_pin_reference(p15card, profile, 
			SC_AC_SYMBOLIC, SC_PKCS15INIT_USER_PIN);
	if (pin_id >= 0) {
		r = sc_pkcs15init_verify_secret(profile, p15card, NULL, SC_AC_CHV, pin_id);
		if (r < 0)
			return r;
	}
	if (use_ext_rsa == 0)
		temp->ef_structure = SC_FILE_EF_LINEAR_VARIABLE_TLV;
	else
		temp->ef_structure = SC_FILE_EF_TRANSPARENT;

	if ((r = sc_pkcs15init_create_file(profile, p15card, temp)) < 0)
		goto out;
	delete_it = 1;

	init_key_object(&key_obj, abignum, keybits >> 3);

	r = cardos_put_key(profile, p15card, algorithm, key_info, &key_obj);
	if (r < 0)
		goto out;

	memset(&args, 0, sizeof(args));
	args.key_id = key_info->key_reference;
	args.key_bits = keybits;
	args.fid = temp->id;
	r = sc_card_ctl(p15card->card, SC_CARDCTL_CARDOS_GENERATE_KEY, &args);
	if (r < 0)
		goto out;

	r = cardos_extract_pubkey(p15card->card, pubkey, temp, use_ext_rsa);
out:
	if (delete_it != 0)
		sc_pkcs15init_rmdir(p15card, profile, temp);
	sc_file_free(temp);

	if (r < 0) {
		if (pubkey->u.rsa.modulus.data)
			free (pubkey->u.rsa.modulus.data);
		if (pubkey->u.rsa.exponent.data)
			free (pubkey->u.rsa.exponent.data);
	}
	return r;
}
Esempio n. 24
0
/*
 * Generate a keypair
 */
static int
jcop_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		  sc_pkcs15_object_t *obj,
		  sc_pkcs15_pubkey_t *pubkey)
{
     sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
     struct sc_cardctl_jcop_genkey args;
     sc_file_t       *temppubfile=NULL, *keyfile=NULL;
     unsigned char   *keybuf=NULL;
     size_t          mod_len, exp_len, pub_len, keybits;
     int             r,delete_ok=0;

     if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
	  sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "JCOP supports only RSA keys.");
	  return SC_ERROR_NOT_SUPPORTED;
     }

     r=sc_profile_get_file(profile, "temp-pubkey", &temppubfile);
     if (r < 0)
	  goto out;

     r = sc_select_file(p15card->card, &key_info->path, &keyfile);
     if (r < 0)
	  goto out;

     mod_len = key_info->modulus_length / 8;
     exp_len = 4;
     pub_len = 2 + mod_len + exp_len;
     temppubfile->size = pub_len;

     r = sc_pkcs15init_fixup_file(profile, p15card, temppubfile);
     if (r < 0)
	  goto out;

     r = sc_pkcs15init_create_file(profile, p15card, temppubfile);
     if (r < 0)
	  goto out;

     delete_ok=1;
     r = sc_pkcs15init_authenticate(profile, p15card, temppubfile, SC_AC_OP_UPDATE);
     if (r < 0)
	  goto out;
     r = sc_pkcs15init_authenticate(profile, p15card, keyfile, SC_AC_OP_UPDATE);
     if (r < 0)
	  goto out;

     keybits = key_info->modulus_length;

     /* generate key */
     /* keysize is _not_ passed to the card at any point. it appears to
	infer it from the file size */
     memset(&args, 0, sizeof(args));
     args.exponent = 0x10001;
     sc_append_file_id(&args.pub_file_ref, temppubfile->id);
     sc_append_file_id(&args.pri_file_ref, keyfile->id);
     keybuf = malloc(keybits / 8);
     if (!keybuf) {
	  r=SC_ERROR_OUT_OF_MEMORY;
	  goto out;
     }
     args.pubkey = keybuf;
     args.pubkey_len = keybits / 8;

     r = sc_card_ctl(p15card->card, SC_CARDCTL_JCOP_GENERATE_KEY, (void *)&args);
     if (r < 0)
	  goto out;

     /* extract public key */
     pubkey->algorithm = SC_ALGORITHM_RSA;
     pubkey->u.rsa.modulus.len   = keybits / 8;
     pubkey->u.rsa.modulus.data  = keybuf;
     pubkey->u.rsa.exponent.len  = 3;
     pubkey->u.rsa.exponent.data = malloc(3);
     if (!pubkey->u.rsa.exponent.data) {
	  pubkey->u.rsa.modulus.data = NULL;
	  r=SC_ERROR_OUT_OF_MEMORY;
	  goto out;
     }
     memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3);

 out:
     if (r < 0 && keybuf)
	  free(keybuf);
     if (delete_ok)
	  sc_pkcs15init_rmdir(p15card, profile, temppubfile);
     if (keyfile)
	  sc_file_free(keyfile);
     if (temppubfile)
	  sc_file_free(temppubfile);
     return r;
}
Esempio n. 25
0
/*
 * Key generation
 */
static int
incrypto34_generate_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_pkcs15_object_t *obj,
		sc_pkcs15_pubkey_t *pubkey)
{
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	struct sc_pkcs15_prkey_rsa key_obj;
	struct sc_cardctl_incrypto34_genkey_info args;
	struct sc_file	*temp;
	u8		abignum[RSAKEY_MAX_SIZE];
	unsigned int	keybits;
	int		algorithm, r, delete_it = 0;

	if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Incrypto34 supports only RSA keys.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	if (incrypto34_key_algorithm(key_info->usage, &algorithm) < 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Incrypto34 does not support keys "
			       "that can both sign _and_ decrypt.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	keybits = key_info->modulus_length & ~7UL;
	if (keybits > RSAKEY_MAX_BITS) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unable to generate key, max size is %d",
				RSAKEY_MAX_BITS);
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	if (sc_profile_get_file(profile, "tempfile", &temp) < 0) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Profile doesn't define temporary file "
				"for key generation.");
		return SC_ERROR_NOT_SUPPORTED;
	}
	memset(pubkey, 0, sizeof(*pubkey));

	if ((r = sc_pkcs15init_create_file(profile, p15card, temp)) < 0)
		goto out;
	delete_it = 1;

	/* Create a key object, initializing components to 0xff */
	memset(&key_obj, 0, sizeof(key_obj));
	memset(abignum, 0xFF, sizeof(abignum));
	key_obj.modulus.data = abignum;
	key_obj.modulus.len = keybits >> 3;
	key_obj.d.data = abignum;
	key_obj.d.len = keybits >> 3;
	r = incrypto34_put_key(profile, p15card, algorithm, key_info, &key_obj);
	if (r < 0)
		goto out;

	memset(&args, 0, sizeof(args));
	args.key_id = key_info->key_reference;
	args.key_bits = keybits;
	args.fid = temp->id;
	r = sc_card_ctl(card, SC_CARDCTL_INCRYPTO34_GENERATE_KEY, &args);
	if (r < 0)
		goto out;

	/* extract public key from file and delete it */
	if ((r = sc_select_file(card, &temp->path, NULL)) < 0)
		goto out;
	r = incrypto34_extract_pubkey(card, 1, 0x10, &pubkey->u.rsa.modulus);
	if (r < 0)
		goto out;
	r = incrypto34_extract_pubkey(card, 2, 0x11, &pubkey->u.rsa.exponent);
	if (r < 0)
		goto out;
	pubkey->algorithm = SC_ALGORITHM_RSA;

out:	if (delete_it) {
		sc_pkcs15init_rmdir(p15card, profile, temp);
	}
	sc_file_free(temp);
	if (r < 0) {
		if (pubkey->u.rsa.modulus.data)
			free (pubkey->u.rsa.modulus.data);
		if (pubkey->u.rsa.exponent.data)
			free (pubkey->u.rsa.exponent.data);
	}
	return r;
}
Esempio n. 26
0
/*
 * Create a new PIN
 */
static int
setcos_create_pin_internal(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
	int ignore_ac, sc_pkcs15_auth_info_t *auth_info,
	const u8 *pin, size_t pin_len,
	const u8 *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	u8  data[32];
	int	r;
	struct sc_cardctl_setcos_data_obj data_obj;
	sc_file_t *pinfile = NULL;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

	if (auth_info->attrs.pin.reference >= SETCOS_MAX_PINS)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
		return SC_ERROR_INVALID_PIN_LENGTH;

	/* Verify required access rights if needed (i.e. if the
	 * pin file isn't in the CREATE life cycle state). */
	if (!ignore_ac) {
		r = sc_profile_get_file(profile, "pinfile", &pinfile);
		if (r >= 0)
			r = sc_pkcs15init_authenticate(profile, p15card, pinfile, SC_AC_OP_UPDATE);
		sc_file_free(pinfile);
		if (r < 0)
			return r;
	}

	/* Make command to add a pin-record */

	data_obj.P1 = 01;
	data_obj.P2 = 01;

	/* setcos pin number */
	data[0] = auth_info->attrs.pin.reference;

	memset(&data[1], auth_info->attrs.pin.pad_char, 16); /* padding */
	memcpy(&data[1], (u8 *)pin, pin_len);     /* copy pin*/
	memcpy(&data[9], (u8 *)puk, puk_len);     /* copy puk */

	data[17] = auth_info->tries_left & 0x0F;
	data[18] = auth_info->tries_left & 0x0F;
	/* 0xF0: unlimited unblock tries */
	data[19] = 0xF0 | setcos_puk_retries(profile, auth_info->attrs.pin.reference);

	/* Allow an unlimited number of signatures after a pin verification.
	 * If set to 1 or so, we would have a UserConsent PIN. */
	data[20] = 0x00;

	if (auth_info->attrs.pin.type == 0)
		data[21] = 0x01; /* BCD */
	else
		data[21] = 0x00; /* ASCII */
	if ((auth_info->attrs.pin.flags & 0x010) == 0) /* test for initial pin */
		data[21] |= 0x80;

	data[22]        = 0x00;			/* not used */
	data[23]        = 0x00;			/* not used */

	data_obj.Data    = data;
	data_obj.DataLen = 24;

	r = sc_card_ctl(p15card->card, SC_CARDCTL_SETCOS_PUTDATA, &data_obj);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Esempio n. 27
0
static int entersafe_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
								sc_file_t *df)
{
	struct sc_card *card = p15card->card;
	int             ret;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	{/* df */
		 sc_entersafe_create_data df_data;

		 df_data.type = SC_ENTERSAFE_DF_DATA;
		 df_data.data.df.file_id[0]=(df->id >> 8) & 0xFF;
		 df_data.data.df.file_id[1]=df->id & 0xFF;
		 df_data.data.df.file_count=0x30;
		 df_data.data.df.flag=0x01;
		 df_data.data.df.ikf_size[0]=(df->size>>8)&0xFF;
		 df_data.data.df.ikf_size[1]=df->size&0xFF;
		 df_data.data.df.create_ac=0x10;
		 df_data.data.df.append_ac=0xC0;
		 df_data.data.df.lock_ac=0x10;
		 memcpy(df_data.data.df.aid,df->name,df->namelen);

		 ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &df_data);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Crate DF failed");
	}

	{/* GPKF */
		 sc_file_t *gpkf_file;
		 sc_entersafe_create_data ef_data;

		 /* get p15_gpkf profile */
		 ret = sc_profile_get_file(profile, "p15_gpkf", &gpkf_file);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Get GPKF info failed");

		 ef_data.type=SC_ENTERSAFE_EF_DATA;
		 ef_data.data.ef.file_id[0]=(gpkf_file->id>>8)&0xFF;
		 ef_data.data.ef.file_id[1]=gpkf_file->id&0xFF;
		 ef_data.data.ef.size[0]=(gpkf_file->size>>8)&0xFF;
		 ef_data.data.ef.size[1]=gpkf_file->size&0xFF;
		 ef_data.data.ef.attr[0]=0x15;
		 ef_data.data.ef.attr[1]=0x80;
		 ef_data.data.ef.name=0x00;
		 memset(ef_data.data.ef.ac,0x10,sizeof(ef_data.data.ef.ac));
		 memset(ef_data.data.ef.sm,0x00,sizeof(ef_data.data.ef.sm));

		 sc_file_free(gpkf_file);

		 ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &ef_data);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create GPKF failed");
	}

	{/* p15 efs */
		 const char * create_efs[]={
			  "PKCS15-ODF",
			  "PKCS15-TokenInfo",
			  "PKCS15-UnusedSpace",
			  "PKCS15-AODF",
			  "PKCS15-PrKDF",
			  "PKCS15-PuKDF",
			  "PKCS15-CDF",
			  "PKCS15-DODF",
			  NULL,
		 };
		 int i;
		 sc_file_t *file=0;
		 sc_entersafe_create_data tmp;

		 for(i = 0; create_efs[i]; ++i)   {
			  if (sc_profile_get_file(profile, create_efs[i], &file))   {
				   sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Inconsistent profile: cannot find %s", create_efs[i]);
				   SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INCONSISTENT_PROFILE);
			  }

			  tmp.type=SC_ENTERSAFE_EF_DATA;
			  tmp.data.ef.file_id[0]=(file->id>>8)&0xFF;
			  tmp.data.ef.file_id[1]=file->id&0xFF;
			  tmp.data.ef.size[0]=(file->size>>8)&0xFF;
			  tmp.data.ef.size[1]=file->size&0xFF;
			  tmp.data.ef.attr[0]=0x00;
			  tmp.data.ef.attr[1]=0x00;
			  tmp.data.ef.name=0x00;
			  memset(tmp.data.ef.ac,ENTERSAFE_AC_ALWAYS,sizeof(tmp.data.ef.ac));
			  tmp.data.ef.ac[0]=process_acl_entry(file,SC_AC_OP_READ,ENTERSAFE_AC_ALWAYS); /* read */
			  tmp.data.ef.ac[1]=process_acl_entry(file,SC_AC_OP_UPDATE,ENTERSAFE_AC_ALWAYS); /* update */
			  memset(tmp.data.ef.sm,0x00,sizeof(tmp.data.ef.sm));

			  sc_file_free(file);

			  ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &tmp);
			  SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create pkcs15 file failed");
		 }
	}

	{/* Preinstall keys */
		 ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_PREINSTALL_KEYS, 0);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Preinstall keys failed");
	}

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,ret);
}
Esempio n. 28
0
static int entersafe_init_card(sc_profile_t *profile, sc_pkcs15_card_t *p15card)
{
	struct sc_card *card = p15card->card;
	int ret;

	{/* MF */
		 sc_file_t *mf_file;
		 sc_entersafe_create_data mf_data;

		 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

		 ret = sc_profile_get_file(profile, "MF", &mf_file);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Get MF info failed");

		 mf_data.type = SC_ENTERSAFE_MF_DATA;
		 mf_data.data.df.file_id[0]=0x3F;
		 mf_data.data.df.file_id[1]=0x00;
		 mf_data.data.df.file_count=0x04;
		 mf_data.data.df.flag=0x11;
		 mf_data.data.df.ikf_size[0]=(mf_file->size>>8)&0xFF;
		 mf_data.data.df.ikf_size[1]=mf_file->size&0xFF;
		 mf_data.data.df.create_ac=0x10;
		 mf_data.data.df.append_ac=0xC0;
		 mf_data.data.df.lock_ac=0x10;
		 memcpy(mf_data.data.df.aid,mf_file->name,mf_file->namelen);
		 sc_file_free(mf_file);

		 ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &mf_data);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create MF failed");
	}

	{/* EF(DIR) */
		 sc_file_t *dir_file;
		 size_t fid,size;
		 sc_entersafe_create_data ef_data;
		 u8 *buff=0;

		 /* get dir profile */
		 ret = sc_profile_get_file(profile, "dir", &dir_file);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Get EF(DIR) info failed");
		 fid=dir_file->id;
		 size=dir_file->size;
		 sc_file_free(dir_file);

		 ef_data.type=SC_ENTERSAFE_EF_DATA;
		 ef_data.data.ef.file_id[0]=(fid>>8)&0xFF;
		 ef_data.data.ef.file_id[1]=fid&0xFF;
		 ef_data.data.ef.size[0]=(size>>8)&0xFF;
		 ef_data.data.ef.size[1]=size&0xFF;
		 ef_data.data.ef.attr[0]=0x00;
		 ef_data.data.ef.attr[1]=0x00;
		 ef_data.data.ef.name=0x00;
		 memset(ef_data.data.ef.ac,0x10,sizeof(ef_data.data.ef.ac));
		 memset(ef_data.data.ef.sm,0x00,sizeof(ef_data.data.ef.sm));

		 ret = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_CREATE_FILE, &ef_data);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Create EF(DIR) failed");


		 /* fill file by 0 */
		 buff = calloc(1,size);
		 if(!buff)
			  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS);
		 memset(buff,0,size);

		 ret = sc_update_binary(card,0,buff,size,0);
		 free(buff);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL,ret,"Initialize EF(DIR) failed");
	}

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS);

}