static int apps_startup() { #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif CRYPTO_malloc_init(); ERR_load_crypto_strings(); ERR_load_SSL_strings(); OPENSSL_load_builtin_modules(); #ifndef OPENSSL_NO_ENGINE ENGINE_load_builtin_engines(); #endif if (!app_load_modules(NULL)) { ERR_print_errors(bio_err); BIO_printf(bio_err, "Error loading default configuration\n"); return 0; } OpenSSL_add_all_algorithms(); OpenSSL_add_ssl_algorithms(); setup_ui_method(); /*SSL_library_init();*/ return 1; }
int ts_main(int argc, char **argv) { CONF *conf = NULL; char *CAfile = NULL, *untrusted = NULL, *engine = NULL, *prog, **helpp; char *configfile = default_config_file; char *section = NULL, *password = NULL; char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL; char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL; char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL; const EVP_MD *md = NULL; OPTION_CHOICE o, mode = OPT_ERR; int ret = 1, no_nonce = 0, cert = 0, text = 0; int vpmtouched = 0; X509_VERIFY_PARAM *vpm = NULL; /* Input is ContentInfo instead of TimeStampResp. */ int token_in = 0; /* Output is ContentInfo instead of TimeStampResp. */ int token_out = 0; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) goto end; prog = opt_init(argc, argv, ts_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(ts_options); for (helpp = opt_helplist; *helpp; ++helpp) BIO_printf(bio_err, "%s\n", *helpp); ret = 0; goto end; case OPT_CONFIG: configfile = opt_arg(); break; case OPT_SECTION: section = opt_arg(); break; case OPT_QUERY: case OPT_REPLY: case OPT_VERIFY: if (mode != OPT_ERR) goto opthelp; mode = o; break; case OPT_DATA: data = opt_arg(); break; case OPT_DIGEST: digest = opt_arg(); break; case OPT_RAND: rnd = opt_arg(); break; case OPT_TSPOLICY: policy = opt_arg(); break; case OPT_NO_NONCE: no_nonce = 1; break; case OPT_CERT: cert = 1; break; case OPT_IN: in = opt_arg(); break; case OPT_TOKEN_IN: token_in = 1; break; case OPT_OUT: out = opt_arg(); break; case OPT_TOKEN_OUT: token_out = 1; break; case OPT_TEXT: text = 1; break; case OPT_QUERYFILE: queryfile = opt_arg(); break; case OPT_PASSIN: passin = opt_arg(); break; case OPT_INKEY: inkey = opt_arg(); break; case OPT_SIGNER: signer = opt_arg(); break; case OPT_CHAIN: chain = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_UNTRUSTED: untrusted = opt_arg(); break; case OPT_ENGINE: engine = opt_arg(); break; case OPT_MD: if (!opt_md(opt_unknown(), &md)) goto opthelp; break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; vpmtouched++; break; } } if (mode == OPT_ERR || opt_num_rest() != 0) goto opthelp; /* Seed the random number generator if it is going to be used. */ if (mode == OPT_QUERY && !no_nonce) { if (!app_RAND_load_file(NULL, 1) && rnd == NULL) BIO_printf(bio_err, "warning, not much extra random " "data, consider using the -rand option\n"); if (rnd != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(rnd)); } if (mode == OPT_REPLY && passin && !app_passwd(passin, NULL, &password, NULL)) { BIO_printf(bio_err, "Error getting password.\n"); goto end; } conf = load_config_file(configfile); if (configfile != default_config_file && !app_load_modules(conf)) goto end; /* Check parameter consistency and execute the appropriate function. */ switch (mode) { default: case OPT_ERR: goto opthelp; case OPT_QUERY: if (vpmtouched) goto opthelp; if ((data != NULL) && (digest != NULL)) goto opthelp; ret = !query_command(data, digest, md, policy, no_nonce, cert, in, out, text); break; case OPT_REPLY: if (vpmtouched) goto opthelp; if ((in != NULL) && (queryfile != NULL)) goto opthelp; if (in == NULL) { if ((conf == NULL) || (token_in != 0)) goto opthelp; } ret = !reply_command(conf, section, engine, queryfile, password, inkey, md, signer, chain, policy, in, token_in, out, token_out, text); break; case OPT_VERIFY: if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest)) goto opthelp; ret = !verify_command(data, digest, queryfile, in, token_in, CApath, CAfile, untrusted, vpmtouched ? vpm : NULL); } end: X509_VERIFY_PARAM_free(vpm); app_RAND_write_file(NULL); NCONF_free(conf); OPENSSL_free(password); return (ret); }
int dgst_main(int argc, char **argv) { BIO *in = NULL, *inp, *bmd = NULL, *out = NULL; ENGINE *e = NULL, *impl = NULL; EVP_PKEY *sigkey = NULL; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; char *hmac_key = NULL; char *mac_name = NULL; char *passinarg = NULL, *passin = NULL; const EVP_MD *md = NULL, *m; const char *outfile = NULL, *keyfile = NULL, *prog = NULL; const char *sigfile = NULL, *randfile = NULL; OPTION_CHOICE o; int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0; int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0, non_fips_allow = 0; unsigned char *buf = NULL, *sigbuf = NULL; int engine_impl = 0; prog = opt_progname(argv[0]); buf = app_malloc(BUFSIZE, "I/O buffer"); md = EVP_get_digestbyname(prog); prog = opt_init(argc, argv, dgst_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(dgst_options); ret = 0; goto end; case OPT_C: separator = 1; break; case OPT_R: separator = 2; break; case OPT_RAND: randfile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_SIGN: keyfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_VERIFY: keyfile = opt_arg(); want_pub = do_verify = 1; break; case OPT_PRVERIFY: keyfile = opt_arg(); do_verify = 1; break; case OPT_SIGNATURE: sigfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_ENGINE_IMPL: engine_impl = 1; break; case OPT_HEX: out_bin = 0; break; case OPT_BINARY: out_bin = 1; break; case OPT_DEBUG: debug = 1; break; case OPT_FIPS_FINGERPRINT: hmac_key = "etaonrishdlcupfm"; break; case OPT_NON_FIPS_ALLOW: non_fips_allow = 1; break; case OPT_HMAC: hmac_key = opt_arg(); break; case OPT_MAC: mac_name = opt_arg(); break; case OPT_SIGOPT: if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) goto opthelp; break; case OPT_MACOPT: if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); if (!macopts || !sk_OPENSSL_STRING_push(macopts, opt_arg())) goto opthelp; break; case OPT_DIGEST: if (!opt_md(opt_unknown(), &m)) goto opthelp; md = m; break; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_load_modules(NULL)) goto end; if (do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } if (engine_impl) impl = e; in = BIO_new(BIO_s_file()); bmd = BIO_new(BIO_f_md()); if ((in == NULL) || (bmd == NULL)) { ERR_print_errors(bio_err); goto end; } if (debug) { BIO_set_callback(in, BIO_debug_callback); /* needed for windows 3.1 */ BIO_set_callback_arg(in, (char *)bio_err); } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (out_bin == -1) { if (keyfile) out_bin = 1; else out_bin = 0; } if (randfile) app_RAND_load_file(randfile, 0); out = bio_open_default(outfile, out_bin ? "wb" : "w"); if (out == NULL) goto end; if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) { BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n"); goto end; } if (keyfile) { if (want_pub) sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file"); else sigkey = load_key(keyfile, keyform, 0, passin, e, "key file"); if (!sigkey) { /* * load_[pub]key() has already printed an appropriate message */ goto end; } } if (mac_name) { EVP_PKEY_CTX *mac_ctx = NULL; int r = 0; if (!init_gen_str(&mac_ctx, mac_name, impl, 0)) goto mac_end; if (macopts) { char *macopt; for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) { macopt = sk_OPENSSL_STRING_value(macopts, i); if (pkey_ctrl_string(mac_ctx, macopt) <= 0) { BIO_printf(bio_err, "MAC parameter error \"%s\"\n", macopt); ERR_print_errors(bio_err); goto mac_end; } } } if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto mac_end; } r = 1; mac_end: EVP_PKEY_CTX_free(mac_ctx); if (r == 0) goto end; } if (non_fips_allow) { EVP_MD_CTX *md_ctx; BIO_get_md_ctx(bmd, &md_ctx); EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } if (hmac_key) { sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl, (unsigned char *)hmac_key, -1); if (!sigkey) goto end; } if (sigkey) { EVP_MD_CTX *mctx = NULL; EVP_PKEY_CTX *pctx = NULL; int r; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (do_verify) r = EVP_DigestVerifyInit(mctx, &pctx, md, impl, sigkey); else r = EVP_DigestSignInit(mctx, &pctx, md, impl, sigkey); if (!r) { BIO_printf(bio_err, "Error setting context\n"); ERR_print_errors(bio_err); goto end; } if (sigopts) { char *sigopt; for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { sigopt = sk_OPENSSL_STRING_value(sigopts, i); if (pkey_ctrl_string(pctx, sigopt) <= 0) { BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); ERR_print_errors(bio_err); goto end; } } } } /* we use md as a filter, reading from 'in' */ else { EVP_MD_CTX *mctx = NULL; if (!BIO_get_md_ctx(bmd, &mctx)) { BIO_printf(bio_err, "Error getting context\n"); ERR_print_errors(bio_err); goto end; } if (md == NULL) md = EVP_md5(); if (!EVP_DigestInit_ex(mctx, md, impl)) { BIO_printf(bio_err, "Error setting digest\n"); ERR_print_errors(bio_err); goto end; } } if (sigfile && sigkey) { BIO *sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } siglen = EVP_PKEY_size(sigkey); sigbuf = app_malloc(siglen, "signature buffer"); siglen = BIO_read(sigbio, sigbuf, siglen); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } } inp = BIO_push(bmd, in); if (md == NULL) { EVP_MD_CTX *tctx; BIO_get_md_ctx(bmd, &tctx); md = EVP_MD_CTX_md(tctx); } if (argc == 0) { BIO_set_fp(in, stdin, BIO_NOCLOSE); ret = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, NULL, NULL, "stdin", bmd); } else { const char *md_name = NULL, *sig_name = NULL; if (!out_bin) { if (sigkey) { const EVP_PKEY_ASN1_METHOD *ameth; ameth = EVP_PKEY_get0_asn1(sigkey); if (ameth) EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &sig_name, ameth); } if (md) md_name = EVP_MD_name(md); } ret = 0; for (i = 0; i < argc; i++) { int r; if (BIO_read_filename(in, argv[i]) <= 0) { perror(argv[i]); ret++; continue; } else r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf, siglen, sig_name, md_name, argv[i], bmd); if (r) ret = r; (void)BIO_reset(bmd); } } end: OPENSSL_clear_free(buf, BUFSIZE); BIO_free(in); OPENSSL_free(passin); BIO_free_all(out); EVP_PKEY_free(sigkey); sk_OPENSSL_STRING_free(sigopts); sk_OPENSSL_STRING_free(macopts); OPENSSL_free(sigbuf); BIO_free(bmd); return (ret); }
int crl2pkcs7_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; PKCS7 *p7 = NULL; PKCS7_SIGNED *p7s = NULL; STACK_OF(OPENSSL_STRING) *certflst = NULL; STACK_OF(X509) *cert_stack = NULL; STACK_OF(X509_CRL) *crl_stack = NULL; X509_CRL *crl = NULL; char *infile = NULL, *outfile = NULL, *prog, *certfile; int i = 0, informat = FORMAT_PEM, outformat = FORMAT_PEM, ret = 1, nocrl = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, crl2pkcs7_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(crl2pkcs7_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_NOCRL: nocrl = 1; break; case OPT_CERTFILE: if ((certflst == NULL) && (certflst = sk_OPENSSL_STRING_new_null()) == NULL) goto end; if (!sk_OPENSSL_STRING_push(certflst, *(++argv))) { sk_OPENSSL_STRING_free(certflst); goto end; } break; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_load_modules(NULL)) goto end; if (!nocrl) { in = bio_open_default(infile, RB(informat)); if (in == NULL) goto end; if (informat == FORMAT_ASN1) crl = d2i_X509_CRL_bio(in, NULL); else if (informat == FORMAT_PEM) crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); if (crl == NULL) { BIO_printf(bio_err, "unable to load CRL\n"); ERR_print_errors(bio_err); goto end; } } if ((p7 = PKCS7_new()) == NULL) goto end; if ((p7s = PKCS7_SIGNED_new()) == NULL) goto end; p7->type = OBJ_nid2obj(NID_pkcs7_signed); p7->d.sign = p7s; p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data); if (!ASN1_INTEGER_set(p7s->version, 1)) goto end; if ((crl_stack = sk_X509_CRL_new_null()) == NULL) goto end; p7s->crl = crl_stack; if (crl != NULL) { sk_X509_CRL_push(crl_stack, crl); crl = NULL; /* now part of p7 for OPENSSL_freeing */ } if ((cert_stack = sk_X509_new_null()) == NULL) goto end; p7s->cert = cert_stack; if (certflst) for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) { certfile = sk_OPENSSL_STRING_value(certflst, i); if (add_certs_from_file(cert_stack, certfile) < 0) { BIO_printf(bio_err, "error loading certificates\n"); ERR_print_errors(bio_err); goto end; } } sk_OPENSSL_STRING_free(certflst); out = bio_open_default(outfile, WB(outformat)); if (out == NULL) goto end; if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else if (outformat == FORMAT_PEM) i = PEM_write_bio_PKCS7(out, p7); if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } ret = 0; end: BIO_free(in); BIO_free_all(out); PKCS7_free(p7); X509_CRL_free(crl); return (ret); }
int rsautl_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; X509 *x; char *infile = NULL, *outfile = NULL, *keyfile = NULL; char *passinarg = NULL, *passin = NULL, *prog; char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; unsigned char *rsa_in = NULL, *rsa_out = NULL, pad = RSA_PKCS1_PADDING; int rsa_inlen, keyformat = FORMAT_PEM, keysize, ret = 1; int rsa_outlen = 0, hexdump = 0, asn1parse = 0, need_priv = 0, rev = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, rsautl_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(rsautl_options); ret = 0; goto end; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_ASN1PARSE: asn1parse = 1; break; case OPT_HEXDUMP: hexdump = 1; break; case OPT_RAW: pad = RSA_NO_PADDING; break; case OPT_OAEP: pad = RSA_PKCS1_OAEP_PADDING; break; case OPT_SSL: pad = RSA_SSLV23_PADDING; break; case OPT_PKCS: pad = RSA_PKCS1_PADDING; break; case OPT_X931: pad = RSA_X931_PADDING; break; case OPT_SIGN: rsa_mode = RSA_SIGN; need_priv = 1; break; case OPT_VERIFY: rsa_mode = RSA_VERIFY; break; case OPT_REV: rev = 1; break; case OPT_ENCRYPT: rsa_mode = RSA_ENCRYPT; break; case OPT_DECRYPT: rsa_mode = RSA_DECRYPT; need_priv = 1; break; case OPT_PUBIN: key_type = KEY_PUBKEY; break; case OPT_CERTIN: key_type = KEY_CERT; break; case OPT_INKEY: keyfile = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; } } argc = opt_num_rest(); argv = opt_rest(); if (need_priv && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!app_load_modules(NULL)) goto end; /* FIXME: seed PRNG only if needed */ app_RAND_load_file(NULL, 0); switch (key_type) { case KEY_PRIVKEY: pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(keyfile, keyformat, 0, NULL, e, "Public Key"); break; case KEY_CERT: x = load_cert(keyfile, keyformat, NULL, e, "Certificate"); if (x) { pkey = X509_get_pubkey(x); X509_free(x); } break; } if (!pkey) { return 1; } rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if (!rsa) { BIO_printf(bio_err, "Error getting RSA key\n"); ERR_print_errors(bio_err); goto end; } in = bio_open_default(infile, 'r', FORMAT_BINARY); if (in == NULL) goto end; out = bio_open_default(outfile, 'w', FORMAT_BINARY); if (out == NULL) goto end; keysize = RSA_size(rsa); rsa_in = app_malloc(keysize * 2, "hold rsa key"); rsa_out = app_malloc(keysize, "output rsa key"); /* Read the input data */ rsa_inlen = BIO_read(in, rsa_in, keysize * 2); if (rsa_inlen <= 0) { BIO_printf(bio_err, "Error reading input Data\n"); goto end; } if (rev) { int i; unsigned char ctmp; for (i = 0; i < rsa_inlen / 2; i++) { ctmp = rsa_in[i]; rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; rsa_in[rsa_inlen - 1 - i] = ctmp; } } switch (rsa_mode) { case RSA_VERIFY: rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_SIGN: rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_ENCRYPT: rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_DECRYPT: rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; } if (rsa_outlen <= 0) { BIO_printf(bio_err, "RSA operation error\n"); ERR_print_errors(bio_err); goto end; } ret = 0; if (asn1parse) { if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { ERR_print_errors(bio_err); } } else if (hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); else BIO_write(out, rsa_out, rsa_outlen); end: RSA_free(rsa); BIO_free(in); BIO_free_all(out); OPENSSL_free(rsa_in); OPENSSL_free(rsa_out); OPENSSL_free(passin); return ret; }
int pkeyutl_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; ENGINE *e = NULL; EVP_PKEY_CTX *ctx = NULL; char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL; char hexdump = 0, asn1parse = 0, rev = 0, *prog; unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; OPTION_CHOICE o; int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform = FORMAT_PEM; int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; int ret = 1, rv = -1; size_t buf_outlen; prog = opt_init(argc, argv, pkeyutl_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(pkeyutl_options); ret = 0; goto end; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_SIGFILE: sigfile = opt_arg(); break; case OPT_INKEY: ctx = init_ctx(&keysize, opt_arg(), keyform, key_type, passinarg, pkey_op, e); if (ctx == NULL) { BIO_puts(bio_err, "%s: Error initializing context\n"); ERR_print_errors(bio_err); goto opthelp; } break; case OPT_PEERKEY: if (!setup_peer(ctx, peerform, opt_arg())) goto opthelp; break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_PEERFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &peerform)) goto opthelp; break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyform)) goto opthelp; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_PUBIN: key_type = KEY_PUBKEY; break; case OPT_CERTIN: key_type = KEY_CERT; break; case OPT_ASN1PARSE: asn1parse = 1; break; case OPT_HEXDUMP: hexdump = 1; break; case OPT_SIGN: pkey_op = EVP_PKEY_OP_SIGN; break; case OPT_VERIFY: pkey_op = EVP_PKEY_OP_VERIFY; break; case OPT_VERIFYRECOVER: pkey_op = EVP_PKEY_OP_VERIFYRECOVER; break; case OPT_REV: rev = 1; case OPT_ENCRYPT: pkey_op = EVP_PKEY_OP_ENCRYPT; break; case OPT_DECRYPT: pkey_op = EVP_PKEY_OP_DECRYPT; break; case OPT_DERIVE: pkey_op = EVP_PKEY_OP_DERIVE; break; case OPT_PKEYOPT: if (ctx == NULL) { BIO_printf(bio_err, "%s: Must have -inkey before -pkeyopt\n", prog); goto opthelp; } if (pkey_ctrl_string(ctx, opt_arg()) <= 0) { BIO_printf(bio_err, "%s: Can't set parameter:\n", prog); ERR_print_errors(bio_err); goto end; } break; } } argc = opt_num_rest(); argv = opt_rest(); if (ctx == NULL) goto opthelp; if (!app_load_modules(NULL)) goto end; if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { BIO_printf(bio_err, "%s: Signature file specified for non verify\n", prog); goto end; } if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { BIO_printf(bio_err, "%s: No signature file specified for verify\n", prog); goto end; } /* FIXME: seed PRNG only if needed */ app_RAND_load_file(NULL, 0); if (pkey_op != EVP_PKEY_OP_DERIVE) { in = bio_open_default(infile, "rb"); if (in == NULL) goto end; } out = bio_open_default(outfile, "wb"); if (out == NULL) goto end; if (sigfile) { BIO *sigbio = BIO_new_file(sigfile, "rb"); if (!sigbio) { BIO_printf(bio_err, "Can't open signature file %s\n", sigfile); goto end; } siglen = bio_to_mem(&sig, keysize * 10, sigbio); BIO_free(sigbio); if (siglen <= 0) { BIO_printf(bio_err, "Error reading signature data\n"); goto end; } } if (in) { /* Read the input data */ buf_inlen = bio_to_mem(&buf_in, keysize * 10, in); if (buf_inlen <= 0) { BIO_printf(bio_err, "Error reading input Data\n"); exit(1); } if (rev) { size_t i; unsigned char ctmp; size_t l = (size_t)buf_inlen; for (i = 0; i < l / 2; i++) { ctmp = buf_in[i]; buf_in[i] = buf_in[l - 1 - i]; buf_in[l - 1 - i] = ctmp; } } } if (pkey_op == EVP_PKEY_OP_VERIFY) { rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen, buf_in, (size_t)buf_inlen); if (rv == 1) { BIO_puts(out, "Signature Verified Successfully\n"); ret = 0; } else BIO_puts(out, "Signature Verification Failure\n"); goto end; } rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, buf_in, (size_t)buf_inlen); if (rv > 0) { buf_out = app_malloc(buf_outlen, "buffer output"); rv = do_keyop(ctx, pkey_op, buf_out, (size_t *)&buf_outlen, buf_in, (size_t)buf_inlen); } if (rv <= 0) { ERR_print_errors(bio_err); goto end; } ret = 0; if (asn1parse) { if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) ERR_print_errors(bio_err); } else if (hexdump) BIO_dump(out, (char *)buf_out, buf_outlen); else BIO_write(out, buf_out, buf_outlen); end: EVP_PKEY_CTX_free(ctx); BIO_free(in); BIO_free_all(out); OPENSSL_free(buf_in); OPENSSL_free(buf_out); OPENSSL_free(sig); return ret; }
int pkeyparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; EVP_PKEY *pkey = NULL; int text = 0, noout = 0, ret = 1; OPTION_CHOICE o; char *infile = NULL, *outfile = NULL, *prog; prog = opt_init(argc, argv, pkeyparam_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(pkeyparam_options); ret = 0; goto end; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENGINE: (void)setup_engine(opt_arg(), 0); break; case OPT_TEXT: text = 1; break; case OPT_NOOUT: noout = 1; break; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_load_modules(NULL)) goto end; in = bio_open_default(infile, 'r', FORMAT_PEM); if (in == NULL) goto end; out = bio_open_default(outfile, 'w', FORMAT_PEM); if (out == NULL) goto end; pkey = PEM_read_bio_Parameters(in, NULL); if (!pkey) { BIO_printf(bio_err, "Error reading parameters\n"); ERR_print_errors(bio_err); goto end; } if (!noout) PEM_write_bio_Parameters(out, pkey); if (text) EVP_PKEY_print_params(out, pkey, 0, NULL); ret = 0; end: EVP_PKEY_free(pkey); BIO_free_all(out); BIO_free(in); return ret; }
int srp_main(int argc, char **argv) { CA_DB *db = NULL; CONF *conf = NULL; int gNindex = -1, maxgN = -1, ret = 1, errors = 0, verbose = 0, i; int doupdatedb = 0, mode = OPT_ERR; char *user = NULL, *passinarg = NULL, *passoutarg = NULL; char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL; char *randfile = NULL, *section = NULL; char **gNrow = NULL, *configfile = NULL; char *srpvfile = NULL, **pp, *prog; OPTION_CHOICE o; prog = opt_init(argc, argv, srp_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(srp_options); ret = 0; goto end; case OPT_VERBOSE: verbose++; break; case OPT_CONFIG: configfile = opt_arg(); break; case OPT_NAME: section = opt_arg(); break; case OPT_SRPVFILE: srpvfile = opt_arg(); break; case OPT_ADD: case OPT_DELETE: case OPT_MODIFY: case OPT_LIST: if (mode != OPT_ERR) { BIO_printf(bio_err, "%s: Only one of -add/delete-modify/-list\n", prog); goto opthelp; } mode = o; break; case OPT_GN: gN = opt_arg(); break; case OPT_USERINFO: userinfo = opt_arg(); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_PASSOUT: passoutarg = opt_arg(); break; case OPT_ENGINE: (void)setup_engine(opt_arg(), 0); break; } } argc = opt_num_rest(); argv = opt_rest(); if (srpvfile && configfile) { BIO_printf(bio_err, "-srpvfile and -configfile cannot be specified together.\n"); goto end; } if (mode == OPT_ERR) { BIO_printf(bio_err, "Exactly one of the options -add, -delete, -modify -list must be specified.\n"); goto opthelp; } if ((mode == OPT_DELETE || mode == OPT_MODIFY || mode == OPT_ADD) && argc < 1) { BIO_printf(bio_err, "Need at least one user for options -add, -delete, -modify. \n"); goto opthelp; } if ((passin || passout) && argc != 1) { BIO_printf(bio_err, "-passin, -passout arguments only valid with one user.\n"); goto opthelp; } if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if (!srpvfile) { if (!configfile) configfile = default_config_file; if (verbose) BIO_printf(bio_err, "Using configuration from %s\n", configfile); conf = app_load_config(configfile); if (conf == NULL) goto end; if (configfile != default_config_file && !app_load_modules(conf)) goto end; /* Lets get the config section we are using */ if (section == NULL) { if (verbose) BIO_printf(bio_err, "trying to read " ENV_DEFAULT_SRP " in " BASE_SECTION "\n"); section = lookup_conf(conf, BASE_SECTION, ENV_DEFAULT_SRP); if (section == NULL) goto end; } if (randfile == NULL) randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE"); if (verbose) BIO_printf(bio_err, "trying to read " ENV_DATABASE " in section \"%s\"\n", section); srpvfile = lookup_conf(conf, section, ENV_DATABASE); if (srpvfile == NULL) goto end; } if (randfile == NULL) ERR_clear_error(); else app_RAND_load_file(randfile, 0); if (verbose) BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n", srpvfile); db = load_index(srpvfile, NULL); if (db == NULL) goto end; /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_srptype][0] == DB_SRP_INDEX) { maxgN = i; if ((gNindex < 0) && (gN != NULL) && strcmp(gN, pp[DB_srpid]) == 0) gNindex = i; print_index(db, i, verbose > 1); } } if (verbose) BIO_printf(bio_err, "Database initialised\n"); if (gNindex >= 0) { gNrow = sk_OPENSSL_PSTRING_value(db->db->data, gNindex); print_entry(db, gNindex, verbose > 1, "Default g and N"); } else if (maxgN > 0 && !SRP_get_default_gN(gN)) { BIO_printf(bio_err, "No g and N value for index \"%s\"\n", gN); goto end; } else { if (verbose) BIO_printf(bio_err, "Database has no g N information.\n"); gNrow = NULL; } if (verbose > 1) BIO_printf(bio_err, "Starting user processing\n"); if (argc > 0) user = *(argv++); while (mode == OPT_LIST || user) { int userindex = -1; if (user != NULL && verbose > 1) BIO_printf(bio_err, "Processing user \"%s\"\n", user); if ((userindex = get_index(db, user, 'U')) >= 0) { print_user(db, userindex, (verbose > 0) || mode == OPT_LIST); } if (mode == OPT_LIST) { if (user == NULL) { BIO_printf(bio_err, "List all users\n"); for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { print_user(db, i, 1); } } else if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, ignored. t\n", user); errors++; } } else if (mode == OPT_ADD) { if (userindex >= 0) { /* reactivation of a new user */ char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex); BIO_printf(bio_err, "user \"%s\" reactivated.\n", user); row[DB_srptype][0] = 'V'; doupdatedb = 1; } else { char *row[DB_NUMBER]; char *gNid; row[DB_srpverifier] = NULL; row[DB_srpsalt] = NULL; row[DB_srpinfo] = NULL; if (! (gNid = srp_create_user(user, &(row[DB_srpverifier]), &(row[DB_srpsalt]), gNrow ? gNrow[DB_srpsalt] : gN, gNrow ? gNrow[DB_srpverifier] : NULL, passout, verbose))) { BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned .\n", user); errors++; goto end; } row[DB_srpid] = OPENSSL_strdup(user); row[DB_srptype] = OPENSSL_strdup("v"); row[DB_srpgN] = OPENSSL_strdup(gNid); if ((row[DB_srpid] == NULL) || (row[DB_srpgN] == NULL) || (row[DB_srptype] == NULL) || (row[DB_srpverifier] == NULL) || (row[DB_srpsalt] == NULL) || (userinfo && ((row[DB_srpinfo] = OPENSSL_strdup(userinfo)) == NULL)) || !update_index(db, row)) { OPENSSL_free(row[DB_srpid]); OPENSSL_free(row[DB_srpgN]); OPENSSL_free(row[DB_srpinfo]); OPENSSL_free(row[DB_srptype]); OPENSSL_free(row[DB_srpverifier]); OPENSSL_free(row[DB_srpsalt]); goto end; } doupdatedb = 1; } } else if (mode == OPT_MODIFY) { if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored.\n", user); errors++; } else { char **row = sk_OPENSSL_PSTRING_value(db->db->data, userindex); char type = row[DB_srptype][0]; if (type == 'v') { BIO_printf(bio_err, "user \"%s\" already updated, operation ignored.\n", user); errors++; } else { char *gNid; if (row[DB_srptype][0] == 'V') { int user_gN; char **irow = NULL; if (verbose) BIO_printf(bio_err, "Verifying password for user \"%s\"\n", user); if ((user_gN = get_index(db, row[DB_srpgN], DB_SRP_INDEX)) >= 0) irow = sk_OPENSSL_PSTRING_value(db->db->data, userindex); if (!srp_verify_user (user, row[DB_srpverifier], row[DB_srpsalt], irow ? irow[DB_srpsalt] : row[DB_srpgN], irow ? irow[DB_srpverifier] : NULL, passin, verbose)) { BIO_printf(bio_err, "Invalid password for user \"%s\", operation abandoned.\n", user); errors++; goto end; } } if (verbose) BIO_printf(bio_err, "Password for user \"%s\" ok.\n", user); if (! (gNid = srp_create_user(user, &(row[DB_srpverifier]), &(row[DB_srpsalt]), gNrow ? gNrow[DB_srpsalt] : NULL, gNrow ? gNrow[DB_srpverifier] : NULL, passout, verbose))) { BIO_printf(bio_err, "Cannot create srp verifier for user \"%s\", operation abandoned.\n", user); errors++; goto end; } row[DB_srptype][0] = 'v'; row[DB_srpgN] = OPENSSL_strdup(gNid); if (row[DB_srpid] == NULL || row[DB_srpgN] == NULL || row[DB_srptype] == NULL || row[DB_srpverifier] == NULL || row[DB_srpsalt] == NULL || (userinfo && ((row[DB_srpinfo] = OPENSSL_strdup(userinfo)) == NULL))) goto end; doupdatedb = 1; } } } else if (mode == OPT_DELETE) { if (userindex < 0) { BIO_printf(bio_err, "user \"%s\" does not exist, operation ignored. t\n", user); errors++; } else { char **xpp = sk_OPENSSL_PSTRING_value(db->db->data, userindex); BIO_printf(bio_err, "user \"%s\" revoked. t\n", user); xpp[DB_srptype][0] = 'R'; doupdatedb = 1; } } if (--argc > 0) user = *(argv++); else { user = NULL; } } if (verbose) BIO_printf(bio_err, "User procession done.\n"); if (doupdatedb) { /* Lets check some fields */ for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { pp = sk_OPENSSL_PSTRING_value(db->db->data, i); if (pp[DB_srptype][0] == 'v') { pp[DB_srptype][0] = 'V'; print_user(db, i, verbose); } } if (verbose) BIO_printf(bio_err, "Trying to update srpvfile.\n"); if (!save_index(srpvfile, "new", db)) goto end; if (verbose) BIO_printf(bio_err, "Temporary srpvfile created.\n"); if (!rotate_index(srpvfile, "new", "old")) goto end; if (verbose) BIO_printf(bio_err, "srpvfile updated.\n"); } ret = (errors != 0); end: if (errors != 0) if (verbose) BIO_printf(bio_err, "User errors %d.\n", errors); if (verbose) BIO_printf(bio_err, "SRP terminating with code %d.\n", ret); OPENSSL_free(passin); OPENSSL_free(passout); if (ret) ERR_print_errors(bio_err); if (randfile) app_RAND_write_file(randfile); NCONF_free(conf); free_index(db); return (ret); }
int crl_main(int argc, char **argv) { X509_CRL *x = NULL; BIO *out = NULL; X509_STORE *store = NULL; X509_STORE_CTX ctx; X509_LOOKUP *lookup = NULL; X509_OBJECT xobj; EVP_PKEY *pkey; const EVP_MD *digest = EVP_sha1(); unsigned long nmflag = 0; char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL; char *CAfile = NULL, *CApath = NULL, *prog; OPTION_CHOICE o; int hash = 0, issuer = 0, lastupdate = 0, nextupdate = 0, noout = 0, text = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM; int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0, i, do_ver = 0; #ifndef OPENSSL_NO_MD5 int hash_old = 0; #endif prog = opt_init(argc, argv, crl_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(crl_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat)) goto opthelp; break; case OPT_KEY: keyfile = opt_arg(); break; case OPT_GENDELTA: crldiff = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); do_ver = 1; break; case OPT_CAFILE: CAfile = opt_arg(); do_ver = 1; break; #ifndef OPENSSL_NO_MD5 case OPT_HASH_OLD: hash_old = ++num; break; #endif case OPT_VERIFY: do_ver = 1; break; case OPT_TEXT: text = 1; break; case OPT_HASH: hash = ++num; break; case OPT_ISSUER: issuer = ++num; break; case OPT_LASTUPDATE: lastupdate = ++num; break; case OPT_NEXTUPDATE: nextupdate = ++num; break; case OPT_NOOUT: noout = ++num; break; case OPT_FINGERPRINT: fingerprint = ++num; break; case OPT_CRLNUMBER: crlnumber = ++num; break; case OPT_BADSIG: badsig = 1; break; case OPT_NAMEOPT: if (!set_name_ex(&nmflag, opt_arg())) goto opthelp; break; case OPT_MD: if (!opt_md(opt_unknown(), &digest)) goto opthelp; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_load_modules(NULL)) goto end; x = load_crl(infile, informat); if (x == NULL) goto end; if (do_ver) { if ((store = setup_verify(CAfile, CApath)) == NULL) goto end; lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; if (!X509_STORE_CTX_init(&ctx, store, NULL, NULL)) { BIO_printf(bio_err, "Error initialising X509 store\n"); goto end; } i = X509_STORE_get_by_subject(&ctx, X509_LU_X509, X509_CRL_get_issuer(x), &xobj); if (i <= 0) { BIO_printf(bio_err, "Error getting CRL issuer certificate\n"); goto end; } pkey = X509_get_pubkey(xobj.data.x509); X509_OBJECT_free_contents(&xobj); if (!pkey) { BIO_printf(bio_err, "Error getting CRL issuer public key\n"); goto end; } i = X509_CRL_verify(x, pkey); EVP_PKEY_free(pkey); if (i < 0) goto end; if (i == 0) BIO_printf(bio_err, "verify failure\n"); else BIO_printf(bio_err, "verify OK\n"); } if (crldiff) { X509_CRL *newcrl, *delta; if (!keyfile) { BIO_puts(bio_err, "Missing CRL signing key\n"); goto end; } newcrl = load_crl(crldiff, informat); if (!newcrl) goto end; pkey = load_key(keyfile, keyformat, 0, NULL, NULL, "CRL signing key"); if (!pkey) { X509_CRL_free(newcrl); goto end; } delta = X509_CRL_diff(x, newcrl, pkey, digest, 0); X509_CRL_free(newcrl); EVP_PKEY_free(pkey); if (delta) { X509_CRL_free(x); x = delta; } else { BIO_puts(bio_err, "Error creating delta CRL\n"); goto end; } } if (num) { for (i = 1; i <= num; i++) { if (issuer == i) { print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag); } if (crlnumber == i) { ASN1_INTEGER *crlnum; crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number, NULL, NULL); BIO_printf(bio_out, "crlNumber="); if (crlnum) { i2a_ASN1_INTEGER(bio_out, crlnum); ASN1_INTEGER_free(crlnum); } else BIO_puts(bio_out, "<NONE>"); BIO_printf(bio_out, "\n"); } if (hash == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash(X509_CRL_get_issuer(x))); } #ifndef OPENSSL_NO_MD5 if (hash_old == i) { BIO_printf(bio_out, "%08lx\n", X509_NAME_hash_old(X509_CRL_get_issuer(x))); } #endif if (lastupdate == i) { BIO_printf(bio_out, "lastUpdate="); ASN1_TIME_print(bio_out, X509_CRL_get_lastUpdate(x)); BIO_printf(bio_out, "\n"); } if (nextupdate == i) { BIO_printf(bio_out, "nextUpdate="); if (X509_CRL_get_nextUpdate(x)) ASN1_TIME_print(bio_out, X509_CRL_get_nextUpdate(x)); else BIO_printf(bio_out, "NONE"); BIO_printf(bio_out, "\n"); } if (fingerprint == i) { int j; unsigned int n; unsigned char md[EVP_MAX_MD_SIZE]; if (!X509_CRL_digest(x, digest, md, &n)) { BIO_printf(bio_err, "out of memory\n"); goto end; } BIO_printf(bio_out, "%s Fingerprint=", OBJ_nid2sn(EVP_MD_type(digest))); for (j = 0; j < (int)n; j++) { BIO_printf(bio_out, "%02X%c", md[j], (j + 1 == (int)n) ? '\n' : ':'); } } } } out = bio_open_default(outfile, "w"); if (out == NULL) goto end; if (text) X509_CRL_print(out, x); if (noout) { ret = 0; goto end; } if (badsig) x->signature->data[x->signature->length - 1] ^= 0x1; if (outformat == FORMAT_ASN1) i = (int)i2d_X509_CRL_bio(out, x); else i = PEM_write_bio_X509_CRL(out, x); if (!i) { BIO_printf(bio_err, "unable to write CRL\n"); goto end; } ret = 0; end: if (ret != 0) ERR_print_errors(bio_err); BIO_free_all(out); X509_CRL_free(x); if (store) { X509_STORE_CTX_cleanup(&ctx); X509_STORE_free(store); } return (ret); }
int verify_main(int argc, char **argv) { ENGINE *e = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL; STACK_OF(X509_CRL) *crls = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *prog, *CApath = NULL, *CAfile = NULL; char *untfile = NULL, *trustfile = NULL, *crlfile = NULL; int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1; OPTION_CHOICE o; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) goto end; prog = opt_init(argc, argv, verify_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(verify_options); BIO_printf(bio_err, "Recognized usages:\n"); for (i = 0; i < X509_PURPOSE_get_count(); i++) { X509_PURPOSE *ptmp; ptmp = X509_PURPOSE_get0(i); BIO_printf(bio_err, "\t%-10s\t%s\n", X509_PURPOSE_get0_sname(ptmp), X509_PURPOSE_get0_name(ptmp)); } BIO_printf(bio_err, "Recognized verify names:\n"); for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) { const X509_VERIFY_PARAM *vptmp; vptmp = X509_VERIFY_PARAM_get0(i); BIO_printf(bio_err, "\t%-10s\n", X509_VERIFY_PARAM_get0_name(vptmp)); } ret = 0; goto end; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; vpmtouched++; break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_UNTRUSTED: untfile = opt_arg(); break; case OPT_TRUSTED: trustfile = opt_arg(); break; case OPT_CRLFILE: crlfile = opt_arg(); break; case OPT_CRL_DOWNLOAD: crl_download = 1; break; case OPT_SHOW_CHAIN: show_chain = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_VERBOSE: v_verbose = 1; break; } } argc = opt_num_rest(); argv = opt_rest(); if (trustfile && (CAfile || CApath)) { BIO_printf(bio_err, "%s: Cannot use -trusted with -CAfile or -CApath\n", prog); goto end; } if (!app_load_modules(NULL)) goto end; if ((store = setup_verify(CAfile, CApath)) == NULL) goto end; X509_STORE_set_verify_cb(store, cb); if (vpmtouched) X509_STORE_set1_param(store, vpm); ERR_clear_error(); if (untfile) { untrusted = load_certs(untfile, FORMAT_PEM, NULL, e, "untrusted certificates"); if (!untrusted) goto end; } if (trustfile) { trusted = load_certs(trustfile, FORMAT_PEM, NULL, e, "trusted certificates"); if (!trusted) goto end; } if (crlfile) { crls = load_crls(crlfile, FORMAT_PEM, NULL, e, "other CRLs"); if (!crls) goto end; } if (crl_download) store_setup_crl_download(store); ret = 0; if (argc < 1) { if (check(store, NULL, untrusted, trusted, crls, e, show_chain) != 1) ret = -1; } else { for (i = 0; i < argc; i++) if (check(store, argv[i], untrusted, trusted, crls, e, show_chain) != 1) ret = -1; } end: X509_VERIFY_PARAM_free(vpm); X509_STORE_free(store); sk_X509_pop_free(untrusted, X509_free); sk_X509_pop_free(trusted, X509_free); sk_X509_CRL_pop_free(crls, X509_CRL_free); return (ret < 0 ? 2 : ret); }
int ocsp_main(int argc, char **argv) { BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL; const EVP_MD *cert_id_md = NULL, *rsign_md = NULL; CA_DB *rdb = NULL; EVP_PKEY *key = NULL, *rkey = NULL; OCSP_BASICRESP *bs = NULL; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; STACK_OF(CONF_VALUE) *headers = NULL; STACK_OF(OCSP_CERTID) *ids = NULL; STACK_OF(OPENSSL_STRING) *reqnames = NULL; STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL; STACK_OF(X509) *issuers = NULL; X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL; X509 *signer = NULL, *rsigner = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; char *CAfile = NULL, *CApath = NULL, *header, *value; char *host = NULL, *port = NULL, *path = "/", *outfile = NULL; char *rca_filename = NULL, *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL, *ridx_filename = NULL; char *rsignfile = NULL, *rkeyfile = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; char *signfile = NULL, *keyfile = NULL; char *thost = NULL, *tport = NULL, *tpath = NULL; int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; int req_text = 0, resp_text = 0, req_timeout = -1, ret = 1; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; OPTION_CHOICE o; char *prog; reqnames = sk_OPENSSL_STRING_new_null(); if (!reqnames) goto end; ids = sk_OCSP_CERTID_new_null(); if (!ids) goto end; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; prog = opt_init(argc, argv, ocsp_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: ret = 0; opt_help(ocsp_options); goto end; case OPT_OUTFILE: outfile = opt_arg(); break; case OPT_TIMEOUT: req_timeout = atoi(opt_arg()); break; case OPT_URL: OPENSSL_free(thost); OPENSSL_free(tport); OPENSSL_free(tpath); if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) { BIO_printf(bio_err, "%s Error parsing URL\n", prog); goto end; } thost = host; tport = port; tpath = path; break; case OPT_HOST: host = opt_arg(); break; case OPT_PORT: port = opt_arg(); break; case OPT_IGNORE_ERR: ignore_err = 1; break; case OPT_NOVERIFY: noverify = 1; break; case OPT_NONCE: add_nonce = 2; break; case OPT_NO_NONCE: add_nonce = 0; break; case OPT_RESP_NO_CERTS: rflags |= OCSP_NOCERTS; break; case OPT_RESP_KEY_ID: rflags |= OCSP_RESPID_KEY; break; case OPT_NO_CERTS: sign_flags |= OCSP_NOCERTS; break; case OPT_NO_SIGNATURE_VERIFY: verify_flags |= OCSP_NOSIGS; break; case OPT_NO_CERT_VERIFY: verify_flags |= OCSP_NOVERIFY; break; case OPT_NO_CHAIN: verify_flags |= OCSP_NOCHAIN; break; case OPT_NO_CERT_CHECKS: verify_flags |= OCSP_NOCHECKS; break; case OPT_NO_EXPLICIT: verify_flags |= OCSP_NOEXPLICIT; break; case OPT_TRUST_OTHER: verify_flags |= OCSP_TRUSTOTHER; break; case OPT_NO_INTERN: verify_flags |= OCSP_NOINTERN; break; case OPT_BADSIG: badsig = 1; break; case OPT_TEXT: req_text = resp_text = 1; break; case OPT_REQ_TEXT: req_text = 1; break; case OPT_RESP_TEXT: resp_text = 1; break; case OPT_REQIN: reqin = opt_arg(); break; case OPT_RESPIN: respin = opt_arg(); break; case OPT_SIGNER: signfile = opt_arg(); break; case OPT_VAFILE: verify_certfile = opt_arg(); verify_flags |= OCSP_TRUSTOTHER; break; case OPT_SIGN_OTHER: sign_certfile = opt_arg(); break; case OPT_VERIFY_OTHER: verify_certfile = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto end; vpmtouched++; break; case OPT_VALIDITY_PERIOD: opt_long(opt_arg(), &nsec); break; case OPT_STATUS_AGE: opt_long(opt_arg(), &maxage); break; case OPT_SIGNKEY: keyfile = opt_arg(); break; case OPT_REQOUT: reqout = opt_arg(); break; case OPT_RESPOUT: respout = opt_arg(); break; case OPT_PATH: path = opt_arg(); break; case OPT_ISSUER: X509_free(issuer); issuer = load_cert(opt_arg(), FORMAT_PEM, NULL, NULL, "issuer certificate"); if (issuer == NULL) goto end; if ((issuers = sk_X509_new_null()) == NULL) goto end; sk_X509_push(issuers, issuer); break; case OPT_CERT: X509_free(cert); cert = load_cert(opt_arg(), FORMAT_PEM, NULL, NULL, "certificate"); if (cert == NULL) goto end; if (cert_id_md == NULL) cert_id_md = EVP_sha1(); if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) goto end; if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) goto end; break; case OPT_SERIAL: if (cert_id_md == NULL) cert_id_md = EVP_sha1(); if (!add_ocsp_serial(&req, opt_arg(), cert_id_md, issuer, ids)) goto end; if (!sk_OPENSSL_STRING_push(reqnames, opt_arg())) goto end; break; case OPT_INDEX: ridx_filename = opt_arg(); break; case OPT_CA: rca_filename = opt_arg(); break; case OPT_NMIN: opt_int(opt_arg(), &nmin); if (ndays == -1) ndays = 0; break; case OPT_REQUEST: opt_int(opt_arg(), &accept_count); break; case OPT_NDAYS: ndays = atoi(opt_arg()); break; case OPT_RSIGNER: rsignfile = opt_arg(); break; case OPT_RKEY: rkeyfile = opt_arg(); break; case OPT_ROTHER: rcertfile = opt_arg(); break; case OPT_RMD: if (!opt_md(opt_arg(), &rsign_md)) goto end; break; case OPT_HEADER: header = opt_arg(); value = strchr(header, '='); if (value == NULL) { BIO_printf(bio_err, "Missing = in header key=value\n"); goto opthelp; } *value++ = '\0'; if (!X509V3_add_value(header, value, &headers)) goto end; break; case OPT_MD: if (cert_id_md != NULL) { BIO_printf(bio_err, "%s: Digest must be before -cert or -serial\n", prog); goto opthelp; } if (!opt_md(opt_unknown(), &cert_id_md)) goto opthelp; break; } } argc = opt_num_rest(); argv = opt_rest(); /* Have we anything to do? */ if (!req && !reqin && !respin && !(port && ridx_filename)) goto opthelp; if (!app_load_modules(NULL)) goto end; out = bio_open_default(outfile, "w"); if (out == NULL) goto end; if (!req && (add_nonce != 2)) add_nonce = 0; if (!req && reqin) { derbio = bio_open_default(reqin, "rb"); if (derbio == NULL) goto end; req = d2i_OCSP_REQUEST_bio(derbio, NULL); BIO_free(derbio); if (!req) { BIO_printf(bio_err, "Error reading OCSP request\n"); goto end; } } if (!req && port) { acbio = init_responder(port); if (!acbio) goto end; } if (rsignfile && !rdb) { if (!rkeyfile) rkeyfile = rsignfile; rsigner = load_cert(rsignfile, FORMAT_PEM, NULL, NULL, "responder certificate"); if (!rsigner) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } rca_cert = load_cert(rca_filename, FORMAT_PEM, NULL, NULL, "CA certificate"); if (rcertfile) { rother = load_certs(rcertfile, FORMAT_PEM, NULL, NULL, "responder other certificates"); if (!rother) goto end; } rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL, "responder private key"); if (!rkey) goto end; } if (acbio) BIO_printf(bio_err, "Waiting for OCSP client connections...\n"); redo_accept: if (acbio) { if (!do_responder(&req, &cbio, acbio, port)) goto end; if (!req) { resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, NULL); send_ocsp_response(cbio, resp); goto done_resp; } } if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) { BIO_printf(bio_err, "Need an OCSP request for this operation!\n"); goto end; } if (req && add_nonce) OCSP_request_add1_nonce(req, NULL, -1); if (signfile) { if (!keyfile) keyfile = signfile; signer = load_cert(signfile, FORMAT_PEM, NULL, NULL, "signer certificate"); if (!signer) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile) { sign_other = load_certs(sign_certfile, FORMAT_PEM, NULL, NULL, "signer certificates"); if (!sign_other) goto end; } key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL, "signer private key"); if (!key) goto end; if (!OCSP_request_sign (req, signer, key, NULL, sign_other, sign_flags)) { BIO_printf(bio_err, "Error signing OCSP request\n"); goto end; } } if (req_text && req) OCSP_REQUEST_print(out, req, 0); if (reqout) { derbio = bio_open_default(reqout, "wb"); if (derbio == NULL) goto end; i2d_OCSP_REQUEST_bio(derbio, req); BIO_free(derbio); } if (ridx_filename && (!rkey || !rsigner || !rca_cert)) { BIO_printf(bio_err, "Need a responder certificate, key and CA for this operation!\n"); goto end; } if (ridx_filename && !rdb) { rdb = load_index(ridx_filename, NULL); if (!rdb) goto end; if (!index_index(rdb)) goto end; } if (rdb) { make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rsign_md, rother, rflags, nmin, ndays, badsig); if (cbio) send_ocsp_response(cbio, resp); } else if (host) { # ifndef OPENSSL_NO_SOCK resp = process_responder(req, host, path, port, use_ssl, headers, req_timeout); if (!resp) goto end; # else BIO_printf(bio_err, "Error creating connect BIO - sockets not supported.\n"); goto end; # endif } else if (respin) { derbio = bio_open_default(respin, "rb"); if (derbio == NULL) goto end; resp = d2i_OCSP_RESPONSE_bio(derbio, NULL); BIO_free(derbio); if (!resp) { BIO_printf(bio_err, "Error reading OCSP response\n"); goto end; } } else { ret = 0; goto end; } done_resp: if (respout) { derbio = bio_open_default(respout, "wb"); if (derbio == NULL) goto end; i2d_OCSP_RESPONSE_bio(derbio, resp); BIO_free(derbio); } i = OCSP_response_status(resp); if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) { BIO_printf(out, "Responder Error: %s (%d)\n", OCSP_response_status_str(i), i); if (ignore_err) goto redo_accept; ret = 0; goto end; } if (resp_text) OCSP_RESPONSE_print(out, resp, 0); /* If running as responder don't verify our own response */ if (cbio) { if (--accept_count <= 0) { ret = 0; goto end; } BIO_free_all(cbio); cbio = NULL; OCSP_REQUEST_free(req); req = NULL; OCSP_RESPONSE_free(resp); resp = NULL; goto redo_accept; } if (ridx_filename) { ret = 0; goto end; } if (!store) { store = setup_verify(CAfile, CApath); if (!store) goto end; } if (vpmtouched) X509_STORE_set1_param(store, vpm); if (verify_certfile) { verify_other = load_certs(verify_certfile, FORMAT_PEM, NULL, NULL, "validator certificate"); if (!verify_other) goto end; } bs = OCSP_response_get1_basic(resp); if (!bs) { BIO_printf(bio_err, "Error parsing response\n"); goto end; } ret = 0; if (!noverify) { if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) { if (i == -1) BIO_printf(bio_err, "WARNING: no nonce in response\n"); else { BIO_printf(bio_err, "Nonce Verify error\n"); ret = 1; goto end; } } i = OCSP_basic_verify(bs, verify_other, store, verify_flags); if (i <= 0 && issuers) { i = OCSP_basic_verify(bs, issuers, store, OCSP_TRUSTOTHER); if (i > 0) ERR_clear_error(); } if (i <= 0) { BIO_printf(bio_err, "Response Verify Failure\n"); ERR_print_errors(bio_err); ret = 1; } else BIO_printf(bio_err, "Response verify OK\n"); } print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage); end: ERR_print_errors(bio_err); X509_free(signer); X509_STORE_free(store); X509_VERIFY_PARAM_free(vpm); EVP_PKEY_free(key); EVP_PKEY_free(rkey); X509_free(cert); X509_free(rsigner); X509_free(rca_cert); free_index(rdb); BIO_free_all(cbio); BIO_free_all(acbio); BIO_free(out); OCSP_REQUEST_free(req); OCSP_RESPONSE_free(resp); OCSP_BASICRESP_free(bs); sk_OPENSSL_STRING_free(reqnames); sk_OCSP_CERTID_free(ids); sk_X509_pop_free(sign_other, X509_free); sk_X509_pop_free(verify_other, X509_free); sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); OPENSSL_free(thost); OPENSSL_free(tport); OPENSSL_free(tpath); return (ret); }
int smime_main(int argc, char **argv) { BIO *in = NULL, *out = NULL, *indata = NULL; EVP_PKEY *key = NULL; PKCS7 *p7 = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; const EVP_CIPHER *cipher = NULL; const EVP_MD *sign_md = NULL; char *CAfile = NULL, *CApath = NULL, *inrand = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *prog; char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL; char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL; OPTION_CHOICE o; int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform = FORMAT_PEM; int vpmtouched = 0, rv = 0; ENGINE *e = NULL; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; prog = opt_init(argc, argv, smime_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(smime_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENCRYPT: operation = SMIME_ENCRYPT; break; case OPT_DECRYPT: operation = SMIME_DECRYPT; break; case OPT_SIGN: operation = SMIME_SIGN; break; case OPT_RESIGN: operation = SMIME_RESIGN; break; case OPT_VERIFY: operation = SMIME_VERIFY; break; case OPT_PK7OUT: operation = SMIME_PK7OUT; break; case OPT_TEXT: flags |= PKCS7_TEXT; break; case OPT_NOINTERN: flags |= PKCS7_NOINTERN; break; case OPT_NOVERIFY: flags |= PKCS7_NOVERIFY; break; case OPT_NOCHAIN: flags |= PKCS7_NOCHAIN; break; case OPT_NOCERTS: flags |= PKCS7_NOCERTS; break; case OPT_NOATTR: flags |= PKCS7_NOATTR; break; case OPT_NODETACH: flags &= ~PKCS7_DETACHED; break; case OPT_NOSMIMECAP: flags |= PKCS7_NOSMIMECAP; break; case OPT_BINARY: flags |= PKCS7_BINARY; break; case OPT_NOSIGS: flags |= PKCS7_NOSIGS; break; case OPT_STREAM: case OPT_INDEF: indef = 1; break; case OPT_NOINDEF: indef = 0; break; case OPT_NOOLDMIME: flags |= PKCS7_NOOLDMIMETYPE; break; case OPT_CRLFEOL: flags |= PKCS7_CRLFEOL; break; case OPT_RAND: inrand = opt_arg(); need_rand = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_TO: to = opt_arg(); break; case OPT_FROM: from = opt_arg(); break; case OPT_SUBJECT: subject = opt_arg(); break; case OPT_SIGNER: /* If previous -signer argument add signer to list */ if (signerfile) { if (sksigners == NULL && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); if (keyfile == NULL) keyfile = signerfile; if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = opt_arg(); break; case OPT_RECIP: recipfile = opt_arg(); break; case OPT_MD: if (!opt_md(opt_arg(), &sign_md)) goto opthelp; break; case OPT_CIPHER: if (!opt_cipher(opt_unknown(), &cipher)) goto opthelp; break; case OPT_INKEY: /* If previous -inkey arument add signer to list */ if (keyfile) { if (signerfile == NULL) { BIO_printf(bio_err, "%s: Must have -signer before -inkey\n", prog); goto opthelp; } if (sksigners == NULL && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_CERTFILE: certfile = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_CONTENT: contfile = opt_arg(); break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto opthelp; vpmtouched++; break; } } argc = opt_num_rest(); argv = opt_rest(); if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto opthelp; } if (operation & SMIME_SIGNERS) { /* Check to see if any final signer needs to be appended */ if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto opthelp; } if (signerfile) { if (!sksigners && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); goto opthelp; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); goto opthelp; } } else if (operation == SMIME_ENCRYPT) { if (argc == 0) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); goto opthelp; } need_rand = 1; } else if (!operation) goto opthelp; if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (!app_load_modules(NULL)) goto end; if (need_rand) { app_RAND_load_file(NULL, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err, "%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (!(operation & SMIME_SIGNERS)) flags &= ~PKCS7_DETACHED; if (!(operation & SMIME_OP)) { if (flags & PKCS7_BINARY) outformat = FORMAT_BINARY; } if (!(operation & SMIME_IP)) { if (flags & PKCS7_BINARY) informat = FORMAT_BINARY; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } encerts = sk_X509_new_null(); if (!encerts) goto end; while (*argv) { cert = load_cert(*argv, FORMAT_PEM, NULL, e, "recipient certificate file"); if (cert == NULL) goto end; sk_X509_push(encerts, cert); cert = NULL; argv++; } } if (certfile) { if ((other = load_certs(certfile, FORMAT_PEM, NULL, e, "certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if ((recip = load_cert(recipfile, FORMAT_PEM, NULL, e, "recipient certificate file")) == NULL) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if (operation == SMIME_SIGN) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) p7 = SMIME_read_PKCS7(in, &indata); else if (informat == FORMAT_PEM) p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); goto end; } if (!p7) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if ((indata = BIO_new_file(contfile, "rb")) == NULL) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (operation == SMIME_VERIFY) { if ((store = setup_verify(CAfile, CApath)) == NULL) goto end; X509_STORE_set_verify_cb(store, smime_cb); if (vpmtouched) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_ENCRYPT) { if (indef) flags |= PKCS7_STREAM; p7 = PKCS7_encrypt(encerts, in, cipher, flags); } else if (operation & SMIME_SIGNERS) { int i; /* * If detached data content we only enable streaming if S/MIME output * format. */ if (operation == SMIME_SIGN) { if (flags & PKCS7_DETACHED) { if (outformat == FORMAT_SMIME) flags |= PKCS7_STREAM; } else if (indef) flags |= PKCS7_STREAM; flags |= PKCS7_PARTIAL; p7 = PKCS7_sign(NULL, NULL, other, in, flags); if (!p7) goto end; if (flags & PKCS7_NOCERTS) { for (i = 0; i < sk_X509_num(other); i++) { X509 *x = sk_X509_value(other, i); PKCS7_add_certificate(p7, x); } } } else flags |= PKCS7_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(signerfile, FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) goto end; X509_free(signer); signer = NULL; EVP_PKEY_free(key); key = NULL; } /* If not streaming or resigning finalize structure */ if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) { if (!PKCS7_final(p7, in, flags)) goto end; } } if (!p7) { BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (!PKCS7_decrypt(p7, key, recip, out, flags)) { BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); goto end; } } else if (operation == SMIME_VERIFY) { STACK_OF(X509) *signers; if (PKCS7_verify(p7, other, store, indata, out, flags)) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } signers = PKCS7_get0_signers(p7, other, flags); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } else if (operation == SMIME_PK7OUT) PEM_write_bio_PKCS7(out, p7); else { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (outformat == FORMAT_SMIME) { if (operation == SMIME_RESIGN) rv = SMIME_write_PKCS7(out, p7, indata, flags); else rv = SMIME_write_PKCS7(out, p7, in, flags); } else if (outformat == FORMAT_PEM) rv = PEM_write_bio_PKCS7_stream(out, p7, in, flags); else if (outformat == FORMAT_ASN1) rv = i2d_PKCS7_bio_stream(out, p7, in, flags); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } if (rv == 0) { BIO_printf(bio_err, "Error writing output\n"); ret = 3; goto end; } } ret = 0; end: if (need_rand) app_RAND_write_file(NULL); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); X509_VERIFY_PARAM_free(vpm); sk_OPENSSL_STRING_free(sksigners); sk_OPENSSL_STRING_free(skkeys); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); PKCS7_free(p7); BIO_free(in); BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); return (ret); }