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

📄 pkcs11-tool.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * pkcs11-tool.c: Tool for poking around pkcs11 modules/tokens * * Copyright (C) 2002  Olaf Kirch <okir@lst.de> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <getopt.h>#include <opensc/pkcs11.h>#include "util.h"#ifdef HAVE_OPENSSL#include "openssl/evp.h"#include "openssl/x509.h"#include "openssl/err.h"#endif#define NEED_SESSION_RO	0x01#define NEED_SESSION_RW	0x02#define NO_SLOT		((CK_SLOT_ID) -1)#define NO_MECHANISM	((CK_MECHANISM_TYPE) -1)enum {	OPT_MODULE = 0x100,	OPT_SLOT,	OPT_SLOT_LABEL,};const struct option options[] = {	{ "show-info",		0, 0,		'I' },	{ "list-slots",		0, 0,		'L' },	{ "list-mechanisms",	0, 0,		'M' },	{ "list-objects",	0, 0,		'O' },	{ "sign",		0, 0,		's' },	{ "hash",		0, 0,		'h' },	{ "mechanism",		1, 0,		'm' },	{ "login",		0, 0,		'l' },	{ "pin",		1, 0,		'p' },	{ "change-pin",		0, 0,		'c' },	{ "keypairgen", 	0, 0, 		'k' },	{ "write-object",	1, 0, 		'w' },	{ "type", 		1, 0, 		'y' },	{ "id", 		1, 0, 		'd' },	{ "label", 		1, 0, 		'a' },	{ "set-id",		1, 0, 		'e' },	{ "slot",		1, 0,		OPT_SLOT },	{ "slot-label",		1, 0,		OPT_SLOT_LABEL },	{ "input-file",		1, 0,		'i' },	{ "output-file",	1, 0,		'o' },	{ "module",		1, 0,		OPT_MODULE },	{ "quiet",		0, 0,		'q' },	{ "test",		0, 0,		't' },	{ "moz-cert",		1, 0,		'z' },	{ 0, 0, 0, 0 }};const char *option_help[] = {	"Show global token information",	"List slots available on the token",	"Show slot information",	"List mechanisms supported by the token",	"Sign some data",	"Hash some data",	"Specify mechanism (use -M for a list of supported mechanisms)",	"Log into the token first (not needed when using --pin)",	"Supply PIN on the command line (if used in scripts: careful!)",	"Change your (user) PIN",	"Key pair generation",	"Write an object (key, cert) to the card",	"Specify the type of object (e.g. cert, privkey, pubkey)",	"Specify the id of the object",	"Specify the label of the object",	"Specify number of the slot to use",	"Specify label of the slot to use",	"Set the CKA_ID of an object, >args>= the (new) CKA_ID",	"Specify the input file",	"Specify the output file",	"Specify the module to load",	"Quiet operation",	"Test (best used with the --login or --pin option)",	"Test Mozilla-like keypair gen and cert req, <arg>=certfile"};const char *		app_name = "pkcs11-tool"; /* for utils.c */static int		opt_quiet = 0;static const char *	opt_input = NULL;static const char *	opt_output = NULL;static const char *	opt_module = NULL;static CK_SLOT_ID	opt_slot = NO_SLOT;static const char *	opt_slot_label = NULL;static CK_MECHANISM_TYPE opt_mechanism = NO_MECHANISM;static const char *	opt_file_to_write = NULL;static const char *	opt_object_class_str = NULL;static CK_OBJECT_CLASS	opt_object_class = -1;static CK_BYTE		opt_object_id[100], new_object_id[100];static size_t		opt_object_id_len = 0, new_object_id_len = 0;static char *		opt_object_label = NULL;static void *module = NULL;static CK_FUNCTION_LIST_PTR p11 = NULL;static CK_SLOT_ID_PTR p11_slots = NULL;static CK_ULONG p11_num_slots = 0;struct flag_info {	CK_FLAGS	value;	const char *	name;};struct mech_info {	CK_MECHANISM_TYPE mech;	const char *	name;	const char *	short_name;};static void		show_cryptoki_info(void);static void		list_slots(void);static void		show_token(CK_SLOT_ID);static void		list_mechs(CK_SLOT_ID);static void		list_objects(CK_SESSION_HANDLE);static int		change_pin(CK_SLOT_ID, CK_SESSION_HANDLE);static void		show_object(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);static void		show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, int);static void		show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);static void		sign_data(CK_SLOT_ID,				CK_SESSION_HANDLE, CK_OBJECT_HANDLE);static void		hash_data(CK_SLOT_ID, CK_SESSION_HANDLE);static int		gen_keypair(CK_SLOT_ID, CK_SESSION_HANDLE,				CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *);static int 		write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session);static void 		set_id_attr(CK_SLOT_ID slot, CK_SESSION_HANDLE session);static int		find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS,				CK_OBJECT_HANDLE_PTR,				const unsigned char *, size_t id_len, int obj_index);static CK_MECHANISM_TYPE find_mechanism(CK_SLOT_ID, CK_FLAGS,			 	int stop_if_not_found);static CK_SLOT_ID	find_slot_by_label(const char *);static void		get_token_info(CK_SLOT_ID, CK_TOKEN_INFO_PTR);static void		get_mechanisms(CK_SLOT_ID,				CK_MECHANISM_TYPE_PTR *, CK_ULONG_PTR);static void		p11_fatal(const char *, CK_RV);static const char *	p11_slot_info_flags(CK_FLAGS);static const char *	p11_token_info_flags(CK_FLAGS);static const char *	p11_utf8_to_local(CK_UTF8CHAR *, size_t);static const char *	p11_flag_names(struct flag_info *, CK_FLAGS);static const char *	p11_mechanism_to_name(CK_MECHANISM_TYPE);static CK_MECHANISM_TYPE p11_name_to_mechanism(const char *);static void		p11_perror(const char *, CK_RV);static const char *	CKR2Str(CK_ULONG res);static int		p11_test(CK_SLOT_ID slot, CK_SESSION_HANDLE session);static int		hex_to_bin(const char *in, CK_BYTE *out, size_t *outlen);static void		test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session);/* win32 needs this in open(2) */#ifndef O_BINARY# define O_BINARY 0#endifintmain(int argc, char * const argv[]){	CK_SESSION_HANDLE session = CK_INVALID_HANDLE;	CK_OBJECT_HANDLE object = CK_INVALID_HANDLE;	char *opt_pin = NULL;	int err = 0, c, long_optind = 0;	int do_show_info = 0;	int do_list_slots = 0;	int do_list_mechs = 0;	int do_list_objects = 0;	int do_sign = 0;	int do_hash = 0;	int do_gen_keypair = 0;	int do_write_object = 0;	int do_set_id = 0;	int do_test = 0;	int do_test_kpgen_certwrite = 0;	int need_session = 0;	int opt_login = 0;	int do_change_pin = 0;	int action_count = 0;	CK_RV rv;	while (1) {               c = getopt_long(argc, argv, "ILMOa:d:e:hi:klm:o:p:scqty:w:z:",					options, &long_optind);		if (c == -1)			break;		switch (c) {		case 'I':			do_show_info = 1;			action_count++;			break;		case 'L':			do_list_slots = 1;			action_count++;			break;		case 'M':			do_list_mechs = 1;			action_count++;			break;		case 'O':			need_session |= NEED_SESSION_RO;			do_list_objects = 1;			action_count++;			break;		case 'h':			need_session |= NEED_SESSION_RO;			do_hash = 1;			action_count++;			break;		case 'k':			need_session |= NEED_SESSION_RW;			do_gen_keypair = 1;			action_count++;			break;		case 'w':			need_session |= NEED_SESSION_RW;			do_write_object = 1;			opt_file_to_write = optarg;			action_count++;			break;		case 'e':			need_session |= NEED_SESSION_RW;			do_set_id = 1;			new_object_id_len = sizeof(new_object_id);			if (!hex_to_bin(optarg, new_object_id, &new_object_id_len)) {				printf("Invalid ID \"%s\"\n", optarg);				print_usage_and_die();			}			action_count++;			break;		case 'y':			opt_object_class_str = optarg;			if (strcmp(optarg, "cert") == 0)				opt_object_class = CKO_CERTIFICATE;			else if (strcmp(optarg, "privkey") == 0)				opt_object_class = CKO_PRIVATE_KEY;			else if (strcmp(optarg, "pubkey") == 0)				opt_object_class = CKO_PUBLIC_KEY;			else {				printf("Unsupported object type \"%s\"\n", optarg);				print_usage_and_die();			}			break;		case 'd':			opt_object_id_len = sizeof(opt_object_id);			if (!hex_to_bin(optarg, opt_object_id, &opt_object_id_len)) {				printf("Invalid ID \"%s\"\n", optarg);				print_usage_and_die();			}			break;		case 'a':			opt_object_label = optarg;			break;		case 'i':			opt_input = optarg;			break;		case 'l':			need_session |= NEED_SESSION_RW;			opt_login = 1;			break;		case 'm':			opt_mechanism = p11_name_to_mechanism(optarg);			break;		case 'o':			opt_output = optarg;			break;		case 'p':			need_session |= NEED_SESSION_RW;			opt_login = 1;			opt_pin = optarg;			break;		case 'c':			do_change_pin = 1;			need_session |= CKF_SERIAL_SESSION; /* no need for a R/W session */			action_count++;			break;		case 's':			need_session |= NEED_SESSION_RW;			do_sign = 1;			action_count++;			break;		case 't':			do_test = 1;			action_count++;			break;		case 'z':			do_test_kpgen_certwrite = 1;			opt_file_to_write = optarg;			action_count++;			break;		case 'q':			opt_quiet++;			break;		case OPT_SLOT:			opt_slot = (CK_SLOT_ID) atoi(optarg);			break;		case OPT_SLOT_LABEL:			opt_slot_label = optarg;			break;		case OPT_MODULE:			opt_module = optarg;			break;		default:			print_usage_and_die();		}	}	if (action_count == 0)		print_usage_and_die();	module = C_LoadModule(opt_module, &p11);	if (module == NULL)		fatal("Failed to load pkcs11 module");	rv = p11->C_Initialize(NULL);	if (rv != CKR_OK)		p11_fatal("C_Initialize", rv);	if (do_show_info)		show_cryptoki_info();	/* Get the list of slots */	rv = p11->C_GetSlotList(FALSE, p11_slots, &p11_num_slots);	if (rv != CKR_OK && rv != CKR_BUFFER_TOO_SMALL)		p11_fatal("C_GetSlotList", rv);	p11_slots = (CK_SLOT_ID *) calloc(p11_num_slots, sizeof(CK_SLOT_ID));	if (p11_slots == NULL) {		perror("calloc failed");		err = 1;		goto end;	}	rv = p11->C_GetSlotList(FALSE, p11_slots, &p11_num_slots);	if (rv != CKR_OK)		p11_fatal("C_GetSlotList", rv);	if (do_list_slots)		list_slots();	if (p11_num_slots == 0) {		fprintf(stderr, "No slots...\n");		err = 1;		goto end;	}	if (opt_slot_label) {		CK_SLOT_ID slot;		slot = find_slot_by_label(opt_slot_label);		if (slot == NO_SLOT) {			fprintf(stderr,				"No slot named \"%s\"\n", opt_slot_label);			err = 1;			goto end;		}		if (opt_slot != NO_SLOT && opt_slot != slot) {			fprintf(stderr,				"Conflicting slots specified\n");			err = 1;			goto end;		}		opt_slot = slot;	}	if (opt_slot == NO_SLOT)		opt_slot = p11_slots[0];	/* XXX: add wait for slot event */	if (do_list_mechs)		list_mechs(opt_slot);	if (do_sign) {		CK_TOKEN_INFO	info;		get_token_info(opt_slot, &info);		if (!(info.flags & CKF_TOKEN_INITIALIZED))			fatal("Token not initialized\n");		if (info.flags & CKF_LOGIN_REQUIRED)			opt_login++;	}	if (need_session) {		int flags = CKF_SERIAL_SESSION;		if (need_session & NEED_SESSION_RW)			flags |= CKF_RW_SESSION;		rv = p11->C_OpenSession(opt_slot, flags,				NULL, NULL, &session);		if (rv != CKR_OK)			p11_fatal("C_OpenSession", rv);	}	if (do_change_pin)		/* To be sure we won't mix things up with the -l or -p options,		 * we safely stop here. */		return change_pin(opt_slot, session);	if (opt_login) {		char	*pin;		CK_TOKEN_INFO	info;		get_token_info(opt_slot, &info);		/* Identify which pin to enter */		if (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {			pin = NULL;		} else		if (info.flags & CKF_LOGIN_REQUIRED) {			if (opt_pin == NULL)				pin = getpass("Please enter PIN: ");			else				pin = opt_pin;			if (!pin || !*pin)				return 1;		} else {			goto skip_login;		}		rv = p11->C_Login(session, CKU_USER, (CK_UTF8CHAR *) pin,			pin == NULL ? 0 : strlen(pin));		if (rv != CKR_OK)			p11_fatal("C_Login", rv);	}skip_login:	if (do_sign) {		if (!find_object(session, CKO_PRIVATE_KEY, &object, NULL, 0, 0))			fatal("Private key not found");	}	if (do_list_objects)		list_objects(session);	if (do_sign)		sign_data(opt_slot, session, object);	if (do_hash)		hash_data(opt_slot, session);	if (do_gen_keypair) {		CK_OBJECT_HANDLE hPublicKey, hPrivateKey;		gen_keypair(opt_slot, session, &hPublicKey, &hPrivateKey);	}	if (do_write_object) {		if (opt_object_class_str == NULL)			fatal("You should specify the object type with the -y option\n");		write_object(opt_slot, session);	}	if (do_set_id) {		if (opt_object_class_str == NULL)			fatal("You should specify the object type with the -y option\n");		if (opt_object_id_len == 0)			fatal("You should specify the current ID with the -d option\n");		set_id_attr(opt_slot, session);	}	if (do_test)		p11_test(opt_slot, session);	if (do_test_kpgen_certwrite)		test_kpgen_certwrite(opt_slot, session);end:	if (session)		p11->C_CloseSession(session);	if (p11)		p11->C_Finalize(NULL_PTR);	if (module)		C_UnloadModule(module);	return err;}voidshow_cryptoki_info(void){	CK_INFO	info;	CK_RV	rv;	rv = p11->C_GetInfo(&info);	if (rv != CKR_OK)		p11_fatal("C_GetInfo", rv);	printf("Cryptoki version %u.%u\n",

⌨️ 快捷键说明

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