示例#1
0
/*
 * Object deletion.
 */
static int
cardos_delete_object(sc_profile_t *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *obj, const struct sc_path *path)
{
	int r = SC_SUCCESS, stored_in_ef = 0, algorithm = 0;
	size_t keybits;
	sc_file_t *file = NULL;
	struct sc_pkcs15_prkey_info *key_info;
	struct sc_pkcs15_prkey_rsa key_obj;
	struct sc_context *ctx = p15card->card->ctx;
	uint8_t abignum[256];

	LOG_FUNC_CALLED(ctx);
	/*
	 * If we are deleting a private key, overwrite it so it can't be used.
	 */
	if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_PRKEY) {
		key_info = obj->data;
		keybits = key_info->modulus_length & ~7UL;
		init_key_object(&key_obj, abignum, keybits >> 3);
		r = cardos_key_algorithm(key_info->usage, keybits, &algorithm);
		LOG_TEST_RET(ctx, r, "cardos_key_algorithm failed");

		r = sc_select_file(p15card->card, &key_info->path, &file);
		LOG_TEST_RET(ctx, r, "Failed to store key: cannot select parent DF");

		r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
		sc_file_free(file);
		LOG_TEST_RET(ctx, r, "Failed to store key: UPDATE authentication failed");

		r = cardos_put_key(profile, p15card, algorithm, key_info, &key_obj);
		LOG_TEST_RET(ctx, r, "cardos_put_key failed");
	}
示例#2
0
/*
 * Store a private key object.
 */
static int
cardos_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_pkcs15_object_t *obj,
			sc_pkcs15_prkey_t *key)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	struct sc_file *file = NULL;
	int		algorithm = 0, r;

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

	if (cardos_key_algorithm(key_info->usage, key_info->modulus_length, &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;
	}

	r = sc_select_file(p15card->card, &key_info->path, &file);
	if (r)   {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to store key: cannot select parent DF");
		return r;
	}

	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	sc_file_free(file);
	if (r)   {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to store key: 'UPDATE' authentication failed");
		return r;
	}

	r = cardos_put_key(profile, p15card, algorithm, key_info, &key->u.rsa);

	return r;
}
/*
 * Store a private key object.
 */
static int
cardos_store_key(sc_profile_t *profile, sc_card_t *card,
			sc_pkcs15_object_t *obj,
			sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data;
	int		algorithm, r;

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

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

	r = cardos_put_key(profile, card, algorithm, key_info, &key->u.rsa);

	return r;
}
示例#4
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;
}