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

📄 pkcs11-tool.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef HAVE_OPENSSL	printf("unable to verify signature (compile with HAVE_OPENSSL)\n");#else	if (!(pkey = get_public_key(session, privKeyObject)))		return errors;	EVP_VerifyInit(&md_ctx, evp_mds[evp_md_index]);	EVP_VerifyUpdate(&md_ctx, verifyData, verifyDataLen);	err = EVP_VerifyFinal(&md_ctx, sig1, sigLen1, pkey);	if (err == 0) {		printf("ERR: verification failed\n");		errors++;	} else if (err != 1) {		printf("openssl error during verification: 0x%0x (%d)\n", err, err);		/* ERR_print_errors_fp(stderr); */	} else		printf("OK\n");	/* free(cert); */#endif	return errors;}/* * Test signature functions */static inttest_signature(CK_SLOT_ID slot, CK_SESSION_HANDLE session){	int             errors = 0;	CK_RV           rv;	CK_OBJECT_HANDLE privKeyObject;	CK_SESSION_HANDLE sess;	CK_MECHANISM    ck_mech = { CKM_MD5, NULL, 0 };	CK_MECHANISM_TYPE firstMechType;	CK_SESSION_INFO sessionInfo;	CK_ULONG        i, j;	unsigned char   data[200];	CK_ULONG        modLenBytes;	CK_ULONG        dataLen;	unsigned char   sig1[1024], sig2[1024];	CK_ULONG        sigLen1, sigLen2;	unsigned char   verifyData[100];	char 		*label;	CK_MECHANISM_TYPE mechTypes[] = {		CKM_RSA_X_509,		CKM_RSA_PKCS,		CKM_SHA1_RSA_PKCS,		CKM_MD5_RSA_PKCS,		CKM_RIPEMD160_RSA_PKCS,		0xffffff	};	unsigned char  *datas[] = {		/* PCKS1_wrap(SHA1_encode(SHA-1(verifyData))),		 * is done further on		 */		NULL,		/* SHA1_encode(SHA-1(verifyData)) */		(unsigned char *) "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1",		verifyData,		verifyData,		verifyData,	};	CK_ULONG        dataLens[] = {		0,		/* should be modulus length, is done further on */		35,		sizeof(verifyData),		sizeof(verifyData),		sizeof(verifyData),	};	rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION,		NULL, NULL, &sess);	if (rv != CKR_OK)		p11_fatal("C_OpenSession", rv);	rv = p11->C_GetSessionInfo(sess, &sessionInfo);	if (rv != CKR_OK)		p11_fatal("C_OpenSession", rv);	if ((sessionInfo.state & CKS_RO_USER_FUNCTIONS) == 0) {		printf("Signatures: not logged in, skipping signature tests\n");		return errors;	}	firstMechType = find_mechanism(slot, CKF_SIGN | CKF_HW, 0);	if (firstMechType == NO_MECHANISM) {		printf("Signatures: not implemented\n");		return errors;	}	printf("Signatures (currently only RSA signatures)\n");	for (j = 0; find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j); j++) {		printf("  testing key %ld ", j);		if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) {			printf("(%s) ", label);			free(label);		}		if (!getSIGN(sess, privKeyObject)) {			printf(" -- can't be used for signature, skipping\n");			continue;		}		printf("\n");		break;	}	if (privKeyObject == CK_INVALID_HANDLE) {		printf("Signatures: no private key found in this slot\n");		return 0;	}	data[0] = 0;	modLenBytes = (getMODULUS_BITS(sess, privKeyObject) + 7) / 8;	/* 1st test */	switch (firstMechType) {	case CKM_RSA_PKCS:		dataLen = 35;		break;	case CKM_RSA_X_509:		dataLen = modLenBytes;		break;	default:		dataLen = sizeof(data);	/* let's hope it's OK */		break;	}	ck_mech.mechanism = firstMechType;	rv = p11->C_SignInit(sess, &ck_mech, privKeyObject);	if (rv != CKR_OK)		p11_fatal("C_SignInit", rv);	rv = p11->C_SignUpdate(sess, data, 5);	if (rv == CKR_FUNCTION_NOT_SUPPORTED) {		printf("  Note: C_SignUpdate(), SignFinal() not supported\n");		/* finish the digest operation */		sigLen2 = sizeof(sig2);		rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);		if (rv != CKR_OK)			p11_fatal("C_Sign", rv);	} else {		if (rv != CKR_OK)			p11_fatal("C_SignUpdate", rv);		rv = p11->C_SignUpdate(sess, data + 5, 10);		if (rv != CKR_OK)			p11_fatal("C_SignUpdate", rv);		rv = p11->C_SignUpdate(sess, data + 15, dataLen - 15);		if (rv != CKR_OK)			p11_fatal("C_SignUpdate", rv);		sigLen1 = sizeof(sig1);		rv = p11->C_SignFinal(sess, sig1, &sigLen1);		if (rv != CKR_OK)			p11_fatal("C_SignFinal", rv);		rv = p11->C_SignInit(sess, &ck_mech, privKeyObject);		if (rv != CKR_OK)			p11_fatal("C_SignInit", rv);		sigLen2 = sizeof(sig2);		rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);		if (rv != CKR_OK)			p11_fatal("C_Sign", rv);		if (sigLen1 != sigLen2) {			errors++;			printf("  ERR: signature lengths returned by C_SignFinal() different from C_Sign()\n");		} else if (memcmp(sig1, sig2, sigLen1) != 0) {			errors++;			printf("  ERR: signatures returned by C_SignFinal() different from C_Sign()\n");		} else			printf("  all 4 signature functions seem to work\n");	}	/* 2nd test */	ck_mech.mechanism = firstMechType;	rv = p11->C_SignInit(sess, &ck_mech, privKeyObject);	if (rv != CKR_OK)		p11_fatal("C_SignInit", rv);	sigLen2 = 1;		/* too short */	rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);	if (rv != CKR_BUFFER_TOO_SMALL) {		errors++;		printf("  ERR: C_Sign() didn't return CKR_BUFFER_TOO_SMALL but %s (0x%0x)\n", CKR2Str(rv), (int) rv);	}	/* output buf = NULL */	rv = p11->C_Sign(sess, data, dataLen, NULL, &sigLen2);	if (rv != CKR_OK) {	   errors++;	   printf("  ERR: C_Sign() didn't return CKR_OK for a NULL output buf, but %s (0x%0x)\n",	   CKR2Str(rv), (int) rv);	}	rv = p11->C_Sign(sess, data, dataLen, sig2, &sigLen2);	if (rv == CKR_OPERATION_NOT_INITIALIZED) {		printf("  ERR: signature operation ended prematurely\n");		errors++;	} else if (rv != CKR_OK)		p11_fatal("C_Sign", rv);	/* 3rd test */	/* input = "01234567890123456...456789" */	for (i = 0; i < 10; i++)		for (j = 0; j < 10; j++)			verifyData[10 * i + j] = (unsigned char) (0x30 + j);	/* Fill in data[0] and dataLens[0] */	dataLen = modLenBytes;	data[1] = 0x01;	memset(data + 2, 0xFF, dataLen - 3 - dataLens[1]);	data[dataLen - 36] = 0x00;	memcpy(data + (dataLen - dataLens[1]), datas[1], dataLens[1]);	datas[0] = data;	dataLens[0] = dataLen;	printf("  testing signature mechanisms:\n");	for (i = 0; mechTypes[i] != 0xffffff; i++) {		ck_mech.mechanism = mechTypes[i];		errors += sign_verify_openssl(slot, sess, &ck_mech, privKeyObject,			datas[i], dataLens[i], verifyData, sizeof(verifyData),			modLenBytes, i);	}	/* 4rd test: the other signature keys */	for (i = 0; mechTypes[i] != 0xffffff; i++)		if (i == firstMechType)			break;	ck_mech.mechanism = mechTypes[i];	j = 1;  /* j-th signature key */	while (find_object(sess, CKO_PRIVATE_KEY, &privKeyObject, NULL, 0, j++) != 0) {		printf("  testing key %d ", (int) (j-1));		if ((label = getLABEL(sess, privKeyObject, NULL)) != NULL) {			printf("(%s) ", label);			free(label);		}		printf("with 1 signature mechanism\n");		errors += sign_verify_openssl(slot, sess, &ck_mech, privKeyObject,			datas[i], dataLens[i], verifyData, sizeof(verifyData),			modLenBytes, i);	}	return errors;}static intsign_verify(CK_SLOT_ID slot, CK_SESSION_HANDLE session,	CK_OBJECT_HANDLE priv_key, int key_len,	CK_OBJECT_HANDLE pub_key, int one_test){	CK_RV rv;	CK_MECHANISM_TYPE mech_types[] = {		CKM_RSA_X_509,		CKM_RSA_PKCS,		CKM_SHA1_RSA_PKCS,		CKM_MD5_RSA_PKCS,		CKM_RIPEMD160_RSA_PKCS,		0xffffff	};	CK_MECHANISM_TYPE *mech_type;	unsigned char buf[512] = {0};	unsigned char *datas[] = {		buf,		(unsigned char *) "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14\x29\xb0\xe7\x87\x82\x71\x64\x5f\xff\xb7\xee\xc7\xdb\x4a\x74\x73\xa1\xc0\x0b\xc1",		buf,		buf,		buf	};		int data_lens[] = {		key_len,		35,		234,		345,		456	};	unsigned char signat[512];	CK_ULONG signat_len;	int j, errors = 0;	for (j = 0, mech_type = mech_types; *mech_type != 0xffffff; mech_type++, j++) {		CK_MECHANISM mech = {*mech_type, NULL, 0};		rv = p11->C_SignInit(session, &mech, priv_key);		if (rv == CKR_MECHANISM_INVALID)			break;		if (rv != CKR_OK) {			printf("  ERR: C_SignInit() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);			return ++errors;		}		printf("    %s: ", p11_mechanism_to_name(*mech_type));		signat_len = sizeof(signat);		rv = p11->C_Sign(session, datas[j], data_lens[j], signat, &signat_len);		if (rv != CKR_OK) {			printf("  ERR: C_Sign() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);			return ++errors;		}		rv = p11->C_VerifyInit(session, &mech, pub_key);		if (rv != CKR_OK) {			printf("  ERR: C_VerifyInit() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);			return ++errors;		}		rv = p11->C_Verify(session, datas[j], data_lens[j], signat, signat_len);		if (rv == CKR_SIGNATURE_INVALID) {			printf("  ERR: verification failed");			errors++;		}			if (rv != CKR_OK) {			printf("  ERR: C_Verify() returned %s (0x%0x)\n", CKR2Str(rv), (int) rv);			return ++errors;		}		else			printf("OK\n");		if (one_test)			return errors;	}	return errors;}static inttest_verify(CK_SLOT_ID slot, CK_SESSION_HANDLE sess){	int key_len, i, errors = 0;	CK_OBJECT_HANDLE priv_key, pub_key;	CK_MECHANISM_TYPE first_mech_type;	CK_SESSION_INFO sessionInfo;	CK_RV rv;	rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &sess);	if (rv != CKR_OK)		p11_fatal("C_OpenSession", rv);	rv = p11->C_GetSessionInfo(sess, &sessionInfo);	if (rv != CKR_OK)		p11_fatal("C_OpenSession", rv);	if ((sessionInfo.state & CKS_RO_USER_FUNCTIONS) == 0) {		printf("Verify: not logged in, skipping verify tests\n");		return errors;	}	first_mech_type = find_mechanism(slot, CKF_VERIFY, 0);	if (first_mech_type == NO_MECHANISM) {		printf("Verify: not implemented\n");		return errors;	}	printf("Verify (currently only for RSA):\n");	for (i = 0; find_object(sess, CKO_PRIVATE_KEY, &priv_key, NULL, 0, i); i++) {		char *label;		unsigned char *id;		CK_ULONG id_len;				printf("  testing key %d", i);		if ((label = getLABEL(sess, priv_key, NULL)) != NULL) {			printf(" (%s)", label);			free(label);		}		if (i != 0)			printf(" with 1 mechanism");		printf("\n");		if (!getSIGN(sess, priv_key)) {			printf(" -- can't be used to sign/verify, skipping\n");			continue;		}		if ((id = getID(sess, priv_key, &id_len)) != NULL) {			int r;			r = find_object(sess, CKO_PUBLIC_KEY, &pub_key, id, id_len, 0);			free(id);			if (r == 0) {				printf(" -- can't find corresponding public key, skipping\n");				continue;			}		}		else {			printf(" -- can't get the ID for looking up the public key, skipping\n");			continue;		}		key_len = (getMODULUS_BITS(sess, priv_key) + 7) / 8;		errors += sign_verify(slot, sess, priv_key, key_len, pub_key, i != 0);	}	if (i == 0)		printf("  No private key found for testing\n");	return errors;}#ifdef HAVE_OPENSSLstatic intwrap_unwrap(CK_SLOT_ID slot, CK_SESSION_HANDLE session,	    const EVP_CIPHER *algo, CK_OBJECT_HANDLE privKeyObject){	CK_OBJECT_HANDLE cipherKeyObject;	CK_RV           rv;	EVP_PKEY       *pkey;	EVP_CIPHER_CTX	seal_ctx;	unsigned char	keybuf[512], *key = keybuf;	int		key_len;	unsigned char	iv[32], ciphered[1024], cleartext[1024];	int		ciphered_len, cleartext_len, len;	CK_MECHANISM	mech;	CK_ULONG	key_type = CKM_DES_CBC;	CK_ATTRIBUTE	key_template = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };	pkey = get_public_key(session, privKeyObject);	if (pkey == NULL)		return 0;	printf("    %s: ", OBJ_nid2sn(EVP_CIPHER_nid(algo)));	EVP_SealInit(&seal_ctx, algo,			&key, &key_len,			iv, &pkey, 1);		/* Encrypt something */	len = sizeof(ciphered);	EVP_SealUpdate(&seal_ctx, ciphered, &len, (const unsigned char *) "hello world", 11);	ciphered_len = len;	len = sizeof(ciphered) - ciphered_len;	EVP_SealFinal(&seal_ctx, ciphered + ciphered_len, &len);	ciphered_len += len;	mech.mechanism = CKM_RSA_PKCS;	rv = p11->C_UnwrapKey(session, &mech, privKeyObject,			key, key_len,			&key_template, 1,			&cipherKeyObject);	/* mechanism not implemented, don't test */	if (rv == CKR_MECHANISM_INVALID)		return 0;	if (rv != CKR_OK) {		p11_perror("C_UnwrapKey", rv);		return 1;	}	/* Try to decrypt */	key = getVALUE(session, cipherKeyObject, (unsigned long *) &key_len);	if (key == NULL) {		printf("  Could not get unwrapped key\n");		return 1;	}	if (key_len != EVP_CIPHER_key_length(algo)) {		printf("  Key length mismatch (%d != %d)\n",				key_len, EVP_CIPHER_key_length(algo));		return 1;	}	EVP_DecryptInit(&seal_ctx, algo, key, iv);	len = sizeof(cleartext);	EVP_DecryptUpdate(&seal_ctx, cleartext, &len, ciphered, ciphered_len);	cleartext_len = len;	len = sizeof(cleartext) - len;	EVP_DecryptFinal(&seal_ctx, cleartext + cleartext_len, &len);	cleartext_len += len;	if (cleartext_len != 11	 || memcmp(cleartext, "hello world", 11)) {		printf("  resulting cleartext doesn't match input\n");		return 1;	}	printf("OK\n");	return 0;}#endif/* * Test unwrap functions */static inttest_unwrap(CK_SLOT_ID slot, CK_SESSION_HANDLE session){	int             errors = 0;	CK_RV           rv;	CK_OBJECT_HANDLE privKeyObject;	CK_SESSION_HANDLE sess;	CK_MECHANISM_TYPE firstMechType;	CK_SESSION_INFO sessionInfo;	CK_ULONG        j;	char 		*label;	rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &sess);	if (rv != CKR_OK)

⌨️ 快捷键说明

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