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

📄 mechanism.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Generic handling of PKCS11 mechanisms * * Copyright (C) 2002 Olaf Kirch <okir@lst.de> */#include <stdlib.h>#include <string.h>#include "sc-pkcs11.h"/* Also used for verification data */struct hash_signature_info {	CK_MECHANISM_TYPE	mech;	CK_MECHANISM_TYPE	hash_mech;	CK_MECHANISM_TYPE	sign_mech;	sc_pkcs11_mechanism_type_t *hash_type;	sc_pkcs11_mechanism_type_t *sign_type;};/* Also used for verification data */struct signature_data {	struct sc_pkcs11_object *key;	struct hash_signature_info *info;	sc_pkcs11_operation_t *	md;	CK_BYTE			buffer[4096/8];	unsigned int		buffer_len;};/* * Register a mechanism */CK_RVsc_pkcs11_register_mechanism(struct sc_pkcs11_card *p11card,				sc_pkcs11_mechanism_type_t *mt){	sc_pkcs11_mechanism_type_t **p;	if (mt == NULL)		return CKR_HOST_MEMORY;	p = (sc_pkcs11_mechanism_type_t **) realloc(p11card->mechanisms,			(p11card->nmechanisms + 2) * sizeof(*p));	if (p == NULL)		return CKR_HOST_MEMORY;	p11card->mechanisms = p;	p[p11card->nmechanisms++] = mt;	p[p11card->nmechanisms] = NULL;	return CKR_OK;}/* * Look up a mechanism */sc_pkcs11_mechanism_type_t *sc_pkcs11_find_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mech, int flags){	sc_pkcs11_mechanism_type_t *mt;	unsigned int n;	for (n = 0; n < p11card->nmechanisms; n++) {		mt = p11card->mechanisms[n];		if (mt && mt->mech == mech && ((mt->mech_info.flags & flags) == flags))			return mt;	}	return NULL;}/* * Query mechanisms. * All of this is greatly simplified by having the framework * register all supported mechanisms at initialization * time. */CK_RVsc_pkcs11_get_mechanism_list(struct sc_pkcs11_card *p11card,				CK_MECHANISM_TYPE_PTR pList,				CK_ULONG_PTR pulCount){	sc_pkcs11_mechanism_type_t *mt;	unsigned int n, count = 0;	int rv;	for (n = 0; n < p11card->nmechanisms; n++) {		if (!(mt = p11card->mechanisms[n]))			continue;		if (count < *pulCount && pList)			pList[count] = mt->mech;		count++;	}	rv = CKR_OK;	if (pList && count > *pulCount)		rv = CKR_BUFFER_TOO_SMALL;	*pulCount = count;	return rv;}CK_RVsc_pkcs11_get_mechanism_info(struct sc_pkcs11_card *p11card,			CK_MECHANISM_TYPE mechanism,			CK_MECHANISM_INFO_PTR pInfo){	sc_pkcs11_mechanism_type_t *mt;	if (!(mt = sc_pkcs11_find_mechanism(p11card, mechanism, 0)))		return CKR_MECHANISM_INVALID;	memcpy(pInfo, &mt->mech_info, sizeof(*pInfo));	return CKR_OK;}/* * Create/destroy operation handle */sc_pkcs11_operation_t *sc_pkcs11_new_operation(sc_pkcs11_session_t *session,			sc_pkcs11_mechanism_type_t *type){	sc_pkcs11_operation_t *res;	res = (sc_pkcs11_operation_t *) calloc(1, type->obj_size);	if (res) {		res->session = session;		res->type = type;	}	return res;}voidsc_pkcs11_release_operation(sc_pkcs11_operation_t **ptr){	sc_pkcs11_operation_t *operation = *ptr;	if (!operation)		return;	if (operation->type && operation->type->release)		operation->type->release(operation);	memset(operation, 0, sizeof(*operation));	free(operation);	*ptr = NULL;}CK_RVsc_pkcs11_md_init(struct sc_pkcs11_session *session,			CK_MECHANISM_PTR pMechanism){	struct sc_pkcs11_card *p11card;	sc_pkcs11_operation_t *operation;	sc_pkcs11_mechanism_type_t *mt;	int rv;	if (!session || !session->slot	 || !(p11card = session->slot->card))		return CKR_ARGUMENTS_BAD;	/* See if we support this mechanism type */	mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_DIGEST);	if (mt == NULL)		return CKR_MECHANISM_INVALID;	rv = session_start_operation(session, SC_PKCS11_OPERATION_DIGEST, mt, &operation);	if (rv != CKR_OK)		return rv;	memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM));	rv = mt->md_init(operation);	if (rv != CKR_OK)		session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST);	return rv;}CK_RVsc_pkcs11_md_update(struct sc_pkcs11_session *session,			CK_BYTE_PTR pData, CK_ULONG ulDataLen){	sc_pkcs11_operation_t *op;	int rv;	rv = session_get_operation(session, SC_PKCS11_OPERATION_DIGEST, &op);	if (rv != CKR_OK)		goto done;	rv = op->type->md_update(op, pData, ulDataLen);done:	if (rv != CKR_OK)		session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST);	return rv;}CK_RVsc_pkcs11_md_final(struct sc_pkcs11_session *session,			CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen){	sc_pkcs11_operation_t *op;	int rv;	rv = session_get_operation(session, SC_PKCS11_OPERATION_DIGEST, &op);	if (rv != CKR_OK)		return rv;	/* This is a request for the digest length */	if (pData == NULL)		*pulDataLen = 0;	rv = op->type->md_final(op, pData, pulDataLen);	if (rv == CKR_BUFFER_TOO_SMALL)		return pData == NULL ? CKR_OK : rv;	session_stop_operation(session, SC_PKCS11_OPERATION_DIGEST);	return rv;}/* * Initialize a signing context. When we get here, we know * the key object is capable of signing _something_ */CK_RVsc_pkcs11_sign_init(struct sc_pkcs11_session *session,		    CK_MECHANISM_PTR pMechanism,		    struct sc_pkcs11_object *key,		    CK_MECHANISM_TYPE key_type){	struct sc_pkcs11_card *p11card;	sc_pkcs11_operation_t *operation;	sc_pkcs11_mechanism_type_t *mt;	int rv;	if (!session || !session->slot	 || !(p11card = session->slot->card))		return CKR_ARGUMENTS_BAD;	/* See if we support this mechanism type */	mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_SIGN);	if (mt == NULL)		return CKR_MECHANISM_INVALID;	/* See if compatible with key type */	if (mt->key_type != key_type)		return CKR_KEY_TYPE_INCONSISTENT;	rv = session_start_operation(session, SC_PKCS11_OPERATION_SIGN, mt, &operation);	if (rv != CKR_OK)		return rv;	memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM));	rv = mt->sign_init(operation, key);	if (rv != CKR_OK)		session_stop_operation(session, SC_PKCS11_OPERATION_SIGN);	return rv;}CK_RVsc_pkcs11_sign_update(struct sc_pkcs11_session *session,		      CK_BYTE_PTR pData, CK_ULONG ulDataLen){	sc_pkcs11_operation_t *op;	int rv;	rv = session_get_operation(session, SC_PKCS11_OPERATION_SIGN, &op);	if (rv != CKR_OK)		return rv;	if (op->type->sign_update == NULL) {		rv = CKR_KEY_TYPE_INCONSISTENT;		goto done;	}	rv = op->type->sign_update(op, pData, ulDataLen);done:	if (rv != CKR_OK)		session_stop_operation(session, SC_PKCS11_OPERATION_SIGN);	return rv;}CK_RVsc_pkcs11_sign_final(struct sc_pkcs11_session *session,		     CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen){	sc_pkcs11_operation_t *op;	int rv;	rv = session_get_operation(session, SC_PKCS11_OPERATION_SIGN, &op);	if (rv != CKR_OK)		return rv;	/* Bail out for signature mechanisms that don't do hashing */	if (op->type->sign_final == NULL) {		rv = CKR_KEY_TYPE_INCONSISTENT;		goto done;	}	rv = op->type->sign_final(op, pSignature, pulSignatureLen);done:	if (rv != CKR_BUFFER_TOO_SMALL && pSignature != NULL)		session_stop_operation(session, SC_PKCS11_OPERATION_SIGN);	return rv;}CK_RVsc_pkcs11_sign_size(struct sc_pkcs11_session *session, CK_ULONG_PTR pLength){	sc_pkcs11_operation_t *op;	int rv;	rv = session_get_operation(session, SC_PKCS11_OPERATION_SIGN, &op);	if (rv != CKR_OK)		return rv;	/* Bail out for signature mechanisms that don't do hashing */	if (op->type->sign_size == NULL) {		rv = CKR_KEY_TYPE_INCONSISTENT;		goto done;	}	rv = op->type->sign_size(op, pLength);done:	if (rv != CKR_OK)		session_stop_operation(session, SC_PKCS11_OPERATION_SIGN);	return rv;}/* * Initialize a signature operation */static CK_RVsc_pkcs11_signature_init(sc_pkcs11_operation_t *operation,		    struct sc_pkcs11_object *key){	struct hash_signature_info *info;	struct signature_data *data;	int rv;	if (!(data = (struct signature_data *) calloc(1, sizeof(*data))))		return CKR_HOST_MEMORY;	data->info = NULL;	data->key = key;	/* If this is a signature with hash operation, set up the	 * hash operation */	info = (struct hash_signature_info *) operation->type->mech_data;	if (info != NULL) {		/* Initialize hash operation */		data->md = sc_pkcs11_new_operation(operation->session,						   info->hash_type);		if (data->md == NULL)			rv = CKR_HOST_MEMORY;		else			rv = info->hash_type->md_init(data->md);		if (rv != CKR_OK) {			sc_pkcs11_release_operation(&data->md);

⌨️ 快捷键说明

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