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

📄 framework-pkcs15.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			return sc_to_cryptoki_error(rv, ses->slot->card->reader);		rv = revalidate_pin(data, ses);		if (rv == 0)			rv = sc_pkcs15_compute_signature(fw_data->p15_card,				prkey->prv_p15obj, flags, pData, ulDataLen,				pSignature, *pulDataLen);		sc_unlock(ses->slot->card->card);	}        sc_debug(context, "Sign complete. Result %d.\n", rv);	if (rv > 0) {                *pulDataLen = rv;                return CKR_OK;	}        return sc_to_cryptoki_error(rv, ses->slot->card->reader);}static CK_RVpkcs15_prkey_unwrap(struct sc_pkcs11_session *ses, void *obj,		CK_MECHANISM_PTR pMechanism,		CK_BYTE_PTR pData, CK_ULONG ulDataLen,		CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount,		void **result){	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data;	struct pkcs15_prkey_object *prkey;	struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data);	u8	unwrapped_key[256];	int	rv;	sc_debug(context, "Initiating key unwrap.\n");	/* See which of the alternative keys supports unwrap */	prkey = (struct pkcs15_prkey_object *) obj;	while (prkey	 && !(prkey->prv_info->usage	     & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP)))		prkey = prkey->prv_next;	if (prkey == NULL)		return CKR_KEY_FUNCTION_NOT_PERMITTED;	if (pMechanism->mechanism != CKM_RSA_PKCS)		return CKR_MECHANISM_INVALID;	rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj,				 SC_ALGORITHM_RSA_PAD_PKCS1,				 pData, ulDataLen,				 unwrapped_key, sizeof(unwrapped_key));	/* Do we have to try a re-login and then try to decrypt again? */	if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {		/* Ensure that revalidate_pin() doesn't do a final sc_unlock()		   that would clear the card's current_path */		rv = sc_lock(ses->slot->card->card);		if (rv < 0)			return sc_to_cryptoki_error(rv, ses->slot->card->reader);		rv = revalidate_pin(data, ses);		if (rv == 0)			rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj,						SC_ALGORITHM_RSA_PAD_PKCS1,						pData, ulDataLen,						unwrapped_key, sizeof(unwrapped_key));		sc_unlock(ses->slot->card->card);	}	sc_debug(context, "Key unwrap complete. Result %d.\n", rv);	if (rv < 0)		return sc_to_cryptoki_error(rv, ses->slot->card->reader);	return sc_pkcs11_create_secret_key(ses,			unwrapped_key, rv,			pTemplate, ulAttributeCount,			(struct sc_pkcs11_object **) result);}struct sc_pkcs11_object_ops pkcs15_prkey_ops = {	pkcs15_prkey_release,	pkcs15_prkey_set_attribute,	pkcs15_prkey_get_attribute,	sc_pkcs11_any_cmp_attribute,	NULL,	NULL,        pkcs15_prkey_sign,	pkcs15_prkey_unwrap};/* * PKCS#15 RSA Public Key Object */void pkcs15_pubkey_release(void *object){	struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;	struct sc_pkcs15_pubkey *key_data = pubkey->pub_data;	if (__pkcs15_release_object((struct pkcs15_any_object *) object) == 0)		sc_pkcs15_free_pubkey(key_data);}CK_RV pkcs15_pubkey_set_attribute(struct sc_pkcs11_session *session,                               void *object,                               CK_ATTRIBUTE_PTR attr){       struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;       return pkcs15_set_attrib(session, pubkey->base.p15_object, attr);}CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session,				void *object,				CK_ATTRIBUTE_PTR attr){	struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object;	struct pkcs15_cert_object *cert = pubkey->pub_cert;	size_t len;	switch (attr->type) {	case CKA_CLASS:		check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS));		*(CK_OBJECT_CLASS*)attr->pValue = CKO_PUBLIC_KEY;                break;	case CKA_TOKEN:	case CKA_LOCAL:	case CKA_SENSITIVE:	case CKA_ALWAYS_SENSITIVE:	case CKA_NEVER_EXTRACTABLE:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = TRUE;                break;	case CKA_PRIVATE:	case CKA_MODIFIABLE:	case CKA_EXTRACTABLE:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = FALSE;                break;	case CKA_LABEL:		if (pubkey->pub_p15obj) {			len = strlen(pubkey->pub_p15obj->label);			check_attribute_buffer(attr, len);			memcpy(attr->pValue, pubkey->pub_p15obj->label, len);		} else if (cert && cert->cert_p15obj) {			len = strlen(cert->cert_p15obj->label);			check_attribute_buffer(attr, len);			memcpy(attr->pValue, cert->cert_p15obj->label, len);		} else {			return CKR_ATTRIBUTE_TYPE_INVALID;		}		break;	case CKA_KEY_TYPE:		check_attribute_buffer(attr, sizeof(CK_KEY_TYPE));                *(CK_KEY_TYPE*)attr->pValue = CKK_RSA;                break;	case CKA_ID:		if (pubkey->pub_info) {			check_attribute_buffer(attr, pubkey->pub_info->id.len);			memcpy(attr->pValue, pubkey->pub_info->id.value, pubkey->pub_info->id.len);		} else if (cert && cert->cert_info) {			check_attribute_buffer(attr, cert->cert_info->id.len);			memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len);		} else {			return CKR_ATTRIBUTE_TYPE_INVALID;		}                break;	case CKA_KEY_GEN_MECHANISM:		check_attribute_buffer(attr, sizeof(CK_MECHANISM_TYPE));                *(CK_MECHANISM_TYPE*)attr->pValue = CK_UNAVAILABLE_INFORMATION;		break;	case CKA_ENCRYPT:	case CKA_DECRYPT:	case CKA_SIGN:	case CKA_SIGN_RECOVER:	case CKA_WRAP:	case CKA_UNWRAP:	case CKA_VERIFY:	case CKA_VERIFY_RECOVER:	case CKA_DERIVE:		if (pubkey->pub_info) {			return get_usage_bit(pubkey->pub_info->usage, attr);		} else {			return get_usage_bit(SC_PKCS15_PRKEY_USAGE_ENCRYPT					|SC_PKCS15_PRKEY_USAGE_VERIFY					|SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,					attr);		}	case CKA_MODULUS:		return get_modulus(pubkey->pub_data, attr);	case CKA_MODULUS_BITS:		return get_modulus_bits(pubkey->pub_data, attr);	case CKA_PUBLIC_EXPONENT:		return get_public_exponent(pubkey->pub_data, attr);	case CKA_VALUE:		if (pubkey->pub_data) {			check_attribute_buffer(attr, pubkey->pub_data->data.len);			memcpy(attr->pValue, pubkey->pub_data->data.value,					      pubkey->pub_data->data.len);		} else if (cert && cert->cert_data) {			check_attribute_buffer(attr, cert->cert_data->data_len);			memcpy(attr->pValue, cert->cert_data->data, cert->cert_data->data_len);		}		break;	default:                return CKR_ATTRIBUTE_TYPE_INVALID;	}        return CKR_OK;}struct sc_pkcs11_object_ops pkcs15_pubkey_ops = {	pkcs15_pubkey_release,	pkcs15_pubkey_set_attribute,	pkcs15_pubkey_get_attribute,	sc_pkcs11_any_cmp_attribute,	NULL,	NULL,        NULL};/* * get_attribute helpers */static CK_RVget_bignum(sc_pkcs15_bignum_t *bn, CK_ATTRIBUTE_PTR attr){	check_attribute_buffer(attr, bn->len);	memcpy(attr->pValue, bn->data, bn->len);	return CKR_OK;}static CK_RVget_bignum_bits(sc_pkcs15_bignum_t *bn, CK_ATTRIBUTE_PTR attr){	CK_ULONG	bits, mask;	bits = bn->len * 8;	for (mask = 0x80; mask; mask >>= 1, bits--) {		if (bn->data[0] & mask)			break;	}	check_attribute_buffer(attr, sizeof(bits));	*(CK_ULONG *) attr->pValue = bits;	return CKR_OK;}static CK_RVget_modulus(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr){	if (key == NULL)		return CKR_ATTRIBUTE_TYPE_INVALID;	switch (key->algorithm) {	case SC_ALGORITHM_RSA:		return get_bignum(&key->u.rsa.modulus, attr);	}	return CKR_ATTRIBUTE_TYPE_INVALID;}static CK_RVget_modulus_bits(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr){	if (key == NULL)		return CKR_ATTRIBUTE_TYPE_INVALID;	switch (key->algorithm) {	case SC_ALGORITHM_RSA:		return get_bignum_bits(&key->u.rsa.modulus, attr);	}	return CKR_ATTRIBUTE_TYPE_INVALID;}static CK_RVget_public_exponent(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr){	if (key == NULL)		return CKR_ATTRIBUTE_TYPE_INVALID;	switch (key->algorithm) {	case SC_ALGORITHM_RSA:		return get_bignum(&key->u.rsa.exponent, attr);	}	return CKR_ATTRIBUTE_TYPE_INVALID;}/* * Map pkcs15 usage bits to pkcs11 usage attributes. * * It's not totally clear to me whether SC_PKCS15_PRKEY_USAGE_NONREPUDIATION should * be treated as being equivalent with CKA_SIGN or not... */static CK_RVget_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr){	static struct {		CK_ATTRIBUTE_TYPE type;		unsigned int	flag;	} flag_mapping[] = {	      	{ CKA_ENCRYPT,		SC_PKCS15_PRKEY_USAGE_ENCRYPT },	      	{ CKA_DECRYPT,		SC_PKCS15_PRKEY_USAGE_DECRYPT },		{ CKA_SIGN,		SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_NONREPUDIATION },		{ CKA_SIGN_RECOVER,	SC_PKCS15_PRKEY_USAGE_SIGNRECOVER },		{ CKA_WRAP,		SC_PKCS15_PRKEY_USAGE_WRAP },		{ CKA_UNWRAP,		SC_PKCS15_PRKEY_USAGE_UNWRAP },		{ CKA_VERIFY,		SC_PKCS15_PRKEY_USAGE_VERIFY },		{ CKA_VERIFY_RECOVER,	SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER },		{ CKA_DERIVE,		SC_PKCS15_PRKEY_USAGE_DERIVE },		{ 0, 0 }	};	unsigned int mask = 0, j;	for (j = 0; (mask = flag_mapping[j].flag) != 0; j++) {		if (flag_mapping[j].type == attr->type)			break;	}	if (mask == 0)		return CKR_ATTRIBUTE_TYPE_INVALID;	check_attribute_buffer(attr, sizeof(CK_BBOOL));	*(CK_BBOOL*)attr->pValue = (usage & mask)? TRUE : FALSE;	return CKR_OK;}static CK_RVasn1_sequence_wrapper(const u8 *data, size_t len, CK_ATTRIBUTE_PTR attr){	u8		*dest;	unsigned int	n;	size_t		len2;	len2 = len;	check_attribute_buffer(attr, len + 1 + sizeof(len));	dest = (u8 *) attr->pValue;	*dest++ = 0x30;	/* SEQUENCE tag */	if (len <= 127) {		*dest++ = len;	} else {		for (n = 4; (len & 0xFF000000) == 0; n--)			len <<= 8;		*dest++ = 0x80 + n;		while (n--) {			*dest++ = len >> 24;			len <<= 8;		}	}	memcpy(dest, data, len2);	attr->ulValueLen = (dest - (u8 *) attr->pValue) + len2;	return CKR_OK;}static voidcache_pin(void *p, int user, const void *pin, size_t len){	struct pkcs15_slot_data *data = (struct pkcs15_slot_data *) p;	if ((user != 0 && user != 1) || !sc_pkcs11_conf.cache_pins)		return;	memset(data->pin + user, 0, sizeof(data->pin[user]));	if (len && len <= MAX_CACHE_PIN) {		memcpy(data->pin[user].value, pin, len);		data->pin[user].len = len;	}}static intrevalidate_pin(struct pkcs15_slot_data *data, struct sc_pkcs11_session *ses){	int rv;	u8 value[MAX_CACHE_PIN];	sc_debug(context, "revalidate_pin called\n");	if (!sc_pkcs11_conf.cache_pins &&	    !(ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH))		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;	if (ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)		rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER, NULL, 0);	else {		memcpy(value, data->pin[CKU_USER].value, data->pin[CKU_USER].len);		rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER,			value, data->pin[CKU_USER].len);	}	if (rv != CKR_OK)		sc_debug(context, "Re-login failed: 0x%0x (%d)\n", rv, rv);	return rv;}/* * Mechanism handling * FIXME: We should consult the card's algorithm list to * find out what operations it supports */intregister_mechanisms(struct sc_pkcs11_card *p11card){	sc_card_t *card = p11card->card;	sc_algorithm_info_t *alg_info;	CK_MECHANISM_INFO mech_info;	sc_pkcs11_mechanism_type_t *mt;	unsigned int num;	int rc, flags = 0;	/* Register generic mechanisms */	sc_pkcs11_register_generic_mechanisms(p11card);	mech_info.flags = CKF_HW | CKF_SIGN | CKF_UNWRAP;#ifdef HAVE_OPENSSL	mech_info.flags |= CKF_VERIFY;#endif	mech_info.ulMinKeySize = ~0;	mech_info.ulMaxKeySize = 0;	/* For now, we just OR all the algorithm specific	 * flags, based on the assumption that cards don't	 * support different modes for different key sizes	 */	num = card->algorithm_count;	alg_info = card->algorithms;	while (num--) {		if (alg_info->algorithm != SC_ALGORITHM_RSA)			continue;		if (alg_info->key_length < mech_info.ulMinKeySize)			mech_info.ulMinKeySize = alg_info->key_length;		if (alg_info->key_length > mech_info.ulMaxKeySize)			mech_info.ulMaxKeySize = alg_info->key_length;		flags |= alg_info->flags;		alg_info++;	}	/* Check if we support raw RSA */	if (flags & SC_ALGORITHM_RSA_RAW) {		mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509,					&mech_info, CKK_RSA, NULL);		rc = sc_pkcs11_register_mechanism(p11card, mt);		if (rc != CKR_OK)			return rc;		/* If the card supports RAW, it should 

⌨️ 快捷键说明

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