📄 pkcs15-init.c
字号:
/* * 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 + -