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

📄 framework-pkcs15.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * framework-pkcs15.c: PKCS#15 framework and related objects * * Copyright (C) 2002  Timo Ter鋝 <timo.teras@iki.fi> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdlib.h>#include <string.h>#include "sc-pkcs11.h"#ifdef USE_PKCS15_INIT#include "opensc/pkcs15-init.h"#endif#define MAX_CACHE_PIN		32struct pkcs15_slot_data {	struct sc_pkcs15_object *auth_obj;	struct {		u8		value[MAX_CACHE_PIN];		unsigned int	len;	}			pin[2];};#define slot_data(p)		((struct pkcs15_slot_data *) p)#define slot_data_auth(p)	(slot_data(p)->auth_obj)#define slot_data_pin_info(p)	(slot_data_auth(p)? \		(struct sc_pkcs15_pin_info *) slot_data_auth(p)->data : NULL)#define check_attribute_buffer(attr,size)	\	if (attr->pValue == NULL_PTR) {         \		attr->ulValueLen = size;        \		return CKR_OK;                  \	}                                       \	if (attr->ulValueLen < size) {		\		attr->ulValueLen = size;	\		return CKR_BUFFER_TOO_SMALL;    \	}                                       \        attr->ulValueLen = size;#define MAX_OBJECTS	64struct pkcs15_fw_data {	struct sc_pkcs15_card *		p15_card;	struct pkcs15_any_object *	objects[MAX_OBJECTS];	unsigned int			num_objects;	unsigned int			locked;};struct pkcs15_any_object {	struct sc_pkcs11_object		base;	unsigned int			refcount;	size_t				size;	struct sc_pkcs15_object *	p15_object;	struct pkcs15_pubkey_object *	related_pubkey;	struct pkcs15_cert_object *	related_cert;	struct pkcs15_prkey_object *	related_privkey;};struct pkcs15_cert_object {	struct pkcs15_any_object	base;	struct sc_pkcs15_cert_info *	cert_info;        struct sc_pkcs15_cert *		cert_data;};#define cert_flags		base.base.flags#define cert_p15obj		base.p15_object#define cert_pubkey		base.related_pubkey#define cert_issuer		base.related_certstruct pkcs15_prkey_object {	struct pkcs15_any_object	base;	struct sc_pkcs15_prkey_info *	prv_info;};#define prv_flags		base.base.flags#define prv_p15obj		base.p15_object#define prv_pubkey		base.related_pubkey#define prv_cert		base.related_cert#define prv_next		base.related_privkeystruct pkcs15_pubkey_object {	struct pkcs15_any_object	base;	struct sc_pkcs15_pubkey_info *	pub_info;	/* NULL for key extracted from cert */	struct sc_pkcs15_pubkey *	pub_data;};#define pub_flags		base.base.flags#define pub_p15obj		base.p15_object#define pub_cert		base.related_cert#define __p15_type(obj)		(((obj) && (obj)->p15_object)? ((obj)->p15_object->type) : -1)#define is_privkey(obj)		(__p15_type(obj) == SC_PKCS15_TYPE_PRKEY_RSA)#define is_pubkey(obj)		(__p15_type(obj) == SC_PKCS15_TYPE_PUBKEY_RSA)#define is_cert(obj)		(__p15_type(obj) == SC_PKCS15_TYPE_CERT_X509)extern struct sc_pkcs11_object_ops pkcs15_cert_ops;extern struct sc_pkcs11_object_ops pkcs15_prkey_ops;extern struct sc_pkcs11_object_ops pkcs15_pubkey_ops;static int	__pkcs15_release_object(struct pkcs15_any_object *);static int	register_mechanisms(struct sc_pkcs11_card *p11card);static CK_RV	get_public_exponent(struct sc_pkcs15_pubkey *,					CK_ATTRIBUTE_PTR);static CK_RV	get_modulus(struct sc_pkcs15_pubkey *,					CK_ATTRIBUTE_PTR);static CK_RV	get_modulus_bits(struct sc_pkcs15_pubkey *,					CK_ATTRIBUTE_PTR);static CK_RV	get_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr);static CK_RV	asn1_sequence_wrapper(const u8 *, size_t, CK_ATTRIBUTE_PTR);static void	cache_pin(void *, int, const void *, size_t);static int	revalidate_pin(struct pkcs15_slot_data *data,				struct sc_pkcs11_session *ses);static int	lock_card(struct pkcs15_fw_data *);static int	unlock_card(struct pkcs15_fw_data *);/* PKCS#15 Framework */static CK_RV pkcs15_bind(struct sc_pkcs11_card *p11card){	struct pkcs15_fw_data *fw_data;	int rc;	if (!(fw_data = (struct pkcs15_fw_data *) calloc(1, sizeof(*fw_data))))		return CKR_HOST_MEMORY;	p11card->fw_data = fw_data;	rc = sc_pkcs15_bind(p11card->card, &fw_data->p15_card);	sc_debug(context, "Binding to PKCS#15, rc=%d\n", rc);	if (rc < 0)		return sc_to_cryptoki_error(rc, p11card->reader);	return register_mechanisms(p11card);}static CK_RV pkcs15_unbind(struct sc_pkcs11_card *p11card){        struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	unsigned int i;	int rc;	for (i = 0; i < fw_data->num_objects; i++) 		__pkcs15_release_object(fw_data->objects[i]);	unlock_card(fw_data);	rc = sc_pkcs15_unbind(fw_data->p15_card);        return sc_to_cryptoki_error(rc, p11card->reader);}static void pkcs15_init_token_info(struct sc_pkcs15_card *card, CK_TOKEN_INFO_PTR pToken){	int sn_start = strlen(card->serial_number) - 16;	strcpy_bp(pToken->manufacturerID, card->manufacturer_id, 32);	strcpy_bp(pToken->model, "PKCS #15 SCard", 16);	/* Take the last 16 chars of the serial number (if the are more then 16).	   _Assuming_ that the serial number is a Big Endian counter, this will	   assure that the serial within each type of card will be unique in pkcs11	   (at least for the first 16^16 cards :-) */	if (sn_start < 0)		sn_start = 0;	strcpy_bp(pToken->serialNumber, card->serial_number + sn_start, 16);	pToken->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;	pToken->ulSessionCount = 0; /* FIXME */	pToken->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;	pToken->ulRwSessionCount = 0; /* FIXME */	pToken->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;	pToken->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;	pToken->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;	pToken->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;	pToken->hardwareVersion.major = 1;	pToken->hardwareVersion.minor = 0;	pToken->firmwareVersion.major = 1;	pToken->firmwareVersion.minor = 0;}static int__pkcs15_create_object(struct pkcs15_fw_data *fw_data,		       struct pkcs15_any_object **result,		       struct sc_pkcs15_object *p15_object,		       struct sc_pkcs11_object_ops *ops,		       size_t size){	struct pkcs15_any_object *obj;	if (fw_data->num_objects >= MAX_OBJECTS)		return SC_ERROR_TOO_MANY_OBJECTS;	if (!(obj = (struct pkcs15_any_object *) calloc(1, size)))		return SC_ERROR_OUT_OF_MEMORY;	fw_data->objects[fw_data->num_objects++] = obj;	obj->base.ops = ops;	obj->p15_object = p15_object;	obj->refcount = 1;	obj->size = size;	*result = obj;	return 0;}static int__pkcs15_release_object(struct pkcs15_any_object *obj){	if (--(obj->refcount) != 0)		return obj->refcount;		memset(obj, 0xAA, obj->size);	free(obj);	return 0;}static int__pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data,	struct sc_pkcs15_object *cert, struct pkcs15_any_object **cert_object){	struct sc_pkcs15_cert_info *p15_info;	struct sc_pkcs15_cert *p15_cert;	struct pkcs15_cert_object *object;        struct pkcs15_pubkey_object *obj2;	int rv;	p15_info = (struct sc_pkcs15_cert_info *) cert->data;	if ((rv = sc_pkcs15_read_certificate(fw_data->p15_card, p15_info, &p15_cert) < 0))		return rv;        /* Certificate object */	rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &object,					cert, &pkcs15_cert_ops,					sizeof(struct pkcs15_cert_object));	if (rv < 0)		return rv;	object->cert_info = p15_info;	object->cert_data = p15_cert;        /* Corresponding public key */	rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &obj2,					NULL, &pkcs15_pubkey_ops,					sizeof(struct pkcs15_pubkey_object));	if (rv < 0)		return rv;	obj2->pub_data = &p15_cert->key;	obj2->pub_cert = object;	object->cert_pubkey = obj2;	if (cert_object != NULL)		*cert_object = (struct pkcs15_any_object *) object;	return 0;}static int__pkcs15_create_pubkey_object(struct pkcs15_fw_data *fw_data,	struct sc_pkcs15_object *pubkey, struct pkcs15_any_object **pubkey_object){	struct pkcs15_pubkey_object *object;	struct sc_pkcs15_pubkey *p15_key;	int rv;	/* Read public key from card */	if ((rv = sc_pkcs15_read_pubkey(fw_data->p15_card, pubkey, &p15_key)) < 0)		return rv;        /* Public key object */	rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &object,					pubkey, &pkcs15_pubkey_ops,					sizeof(struct pkcs15_pubkey_object));	if (rv >= 0) {		object->pub_info = (struct sc_pkcs15_pubkey_info *) pubkey->data;		object->pub_data = p15_key;	}	if (pubkey_object != NULL)		*pubkey_object = (struct pkcs15_any_object *) object;	return rv;}static int__pkcs15_create_prkey_object(struct pkcs15_fw_data *fw_data,	struct sc_pkcs15_object *prkey, struct pkcs15_any_object **prkey_object){	struct pkcs15_prkey_object *object;	int rv;	rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &object,					prkey, &pkcs15_prkey_ops,					sizeof(struct pkcs15_prkey_object));	if (rv >= 0)		object->prv_info = (struct sc_pkcs15_prkey_info *) prkey->data;	if (prkey_object != NULL)		*prkey_object = (struct pkcs15_any_object *) object;	return 0;}static intpkcs15_create_pkcs11_objects(struct pkcs15_fw_data *fw_data,			     int p15_type, const char *name,			     int (*create)(struct pkcs15_fw_data *,				     	   struct sc_pkcs15_object *,				     	   struct pkcs15_any_object **any_object)){	struct sc_pkcs15_object *p15_object[MAX_OBJECTS];	int i, count, rv;        rv = count = sc_pkcs15_get_objects(fw_data->p15_card, p15_type, p15_object, MAX_OBJECTS);	if (rv >= 0) {		sc_debug(context, "Found %d %s%s\n", count,				name, (count == 1)? "" : "s");	}	for (i = 0; rv >= 0 && i < count; i++) {		rv = create(fw_data, p15_object[i], NULL);	}	return count;}static void__pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_object *pk){	sc_pkcs15_id_t *id = &pk->prv_info->id;	unsigned int i;	for (i = 0; i < fw_data->num_objects; i++) {		struct pkcs15_any_object *obj = fw_data->objects[i];		if (obj->base.flags & SC_PKCS11_OBJECT_HIDDEN)			continue;		if (is_privkey(obj) && obj != (struct pkcs15_any_object *) pk) {			/* merge private keys with the same ID and			 * different usage bits */			struct pkcs15_prkey_object *other, **pp;			other = (struct pkcs15_prkey_object *) obj;			if (sc_pkcs15_compare_id(&other->prv_info->id, id)) {				obj->base.flags |= SC_PKCS11_OBJECT_HIDDEN;				for (pp = &pk->prv_next; *pp; pp = &(*pp)->prv_next)					;				*pp = (struct pkcs15_prkey_object *) obj;			}		} else		if (is_cert(obj) && !pk->prv_cert) {			struct pkcs15_cert_object *cert;						cert = (struct pkcs15_cert_object *) obj;			if (sc_pkcs15_compare_id(&cert->cert_info->id, id))				pk->prv_cert = cert;		} else		if (is_pubkey(obj) && !pk->prv_pubkey) {			struct pkcs15_pubkey_object *pubkey;						pubkey = (struct pkcs15_pubkey_object *) obj;			if (sc_pkcs15_compare_id(&pubkey->pub_info->id, id))				pk->prv_pubkey = pubkey;		}	}}static void__pkcs15_cert_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_object *cert){	struct sc_pkcs15_cert *c1 = cert->cert_data, *c2;	unsigned int i;	/* Loop over all certificates see if we find the certificate of	 * the issuer */	for (i = 0; i < fw_data->num_objects; i++) {		struct pkcs15_any_object *obj = fw_data->objects[i];		if (!is_cert(obj) || obj == (struct pkcs15_any_object *) cert)			continue;		c2 = ((struct pkcs15_cert_object *) obj)->cert_data;		if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len)			continue;		if (c1->issuer_len == c2->subject_len		 && !memcmp(c1->issuer, c2->subject, c1->issuer_len)) {			cert->cert_issuer = (struct pkcs15_cert_object *) obj;			return;		}	}}static voidpkcs15_bind_related_objects(struct pkcs15_fw_data *fw_data){	unsigned int i;	/* Loop over all private keys and attached related certificate	 * and/or public key	 */	for (i = 0; i < fw_data->num_objects; i++) {		struct pkcs15_any_object *obj = fw_data->objects[i];		if (obj->base.flags & SC_PKCS11_OBJECT_HIDDEN)			continue;		if (is_privkey(obj)) {			__pkcs15_prkey_bind_related(fw_data, (struct pkcs15_prkey_object *) obj);		} else if (is_cert(obj)) {			__pkcs15_cert_bind_related(fw_data, (struct pkcs15_cert_object *) obj);		}	}}static intpool_is_present(struct sc_pkcs11_pool *pool, struct pkcs15_any_object *obj){	struct sc_pkcs11_pool_item *item;	for (item = pool->head; item != NULL; item = item->next) {		if (obj == (struct pkcs15_any_object *) item->item)			return 1;	}	return 0;}static voidpkcs15_add_object(struct sc_pkcs11_slot *slot,		  struct pkcs15_any_object *obj,		  CK_OBJECT_HANDLE_PTR pHandle){	if (obj == NULL	 || (obj->base.flags & (SC_PKCS11_OBJECT_HIDDEN | SC_PKCS11_OBJECT_RECURS)))		return;

⌨️ 快捷键说明

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