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

📄 framework-pkcs15.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
kpgen_done:	sc_unlock(p11card->card);	sc_pkcs15init_unbind(profile);	return rv;}#endifstruct sc_pkcs11_framework_ops framework_pkcs15 = {	pkcs15_bind,	pkcs15_unbind,	pkcs15_create_tokens,	pkcs15_release_token,	pkcs15_login,        pkcs15_logout,	pkcs15_change_pin,        NULL,			/* init_token */#ifdef USE_PKCS15_INIT	pkcs15_init_pin,        pkcs15_create_object,        pkcs15_gen_keypair,#else        NULL,        NULL#endif};CK_RV pkcs15_set_attrib(struct sc_pkcs11_session *session,                               struct sc_pkcs15_object *p15_object,                               CK_ATTRIBUTE_PTR attr){#ifndef USE_PKCS15_INIT       return CKR_FUNCTION_NOT_SUPPORTED;#else       struct sc_profile *profile = NULL;       struct sc_pkcs11_card *p11card = session->slot->card;       struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;       struct pkcs15_slot_data *p15_data = slot_data(session->slot->fw_data);       struct sc_pkcs15_id id;       int rc = 0;       CK_RV rv = CKR_OK;       rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile);       if (rc < 0)               return sc_to_cryptoki_error(rc, p11card->reader);	rc = sc_lock(p11card->card);	if (rc < 0) {		sc_pkcs15init_unbind(profile);		return sc_to_cryptoki_error(rc, p11card->reader);	}       /* 2. Add the PINs the user presented so far. Some initialization        * routines need to present these PINs again because some        * card operations may clobber the authentication state        * (the GPK for instance) */       if (p15_data->pin[CKU_SO].len)               sc_pkcs15init_set_pin_data(profile, SC_PKCS15INIT_SO_PIN,                       p15_data->pin[CKU_SO].value, p15_data->pin[CKU_SO].len);       if (p15_data->pin[CKU_USER].len)               sc_pkcs15init_set_pin_data(profile, SC_PKCS15INIT_USER_PIN,                       p15_data->pin[CKU_USER].value, p15_data->pin[CKU_USER].len);       switch(attr->type)       {       case CKA_LABEL:               rc = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object,                       P15_ATTR_TYPE_LABEL, attr->pValue, attr->ulValueLen);               break;       case CKA_ID:               if (attr->ulValueLen > SC_PKCS15_MAX_ID_SIZE) {                       rc = SC_ERROR_INVALID_ARGUMENTS;                       break;               }               memcpy(id.value, attr->pValue, attr->ulValueLen);               id.len = attr->ulValueLen;               rc = sc_pkcs15init_change_attrib(fw_data->p15_card, profile, p15_object,                       P15_ATTR_TYPE_ID, &id, sizeof(id));               break;	case CKA_SUBJECT:		rc = SC_SUCCESS;		break;       default:               rv = CKR_ATTRIBUTE_READ_ONLY;               goto set_attr_done;       }       rv = sc_to_cryptoki_error(rc, p11card->reader);set_attr_done:	sc_unlock(p11card->card);       sc_pkcs15init_unbind(profile);       return rv;#endif}/* * PKCS#15 Certificate Object */void pkcs15_cert_release(void *obj){	struct pkcs15_cert_object *cert = (struct pkcs15_cert_object *) obj;	struct sc_pkcs15_cert *cert_data = cert->cert_data;	if (__pkcs15_release_object((struct pkcs15_any_object *) obj) == 0)		sc_pkcs15_free_certificate(cert_data);}CK_RV pkcs15_cert_set_attribute(struct sc_pkcs11_session *session,                               void *object,                               CK_ATTRIBUTE_PTR attr){       struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;       return pkcs15_set_attrib(session, cert->base.p15_object, attr);}CK_RV pkcs15_cert_get_attribute(struct sc_pkcs11_session *session,				void *object,				CK_ATTRIBUTE_PTR attr){	struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;	size_t len;	switch (attr->type) {	case CKA_CLASS:		check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS));		*(CK_OBJECT_CLASS*)attr->pValue = CKO_CERTIFICATE;                break;	case CKA_TOKEN:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = TRUE;                break;	case CKA_PRIVATE:	case CKA_MODIFIABLE:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = FALSE;                break;	case CKA_LABEL:		len = strlen(cert->cert_p15obj->label);		check_attribute_buffer(attr, len);                memcpy(attr->pValue, cert->cert_p15obj->label, len);                break;	case CKA_CERTIFICATE_TYPE:		check_attribute_buffer(attr, sizeof(CK_CERTIFICATE_TYPE));                *(CK_CERTIFICATE_TYPE*)attr->pValue = CKC_X_509;		break;	case CKA_ID:		/* Not sure why CA certs should be reported with an		 * ID of 00. --okir 20030413 */		if (cert->cert_info->authority) {			check_attribute_buffer(attr, 1);			*(unsigned char*)attr->pValue = 0;		} else {			check_attribute_buffer(attr, cert->cert_info->id.len);			memcpy(attr->pValue, cert->cert_info->id.value, cert->cert_info->id.len);                }                break;	case CKA_TRUSTED:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = cert->cert_info->authority?TRUE:FALSE;                break;	case CKA_VALUE:		check_attribute_buffer(attr, cert->cert_data->data_len);		memcpy(attr->pValue, cert->cert_data->data, cert->cert_data->data_len);		break;	case CKA_SERIAL_NUMBER:		 check_attribute_buffer(attr, cert->cert_data->serial_len);		 memcpy(attr->pValue, cert->cert_data->serial, cert->cert_data->serial_len);		 break;	case CKA_SUBJECT:		 return asn1_sequence_wrapper(cert->cert_data->subject,				 cert->cert_data->subject_len,				 attr);	case CKA_ISSUER:		 return asn1_sequence_wrapper(cert->cert_data->issuer,				 cert->cert_data->issuer_len,				 attr);	default:                return CKR_ATTRIBUTE_TYPE_INVALID;	}        return CKR_OK;}static intpkcs15_cert_cmp_attribute(struct sc_pkcs11_session *session,				void *object,				CK_ATTRIBUTE_PTR attr){	struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;	u8	*data;	size_t	len;	switch (attr->type) {	/* Check the issuer. Some pkcs11 callers (i.e. netscape) will pass	 * in the ASN.1 encoded SEQUENCE OF SET ... while OpenSC just	 * keeps the SET in the issuer field. */	case CKA_ISSUER:		if (cert->cert_data->issuer_len == 0)			break;		data = (u8 *) attr->pValue;		len = attr->ulValueLen;		/* SEQUENCE is tag 0x30, SET is 0x31		 * I know this code is icky, but hey... this is netscape		 * we're dealing with :-) */		if (cert->cert_data->issuer[0] == 0x31		 && data[0] == 0x30 && len >= 2) {			/* skip the length byte(s) */			len = (data[1] & 0x80)? (data[1] & 0x7F) : 0;			if (attr->ulValueLen < len + 2)				break;			data += len + 2;			len = attr->ulValueLen - len - 2;		}		if (len == cert->cert_data->issuer_len		 && !memcmp(cert->cert_data->issuer, data, len))			return 1;		break;	default:                return sc_pkcs11_any_cmp_attribute(session, object, attr);	}        return 0;}struct sc_pkcs11_object_ops pkcs15_cert_ops = {	pkcs15_cert_release,        pkcs15_cert_set_attribute,	pkcs15_cert_get_attribute,	pkcs15_cert_cmp_attribute,	NULL,	NULL,        NULL};/* * PKCS#15 Private Key Object */void pkcs15_prkey_release(void *object){	__pkcs15_release_object((struct pkcs15_any_object *) object);}CK_RV pkcs15_prkey_set_attribute(struct sc_pkcs11_session *session,                               void *object,                               CK_ATTRIBUTE_PTR attr){       struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object*) object;       return pkcs15_set_attrib(session, prkey->base.p15_object, attr);}CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,				void *object,				CK_ATTRIBUTE_PTR attr){	struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object*) object;	struct sc_pkcs15_pubkey *key = NULL;	unsigned int usage;	size_t len;	if (prkey->prv_cert && prkey->prv_cert->cert_data)		key = &prkey->prv_cert->cert_data->key;	else if (prkey->prv_pubkey)		key = prkey->prv_pubkey->pub_data;	switch (attr->type) {	case CKA_CLASS:		check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS));		*(CK_OBJECT_CLASS*)attr->pValue = CKO_PRIVATE_KEY;                break;	case CKA_TOKEN:	case CKA_LOCAL:	case CKA_SENSITIVE:	case CKA_ALWAYS_SENSITIVE:	case CKA_NEVER_EXTRACTABLE:	case CKA_PRIVATE:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = TRUE;                break;	case CKA_MODIFIABLE:	case CKA_EXTRACTABLE:		check_attribute_buffer(attr, sizeof(CK_BBOOL));		*(CK_BBOOL*)attr->pValue = FALSE;                break;	case CKA_LABEL:		len = strlen(prkey->prv_p15obj->label);		check_attribute_buffer(attr, len);                memcpy(attr->pValue, prkey->prv_p15obj->label, len);		break;	case CKA_KEY_TYPE:		check_attribute_buffer(attr, sizeof(CK_KEY_TYPE));                *(CK_KEY_TYPE*)attr->pValue = CKK_RSA;                break;	case CKA_ID:		check_attribute_buffer(attr, prkey->prv_info->id.len);		memcpy(attr->pValue, prkey->prv_info->id.value, prkey->prv_info->id.len);                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:		/* Combine the usage bits of all split keys */		for (usage = 0; prkey; prkey = prkey->prv_next)			usage |= prkey->prv_info->usage;		return get_usage_bit(usage, attr);	case CKA_MODULUS:		return get_modulus(key, attr);	case CKA_MODULUS_BITS:		check_attribute_buffer(attr, sizeof(CK_ULONG));		*(CK_ULONG *) attr->pValue = prkey->prv_info->modulus_length;		return CKR_OK;	case CKA_PUBLIC_EXPONENT:		return get_public_exponent(key, attr);	case CKA_PRIVATE_EXPONENT:	case CKA_PRIME_1:	case CKA_PRIME_2:	case CKA_EXPONENT_1:	case CKA_EXPONENT_2:	case CKA_COEFFICIENT:		return CKR_ATTRIBUTE_SENSITIVE;	case CKA_SUBJECT:	case CKA_START_DATE:	case CKA_END_DATE:		attr->ulValueLen = 0;		return CKR_OK;	default:                return CKR_ATTRIBUTE_TYPE_INVALID;	}        return CKR_OK;}CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,			CK_MECHANISM_PTR pMechanism, CK_BYTE_PTR pData,			CK_ULONG ulDataLen, CK_BYTE_PTR pSignature,			CK_ULONG_PTR pulDataLen){	struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data;	struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data);	int rv, flags = 0;	sc_debug(context, "Initiating signing operation, mechanism 0x%x.\n",				pMechanism->mechanism);	/* If this key requires user consent for every N operations,	 * we may have to present the PIN again and again.	 * For now, we require that either the terminal has a key pad,	 * or the user allows pin caching. We may want to add GUI	 * function pointers though.	 */	if (prkey->prv_p15obj->user_consent) {		/* XXX we should really keep track how often the key		 * is used, and how often we need to ask the user for		 * her PIN. 		 * For now, we just assume user_consent is 1.		 */		/* XXX - do we require an sc_lock here? */		rv = revalidate_pin(data, ses);		if (rv < 0)			return sc_to_cryptoki_error(rv, ses->slot->card->reader);	}	/* See which of the alternative keys supports signing */	while (prkey	 && !(prkey->prv_info->usage	     & (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|	     	SC_PKCS15_PRKEY_USAGE_NONREPUDIATION))) 		prkey = prkey->prv_next;	if (prkey == NULL)		return CKR_KEY_FUNCTION_NOT_PERMITTED;	switch (pMechanism->mechanism) {	case CKM_RSA_PKCS:		/* Um. We need to guess what netscape is trying to		 * sign here. We're lucky that all these things have		 * different sizes. */		flags = SC_ALGORITHM_RSA_PAD_PKCS1;		switch (ulDataLen) {		case 34:flags |= SC_ALGORITHM_RSA_HASH_MD5;  /* MD5 + header */			pData += 18; ulDataLen -= 18;			break;		case 35:			if (pData[7] == 0x24)				flags |= SC_ALGORITHM_RSA_HASH_RIPEMD160;   /* RIPEMD160 + hdr */			else				flags |= SC_ALGORITHM_RSA_HASH_SHA1;   /* SHA1 + hdr */			pData += 15; ulDataLen -= 15;			break;		case 36:flags |= SC_ALGORITHM_RSA_HASH_MD5_SHA1; /* SSL hash */			break;		case 20:			flags |= SC_ALGORITHM_RSA_HASH_SHA1;	/* SHA1 */			break;		case 16:			flags |= SC_ALGORITHM_RSA_HASH_MD5;	/* MD5 */			break;		default:			flags |= SC_ALGORITHM_RSA_HASH_NONE;		}		break;	case CKM_MD5_RSA_PKCS:		flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_MD5;		break;	case CKM_SHA1_RSA_PKCS:		flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;		break;	case CKM_RIPEMD160_RSA_PKCS:		flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_RIPEMD160;		break;	case CKM_RSA_X_509:		flags = SC_ALGORITHM_RSA_RAW;		break;	default:                return CKR_MECHANISM_INVALID;	}        sc_debug(context, "Selected flags %X. Now computing signature for %d bytes. %d bytes reserved.\n", flags, ulDataLen, *pulDataLen);	rv = sc_pkcs15_compute_signature(fw_data->p15_card,					 prkey->prv_p15obj,					 flags,					 pData,					 ulDataLen,					 pSignature,					 *pulDataLen);	/* Do we have to try a re-login and then try to sign 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)

⌨️ 快捷键说明

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