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

📄 pkcs11-tool.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
		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("Key unwrap: not logged in, skipping key unwrap tests\n");		return errors;	}	firstMechType = find_mechanism(slot, CKF_UNWRAP | CKF_HW, 0);	if (firstMechType == NO_MECHANISM) {		printf("Unwrap: not implemented\n");		return errors;	}	printf("Key unwrap (RSA)\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 (!getUNWRAP(sess, privKeyObject)) {			printf(" -- can't be used to unwrap, skipping\n");			continue;		}		printf("\n");#ifndef HAVE_OPENSSL		printf("No OpenSSL support, unable to validate C_Unwrap\n");#else		errors += wrap_unwrap(slot, sess, EVP_des_cbc(), privKeyObject);		errors += wrap_unwrap(slot, sess, EVP_des_ede3_cbc(), privKeyObject);		errors += wrap_unwrap(slot, sess, EVP_bf_cbc(), privKeyObject);		errors += wrap_unwrap(slot, sess, EVP_cast5_cfb(), privKeyObject);#endif	}	return errors;}static inttest_random(CK_SLOT_ID slot){	CK_SESSION_HANDLE session;	CK_BYTE buf1[100], buf2[100];	CK_BYTE seed1[100];	CK_RV rv;	int errors = 0;	printf("C_SeedRandom() and C_GenerateRandom():\n");	rv = p11->C_OpenSession(slot, CKF_SERIAL_SESSION,		NULL, NULL, &session);	if (rv != CKR_OK)		p11_fatal("C_OpenSession", rv);	rv = p11->C_SeedRandom(session, seed1, 10);	if (rv == CKR_RANDOM_NO_RNG || rv == CKR_FUNCTION_NOT_SUPPORTED) {		printf("  not implemented\n");		return 0;	}	if (rv == CKR_RANDOM_SEED_NOT_SUPPORTED)		printf("  seeding (C_SeedRandom) not supported\n");	else if (rv != CKR_OK) {		p11_perror("C_SeedRandom", rv);		return 1;	}	rv = p11->C_GenerateRandom(session, buf1, 10);	if (rv != CKR_OK) {		p11_perror("C_GenerateRandom", rv);		return 1;	}	rv = p11->C_GenerateRandom(session, buf1, 100);	if (rv != CKR_OK) {		p11_perror("C_GenerateRandom", rv);		return 1;	}	rv = p11->C_GenerateRandom(session, buf1, 0);	if (rv != CKR_OK) {		p11_perror("C_GenerateRandom(,,0)", rv);		return 1;	}	rv = p11->C_GenerateRandom(session, NULL, 100);	if (rv != CKR_OK) {		p11_perror("C_GenerateRandom(,NULL,)", rv);		return 1;	}	if (memcmp(buf1, buf2, 100) == 0) {		printf("  ERR: C_GenerateRandom returned twice the same value!!!\n");		errors++;	}	printf("  seems to be OK\n");	return 0;}static inttest_card_detection(int wait_for_event){	char buffer[256];	CK_SLOT_ID slot_id;	CK_RV rv;	printf("Testing card detection%s\n",		wait_for_event? " using C_WaitForSlotEvent" : "");	while (1) {		printf("Please press return to continue, x to exit: ");		fflush(stdout);		if (fgets(buffer, sizeof(buffer), stdin) == NULL		|| buffer[0] == 'x')			break;				if (wait_for_event) {			printf("Calling C_WaitForSlotEvent: ");			fflush(stdout);			rv = p11->C_WaitForSlotEvent(0, &slot_id, NULL);			if (rv != CKR_OK) {				printf("failed.\n");				p11_perror("C_WaitForSlotEvent", rv);				return 1;			}			printf("event on slot %u\n", (unsigned int) slot_id);		}		list_slots();	}	return 0;}static intp11_test(CK_SLOT_ID slot, CK_SESSION_HANDLE session){	int errors = 0;	errors += test_random(slot);	errors += test_digest(slot);	errors += test_signature(slot, session);	errors += test_verify(slot, session);	errors += test_unwrap(slot, session);	errors += test_card_detection(0);	errors += test_card_detection(1);	if (errors == 0)		printf("No errors\n");	else		printf("%d errors\n", errors);	return errors;}/* Does about the same as Mozilla does when you go to an on-line CA * for obtaining a certificate: key pair generation, signing the * cert request + some other tests, writing certs and changing * some attributes. */static voidtest_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session){	CK_MECHANISM		mech = {CKM_RSA_PKCS, NULL_PTR, 0};	CK_MECHANISM_TYPE	*mech_type = NULL;	CK_OBJECT_HANDLE	pub_key, priv_key;	CK_ULONG		i, num_mechs = 0;	CK_RV			rv;	CK_BYTE			buf[20], *tmp;	CK_BYTE			md5_and_digestinfo[34] = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10";	CK_BYTE			*data, sig[512];	CK_ULONG		data_len, sig_len;	CK_BYTE			*id = (CK_BYTE *) "abcdefghijklmnopqrst";	CK_ULONG		id_len = 20;	CK_BYTE			*label = (CK_BYTE *) "Just a label";	CK_ULONG		label_len = 12;	CK_ATTRIBUTE		attribs[3] = {		{CKA_ID, id, id_len},		{CKA_LABEL, label, label_len},		{CKA_SUBJECT, (void *) "This won't be used in our lib", 29}	};	FILE			*f;	get_mechanisms(slot, &mech_type, &num_mechs);	for (i = 0; i < num_mechs; i++) {		if (mech_type[i] == CKM_RSA_PKCS_KEY_PAIR_GEN)			break;	}	if (i == num_mechs) {		printf("ERR: no \"CKM_RSA_PKCS_KEY_PAIR_GEN\" found in the mechanism list\n");		return;	}	f = fopen(opt_file_to_write, "rb");	if (f == NULL)		fatal("Couldn't open file \"%s\"\n", opt_file_to_write);	fclose(f);	/* Get for a not-yet-existing ID */	while(find_object(session, CKO_PRIVATE_KEY, &priv_key, id, id_len, 0))		id[0]++;		printf("\n*** Generating a 1024 bit RSA key pair ***\n");	if (!gen_keypair(slot, session, &pub_key, &priv_key))		return;	tmp = getID(session, priv_key, (CK_ULONG *) &opt_object_id_len);	if (opt_object_id == NULL || opt_object_id_len == 0) {		printf("ERR: newly generated private key has no (or an empty) CKA_ID\n");		return;	}	memcpy(opt_object_id, tmp, opt_object_id_len);	printf("\n*** Changing the CKA_ID of private and public key into one of 20 bytes ***\n");	rv = p11->C_SetAttributeValue(session, priv_key, attribs, 1);	if (rv != CKR_OK)		p11_fatal("C_SetAttributeValue(priv_key)", rv);	rv = p11->C_SetAttributeValue(session, pub_key, attribs, 1);	if (rv != CKR_OK)		p11_fatal("C_SetAttributeValue(pub_key)", rv);	printf("\n*** Do a signature and verify it (presumably to test the keys) ***\n");	data = buf;	data_len = 20;	rv = p11->C_SignInit(session, &mech, priv_key);	if (rv != CKR_OK)		p11_fatal("C_SignInit", rv);	rv = p11->C_Sign(session, data, data_len, NULL, &sig_len);	if (rv != CKR_OK)		p11_fatal("C_Sign", rv);	sig_len = 20;	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);	if (rv != CKR_BUFFER_TOO_SMALL) {		printf("ERR: C_Sign() didn't return CKR_BUFFER_TO_SMALL but %s\n", CKR2Str(rv));		return;	}	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);	if (rv != CKR_OK)		p11_fatal("C_Sign", rv);	rv = p11->C_VerifyInit(session, &mech, pub_key);	if (rv != CKR_OK)		p11_fatal("C_VerifyInit", rv);	rv = p11->C_Verify(session, data, data_len, sig, sig_len);	if (rv != CKR_OK)		p11_fatal("C_Verify", rv);	printf("\n*** Signing the certificate request ***\n");	/* Sign the certificate request */	data = md5_and_digestinfo;	data_len = 20;	rv = p11->C_SignInit(session, &mech, priv_key);	rv = p11->C_Sign(session, data, data_len, sig, &sig_len);	if (rv != CKR_OK)		p11_fatal("C_SignInit", rv);	if (rv != CKR_OK)		p11_fatal("C_Sign", rv);	printf("\n*** In real life, the cert req should be sent to the CA ***\n");	printf("\n*** Changing the CKA_LABEL, CKA_ID and CKA_SUBJECT of the public key ***\n");	rv = p11->C_SetAttributeValue(session, pub_key, attribs, 3);	if (rv != CKR_OK)		p11_fatal("C_SetAttributeValue", rv);	printf("\n*** Put a cert on the card (NOTE: doesn't correspond with the key!) ***\n");	opt_object_class = CKO_CERTIFICATE;	memcpy(opt_object_id, id, id_len);	opt_object_id_len = id_len;	opt_object_label = (char *) label;	if (!write_object(slot, session))		return;	printf("\n==> OK, successfull! Should work with Mozilla\n");	}const char *p11_flag_names(struct flag_info *list, CK_FLAGS value){	static char	buffer[1024];	const char	*sepa = "";	buffer[0] = '\0';	while (list->value) {		if (list->value & value) {			strcat(buffer, sepa);			strcat(buffer, list->name);			value &= ~list->value;			sepa = ", ";		}		list++;	}	if (value) {		sprintf(buffer+strlen(buffer),			"%sother flags=0x%x", sepa,			(unsigned int) value);	}	return buffer;}const char *p11_slot_info_flags(CK_FLAGS value){	static struct flag_info	slot_flags[] = {		{ CKF_TOKEN_PRESENT, "token present" },		{ CKF_REMOVABLE_DEVICE, "removable device" },		{ CKF_HW_SLOT, "hardware slot" },		{ 0 }	};	return p11_flag_names(slot_flags, value);}const char *p11_token_info_flags(CK_FLAGS value){	static struct flag_info	slot_flags[] = {		{ CKF_RNG, "rng" },		{ CKF_WRITE_PROTECTED, "readonly" },		{ CKF_LOGIN_REQUIRED, "login required" },		{ CKF_USER_PIN_INITIALIZED, "PIN initialized" },		{ CKF_PROTECTED_AUTHENTICATION_PATH, "PIN pad present" },		{ CKF_TOKEN_INITIALIZED, "token initialized" },		{ 0 }	};	return p11_flag_names(slot_flags, value);}const char *p11_utf8_to_local(CK_UTF8CHAR *string, size_t len){	static char	buffer[512];	size_t		n, m;	while (len && string[len-1] == ' ')		len--;	/* For now, simply copy this thing */	for (n = m = 0; n < sizeof(buffer) - 1; n++) {		if (m >= len)			break;		buffer[n] = string[m++];	}	buffer[n] = '\0';	return buffer;}voidp11_fatal(const char *func, CK_RV rv){	fatal("PKCS11 function %s failed: rv = %s (0x%0x)\n",		func, CKR2Str(rv), (unsigned int) rv);}voidp11_perror(const char *msg, CK_RV rv){	fprintf(stderr,		"  ERR: %s failed: %s (0x%0x)\n",		msg, CKR2Str(rv), (unsigned int) rv);}int hex_to_bin(const char *in, unsigned char *out, size_t *outlen){	size_t left, count = 0;	if (in == NULL || *in == '\0') {		*outlen = 0;		return 1;	}        left = *outlen;	while (*in != '\0') {		int byte = 0, nybbles = 2;		char c;		while (nybbles-- && *in && *in != ':') {			byte <<= 4;			c = *in++;			if ('0' <= c && c <= '9')				c -= '0';			else			if ('a' <= c && c <= 'f')				c = c - 'a' + 10;			else			if ('A' <= c && c <= 'F')				c = c - 'A' + 10;			else {				printf("hex_to_bin(): invalid char '%c' in hex string\n", c);				*outlen = 0;				return 0;			}			byte |= c;		}		if (*in == ':')			in++;		if (left <= 0) {			printf("hex_to_bin(): hex string too long");			*outlen = 0;			return 0;		}		out[count++] = (unsigned char) byte;		left--;		c++;	}	*outlen = count;	return 1;}static struct mech_info	p11_mechanisms[] = {      { CKM_RSA_PKCS_KEY_PAIR_GEN,		"RSA-PKCS-KEY-PAIR-GEN" },      { CKM_RSA_PKCS,		"RSA-PKCS" },      { CKM_RSA_9796,		"RSA-9796" },      { CKM_RSA_X_509,		"RSA-X-509" },      { CKM_MD2_RSA_PKCS,	"MD2-RSA-PKCS" },      { CKM_MD5_RSA_PKCS,	"MD5-RSA-PKCS",		"rsa-md5" },      { CKM_SHA1_RSA_PKCS,	"SHA1-RSA-PKCS",	"rsa-sha1" },      { CKM_RIPEMD128_RSA_PKCS,	"RIPEMD128-RSA-PKCS" },      { CKM_RIPEMD160_RSA_PKCS,	"RIPEMD160-RSA-PKCS",	"rsa-ripemd160" },      { CKM_RSA_PKCS_OAEP,	"RSA-PKCS-OAEP" },      { CKM_RSA_X9_31_KEY_PAIR_GEN,"RSA-X9-31-KEY-PAIR-GEN" },      { CKM_RSA_X9_31,		"RSA-X9-31" },      { CKM_SHA1_RSA_X9_31,	"SHA1-RSA-X9-31" },      { CKM_RSA_PKCS_PSS,	"RSA-PKCS-PSS" },      { CKM_SHA1_RSA_PKCS_PSS,	"SHA1-RSA-PKCS-PSS" },      { CKM_DSA_KEY_PAIR_GEN,	"DSA-KEY-PAIR-GEN" },      { CKM_DSA,		"DSA" },      { CKM_DSA_SHA1,		"DSA-SHA1" },      { CKM_DH_PKCS_KEY_PAIR_GEN,"DH-PKCS-KEY-PAIR-GEN" },      { CKM_DH_PKCS_DERIVE,	"DH-PKCS-DERIVE" },      { CKM_X9_42_DH_KEY_PAIR_GEN,"X9-42-DH-KEY-PAIR-GEN" },      { CKM_X9_42_DH_DERIVE,	"X9-42-DH-DERIVE" },      { CKM_X9_42_DH_HYBRID_DERIVE,"X9-42-DH-HYBRID-DERIVE" },      { CKM_X9_42_MQV_DERIVE,	"X9-42-MQV-DERIVE" },      { CKM_RC2_KEY_GEN,	"RC2-KEY-GEN" },      { CKM_RC2_ECB,		"RC2-ECB" },      { CKM_RC2_CBC,		"RC2-CBC" },      { CKM_RC2_MAC,		"RC2-MAC" },      { CKM_RC2_MAC_GENERAL,	"RC2-MAC-GENERAL" },      { CKM_RC2_CBC_PAD,	"RC2-CBC-PAD" },      { CKM_RC4_KEY_GEN,	"RC4-KEY-GEN" },      { CKM_RC4,		"RC4" },      { CKM_DES_KEY_GEN,	"DES-KEY-GEN" },      { CKM_DES_ECB,		"DES-ECB" },      { CKM_DES_CBC,		"DES-CBC" },      { CKM_DES_MAC,		"DES-MAC" },      { CKM_DES_MAC_GENERAL,	"DES-MAC-GENERAL" },      { CKM_DES_CBC_PAD,	"DES-CBC-PAD" },      { CKM_DES2_KEY_GEN,	"DES2-KEY-GEN" },      { CKM_DES3_KEY_GEN,	"DES3-KEY-GEN" },      { CKM_DES3_ECB,		"DES3-ECB" },      { CKM_DES3_CBC,		"DES3-CBC" },      { CKM_DES3_MAC,		"DES3-MAC" },      { CKM_DES3_MAC_GENERAL,	"DES3-MAC-GENERAL" },      { CKM_DES3_CBC_PAD,	"DES3-CBC-PAD" },      { CKM_CDMF_KEY_GEN,	"CDMF-KEY-GEN" },      { CKM_CDMF_ECB,		"CDMF-ECB" },      { CKM_CDMF_CBC,		"CDMF-CBC" },      { CKM_CDMF_MAC,		"CDMF-MAC" },      { CKM_CDMF_MAC_GENERAL,	"CDMF-MAC-GENERAL" },      { CKM_CDMF_CBC_PAD,	"CDMF-CBC-PAD" },      { CKM_MD2,		"MD2" },      { CKM_MD2_HMAC,		"MD2-HMAC" },      { CKM_MD2_HMAC_GENERAL,	"MD2-HMAC-GENERAL" },      { CKM_MD5,		"MD5" },      { CKM_MD5_HMAC,		"MD5-HMAC" },      { CKM_MD5_HMAC_GENERAL,	"MD5-HMAC-GENERAL" },      { CKM_SHA_1,		"SHA-1" },      { CKM_SHA_1_HMAC,		"SHA-1-HMAC" },      { CKM_SHA_1_HMAC_GENERAL,	"SHA-1-HMAC-GENERAL" },      { CKM_RIPEMD128,		"RIPEMD128" },      { CKM_RIPEMD128_HMAC,	"RIPEMD128-HMAC" },      { CKM_RIPEMD128_HMAC_GENERAL,"RIPEMD128-HMAC-GENERAL" },      { CKM_RIPEMD160,		"RIPEMD160" },      { CKM_RIPEMD160_HMAC,	"RIPEMD160-HMAC" },      { CKM_RIPEMD160_HMAC_GENERAL,"RIPEMD160-HMAC-GENERAL" },      { CKM_CAST_KEY_GEN,	"CAST-KEY-GEN" },      { CKM_CAST_ECB,		"CAST-ECB" },      { CKM_CAST_CBC,		"CAST-CBC" },      { CKM_CAST_MAC,		"CAST-MAC" },      { CKM_CAST_MAC_GENERAL,	"CAST-MAC-GENERAL" },      { CKM_CAST_CBC_PAD,	"CAST-CBC-PAD" },      { CKM_CAST3_KE

⌨️ 快捷键说明

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