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

📄 pkcs15-lib.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	return r;}static intsc_pkcs15init_store_data(struct sc_pkcs15_card *p15card,		struct sc_profile *profile,		unsigned int type, sc_pkcs15_der_t *data,		struct sc_path *path){	struct sc_file	*file = NULL;	unsigned int	index;	int		r;	/* Get the number of objects of this type already on this card */	index = sc_pkcs15_get_objects(p15card,			type & SC_PKCS15_TYPE_CLASS_MASK, NULL, 0);	/* Set the SO PIN reference from card */	if ((r = set_so_pin_from_card(p15card, profile)) < 0)		return r;	/* Allocate data file */	r = profile->ops->new_file(profile, p15card->card, type, index, &file);	if (r < 0) {		p15init_error("Unable to allocate file");		goto done;	}	if (file->path.count == 0) {		file->path.index = 0;		file->path.count = -1;	}	r = sc_pkcs15init_update_file(profile, p15card->card,			file, data->value, data->len);	*path = file->path;done:	if (file)		sc_file_free(file);	return r;}/* * Map X509 keyUsage extension bits to PKCS#15 keyUsage bits */static unsigned int	x509_to_pkcs15_private_key_usage[16] = {	SC_PKCS15_PRKEY_USAGE_SIGN	| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,	/* digitalSignature */	SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,	/* NonRepudiation */	SC_PKCS15_PRKEY_USAGE_UNWRAP,		/* keyEncipherment */	SC_PKCS15_PRKEY_USAGE_DECRYPT,		/* dataEncipherment */	SC_PKCS15_PRKEY_USAGE_DERIVE,		/* keyAgreement */	SC_PKCS15_PRKEY_USAGE_SIGN	| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,	/* keyCertSign */	SC_PKCS15_PRKEY_USAGE_SIGN	| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,	/* cRLSign */};static unsigned int	x509_to_pkcs15_public_key_usage[16] = {	SC_PKCS15_PRKEY_USAGE_VERIFY	| SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,	/* digitalSignature */	SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,	/* NonRepudiation */	SC_PKCS15_PRKEY_USAGE_WRAP,		/* keyEncipherment */	SC_PKCS15_PRKEY_USAGE_ENCRYPT,		/* dataEncipherment */	SC_PKCS15_PRKEY_USAGE_DERIVE,		/* keyAgreement */	SC_PKCS15_PRKEY_USAGE_VERIFY	| SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,	/* keyCertSign */	SC_PKCS15_PRKEY_USAGE_VERIFY	| SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,	/* cRLSign */};static intsc_pkcs15init_map_usage(unsigned long x509_usage, int _private){	unsigned int	p15_usage, n, *bits;	bits = _private? x509_to_pkcs15_private_key_usage		      : x509_to_pkcs15_public_key_usage;	for (n = p15_usage = 0; n < 16; n++) {		if (x509_usage & (1 << n))			p15_usage |= bits[n];	}	return p15_usage;}/* * Compute modulus length */size_tsc_pkcs15init_keybits(sc_pkcs15_bignum_t *bn){	unsigned int	mask, bits;	if (!bn || !bn->len)		return 0;	bits = bn->len << 3;	for (mask = 0x80; !(bn->data[0] & mask); mask >>= 1)		bits--;	return bits;}/* * Check whether the card has native crypto support for this key. */static int__check_key_compatibility(struct sc_pkcs15_card *p15card,			  struct sc_pkcs15_prkey *key,			  unsigned int x509_usage,			  unsigned int key_length,			  unsigned int flags){	struct sc_algorithm_info *info;	unsigned int count;	int bad_usage = 0;	count = p15card->card->algorithm_count;	for (info = p15card->card->algorithms; count--; info++) {		/* XXX: check for equality, or <= ? */		if (info->algorithm != key->algorithm		 || info->key_length != key_length		 || (info->flags & flags) != flags)			continue;		if (key->algorithm == SC_ALGORITHM_RSA		 && info->u._rsa.exponent != 0) {			sc_pkcs15_bignum_t *e = &key->u.rsa.exponent;			unsigned long	exponent = 0;			unsigned int	n;			if (e->len > 4)				continue;			for (n = 0; n < e->len; n++) {				exponent <<= 8;				exponent |= e->data[n];			}			if (info->u._rsa.exponent != exponent)				continue;		}		/* Some cards will not support keys to do		 * both sign/decrypt.		 * For the convenience of the user, catch these		 * here. */		if (info->flags & SC_ALGORITHM_NEED_USAGE) {			unsigned int	usage;			usage = sc_pkcs15init_map_usage(x509_usage, 1);			if ((usage & (SC_PKCS15_PRKEY_USAGE_UNWRAP				     |SC_PKCS15_PRKEY_USAGE_DECRYPT))			 && (usage & SC_PKCS15_PRKEY_USAGE_SIGN)) {				bad_usage = 1;				continue;			}		}		return 1;	}	return bad_usage? -1 : 0;}static intcheck_key_compatibility(struct sc_pkcs15_card *p15card,			struct sc_pkcs15_prkey *key,			unsigned int x509_usage,			unsigned int key_length,			unsigned int flags){	int	res;	res = __check_key_compatibility(p15card, key,				x509_usage, key_length, flags);	if (res < 0) {		p15init_error("This device requires that keys have a "			"specific key usage.\n"			"Keys can be used for either signature or decryption, "			"but not both.\n"			"Please specify a key usage.\n");		res = 0;	}	return res;}intsc_pkcs15init_requires_restrictive_usage(struct sc_pkcs15_card *p15card,			struct sc_pkcs15init_prkeyargs *keyargs,			unsigned int key_length){	int	res;	if (key_length == 0)		key_length = prkey_bits(&keyargs->key);	res = __check_key_compatibility(p15card, &keyargs->key,			 keyargs->x509_usage,			 key_length, 0);	return res < 0;}/* * Check RSA key for consistency, and compute missing * CRT elements */intprkey_fixup_rsa(struct sc_pkcs15_prkey_rsa *key){	if (!key->modulus.len || !key->exponent.len	 || !key->d.len || !key->p.len || !key->q.len) {		p15init_error("Missing private RSA coefficient");		return SC_ERROR_INVALID_ARGUMENTS;	}#ifdef HAVE_OPENSSL#define GETBN(dst, src, mem) \	do {	dst.len = BN_num_bytes(src); \		assert(dst.len <= sizeof(mem)); \		BN_bn2bin(src, dst.data = mem); \	} while (0)	/* Generate additional parameters.	 * At least the GPK seems to need the full set of CRT	 * parameters; storing just the private exponent produces	 * invalid signatures.	 * The cryptoflex does not seem to be able to do any sort	 * of RSA without the full set of CRT coefficients either	 */	if (!key->dmp1.len || !key->dmq1.len || !key->iqmp.len) {		static u8 dmp1[256], dmq1[256], iqmp[256];		RSA    *rsa;		BIGNUM *aux = BN_new();		BN_CTX *ctx = BN_CTX_new();		rsa = RSA_new();		rsa->n = BN_bin2bn(key->modulus.data, key->modulus.len, 0);		rsa->e = BN_bin2bn(key->exponent.data, key->exponent.len, 0);		rsa->d = BN_bin2bn(key->d.data, key->d.len, 0);		rsa->p = BN_bin2bn(key->p.data, key->p.len, 0);		rsa->q = BN_bin2bn(key->q.data, key->q.len, 0);		if (!rsa->dmp1)			rsa->dmp1 = BN_new();		if (!rsa->dmq1)			rsa->dmq1 = BN_new();		if (!rsa->iqmp)			rsa->iqmp = BN_new();		aux = BN_new();		ctx = BN_CTX_new();		BN_sub(aux, rsa->q, BN_value_one());		BN_mod(rsa->dmq1, rsa->d, aux, ctx);		BN_sub(aux, rsa->p, BN_value_one());		BN_mod(rsa->dmp1, rsa->d, aux, ctx);		BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);		BN_clear_free(aux);		BN_CTX_free(ctx);		/* Not thread safe, but much better than a memory leak */		GETBN(key->dmp1, rsa->dmp1, dmp1);		GETBN(key->dmq1, rsa->dmq1, dmq1);		GETBN(key->iqmp, rsa->iqmp, iqmp);		RSA_free(rsa);	}#undef GETBN#endif	return 0;}static intprkey_fixup(sc_pkcs15_prkey_t *key){	switch (key->algorithm) {	case SC_ALGORITHM_RSA:		return prkey_fixup_rsa(&key->u.rsa);	case SC_ALGORITHM_DSA:		/* for now */		return 0;	}	return 0;}static intprkey_bits(sc_pkcs15_prkey_t *key){	switch (key->algorithm) {	case SC_ALGORITHM_RSA:		return sc_pkcs15init_keybits(&key->u.rsa.modulus);	case SC_ALGORITHM_DSA:		return sc_pkcs15init_keybits(&key->u.dsa.q);	}	p15init_error("Unsupported key algorithm.\n");	return SC_ERROR_NOT_SUPPORTED;}static intprkey_pkcs15_algo(sc_pkcs15_prkey_t *key){	switch (key->algorithm) {	case SC_ALGORITHM_RSA:		return SC_PKCS15_TYPE_PRKEY_RSA;	case SC_ALGORITHM_DSA:		return SC_PKCS15_TYPE_PRKEY_DSA;	}	p15init_error("Unsupported key algorithm.\n");	return SC_ERROR_NOT_SUPPORTED;}static struct sc_pkcs15_df *find_df_by_type(struct sc_pkcs15_card *p15card, int type){	struct sc_pkcs15_df *df = p15card->df_list;		while (df != NULL && df->type != type)		df = df->next;	return df;}intselect_id(struct sc_pkcs15_card *p15card, int type, struct sc_pkcs15_id *id){	unsigned int nid = DEFAULT_ID;	struct sc_pkcs15_object *dummy;	int r, user_provided;	int (*func)(struct sc_pkcs15_card *,			const struct sc_pkcs15_id *,			struct sc_pkcs15_object **);	switch (type) {	case SC_PKCS15_TYPE_PRKEY:		func = sc_pkcs15_find_prkey_by_id;		break;	case SC_PKCS15_TYPE_PUBKEY:		func = sc_pkcs15_find_pubkey_by_id;		break;	case SC_PKCS15_TYPE_CERT:		func = sc_pkcs15_find_cert_by_id;		break;	case SC_PKCS15_TYPE_DATA_OBJECT:		func = sc_pkcs15_find_data_object_by_id;		break;	default:		return SC_ERROR_INVALID_ARGUMENTS;	}	user_provided = (id->len != 0);	while (nid < 255) {		if (!user_provided) {			id->value[0] = nid++;			id->len = 1;		}		r = func(p15card, id, &dummy);		if (r == SC_ERROR_OBJECT_NOT_FOUND)			return 0;		if (user_provided)			return SC_ERROR_ID_NOT_UNIQUE;	}		return SC_ERROR_TOO_MANY_OBJECTS;}/* * Update EF(DIR) */static intsc_pkcs15init_update_dir(struct sc_pkcs15_card *p15card,		struct sc_profile *profile,		struct sc_app_info *app){	struct sc_card *card = p15card->card;	int	r, retry = 1;	do {		struct sc_file	*dir_file;		struct sc_path	path;		card->ctx->log_errors = 0;		r = sc_enum_apps(card);		card->ctx->log_errors = 1;		if (r != SC_ERROR_FILE_NOT_FOUND)			break;		sc_format_path("3F002F00", &path);		if (sc_profile_get_file_by_path(profile, &path, &dir_file) < 0)			return r;		r = sc_pkcs15init_update_file(profile, card, dir_file, NULL, 0);		sc_file_free(dir_file);	} while (retry--);	if (r >= 0) {		card->app[card->app_count++] = app;		r = sc_update_dir(card, NULL);	}	return r;}static intsc_pkcs15init_update_tokeninfo(struct sc_pkcs15_card *p15card,		struct sc_profile *profile){	struct sc_card	*card = p15card->card;	u8		*buf = NULL;	size_t		size;	int		r;	r = sc_pkcs15_encode_tokeninfo(card->ctx, p15card, &buf, &size);	if (r >= 0)		r = sc_pkcs15init_update_file(profile, card,			       p15card->file_tokeninfo, buf, size);	if (buf)		free(buf);	return r;}static intsc_pkcs15init_update_odf(struct sc_pkcs15_card *p15card,		struct sc_profile *profile){	struct sc_card	*card = p15card->card;	u8		*buf = NULL;	size_t		size;	int		r;	r = sc_pkcs15_encode_odf(card->ctx, p15card, &buf, &size);	if (r >= 0)		r = sc_pkcs15init_update_file(profile, card,			       p15card->file_odf, buf, size);	if (buf)		free(buf);	return r;}static intsc_pkcs15init_add_object(struct sc_pkcs15_card *p15card,		struct sc_profile *profile,		unsigned int df_type,		struct sc_pkcs15_object *object){	struct sc_pkcs15_df *df;	struct sc_card	*card = p15card->card;	struct sc_file	*file = NULL, *pfile;	u8		*buf = NULL;	size_t		bufsize;	int		update_odf = 0, r = 0;	df = find_df_by_type(p15card, df_type);	if (df == NULL) {		file = profile->df[df_type];		if (file == NULL) {			p15init_error("Profile doesn't define a DF file %u",			 		df_type);			return SC_ERROR_NOT_SUPPORTED;		}		sc_pkcs15_add_df(p15card, df_type, &file->path, file);		df = find_df_by_type(p15card, df_type);		assert(df != NULL);		update_odf = 1;	}	if (object) {		object->df = df;		r = sc_pkcs15_add_object(p15card, object); 		if (r < 0)			return r;	}		if (!sc_profile_get_file_by_path(profile, &df->path, &pfile))		file = pfile;	r = sc_pkcs15_encode_df(card->ctx, p15card, df, &buf, &bufsize);	if (r >= 0) {		r = sc_pkcs15init_update_file(profile, card,				file, buf, bufsize);		free(buf);	}	if (pfile)		sc_file_free(pfile);	/* Now update the ODF if we have to */	if (r >= 0 && update_odf)		r = sc_pkcs15init_update_odf(p15card, profile);	return r;}intsc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card,		struct sc_profile *profile,		struct sc_pkcs15_object *object,		int new_attrib_type,		void *new_value,		int new_len){	struct sc_card	*card = p15card->card;	u8		*buf = NULL;	size_t		bufsize;	int		df_type, r = 0;	struct sc_pkcs15_df *df;	if (object == NULL || object->df == NULL)		return SC_ERROR_OBJECT_NOT_FOUND;	df_type = object->df->type;	df = find_df_by_type(p15card, df_type);	if (df == NULL)		return SC_ERROR_OBJECT_NOT_FOUND;	switch(new_attrib_type)	{	case P15_ATTR_TYPE_LABEL:		if (new_len >= SC_PKCS15_MAX_LABEL_SIZE)			return SC_ERROR_INVALID_ARGUMENTS;		memcpy(object->label, new_value, new_len);		object->label[new_len] = '\0';		break;	case P15_ATTR_TYPE_ID:		switch(df_type) {		case SC_PKCS15_PRKDF:			((sc_pkcs15_prkey_info_t *) object->data)->id =				*((sc_pkcs15_id_t *) new_value);			break;		case SC_PKCS15_PUKDF:		case SC_PKCS15_PUKDF_TRUSTED:			((sc_pkcs15_pubkey_info_t *) object->data)->id =				*((sc_pkcs15_id_t *) new_value);			break;		case SC_PKCS15_CDF:		case SC_PKCS15_CDF_TRUSTED:		case SC_PKCS15_CDF_USEFUL:			((sc_pkcs15_cert_info_t *) object->data)->id =				*((sc_pkcs15_id_t *) new_value);			break;		default:			return SC_ERROR_NOT_SUPPORTED;		}		break;	default:		return SC_ERROR_NOT_SUPPORTED;	}	r = sc_pkcs15_encode_df(card->ctx, p15card, df, &buf, &bufsize);	if (r >= 0) {		r = sc_pkcs15init_update_file(profile, card,				df->file, buf, bufsize);		free(buf);	}	return r < 0 ? r : 0;}

⌨️ 快捷键说明

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