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

📄 pkcs11-tool.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		p11_fatal("C_FindObjects", rv);done:	if (count == 0)		*ret = CK_INVALID_HANDLE;	p11->C_FindObjectsFinal(sess);	return count;}CK_MECHANISM_TYPEfind_mechanism(CK_SLOT_ID slot, CK_FLAGS flags, int stop_if_not_found){	CK_MECHANISM_TYPE *mechs = NULL, result;	CK_MECHANISM_INFO info;	CK_ULONG	n, count = 0;	CK_RV		rv;	get_mechanisms(slot, &mechs, &count);	result = NO_MECHANISM;	for (n = 0; n < count; n++) {		rv = p11->C_GetMechanismInfo(slot, mechs[n], &info);		if (rv != CKR_OK)			continue;		if ((info.flags & flags) == flags) {			result = mechs[n];			break;		}	}	if (stop_if_not_found && result == NO_MECHANISM)		fatal("No appropriate mechanism found");	free(mechs);	return result;}#define ATTR_METHOD(ATTR, TYPE) \TYPE \get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) \{ \	TYPE		type; \	CK_ATTRIBUTE	attr = { CKA_##ATTR, &type, sizeof(type) }; \	CK_RV		rv; \ \	rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \	if (rv != CKR_OK) \		p11_fatal("C_GetAttributeValue(" #ATTR ")", rv); \	return type; \}#define VARATTR_METHOD(ATTR, TYPE) \TYPE * \get##ATTR(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_ULONG_PTR pulCount) \{ \	CK_ATTRIBUTE	attr = { CKA_##ATTR, NULL, 0 }; \	CK_RV		rv; \ \	rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \	if (rv == CKR_OK) { \		if (!(attr.pValue = calloc(1, attr.ulValueLen + 1))) \			fatal("out of memory in get" #ATTR ": %m"); \		rv = p11->C_GetAttributeValue(sess, obj, &attr, 1); \	} \	if (rv != CKR_OK) \		p11_fatal("C_GetAttributeValue(" #ATTR ")", rv); \	if (pulCount) \		*pulCount = attr.ulValueLen / sizeof(TYPE); \	return (TYPE *) attr.pValue; \}/* * Define attribute accessors */ATTR_METHOD(CLASS, CK_OBJECT_CLASS);ATTR_METHOD(TOKEN, CK_BBOOL);ATTR_METHOD(LOCAL, CK_BBOOL);ATTR_METHOD(SENSITIVE, CK_BBOOL);ATTR_METHOD(ALWAYS_SENSITIVE, CK_BBOOL);ATTR_METHOD(NEVER_EXTRACTABLE, CK_BBOOL);ATTR_METHOD(PRIVATE, CK_BBOOL);ATTR_METHOD(MODIFIABLE, CK_BBOOL);ATTR_METHOD(ENCRYPT, CK_BBOOL);ATTR_METHOD(DECRYPT, CK_BBOOL);ATTR_METHOD(SIGN, CK_BBOOL);ATTR_METHOD(SIGN_RECOVER, CK_BBOOL);ATTR_METHOD(VERIFY, CK_BBOOL);ATTR_METHOD(VERIFY_RECOVER, CK_BBOOL);ATTR_METHOD(WRAP, CK_BBOOL);ATTR_METHOD(UNWRAP, CK_BBOOL);ATTR_METHOD(DERIVE, CK_BBOOL);ATTR_METHOD(EXTRACTABLE, CK_BBOOL);ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE);ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE);ATTR_METHOD(MODULUS_BITS, CK_ULONG);VARATTR_METHOD(LABEL, char);VARATTR_METHOD(ID, unsigned char);VARATTR_METHOD(VALUE, unsigned char);voidshow_object(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj){	CK_OBJECT_CLASS	cls = getCLASS(sess, obj);	switch (cls) {	case CKO_PUBLIC_KEY:		show_key(sess, obj, 1);		break;	case CKO_PRIVATE_KEY:		show_key(sess, obj, 0);		break;	case CKO_CERTIFICATE:		show_cert(sess, obj);		break;	default:		printf("Object %u, type %u\n",				(unsigned int) obj,				(unsigned int) cls);	}}voidshow_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int pub){	CK_KEY_TYPE	key_type = getKEY_TYPE(sess, obj);	CK_ULONG	size;	unsigned char	*id;	char		*label, *sepa;	printf("%s Key Object", pub? "Public" : "Private");	switch (key_type) {	case CKK_RSA:		printf("; RSA %lu bits\n", getMODULUS_BITS(sess, obj));		break;	default:		printf("; unknown key algorithm %lu\n", key_type);		break;	}	if ((label = getLABEL(sess, obj, NULL)) != NULL) {		printf("  label:      %s\n", label);		free(label);	}	if ((id = getID(sess, obj, &size)) != NULL && size) {		unsigned int	n;		printf("  ID:         ");		for (n = 0; n < size; n++)			printf("%02x", id[n]);		printf("\n");		free(id);	}	printf("  Usage:      ");	sepa = "";	if (getENCRYPT(sess, obj)) {		printf("%sencrypt", sepa);		sepa = ", ";	}	if (getDECRYPT(sess, obj)) {		printf("%sdecrypt", sepa);		sepa = ", ";	}	if (getSIGN(sess, obj)) {		printf("%ssign", sepa);		sepa = ", ";	}	if (getVERIFY(sess, obj)) {		printf("%sverify", sepa);		sepa = ", ";	}	if (getWRAP(sess, obj)) {		printf("%swrap", sepa);		sepa = ", ";	}	if (getUNWRAP(sess, obj)) {		printf("%sunwrap", sepa);		sepa = ", ";	}	if (!*sepa)		printf("none");	printf("\n");}voidshow_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj){	CK_CERTIFICATE_TYPE	cert_type = getCERTIFICATE_TYPE(sess, obj);	CK_ULONG	size;	unsigned char	*id;	char		*label;	printf("Certificate Object, type = ");	switch (cert_type) {	case CKC_X_509:		printf("X.509 cert\n");		break;	case CKC_X_509_ATTR_CERT:		printf("X.509 attribute cert\n");		break;	case CKC_VENDOR_DEFINED:		printf("vendor defined");		break;	default:		printf("; unknown cert type\n");		break;	}	if ((label = getLABEL(sess, obj, NULL)) != NULL) {		printf("  label:      %s\n", label);		free(label);	}	if ((id = getID(sess, obj, &size)) != NULL && size) {		unsigned int	n;		printf("  ID:         ");		for (n = 0; n < size; n++)			printf("%02x", id[n]);		printf("\n");		free(id);	}}voidget_token_info(CK_SLOT_ID slot, CK_TOKEN_INFO_PTR info){	CK_RV		rv;	rv = p11->C_GetTokenInfo(slot, info);	if (rv != CKR_OK)		p11_fatal("C_GetTokenInfo", rv);}voidget_mechanisms(CK_SLOT_ID slot,		CK_MECHANISM_TYPE_PTR *pList,		CK_ULONG_PTR pulCount){	CK_RV	rv;	rv = p11->C_GetMechanismList(slot, *pList, pulCount);	*pList = (CK_MECHANISM_TYPE *) calloc(*pulCount, sizeof(*pList));	if (*pList == NULL)		fatal("calloc failed: %m");	rv = p11->C_GetMechanismList(slot, *pList, pulCount);	if (rv != CKR_OK)		p11_fatal("C_GetMechanismList", rv);}static inttest_digest(CK_SLOT_ID slot){	int             errors = 0;	CK_RV           rv;	CK_SESSION_HANDLE session;	CK_MECHANISM    ck_mech = { CKM_MD5, NULL, 0 };	CK_ULONG        i, j;	unsigned char   data[100];	unsigned char   hash1[64], hash2[64];	CK_ULONG        hashLen1, hashLen2;	CK_MECHANISM_TYPE firstMechType;	CK_MECHANISM_TYPE mechTypes[] = {		CKM_MD5,		CKM_SHA_1,		CKM_RIPEMD160,		0xffffff	};	unsigned char  *digests[] = {		(unsigned char *) "\x7a\x08\xb0\x7e\x84\x64\x17\x03\xe5\xf2\xc8\x36\xaa\x59\xa1\x70",		(unsigned char *) "\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1",		(unsigned char *) "\xda\x79\xa5\x8f\xb8\x83\x3d\x61\xf6\x32\x16\x17\xe3\xfd\xf0\x56\x26\x5f\xb7\xcd"	};	CK_ULONG        digestLens[] = {		16,		20,		20	};	firstMechType = find_mechanism(slot, CKF_DIGEST, 0);	if (firstMechType == NO_MECHANISM) {		printf("Digests: not implemented\n");		return errors;	} else		printf("Digests:\n");	rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION,		NULL, NULL, &session);	if (rv != CKR_OK)		p11_fatal("C_OpenSession", rv);	/* 1st test */	ck_mech.mechanism = firstMechType;	rv = p11->C_DigestInit(session, &ck_mech);	if (rv != CKR_OK)		p11_fatal("C_DigestInit", rv);	rv = p11->C_DigestUpdate(session, data, 5);	if (rv == CKR_FUNCTION_NOT_SUPPORTED) {		printf("  Note: C_DigestUpdate(), DigestFinal() not supported\n");		/* finish the digest operation */		hashLen2 = sizeof(hash2);		rv = p11->C_Digest(session, data, sizeof(data), hash2,			&hashLen2);		if (rv != CKR_OK)			p11_fatal("C_Digest", rv);	} else {		if (rv != CKR_OK)			p11_fatal("C_DigestUpdate", rv);		rv = p11->C_DigestUpdate(session, data + 5, 50);		if (rv != CKR_OK)			p11_fatal("C_DigestUpdate", rv);		rv = p11->C_DigestUpdate(session, data + 55,			sizeof(data) - 55);		if (rv != CKR_OK)			p11_fatal("C_DigestUpdate", rv);		hashLen1 = sizeof(hash1);		rv = p11->C_DigestFinal(session, hash1, &hashLen1);		if (rv != CKR_OK)			p11_fatal("C_DigestFinal", rv);		rv = p11->C_DigestInit(session, &ck_mech);		if (rv != CKR_OK)			p11_fatal("C_DigestInit", rv);		hashLen2 = sizeof(hash2);		rv = p11->C_Digest(session, data, sizeof(data), hash2,			&hashLen2);		if (rv != CKR_OK)			p11_fatal("C_Digest", rv);		if (hashLen1 != hashLen2) {			errors++;			printf("  ERR: digest lengths returned by C_DigestFinal() different from C_Digest()\n");		} else if (memcmp(hash1, hash2, hashLen1) != 0) {			errors++;			printf("  ERR: digests returned by C_DigestFinal() different from C_Digest()\n");		} else			printf("  all 4 digest functions seem to work\n");	}	/* 2nd test */	/* input = "01234567890123456...456789" */	for (i = 0; i < 10; i++)		for (j = 0; j < 10; j++)			data[10 * i + j] = (unsigned char) (0x30 + j);	for (i = 0; mechTypes[i] != 0xffffff; i++) {		ck_mech.mechanism = mechTypes[i];		rv = p11->C_DigestInit(session, &ck_mech);		if (rv == CKR_MECHANISM_INVALID)			continue;	/* mechanism not implemented, don't test */		if (rv != CKR_OK)			p11_fatal("C_DigestInit", rv);		printf("  %s: ", p11_mechanism_to_name(mechTypes[i]));		hashLen1 = sizeof(hash1);		rv = p11->C_Digest(session, data, sizeof(data), hash1,			&hashLen1);		if (rv != CKR_OK)			p11_fatal("C_Digest", rv);		if (hashLen1 != digestLens[i]) {			errors++;			printf("ERR: wrong digest length: %ld instead of %ld\n",					hashLen1, digestLens[i]);		} else if (memcmp(hash1, digests[i], hashLen1) != 0) {			errors++;			printf("ERR: wrong digest value\n");		} else			printf("OK\n");	}	/* 3rd test */	ck_mech.mechanism = firstMechType;	rv = p11->C_DigestInit(session, &ck_mech);	if (rv != CKR_OK)		p11_fatal("C_DigestInit", rv);	hashLen2 = 1;		/* too short */	rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2);	if (rv != CKR_BUFFER_TOO_SMALL) {		errors++;		printf("  ERR: C_Digest() didn't return CKR_BUFFER_TOO_SMALL but %s (0x%0x)\n", CKR2Str(rv), (int) rv);	}	/* output buffer = NULL */	rv = p11->C_Digest(session, data, sizeof(data), NULL, &hashLen2);	if (rv != CKR_OK) {		errors++;		printf("  ERR: C_Digest() didn't return CKR_OK for a NULL output buffer, but %s (0x%0x)\n", CKR2Str(rv), (int) rv);	}	rv = p11->C_Digest(session, data, sizeof(data), hash2, &hashLen2);	if (rv == CKR_OPERATION_NOT_INITIALIZED) {		printf("  ERR: digest operation ended prematurely\n");		errors++;	} else if (rv != CKR_OK)		p11_fatal("C_Sign", rv);	rv = p11->C_CloseSession(session);	if (rv != CKR_OK)		p11_fatal("C_CloseSession", rv);	return errors;}#ifdef HAVE_OPENSSLEVP_PKEY *get_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKeyObject){	unsigned char  *id;	CK_ULONG        idLen;	CK_OBJECT_HANDLE pubkeyObject;	unsigned char  *pubkey, *pubkey_sav;	CK_ULONG        pubkeyLen;	EVP_PKEY       *pkey;	id = NULL;	id = getID(session, privKeyObject, &idLen);	if (id == NULL) {		printf("private key has no ID, can't lookup the corresponding pubkey for verification\n");		return NULL;	}	if (!find_object(session, CKO_PUBLIC_KEY, &pubkeyObject, id, idLen, 0)) {		free(id);		printf("coudn't find the corresponding pubkey for validation\n");		return NULL;	}	free(id);	pubkey = getVALUE(session, pubkeyObject, &pubkeyLen);	if (pubkey == NULL) {		printf("couldn't get the pubkey VALUE attribute, no validation done\n");		return NULL;	}	pubkey_sav = pubkey; /* The function below may change pubkey */	pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey, pubkeyLen);	free(pubkey_sav);	if (pkey == NULL) {		printf(" couldn't parse pubkey, no verification done\n");		/* ERR_print_errors_fp(stderr); */		return NULL;	}	return pkey;}#endifint sign_verify_openssl(CK_SLOT_ID slot, CK_SESSION_HANDLE session,		CK_MECHANISM *ck_mech, CK_OBJECT_HANDLE privKeyObject,		unsigned char *data, CK_ULONG dataLen,		unsigned char *verifyData, CK_ULONG verifyDataLen,		int modLenBytes, int evp_md_index){	int 		errors = 0;	CK_RV           rv;	unsigned char   sig1[1024];	CK_ULONG        sigLen1;#ifdef HAVE_OPENSSL	int             err;	EVP_PKEY       *pkey;	EVP_MD_CTX      md_ctx;	const EVP_MD         *evp_mds[] = {		EVP_sha1(),		EVP_sha1(),		EVP_sha1(),		EVP_md5(),		EVP_ripemd160(),	};#endif	rv = p11->C_SignInit(session, ck_mech, privKeyObject);	/* mechanism not implemented, don't test */	if (rv == CKR_MECHANISM_INVALID)		return errors;	if (rv != CKR_OK)		p11_fatal("C_SignInit", rv);	printf("    %s: ", p11_mechanism_to_name(ck_mech->mechanism));	sigLen1 = sizeof(sig1);	rv = p11->C_Sign(session, data, dataLen, sig1,		&sigLen1);	if (rv != CKR_OK)		p11_fatal("C_Sign", rv);	if (sigLen1 != modLenBytes) {		errors++;		printf("  ERR: wrong signature length: %u instead of %u\n",				(unsigned int) sigLen1,				(unsigned int) modLenBytes);	}

⌨️ 快捷键说明

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