📄 pkcs15-init.c
字号:
if (!format || !strcasecmp(format, "pem")) { *out = do_read_pem_certificate(name); } else if (!strcasecmp(format, "der")) { *out = do_read_der_certificate(name); } else { fatal("Error when reading certificate. " "File format \"%s\" not supported.\n", format); } if (!*out) fatal("Unable to read certificate from %s\n", name); return 0;}static int determine_filesize(const char *filename) { FILE *fp; size_t size; if ((fp = fopen(filename,"r")) == NULL) { fatal("Unable to open %s: %m", filename); } fseek(fp,0L,SEEK_END); size = ftell(fp); fclose(fp); return size; }static intdo_read_data_object(const char *name, u8 **out, size_t *outlen){ FILE *inf; size_t filesize = determine_filesize(name); int c; *out = (u8 *) malloc(filesize); if (*out == NULL) { return SC_ERROR_OUT_OF_MEMORY; } inf = fopen(name, "r"); if (inf == NULL) { fprintf(stderr, "Unable to open '%s' for reading.\n", name); return -1; } c = fread(*out, 1, filesize, inf); fclose(inf); if (c < 0) { perror("read"); return -1; } *outlen = filesize; return 0;}static intdo_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src){ if (src == 0) return 0; dst->len = BN_num_bytes(src); dst->data = (u8 *) malloc(dst->len); BN_bn2bin(src, dst->data); return 1;}intdo_convert_private_key(struct sc_pkcs15_prkey *key, EVP_PKEY *pk){ switch (pk->type) { case EVP_PKEY_RSA: { struct sc_pkcs15_prkey_rsa *dst = &key->u.rsa; RSA *src = EVP_PKEY_get1_RSA(pk); key->algorithm = SC_ALGORITHM_RSA; if (!do_convert_bignum(&dst->modulus, src->n) || !do_convert_bignum(&dst->exponent, src->e) || !do_convert_bignum(&dst->d, src->d) || !do_convert_bignum(&dst->p, src->p) || !do_convert_bignum(&dst->q, src->q)) fatal("Invalid/incomplete RSA key.\n"); if (src->iqmp && src->dmp1 && src->dmq1) { do_convert_bignum(&dst->iqmp, src->iqmp); do_convert_bignum(&dst->dmp1, src->dmp1); do_convert_bignum(&dst->dmq1, src->dmq1); } RSA_free(src); break; } case EVP_PKEY_DSA: { struct sc_pkcs15_prkey_dsa *dst = &key->u.dsa; DSA *src = EVP_PKEY_get1_DSA(pk); key->algorithm = SC_ALGORITHM_DSA; do_convert_bignum(&dst->pub, src->pub_key); do_convert_bignum(&dst->p, src->p); do_convert_bignum(&dst->q, src->q); do_convert_bignum(&dst->g, src->g); do_convert_bignum(&dst->priv, src->priv_key); DSA_free(src); break; } default: fatal("Unsupported key algorithm\n"); } return 0;}intdo_convert_public_key(struct sc_pkcs15_pubkey *key, EVP_PKEY *pk){ switch (pk->type) { case EVP_PKEY_RSA: { struct sc_pkcs15_pubkey_rsa *dst = &key->u.rsa; RSA *src = EVP_PKEY_get1_RSA(pk); key->algorithm = SC_ALGORITHM_RSA; if (!do_convert_bignum(&dst->modulus, src->n) || !do_convert_bignum(&dst->exponent, src->e)) fatal("Invalid/incomplete RSA key.\n"); RSA_free(src); break; } case EVP_PKEY_DSA: { struct sc_pkcs15_pubkey_dsa *dst = &key->u.dsa; DSA *src = EVP_PKEY_get1_DSA(pk); key->algorithm = SC_ALGORITHM_DSA; do_convert_bignum(&dst->pub, src->pub_key); do_convert_bignum(&dst->p, src->p); do_convert_bignum(&dst->q, src->q); do_convert_bignum(&dst->g, src->g); DSA_free(src); break; } default: fatal("Unsupported key algorithm\n"); } return 0;}intdo_convert_cert(sc_pkcs15_der_t *der, X509 *cert){ u8 *p; der->len = i2d_X509(cert, NULL); der->value = p = (u8 *) malloc(der->len); i2d_X509(cert, &p); return 0;}/* * Parse X.509 key usage list */static voidparse_x509_usage(const char *list, unsigned int *res){ static const char * x509_usage_names[] = { "digitalSignature", "nonRepudiation", "keyEncipherment", "dataEncipherment", "keyAgreement", "keyCertSign", "cRLSign", NULL }; static struct { const char * name; const char * list; } x509_usage_aliases[] = { { "sign", "digitalSignature,nonRepudiation,keyCertSign,cRLSign" }, { "decrypt", "keyEncipherment,dataEncipherment" }, { NULL, NULL } }; while (1) { int len, n, match = 0; while (*list == ',') list++; if (!*list) break; len = strcspn(list, ","); if (len == 4 && !strncasecmp(list, "help", 4)) { printf("Valid X.509 usage names (case-insensitive):\n"); for (n = 0; x509_usage_names[n]; n++) printf(" %s\n", x509_usage_names[n]); printf("\nAliases:\n"); for (n = 0; x509_usage_aliases[n].name; n++) { printf(" %-12s %s\n", x509_usage_aliases[n].name, x509_usage_aliases[n].list); } printf("\nUse commas to separate several usage names.\n" "Abbreviated names are okay if unique (e.g. dataEnc)\n"); exit(0); } for (n = 0; x509_usage_names[n]; n++) { if (!strncasecmp(x509_usage_names[n], list, len)) { *res |= (1 << n); match++; } } for (n = 0; x509_usage_aliases[n].name; n++) { if (!strncasecmp(x509_usage_aliases[n].name, list, len)) { parse_x509_usage(x509_usage_aliases[n].list, res); match++; } } if (match == 0) { fprintf(stderr, "Unknown X.509 key usage %.*s\n", len, list); exit(1); } if (match > 1) { fprintf(stderr, "Ambiguous X.509 key usage %.*s\n", len, list); exit(1); } list += len; }}/* * Handle one option */static voidhandle_option(const struct option *opt){ unsigned int this_action = ACTION_NONE; switch (opt->val) { case 'a': opt_authid = optarg; break; case 'C': this_action = ACTION_INIT; break; case 'E': this_action = ACTION_ERASE; break; case 'G': this_action = ACTION_GENERATE_KEY; opt_newkey = optarg; break; case 'S': this_action = ACTION_STORE_PRIVKEY; opt_infile = optarg; break; case 'P': this_action = ACTION_STORE_PIN; break; case 'X': this_action = ACTION_STORE_CERT; opt_infile = optarg; break; case 'W': this_action = ACTION_STORE_DATA; opt_infile = optarg; break; case 'd': opt_debug++; break; case 'f': opt_format = optarg; break; case 'h': print_usage_and_die(); case 'i': opt_objectid = optarg; break; case 'l': opt_label = optarg; break; case 'o': opt_outkey = optarg; break; case 'p': opt_profile = optarg; break; case 'c': opt_card_profile = optarg; break; case 'q': opt_quiet = 1; break; case 'r': opt_reader = atoi(optarg); break; case 'u': parse_x509_usage(optarg, &opt_x509_usage); break; case 'w': opt_wait = 1; break; case OPT_OPTIONS: read_options_file(optarg); break; case OPT_PIN1: case OPT_PUK1: case OPT_PIN2: case OPT_PUK2: opt_pins[opt->val & 3] = optarg; break; case OPT_SERIAL: opt_serial = optarg; break; case OPT_PASSPHRASE: opt_passphrase = optarg; break; case OPT_PUBKEY: this_action = ACTION_STORE_PUBKEY; opt_infile = optarg; break; case OPT_UNPROTECTED: opt_unprotected++; break; case OPT_EXTRACTABLE: opt_extractable++; break; case OPT_AUTHORITY: opt_authority = 1; break; case OPT_SOFT_KEYGEN: opt_softkeygen = 1; break; case 'T': opt_use_defkeys = 1; break; case OPT_SPLIT_KEY: opt_split_key = 1; break; case OPT_NO_SOPIN: opt_no_sopin = 1; break; case OPT_NO_PROMPT: opt_no_prompt = 1; break; case OPT_ASSERT_PRISTINE: this_action = ACTION_ASSERT_PRISTINE; break; case OPT_SECRET: parse_secret(&opt_secrets[opt_secret_count], optarg); opt_secret_count++; break; default: print_usage_and_die(); } if ((opt_actions & (1 << this_action)) && opt->has_arg != no_argument) { fprintf(stderr, "Error: you cannot specify option"); if (opt->name) fprintf(stderr, " --%s", opt->name); if (isprint(opt->val)) fprintf(stderr, " -%c", opt->val); fprintf(stderr, " more than once.\n"); print_usage_and_die(); } if (this_action) opt_actions |= (1 << this_action); if ((opt_pins[OPT_PIN2&3] || opt_pins[OPT_PUK2&3]) && opt_no_sopin) { fprintf(stderr, "Error: " "The --no-so-pin option and --so-pin/--so-puk are mutually\n" "exclusive.\n"); print_usage_and_die(); }}/* * Parse the command line. */static voidparse_commandline(int argc, char **argv){ const struct option *o; char shortopts[64], *sp; int c, i; /* We make sure the list of short options is always * consistent with the long options */ for (o = options, sp = shortopts; o->name; o++) { if (o->val <= 0 || o->val >= 256) continue; *sp++ = o->val; switch (o->has_arg) { case optional_argument: *sp++ = ':'; case required_argument: *sp++ = ':'; case no_argument: break; default: fatal("Internal: bad has_arg value"); } } sp[0] = 0; while ((c = getopt_long(argc, argv, shortopts, options, &i)) != -1) { /* The optindex seems to be off with some glibc * getopt implementations */ for (o = options; o->name; o++) { if (o->val == c) { handle_option(o); goto next; } } fatal("Internal error in options handling, option %u\n", c);next: ; }}/* * Read a file containing more command line options. * This allows you to specify PINs to pkcs15-init without * exposing them through ps. */static voidread_options_file(const char *filename){ const struct option *o; char buffer[1024], *name; FILE *fp; if ((fp = fopen(filename, "r")) == NULL) fatal("Unable to open %s: %m", filename); while (fgets(buffer, sizeof(buffer), fp) != NULL) { buffer[strcspn(buffer, "\n")] = '\0'; name = strtok(buffer, " \t"); while (name) { if (*name == '#') break; for (o = options; o->name; o++) if (!strcmp(o->name, name)) break; if (!o->name) { error("Unknown option \"%s\"\n", name); print_usage_and_die(); } if (o->has_arg != no_argument) { optarg = strtok(NULL, ""); if (optarg) { while (isspace((int) *optarg)) optarg++; optarg = strdup(optarg); } } if (o->has_arg == required_argument && (!optarg || !*optarg)) { error("Option %s: missing argument\n", name); print_usage_and_die(); } handle_option(o); name = strtok(NULL, " \t"); } } fclose(fp);}/* * OpenSSL helpers */static voidossl_print_errors(){ static int loaded = 0; long err; if (!loaded) { ERR_load_crypto_strings(); loaded = 1; } while ((err = ERR_get_error()) != 0) fprintf(stderr, "%s\n", ERR_error_string(err, NULL));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -