⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkcs15-etoken.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (sign && decipher)? -1 : 0;}/* * Create a private key object */#define ETOKEN_KEY_OPTIONS	0x02#define ETOKEN_KEY_FLAGS	0x00static intetoken_store_key_component(struct sc_card *card,		int algorithm,		unsigned int key_id, unsigned int pin_id,		unsigned int num,		const u8 *data, size_t len,		int last){	struct sc_cardctl_etoken_obj_info args;	struct tlv	tlv;	unsigned char	buffer[256];	unsigned int	n;	/* Initialize the TLV encoder */	tlv_init(&tlv, buffer, sizeof(buffer));	/* Object address */	tlv_next(&tlv, 0x83);	tlv_add(&tlv, 0x20|num);	/* PSO, n-th component */	tlv_add(&tlv, key_id);	/* Object parameters */	tlv_next(&tlv, 0x85);	tlv_add(&tlv, ETOKEN_KEY_OPTIONS|(last? 0x00 : 0x20));	tlv_add(&tlv, ETOKEN_KEY_FLAGS);	tlv_add(&tlv, algorithm);	tlv_add(&tlv, 0x00);	tlv_add(&tlv, 0xFF);	/* use count */	tlv_add(&tlv, 0xFF);	/* DEK (whatever this is) */	tlv_add(&tlv, 0x00);	tlv_add(&tlv, 0x00);	/* AC bytes */	tlv_next(&tlv, 0x86);	tlv_add(&tlv, pin_id);	/* AC USE */	tlv_add(&tlv, pin_id);	/* AC CHANGE */	tlv_add(&tlv, pin_id);	/* UNKNOWN */	/* The next 4 AC bytes are sent by the eToken run-time	 * as well, but aren't documented anywhere.	 * Key generation won't work without them, however. */	tlv_add(&tlv, 0);	tlv_add(&tlv, 0);	tlv_add(&tlv, 0);	tlv_add(&tlv, 0);	/* SM bytes */	tlv_next(&tlv, 0x8B);	for (n = 0; n < 16; n++)		tlv_add(&tlv, 0xFF);	/* key component */	tlv_next(&tlv, 0x8f);	tlv_add(&tlv, len+1);	tlv_add(&tlv, 0);	while (len--)		tlv_add(&tlv, *data++);	args.data = buffer;	args.len = tlv_len(&tlv);	return sc_card_ctl(card, SC_CARDCTL_ETOKEN_PUT_DATA_OCI, &args);}static intetoken_store_key(struct sc_profile *profile, struct sc_card *card,		int algorithm, unsigned int key_id,		struct sc_pkcs15_prkey_rsa *key){	struct sc_pkcs15_pin_info pin_info;	int		r, pin_id;	sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &pin_info);	if ((pin_id = pin_info.reference) < 0)		pin_id = 0;	r = etoken_store_key_component(card, algorithm, key_id, pin_id, 0,			key->modulus.data, key->modulus.len, 0);	if (r < 0)		return r;	r = etoken_store_key_component(card, algorithm, key_id, pin_id, 1,			key->d.data, key->d.len, 1);	return r;}/* * Store a private key */static intetoken_new_key(struct sc_profile *profile, struct sc_card *card,		struct sc_pkcs15_prkey *key, unsigned int index,		struct sc_pkcs15_prkey_info *info){	struct sc_pkcs15_prkey_rsa *rsa;	int		algorithm, key_id, r;	if (key->algorithm != SC_ALGORITHM_RSA) {		error(profile, "eToken supports RSA keys only.\n");		return SC_ERROR_NOT_SUPPORTED;	}	if (etoken_key_algorithm(info->usage, &algorithm) < 0) {		error(profile, "eToken does not support keys "			       "that can both sign _and_ decrypt.");		return SC_ERROR_NOT_SUPPORTED;	}	rsa = &key->u.rsa;	key_id = ETOKEN_KEY_ID(index);	r = etoken_store_key(profile, card, algorithm, key_id, rsa);	if (r >= 0) {		info->path = profile->df_info->file->path;		info->key_reference = key_id;	}	return r;}/* * Allocate a file */static intetoken_new_file(struct sc_profile *profile, struct sc_card *card,		unsigned int type, unsigned int num,		struct sc_file **out){	struct sc_file	*file;	struct sc_path	*p;	char		name[64], *tag, *desc;	desc = tag = 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;#ifdef SC_PKCS15_TYPE_PRKEY_DSA		case SC_PKCS15_TYPE_PRKEY_DSA:			desc = "DSA private key";			tag = "private-key";			break;		case SC_PKCS15_TYPE_PUBKEY_DSA:			desc = "DSA public key";			tag = "public-key";			break;#endif		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)) {			error(profile, "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) {		error(profile, "Profile doesn't define %s template (%s)\n",				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;}/* * Extract a key component from the public key file populated by * GENERATE KEY PAIR */static intetoken_extract_pubkey(struct sc_card *card, int nr, u8 tag,			sc_pkcs15_bignum_t *bn){	u8	buf[256];	int	r, count;	r = sc_read_record(card, nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR);	if (r < 0)		return r;	count = r - 4;	if (count <= 0 || buf[0] != tag || buf[1] != count + 2	 || buf[2] != count + 1 || buf[3] != 0)		return SC_ERROR_INTERNAL;	bn->len = count;	bn->data = (u8 *) malloc(count);	memcpy(bn->data, buf + 4, count);	return 0;}/* * Key generation */static intetoken_generate_key(struct sc_profile *profile, struct sc_card *card,		unsigned int index, unsigned int keybits,		sc_pkcs15_pubkey_t *pubkey,		struct sc_pkcs15_prkey_info *info){	struct sc_pkcs15_prkey_rsa key_obj;	struct sc_cardctl_etoken_genkey_info args;	struct sc_file	*temp;	u8		abignum[RSAKEY_MAX_SIZE];	u8		randbuf[64], key_id;	int		algorithm, r, delete_it = 0;	keybits &= ~7UL;	if (keybits > RSAKEY_MAX_BITS) {		error(profile, "Unable to generate key, max size is %d\n",				RSAKEY_MAX_BITS);		return SC_ERROR_INVALID_ARGUMENTS;	}	if (etoken_key_algorithm(info->usage, &algorithm) < 0) {		error(profile, "eToken does not support keys "			       "that can both sign _and_ decrypt.");		return SC_ERROR_NOT_SUPPORTED;	}	if (sc_profile_get_file(profile, "tempfile", &temp) < 0) {		error(profile, "Profile doesn't define temporary file "				"for key generation.\n");		return SC_ERROR_NOT_SUPPORTED;	}	memset(pubkey, 0, sizeof(*pubkey));	if ((r = sc_pkcs15init_create_file(profile, card, temp)) < 0)		goto out;	delete_it = 1;	key_id = ETOKEN_KEY_ID(index);	/* 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 = etoken_store_key(profile, card, algorithm, key_id, &key_obj);	if (r < 0)		goto out;	memset(&args, 0, sizeof(args));#ifdef notyet	if ((r = scrandom_get_data(randbuf, sizeof(randbuf))) < 0)		goto out;	/* For now, we have to rely on the card's internal number	 * generator because libscrandom is static, which causes	 * all sorts of headaches when linking against it	 * (some platforms don't allow non-PIC code in a shared lib,	 * such as ia64).	 */	args.random_data = randbuf;	args.random_len = sizeof(randbuf);#endif	args.key_id = key_id;	args.key_bits = keybits;	args.fid = temp->id;	r = sc_card_ctl(card, SC_CARDCTL_ETOKEN_GENERATE_KEY, &args);	memset(randbuf, 0, sizeof(randbuf));	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 = etoken_extract_pubkey(card, 1, 0x10, &pubkey->u.rsa.modulus);	if (r < 0)		goto out;	r = etoken_extract_pubkey(card, 2, 0x11, &pubkey->u.rsa.exponent);	if (r < 0)		goto out;	pubkey->algorithm = SC_ALGORITHM_RSA;	info->key_reference = key_id;	info->path = profile->df_info->file->path;out:	if (delete_it) {		sc_pkcs15init_rmdir(card, 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;}static voiderror(struct sc_profile *profile, const char *fmt, ...){	char	buffer[256];	va_list	ap;	va_start(ap, fmt);	vsnprintf(buffer, sizeof(buffer), fmt, ap);	va_end(ap);	if (profile->cbs)		profile->cbs->error("%s", buffer);}struct sc_pkcs15init_operations sc_pkcs15init_etoken_operations = {	etoken_erase,	etoken_init_app,	etoken_new_pin,	etoken_new_key,	etoken_new_file,	etoken_generate_key};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -