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

📄 pkcs15-init.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Initialize pkcs15 application */static intdo_init_app(struct sc_profile *profile){	struct sc_pkcs15init_initargs args;	struct sc_pkcs15_pin_info info;	memset(&args, 0, sizeof(args));	if (!opt_pins[2] && !opt_no_prompt && !opt_no_sopin) {		sc_pkcs15init_get_pin_info(profile,				SC_PKCS15INIT_SO_PIN, &info);		if (!read_one_pin(profile, "New security officer (SO) PIN",				&info, READ_PIN_RETYPE|READ_PIN_OPTIONAL,				&opt_pins[2]))			goto failed;	}	if (opt_pins[2] && !opt_pins[3] && !opt_no_prompt) {		sc_pkcs15init_get_pin_info(profile,				SC_PKCS15INIT_SO_PUK, &info);		if (!read_one_pin(profile, "Unlock code for new SO PIN",				&info, READ_PIN_RETYPE|READ_PIN_OPTIONAL,				&opt_pins[3]))			goto failed;	}	args.so_pin = (const u8 *) opt_pins[2];	if (args.so_pin)		args.so_pin_len = strlen((char *) args.so_pin);	args.so_puk = (const u8 *) opt_pins[3];	if (args.so_puk)		args.so_puk_len = strlen((char *) args.so_puk);	args.serial = (const char *) opt_serial;	args.label = opt_label;		return sc_pkcs15init_add_app(card, profile, &args);failed:		return SC_ERROR_PKCS15INIT;}/* * Store a PIN/PUK pair */static intdo_store_pin(struct sc_profile *profile){	struct sc_pkcs15init_pinargs args;	struct sc_pkcs15_pin_info info;	if (!opt_authid) {		error("No auth id specified\n");		return SC_ERROR_INVALID_ARGUMENTS;	}	if (opt_pins[0] == NULL) {		sc_pkcs15init_get_pin_info(profile,				SC_PKCS15INIT_USER_PIN, &info);		if (!read_one_pin(profile, "New user PIN", &info,			       	READ_PIN_RETYPE,				&opt_pins[0]))			goto failed;	}	if (*opt_pins[0] == '\0') {		error("You must specify a PIN\n");		return SC_ERROR_INVALID_ARGUMENTS;	}	if (opt_pins[1] == NULL) {		sc_pkcs15init_get_pin_info(profile,				SC_PKCS15INIT_USER_PUK, &info);		if (!read_one_pin(profile,			       	"Unlock code for new user PIN", &info,			       	READ_PIN_RETYPE|READ_PIN_OPTIONAL,			       	&opt_pins[1]))			goto failed;	}	memset(&args, 0, sizeof(args));	sc_pkcs15_format_id(opt_authid, &args.auth_id);	args.pin = (u8 *) opt_pins[0];	args.pin_len = strlen(opt_pins[0]);	args.puk = (u8 *) opt_pins[1];	args.puk_len = opt_pins[1]? strlen(opt_pins[1]) : 0;	args.label = opt_label;	return sc_pkcs15init_store_pin(p15card, profile, &args);failed:		return SC_ERROR_PKCS15INIT;}/* * Display split key error message */static voidsplit_key_error(void){	fprintf(stderr, "\n"	"Error - this token requires a more restrictive key usage.\n"	"Keys stored on this token can be used either for signing or decipherment,\n"	"but not both. You can either specify a more restrictive usage through\n"	"the --key-usage command line argument, or allow me to transparently\n"	"create two key objects with separate usage by specifying --split-key\n");	exit(1);}/* * Store a private key */static intdo_store_private_key(struct sc_profile *profile){	struct sc_pkcs15init_prkeyargs args;	EVP_PKEY	*pkey = NULL;	X509		*cert[MAX_CERTS];	int		r, i, ncerts;	if ((r = init_keyargs(&args)) < 0)		return r;	r = do_read_private_key(opt_infile, opt_format, &pkey, cert, MAX_CERTS);	if (r < 0)		return r;	ncerts = r;	if (ncerts) {		char	namebuf[256];		printf("Importing %d certificates:\n", ncerts);		for (i = 0; i < ncerts; i++) {			printf("  %d: %s\n",				i, X509_NAME_oneline(cert[i]->cert_info->subject,					namebuf, sizeof(namebuf)));		}	}	if ((r = do_convert_private_key(&args.key, pkey)) < 0)		return r;	if (ncerts) {		unsigned int	usage = cert[0]->ex_kusage;		/* No certificate usage? Assume ordinary		 * user cert */		usage = 0x1F;		/* If the user requested a specific key usage on the		 * command line check if it includes _more_		 * usage bits than the one specified by the cert,		 * and complain if it does.		 * If the usage specified on the command line		 * is more restrictive, use that.		 */		if (~usage & opt_x509_usage) {			fprintf(stderr,			    "Warning: requested key usage incompatible with "			    "key usage specified by X.509 certificate\n");		}		args.x509_usage = opt_x509_usage? opt_x509_usage : usage;	}	if (sc_pkcs15init_requires_restrictive_usage(p15card, &args, 0)) {		if (!opt_split_key)			split_key_error();		r = sc_pkcs15init_store_split_key(p15card, profile,				&args, NULL, NULL);	} else {		r = sc_pkcs15init_store_private_key(p15card, profile, &args, NULL);	}	if (r < 0)		return r;	/* If there are certificate as well (e.g. when reading the	 * private key from a PKCS #12 file) store them, too.	 */	for (i = 0; i < ncerts; i++) {		struct sc_pkcs15init_certargs cargs;		char	namebuf[SC_PKCS15_MAX_LABEL_SIZE-1];		memset(&cargs, 0, sizeof(cargs));		/* Just the first certificate gets the same ID		 * as the private key. All others get		 * an ID of their own */		if (i == 0)			cargs.id = args.id;		else			cargs.authority = 1;		cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject,					namebuf, sizeof(namebuf));		cargs.x509_usage = cert[i]->ex_kusage;		r = do_convert_cert(&cargs.der_encoded, cert[i]);		if (r >= 0)			r = sc_pkcs15init_store_certificate(p15card, profile,			       	&cargs, NULL);		free(cargs.der_encoded.value);	}		/* No certificates - store the public key */	if (ncerts == 0) {		r = do_store_public_key(profile, pkey);	}	return r;}/* * Store a public key */static intdo_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey){	struct sc_pkcs15init_pubkeyargs args;	int		r = 0;	memset(&args, 0, sizeof(args));	if (opt_objectid)		sc_pkcs15_format_id(opt_objectid, &args.id);	args.label = opt_label;	if (pkey == NULL)		r = do_read_public_key(opt_infile, opt_format, &pkey);	if (r >= 0)		r = do_convert_public_key(&args.key, pkey);	if (r >= 0)		r = sc_pkcs15init_store_public_key(p15card, profile,					&args, NULL);	return r;}/* * Download certificate to card */static intdo_store_certificate(struct sc_profile *profile){	struct sc_pkcs15init_certargs args;	X509	*cert;	int	r;	memset(&args, 0, sizeof(args));	if (opt_objectid)		sc_pkcs15_format_id(opt_objectid, &args.id);	args.label = opt_label;	args.authority = opt_authority;	r = do_read_certificate(opt_infile, opt_format, &cert);	if (r >= 0)		r = do_convert_cert(&args.der_encoded, cert);	if (r >= 0)		r = sc_pkcs15init_store_certificate(p15card, profile,					&args, NULL);	return r;}/* * Download data object to card */static intdo_store_data_object(struct sc_profile *profile){	struct sc_pkcs15init_dataargs args;	u8	*data;	size_t	datalen;	int	r=0;	memset(&args, 0, sizeof(args));	if (opt_objectid)		sc_pkcs15_format_id(opt_objectid, &args.id);	if (opt_authid)		sc_pkcs15_format_id(opt_authid, &args.auth_id);	args.label = opt_label;	r = do_read_data_object(opt_infile, &data, &datalen);	if (r >= 0) {		/* der_encoded contains the plain data, nothing DER encoded */		args.der_encoded.value = data;		args.der_encoded.len = datalen;		r = sc_pkcs15init_store_data_object(p15card, profile,					&args, NULL);	}	return r;}/* * Generate a new private key */static intdo_generate_key(struct sc_profile *profile, const char *spec){	struct sc_pkcs15init_prkeyargs args;	unsigned int	evp_algo, keybits = 1024;	EVP_PKEY	*pkey;	int		r, split_key = 0;	if ((r = init_keyargs(&args)) < 0)		return r;	/* Parse the key spec given on the command line */	if (!strncasecmp(spec, "rsa", 3)) {		args.key.algorithm = SC_ALGORITHM_RSA;		evp_algo = EVP_PKEY_RSA;		spec += 3;	} else if (!strncasecmp(spec, "dsa", 3)) {		args.key.algorithm = SC_ALGORITHM_DSA;		evp_algo = EVP_PKEY_DSA;		spec += 3;	} else {		error("Unknown algorithm \"%s\"", spec);		return SC_ERROR_INVALID_ARGUMENTS;	}	if (*spec == '/' || *spec == '-')		spec++;	if (*spec) {		char	*end;		keybits = strtoul(spec, &end, 10);		if (*end) {			error("Invalid number of key bits \"%s\"", spec);			return SC_ERROR_INVALID_ARGUMENTS;		}	}	/* If the card doesn't support keys that can both sign _and_	 * decipher, make sure the user specified --split-key */	if (sc_pkcs15init_requires_restrictive_usage(p15card, &args, keybits)) {		if (!opt_split_key)			split_key_error();		split_key = 1;	}	if (!opt_softkeygen && !split_key) {		r = sc_pkcs15init_generate_key(p15card, profile,				&args, keybits, NULL);		if (r >= 0 || r != SC_ERROR_NOT_SUPPORTED)			return r;		if (!opt_quiet)			printf("Warning: card doesn't support on-board "			       "key generation.\n"			       "Trying software generation\n");	}	/* Generate the key ourselves */	if ((r = do_generate_key_soft(evp_algo, keybits, &pkey)) < 0	 || (r = do_convert_private_key(&args.key, pkey) ) < 0)		goto out;	if (split_key) {		sc_pkcs15init_store_split_key(p15card,				profile, &args, NULL, NULL);	} else {		r = sc_pkcs15init_store_private_key(p15card,				profile, &args, NULL);	}	/* Store public key portion on card */	if (r >= 0)		r = do_store_public_key(profile, pkey);out:	EVP_PKEY_free(pkey);	return r;}intinit_keyargs(struct sc_pkcs15init_prkeyargs *args){	memset(args, 0, sizeof(*args));	if (opt_objectid)		sc_pkcs15_format_id(opt_objectid, &args->id);	if (opt_authid) {		sc_pkcs15_format_id(opt_authid, &args->auth_id);	} else if (!opt_unprotected) {		error("no PIN given for key - either use --insecure or \n"		      "specify a PIN using --auth-id");		return SC_ERROR_INVALID_ARGUMENTS;	}	if (opt_extractable) {		args->flags |= SC_PKCS15INIT_EXTRACTABLE;		if (opt_passphrase) {			args->passphrase = opt_passphrase;		} else {			if (!opt_unprotected) {				error("no pass phrase given for key - "				      "either use --insecure or\n"				      "specify a pass phrase using "				      "--passphrase");				return SC_ERROR_PASSPHRASE_REQUIRED;			}			args->flags |= SC_PKCS15INIT_NO_PASSPHRASE;		}	}	args->label = opt_label;	args->x509_usage = opt_x509_usage;	return 0;}/* * Intern secrets given on the command line (mostly for testing) */voidparse_secret(struct secret *secret, const char *arg){	char		*copy, *str, *value;	size_t		len;	str = copy = strdup(arg);	if (!(value = strchr(str, '=')))		goto parse_err;	*value++ = '\0';	if (*str == '@') {		sc_pkcs15_format_id(str+1, &secret->id);		secret->type = SC_AC_CHV;		secret->reference = -1;	} else {		if (strncasecmp(str, "chv", 3))			secret->type = SC_AC_CHV;		else if (strncasecmp(str, "aut", 3))			secret->type = SC_AC_AUT;		else if (strncasecmp(str, "pro", 3))			secret->type = SC_AC_PRO;		else			goto parse_err;		str += 3;		if (!isdigit(str[3]))			goto parse_err;		secret->reference = strtoul(str, &str, 10);		if (*str != '\0')			goto parse_err;	}	if ((len = strlen(value)) < 3 || value[2] != ':') {		memcpy(secret->key, value, len);	} else {		len = sizeof(secret->key);		if (sc_hex_to_bin(value, secret->key, &len) < 0)			goto parse_err;	}	secret->len = len;	free(copy);	return;parse_err:	fatal("Cannot parse secret \"%s\"\n", arg);}voidset_secrets(struct sc_profile *profile){	unsigned int	n;	for (n = 0; n < opt_secret_count; n++) {		struct secret	*secret = &opt_secrets[n];		if (secret->reference < 0)			continue;		sc_pkcs15init_set_secret(profile,				secret->type,				secret->reference,				secret->key,				secret->len);	}}/* * Callbacks from the pkcs15init to retrieve PINs */static intread_one_pin(struct sc_profile *profile, const char *name,		const struct sc_pkcs15_pin_info *info,		int flags, char **out){	char	*pin;	size_t	len;       	int	retries = 5;

⌨️ 快捷键说明

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