static int execute_test(D2I_TEST_FIXTURE fixture) { BIO *bio = NULL; ASN1_VALUE *value = NULL; int ret = 0; unsigned char buf[2048]; const unsigned char *buf_ptr = buf; unsigned char *der = NULL; int derlen; int len; if ((bio = BIO_new_file(test_file, "r")) == NULL) return 0; if (expected_error == ASN1_BIO) { value = ASN1_item_d2i_bio(item_type, bio, NULL); if (value == NULL) ret = 1; goto err; } /* * Unless we are testing it we don't use ASN1_item_d2i_bio because it * performs sanity checks on the input and can reject it before the * decoder is called. */ len = BIO_read(bio, buf, sizeof(buf)); if (len < 0) goto err; value = ASN1_item_d2i(NULL, &buf_ptr, len, item_type); if (value == NULL) { if (expected_error == ASN1_DECODE) ret = 1; goto err; } derlen = ASN1_item_i2d(value, &der, item_type); if (der == NULL || derlen < 0) { if (expected_error == ASN1_ENCODE) ret = 1; goto err; } if (derlen != len || memcmp(der, buf, derlen) != 0) { if (expected_error == ASN1_COMPARE) ret = 1; goto err; } if (expected_error == ASN1_OK) ret = 1; err: /* Don't indicate success for memory allocation errors */ if (ret == 1 && ERR_GET_REASON(ERR_peek_error()) == ERR_R_MALLOC_FAILURE) ret = 0; BIO_free(bio); OPENSSL_free(der); ASN1_item_free(value, item_type); return ret; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; unsigned char *buf=NULL; int i,err=1; const EVP_MD *md=NULL,*m; BIO *in=NULL,*inp; BIO *bmd=NULL; BIO *out = NULL; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; int separator=0; int debug=0; int keyform=FORMAT_PEM; const char *outfile = NULL, *keyfile = NULL; const char *sigfile = NULL, *randfile = NULL; int out_bin = -1, want_pub = 0, do_verify = 0; EVP_PKEY *sigkey = NULL; unsigned char *sigbuf = NULL; int siglen = 0; char *passargin = NULL, *passin = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif char *hmac_key=NULL; char *mac_name=NULL; int non_fips_allow = 0; STACK_OF(OPENSSL_STRING) *sigopts = NULL, *macopts = NULL; apps_startup(); if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL) { BIO_printf(bio_err,"out of memory\n"); goto end; } if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; /* first check the program name */ program_name(argv[0],pname,sizeof pname); md=EVP_get_digestbyname(pname); argc--; argv++; while (argc > 0) { if ((*argv)[0] != '-') break; if (strcmp(*argv,"-c") == 0) separator=1; else if (strcmp(*argv,"-r") == 0) separator=2; else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) break; randfile=*(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) break; outfile=*(++argv); } else if (strcmp(*argv,"-sign") == 0) { if (--argc < 1) break; keyfile=*(++argv); } else if (!strcmp(*argv,"-passin")) { if (--argc < 1) break; passargin=*++argv; } else if (strcmp(*argv,"-verify") == 0) { if (--argc < 1) break; keyfile=*(++argv); want_pub = 1; do_verify = 1; } else if (strcmp(*argv,"-prverify") == 0) { if (--argc < 1) break; keyfile=*(++argv); do_verify = 1; } else if (strcmp(*argv,"-signature") == 0) { if (--argc < 1) break; sigfile=*(++argv); } else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) break; keyform=str2fmt(*(++argv)); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) break; engine= *(++argv); e = setup_engine(bio_err, engine, 0); } #endif else if (strcmp(*argv,"-hex") == 0) out_bin = 0; else if (strcmp(*argv,"-binary") == 0) out_bin = 1; else if (strcmp(*argv,"-d") == 0) debug=1; else if (!strcmp(*argv,"-fips-fingerprint")) hmac_key = "etaonrishdlcupfm"; else if (strcmp(*argv,"-non-fips-allow") == 0) non_fips_allow=1; else if (!strcmp(*argv,"-hmac")) { if (--argc < 1) break; hmac_key=*++argv; } else if (!strcmp(*argv,"-mac")) { if (--argc < 1) break; mac_name=*++argv; } else if (strcmp(*argv,"-sigopt") == 0) { if (--argc < 1) break; if (!sigopts) sigopts = sk_OPENSSL_STRING_new_null(); if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv))) break; } else if (strcmp(*argv,"-macopt") == 0) { if (--argc < 1) break; if (!macopts) macopts = sk_OPENSSL_STRING_new_null(); if (!macopts || !sk_OPENSSL_STRING_push(macopts, *(++argv))) break; } else if ((m=EVP_get_digestbyname(&((*argv)[1]))) != NULL) md=m; else break; argc--; argv++; } if(do_verify && !sigfile) { BIO_printf(bio_err, "No signature to verify: use the -signature option\n"); goto end; } if ((argc > 0) && (argv[0][0] == '-')) /* bad option */ { BIO_printf(bio_err,"unknown option '%s'\n",*argv); BIO_printf(bio_err,"options are\n"); BIO_printf(bio_err,"-c to output the digest with separating colons\n"); BIO_printf(bio_err,"-r to output the digest in coreutils format\n"); BIO_printf(bio_err,"-d to output debug info\n"); BIO_printf(bio_err,"-hex output as hex dump\n"); BIO_printf(bio_err,"-binary output in binary form\n"); BIO_printf(bio_err,"-sign file sign digest using private key in file\n"); BIO_printf(bio_err,"-verify file verify a signature using public key in file\n"); BIO_printf(bio_err,"-prverify file verify a signature using private key in file\n"); BIO_printf(bio_err,"-keyform arg key file format (PEM or ENGINE)\n"); BIO_printf(bio_err,"-out filename output to filename rather than stdout\n"); BIO_printf(bio_err,"-signature file signature to verify\n"); BIO_printf(bio_err,"-sigopt nm:v signature parameter\n"); BIO_printf(bio_err,"-hmac key create hashed MAC with key\n"); BIO_printf(bio_err,"-mac algorithm create MAC (not neccessarily HMAC)\n"); BIO_printf(bio_err,"-macopt nm:v MAC algorithm parameters or key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err,"-engine e use engine e, possibly a hardware device.\n"); #endif EVP_MD_do_all_sorted(list_md_fn, bio_err); goto end; } in=BIO_new(BIO_s_file()); bmd=BIO_new(BIO_f_md()); 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(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if ((in == NULL) || (bmd == NULL)) { ERR_print_errors(bio_err); goto end; } if(out_bin == -1) { if(keyfile) out_bin = 1; else out_bin = 0; } if(randfile) app_RAND_load_file(randfile, bio_err, 0); if(outfile) { if(out_bin) out = BIO_new_file(outfile, "wb"); else out = BIO_new_file(outfile, "w"); } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if(!out) { BIO_printf(bio_err, "Error opening output file %s\n", outfile ? outfile : "(stdout)"); ERR_print_errors(bio_err); 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(bio_err, keyfile, keyform, 0, NULL, e, "key file"); else sigkey = load_key(bio_err, 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(bio_err, &mac_ctx, mac_name,e, 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: if (mac_ctx) 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, e, (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, NULL, sigkey); else r = EVP_DigestSignInit(mctx, &pctx, md, NULL, 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 { if (md == NULL) md = EVP_md5(); if (!BIO_set_md(bmd,md)) { BIO_printf(bio_err, "Error setting digest %s\n", pname); ERR_print_errors(bio_err); goto end; } } if(sigfile && sigkey) { BIO *sigbio; sigbio = BIO_new_file(sigfile, "rb"); siglen = EVP_PKEY_size(sigkey); sigbuf = OPENSSL_malloc(siglen); if(!sigbio) { BIO_printf(bio_err, "Error opening signature file %s\n", sigfile); ERR_print_errors(bio_err); goto end; } 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); err=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); } md_name = EVP_MD_name(md); } err = 0; for (i=0; i<argc; i++) { int r; if (BIO_read_filename(in,argv[i]) <= 0) { perror(argv[i]); err++; continue; } else r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf, siglen,sig_name,md_name, argv[i],bmd); if(r) err=r; (void)BIO_reset(bmd); } } end: if (buf != NULL) { OPENSSL_cleanse(buf,BUFSIZE); OPENSSL_free(buf); } if (in != NULL) BIO_free(in); if (passin) OPENSSL_free(passin); BIO_free_all(out); EVP_PKEY_free(sigkey); if (sigopts) sk_OPENSSL_STRING_free(sigopts); if (macopts) sk_OPENSSL_STRING_free(macopts); if(sigbuf) OPENSSL_free(sigbuf); if (bmd != NULL) BIO_free(bmd); apps_shutdown(); OPENSSL_EXIT(err); }
static int reply_command(CONF *conf, char *section, char *engine, char *queryfile, char *passin, char *inkey, const EVP_MD *md, char *signer, char *chain, const char *policy, char *in, int token_in, char *out, int token_out, int text) { int ret = 0; TS_RESP *response = NULL; BIO *in_bio = NULL; BIO *query_bio = NULL; BIO *inkey_bio = NULL; BIO *signer_bio = NULL; BIO *out_bio = NULL; if (in != NULL) { if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; if (token_in) { response = read_PKCS7(in_bio); } else { response = d2i_TS_RESP_bio(in_bio, NULL); } } else { response = create_response(conf, section, engine, queryfile, passin, inkey, md, signer, chain, policy); if (response) BIO_printf(bio_err, "Response has been generated.\n"); else BIO_printf(bio_err, "Response is not generated.\n"); } if (response == NULL) goto end; /* Write response. */ if (text) { if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL) goto end; if (token_out) { TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end; } else { if (!TS_RESP_print_bio(out_bio, response)) goto end; } } else { if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL) goto end; if (token_out) { PKCS7 *token = TS_RESP_get_token(response); if (!i2d_PKCS7_bio(out_bio, token)) goto end; } else { if (!i2d_TS_RESP_bio(out_bio, response)) goto end; } } ret = 1; end: ERR_print_errors(bio_err); BIO_free_all(in_bio); BIO_free_all(query_bio); BIO_free_all(inkey_bio); BIO_free_all(signer_bio); BIO_free_all(out_bio); TS_RESP_free(response); return ret; }
int MAIN(int argc, char **argv) { BIO *in = NULL, *out = NULL; char *infile = NULL, *outfile = NULL, *sigfile = NULL; ENGINE *e = NULL; int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY; int keyform = FORMAT_PEM, peerform = FORMAT_PEM; char badarg = 0, rev = 0; char hexdump = 0, asn1parse = 0; EVP_PKEY_CTX *ctx = NULL; char *passargin = NULL; int keysize = -1; unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL; size_t buf_outlen; int buf_inlen = 0, siglen = -1; int ret = 1, rv = -1; argc--; argv++; if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); while(argc >= 1) { if (!strcmp(*argv,"-in")) { if (--argc < 1) badarg = 1; else infile= *(++argv); } else if (!strcmp(*argv,"-out")) { if (--argc < 1) badarg = 1; else outfile= *(++argv); } else if (!strcmp(*argv,"-sigfile")) { if (--argc < 1) badarg = 1; else sigfile= *(++argv); } else if(!strcmp(*argv, "-inkey")) { if (--argc < 1) badarg = 1; else { ctx = init_ctx(&keysize, *(++argv), keyform, key_type, passargin, pkey_op, e); if (!ctx) { BIO_puts(bio_err, "Error initializing context\n"); ERR_print_errors(bio_err); badarg = 1; } } } else if (!strcmp(*argv,"-peerkey")) { if (--argc < 1) badarg = 1; else if (!setup_peer(bio_err, ctx, peerform, *(++argv))) badarg = 1; } else if (!strcmp(*argv,"-passin")) { if (--argc < 1) badarg = 1; else passargin= *(++argv); } else if (strcmp(*argv,"-peerform") == 0) { if (--argc < 1) badarg = 1; else peerform=str2fmt(*(++argv)); } else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) badarg = 1; else keyform=str2fmt(*(++argv)); } #ifndef OPENSSL_NO_ENGINE else if(!strcmp(*argv, "-engine")) { if (--argc < 1) badarg = 1; else e = setup_engine(bio_err, *(++argv), 0); } #endif else if(!strcmp(*argv, "-pubin")) key_type = KEY_PUBKEY; else if(!strcmp(*argv, "-certin")) key_type = KEY_CERT; else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1; else if(!strcmp(*argv, "-hexdump")) hexdump = 1; else if(!strcmp(*argv, "-sign")) pkey_op = EVP_PKEY_OP_SIGN; else if(!strcmp(*argv, "-verify")) pkey_op = EVP_PKEY_OP_VERIFY; else if(!strcmp(*argv, "-verifyrecover")) pkey_op = EVP_PKEY_OP_VERIFYRECOVER; else if(!strcmp(*argv, "-rev")) rev = 1; else if(!strcmp(*argv, "-encrypt")) pkey_op = EVP_PKEY_OP_ENCRYPT; else if(!strcmp(*argv, "-decrypt")) pkey_op = EVP_PKEY_OP_DECRYPT; else if(!strcmp(*argv, "-derive")) pkey_op = EVP_PKEY_OP_DERIVE; else if (strcmp(*argv,"-pkeyopt") == 0) { if (--argc < 1) badarg = 1; else if (!ctx) { BIO_puts(bio_err, "-pkeyopt command before -inkey\n"); badarg = 1; } else if (pkey_ctrl_string(ctx, *(++argv)) <= 0) { BIO_puts(bio_err, "parameter setting error\n"); ERR_print_errors(bio_err); goto end; } } else badarg = 1; if(badarg) { usage(); goto end; } argc--; argv++; } if (!ctx) { usage(); goto end; } if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) { BIO_puts(bio_err, "Signature file specified for non verify\n"); goto end; } if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) { BIO_puts(bio_err, "No signature file specified for verify\n"); goto end; } /* FIXME: seed PRNG only if needed */ app_RAND_load_file(NULL, bio_err, 0); if (pkey_op != EVP_PKEY_OP_DERIVE) { if(infile) { if(!(in = BIO_new_file(infile, "rb"))) { BIO_puts(bio_err, "Error Opening Input File\n"); ERR_print_errors(bio_err); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); } if(outfile) { if(!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Error Creating Output File\n"); ERR_print_errors(bio_err); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } 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 == 0) BIO_puts(out, "Signature Verification Failure\n"); else if (rv == 1) BIO_puts(out, "Signature Verified Successfully\n"); if (rv >= 0) goto end; } else { rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen, buf_in, (size_t)buf_inlen); if (rv > 0) { buf_out = OPENSSL_malloc(buf_outlen); if (!buf_out) rv = -1; else rv = do_keyop(ctx, pkey_op, buf_out, (size_t *)&buf_outlen, buf_in, (size_t)buf_inlen); } } if(rv <= 0) { BIO_printf(bio_err, "Public Key operation error\n"); 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: if (ctx) EVP_PKEY_CTX_free(ctx); BIO_free(in); BIO_free_all(out); if (buf_in) OPENSSL_free(buf_in); if (buf_out) OPENSSL_free(buf_out); if (sig) OPENSSL_free(sig); return ret; }
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile) { DH *dh; unsigned long err; if(cert == NULL) { rb_lib_log("rb_setup_ssl_server: No certificate file"); return 0; } if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx, cert) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx, cert)) { err = ERR_get_error(); rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert, get_ssl_error(err)); return 0; } if(keyfile == NULL) { rb_lib_log("rb_setup_ssl_server: No key file"); return 0; } if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx, keyfile, SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ssl_client_ctx, keyfile, SSL_FILETYPE_PEM)) { err = ERR_get_error(); rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile, get_ssl_error(err)); return 0; } if(dhfile != NULL) { /* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */ BIO *bio = BIO_new_file(dhfile, "r"); if(bio != NULL) { dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); if(dh == NULL) { err = ERR_get_error(); rb_lib_log ("rb_setup_ssl_server: Error loading DH params file [%s]: %s", dhfile, get_ssl_error(err)); BIO_free(bio); return 0; } BIO_free(bio); SSL_CTX_set_tmp_dh(ssl_server_ctx, dh); } else { err = ERR_get_error(); rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s", dhfile, get_ssl_error(err)); } } return 1; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL, *rctfile = NULL; char *signerfile = NULL, *recipfile = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; char *certsoutfile = NULL; const EVP_CIPHER *cipher = NULL; CMS_ContentInfo *cms = NULL, *rcms = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL; int badarg = 0; int flags = CMS_DETACHED, noout = 0, print = 0; int verify_retcode = 0; int rr_print = 0, rr_allorfirst = -1; STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL; CMS_ReceiptRequest *rr = NULL; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; const EVP_MD *sign_md = NULL; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif unsigned char *secret_key = NULL, *secret_keyid = NULL; size_t secret_keylen = 0, secret_keyidlen = 0; ASN1_OBJECT *econtent_type = NULL; X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-sign_receipt")) operation = SMIME_SIGN_RECEIPT; else if (!strcmp (*args, "-resign")) operation = SMIME_RESIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-verify_retcode")) verify_retcode = 1; else if (!strcmp(*args,"-verify_receipt")) { operation = SMIME_VERIFY_RECEIPT; if (!args[1]) goto argerr; args++; rctfile = *args; } else if (!strcmp (*args, "-cmsout")) operation = SMIME_CMSOUT; else if (!strcmp (*args, "-data_out")) operation = SMIME_DATAOUT; else if (!strcmp (*args, "-data_create")) operation = SMIME_DATA_CREATE; else if (!strcmp (*args, "-digest_verify")) operation = SMIME_DIGEST_VERIFY; else if (!strcmp (*args, "-digest_create")) operation = SMIME_DIGEST_CREATE; else if (!strcmp (*args, "-compress")) operation = SMIME_COMPRESS; else if (!strcmp (*args, "-uncompress")) operation = SMIME_UNCOMPRESS; else if (!strcmp (*args, "-EncryptedData_decrypt")) operation = SMIME_ENCRYPTED_DECRYPT; else if (!strcmp (*args, "-EncryptedData_encrypt")) operation = SMIME_ENCRYPTED_ENCRYPT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (!strcmp (*args, "-seed")) cipher = EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args,"-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args,"-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-debug_decrypt")) flags |= CMS_DEBUG_DECRYPT; else if (!strcmp (*args, "-text")) flags |= CMS_TEXT; else if (!strcmp (*args, "-nointern")) flags |= CMS_NOINTERN; else if (!strcmp (*args, "-noverify") || !strcmp (*args, "-no_signer_cert_verify")) flags |= CMS_NO_SIGNER_CERT_VERIFY; else if (!strcmp (*args, "-nocerts")) flags |= CMS_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= CMS_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~CMS_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= CMS_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= CMS_BINARY; else if (!strcmp (*args, "-keyid")) flags |= CMS_USE_KEYID; else if (!strcmp (*args, "-nosigs")) flags |= CMS_NOSIGS; else if (!strcmp (*args, "-no_content_verify")) flags |= CMS_NO_CONTENT_VERIFY; else if (!strcmp (*args, "-no_attr_verify")) flags |= CMS_NO_ATTR_VERIFY; else if (!strcmp (*args, "-stream")) flags |= CMS_STREAM; else if (!strcmp (*args, "-indef")) flags |= CMS_STREAM; else if (!strcmp (*args, "-noindef")) flags &= ~CMS_STREAM; else if (!strcmp (*args, "-nooldmime")) flags |= CMS_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= CMS_CRLFEOL; else if (!strcmp (*args, "-noout")) noout = 1; else if (!strcmp (*args, "-receipt_request_print")) rr_print = 1; else if (!strcmp (*args, "-receipt_request_all")) rr_allorfirst = 0; else if (!strcmp (*args, "-receipt_request_first")) rr_allorfirst = 1; else if (!strcmp(*args,"-receipt_request_from")) { if (!args[1]) goto argerr; args++; if (!rr_from) rr_from = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_from, *args); } else if (!strcmp(*args,"-receipt_request_to")) { if (!args[1]) goto argerr; args++; if (!rr_to) rr_to = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(rr_to, *args); } else if (!strcmp (*args, "-print")) { noout = 1; print = 1; } else if (!strcmp(*args,"-secretkey")) { long ltmp; if (!args[1]) goto argerr; args++; secret_key = string_to_hex(*args, <mp); if (!secret_key) { BIO_printf(bio_err, "Invalid key %s\n", *args); goto argerr; } secret_keylen = (size_t)ltmp; } else if (!strcmp(*args,"-secretkeyid")) { long ltmp; if (!args[1]) goto argerr; args++; secret_keyid = string_to_hex(*args, <mp); if (!secret_keyid) { BIO_printf(bio_err, "Invalid id %s\n", *args); goto argerr; } secret_keyidlen = (size_t)ltmp; } else if (!strcmp(*args,"-econtent_type")) { if (!args[1]) goto argerr; args++; econtent_type = OBJ_txt2obj(*args, 0); if (!econtent_type) { BIO_printf(bio_err, "Invalid OID %s\n", *args); goto argerr; } } else if (!strcmp(*args,"-rand")) { if (!args[1]) goto argerr; args++; inrand = *args; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (!args[1]) goto argerr; engine = *++args; } #endif else if (!strcmp(*args,"-passin")) { if (!args[1]) goto argerr; passargin = *++args; } else if (!strcmp (*args, "-to")) { if (!args[1]) goto argerr; to = *++args; } else if (!strcmp (*args, "-from")) { if (!args[1]) goto argerr; from = *++args; } else if (!strcmp (*args, "-subject")) { if (!args[1]) goto argerr; subject = *++args; } else if (!strcmp (*args, "-signer")) { if (!args[1]) goto argerr; /* If previous -signer argument add signer to list */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!keyfile) keyfile = signerfile; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = *++args; } else if (!strcmp (*args, "-recip")) { if (!args[1]) goto argerr; recipfile = *++args; } else if (!strcmp (*args, "-certsout")) { if (!args[1]) goto argerr; certsoutfile = *++args; } else if (!strcmp (*args, "-md")) { if (!args[1]) goto argerr; sign_md = EVP_get_digestbyname(*++args); if (sign_md == NULL) { BIO_printf(bio_err, "Unknown digest %s\n", *args); goto argerr; } } else if (!strcmp (*args, "-inkey")) { if (!args[1]) goto argerr; /* If previous -inkey arument add signer to list */ if (keyfile) { if (!signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = *++args; } else if (!strcmp (*args, "-keyform")) { if (!args[1]) goto argerr; keyform = str2fmt(*++args); } else if (!strcmp (*args, "-rctform")) { if (!args[1]) goto argerr; rctformat = str2fmt(*++args); } else if (!strcmp (*args, "-certfile")) { if (!args[1]) goto argerr; certfile = *++args; } else if (!strcmp (*args, "-CAfile")) { if (!args[1]) goto argerr; CAfile = *++args; } else if (!strcmp (*args, "-CApath")) { if (!args[1]) goto argerr; CApath = *++args; } else if (!strcmp (*args, "-in")) { if (!args[1]) goto argerr; infile = *++args; } else if (!strcmp (*args, "-inform")) { if (!args[1]) goto argerr; informat = str2fmt(*++args); } else if (!strcmp (*args, "-outform")) { if (!args[1]) goto argerr; outformat = str2fmt(*++args); } else if (!strcmp (*args, "-out")) { if (!args[1]) goto argerr; outfile = *++args; } else if (!strcmp (*args, "-content")) { if (!args[1]) goto argerr; contfile = *++args; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL) badarg = 1; args++; } if (((rr_allorfirst != -1) || rr_from) && !rr_to) { BIO_puts(bio_err, "No Signed Receipts Recipients\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) { BIO_puts(bio_err, "Signed receipts only allowed with -sign\n"); goto argerr; } if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto argerr; } if (operation & SMIME_SIGNERS) { if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto argerr; } /* Check to see if any final signer needs to be appended */ if (signerfile) { if (!sksigners) sksigners = sk_OPENSSL_STRING_new_null(); sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys) skkeys = sk_OPENSSL_STRING_new_null(); if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile && !secret_key) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args && !secret_key) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { argerr: BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-cmsout output CMS structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf (bio_err, "-seed encrypt with SEED\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-certsout file certificate output file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-keyid use subject key identifier\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (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 &= ~CMS_DETACHED; if (operation & SMIME_OP) { if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & CMS_BINARY) outmode = "wb"; } if (operation & SMIME_IP) { if (informat == FORMAT_ASN1) inmode = "rb"; } else { if (flags & CMS_BINARY) inmode = "rb"; } 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 } if (secret_key && !secret_keyid) { BIO_printf(bio_err, "No secret key id\n"); goto end; } if (*args) encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) goto end; sk_X509_push(encerts, cert); cert = NULL; args++; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_SIGN_RECEIPT) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL, e, "receipt signer certificate file"))) { ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (operation & SMIME_IP) { if (informat == FORMAT_SMIME) cms = SMIME_read_CMS(in, &indata); else if (informat == FORMAT_PEM) cms = PEM_read_bio_CMS(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) cms = d2i_CMS_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for CMS file\n"); goto end; } if (!cms) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } if (certsoutfile) { STACK_OF(X509) *allcerts; allcerts = CMS_get1_certs(cms); if (!save_certs(certsoutfile, allcerts)) { BIO_printf(bio_err, "Error writing certs to %s\n", certsoutfile); ret = 5; goto end; } sk_X509_pop_free(allcerts, X509_free); } } if (rctfile) { char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r"; if (!(rctin = BIO_new_file(rctfile, rctmode))) { BIO_printf (bio_err, "Can't open receipt file %s\n", rctfile); goto end; } if (rctformat == FORMAT_SMIME) rcms = SMIME_read_CMS(rctin, NULL); else if (rctformat == FORMAT_PEM) rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL); else if (rctformat == FORMAT_ASN1) rcms = d2i_CMS_bio(rctin, NULL); else { BIO_printf(bio_err, "Bad input format for receipt\n"); goto end; } if (!rcms) { BIO_printf(bio_err, "Error reading receipt\n"); goto end; } } if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb(store, cms_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_DATA_CREATE) { cms = CMS_data_create(in, flags); } else if (operation == SMIME_DIGEST_CREATE) { cms = CMS_digest_create(in, sign_md, flags); } else if (operation == SMIME_COMPRESS) { cms = CMS_compress(in, -1, flags); } else if (operation == SMIME_ENCRYPT) { flags |= CMS_PARTIAL; cms = CMS_encrypt(encerts, in, cipher, flags); if (!cms) goto end; if (secret_key) { if (!CMS_add0_recipient_key(cms, NID_undef, secret_key, secret_keylen, secret_keyid, secret_keyidlen, NULL, NULL, NULL)) goto end; /* NULL these because call absorbs them */ secret_key = NULL; secret_keyid = NULL; } if (!(flags & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } else if (operation == SMIME_ENCRYPTED_ENCRYPT) { cms = CMS_EncryptedData_encrypt(in, cipher, secret_key, secret_keylen, flags); } else if (operation == SMIME_SIGN_RECEIPT) { CMS_ContentInfo *srcms = NULL; STACK_OF(CMS_SignerInfo) *sis; CMS_SignerInfo *si; sis = CMS_get0_SignerInfos(cms); if (!sis) goto end; si = sk_CMS_SignerInfo_value(sis, 0); srcms = CMS_sign_receipt(si, signer, key, other, flags); if (!srcms) goto end; CMS_ContentInfo_free(cms); cms = srcms; } else if (operation & SMIME_SIGNERS) { int i; /* If detached data content we enable streaming if * S/MIME output format. */ if (operation == SMIME_SIGN) { if (flags & CMS_DETACHED) { if (outformat == FORMAT_SMIME) flags |= CMS_STREAM; } flags |= CMS_PARTIAL; cms = CMS_sign(NULL, NULL, other, in, flags); if (!cms) goto end; if (econtent_type) CMS_set1_eContentType(cms, econtent_type); if (rr_to) { rr = make_receipt_request(rr_to, rr_allorfirst, rr_from); if (!rr) { BIO_puts(bio_err, "Signed Receipt Request Creation Error\n"); goto end; } } } else flags |= CMS_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { CMS_SignerInfo *si; signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL, e, "signer certificate"); if (!signer) goto end; key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; si = CMS_add1_signer(cms, signer, key, sign_md, flags); if (!si) goto end; if (rr && !CMS_add1_ReceiptRequest(si, rr)) 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 & CMS_STREAM)) { if (!CMS_final(cms, in, NULL, flags)) goto end; } } if (!cms) { BIO_printf(bio_err, "Error creating CMS structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (flags & CMS_DEBUG_DECRYPT) CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags); if (secret_key) { if (!CMS_decrypt_set1_key(cms, secret_key, secret_keylen, secret_keyid, secret_keyidlen)) { BIO_puts(bio_err, "Error decrypting CMS using secret key\n"); goto end; } } if (key) { if (!CMS_decrypt_set1_pkey(cms, key, recip)) { BIO_puts(bio_err, "Error decrypting CMS using private key\n"); goto end; } } if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) { BIO_printf(bio_err, "Error decrypting CMS structure\n"); goto end; } } else if (operation == SMIME_DATAOUT) { if (!CMS_data(cms, out, flags)) goto end; } else if (operation == SMIME_UNCOMPRESS) { if (!CMS_uncompress(cms, indata, out, flags)) goto end; } else if (operation == SMIME_DIGEST_VERIFY) { if (CMS_digest_verify(cms, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else if (operation == SMIME_ENCRYPTED_DECRYPT) { if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen, indata, out, flags)) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); if (verify_retcode) ret = verify_err + 32; goto end; } if (signerfile) { STACK_OF(X509) *signers; signers = CMS_get0_signers(cms); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } if (rr_print) receipt_request_print(bio_err, cms); } else if (operation == SMIME_VERIFY_RECEIPT) { if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } } else { if (noout) { if (print) CMS_ContentInfo_print_ctx(out, cms, 0, NULL); } else if (outformat == FORMAT_SMIME) { 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 (operation == SMIME_RESIGN) ret = SMIME_write_CMS(out, cms, indata, flags); else ret = SMIME_write_CMS(out, cms, in, flags); } else if (outformat == FORMAT_PEM) ret = PEM_write_bio_CMS_stream(out, cms, in, flags); else if (outformat == FORMAT_ASN1) ret = i2d_CMS_bio_stream(out,cms, in, flags); else { BIO_printf(bio_err, "Bad output format for CMS file\n"); goto end; } if (ret <= 0) { ret = 6; goto end; } } ret = 0; end: if (ret) ERR_print_errors(bio_err); if (need_rand) app_RAND_write_file(NULL, bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); if (sksigners) sk_OPENSSL_STRING_free(sksigners); if (skkeys) sk_OPENSSL_STRING_free(skkeys); if (secret_key) OPENSSL_free(secret_key); if (secret_keyid) OPENSSL_free(secret_keyid); if (econtent_type) ASN1_OBJECT_free(econtent_type); if (rr) CMS_ReceiptRequest_free(rr); if (rr_to) sk_OPENSSL_STRING_free(rr_to); if (rr_from) sk_OPENSSL_STRING_free(rr_from); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); CMS_ContentInfo_free(cms); CMS_ContentInfo_free(rcms); BIO_free(rctin); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char **args, *outfile = NULL; char *passarg = NULL; BIO *in = NULL, *out = NULL; const EVP_CIPHER *cipher = NULL; int outformat; int text = 0; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *pass = NULL; int badarg = 0; int ret = 1, rv; int do_param = 0; if (bio_err == NULL) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; outformat = FORMAT_PEM; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-pass")) { if (!args[1]) goto bad; passarg = *(++args); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*args, "-engine") == 0) { if (!args[1]) goto bad; e = setup_engine(bio_err, *(++args), 0); } #endif else if (!strcmp(*args, "-paramfile")) { if (!args[1]) goto bad; args++; if (do_param == 1) goto bad; if (!init_keygen_file(bio_err, &ctx, *args, e)) goto end; } else if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (strcmp(*args, "-algorithm") == 0) { if (!args[1]) goto bad; if (!init_gen_str(bio_err, &ctx, *(++args), e, do_param)) goto end; } else if (strcmp(*args, "-pkeyopt") == 0) { if (!args[1]) goto bad; if (!ctx) { BIO_puts(bio_err, "No keytype specified\n"); goto bad; } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) { BIO_puts(bio_err, "parameter setting error\n"); ERR_print_errors(bio_err); goto end; } } else if (strcmp(*args, "-genparam") == 0) { if (ctx) goto bad; do_param = 1; } else if (strcmp(*args, "-text") == 0) text = 1; else { cipher = EVP_get_cipherbyname(*args + 1); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); badarg = 1; } if (do_param == 1) badarg = 1; } args++; } if (!ctx) badarg = 1; if (badarg) { bad: BIO_printf(bio_err, "Usage: genpkey [options]\n"); BIO_printf(bio_err, "where options may be\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-pass arg output file pass phrase source\n"); BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err, "-paramfile file parameters file\n"); BIO_printf(bio_err, "-algorithm alg the public key algorithm\n"); BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n" " to value <value>\n"); BIO_printf(bio_err, "-genparam generate parameters, not key\n"); BIO_printf(bio_err, "-text print the in text\n"); BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n"); goto end; } if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { BIO_puts(bio_err, "Error getting password\n"); goto end; } if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); if (do_param) { if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { BIO_puts(bio_err, "Error generating parameters\n"); ERR_print_errors(bio_err); goto end; } } else { if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto end; } } if (do_param) rv = PEM_write_bio_Parameters(out, pkey); else if (outformat == FORMAT_PEM) rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); else if (outformat == FORMAT_ASN1) rv = i2d_PrivateKey_bio(out, pkey); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } if (rv <= 0) { BIO_puts(bio_err, "Error writing key\n"); ERR_print_errors(bio_err); } if (text) { if (do_param) rv = EVP_PKEY_print_params(out, pkey, 0, NULL); else rv = EVP_PKEY_print_private(out, pkey, 0, NULL); if (rv <= 0) { BIO_puts(bio_err, "Error printing key\n"); ERR_print_errors(bio_err); } } ret = 0; end: if (pkey) EVP_PKEY_free(pkey); if (ctx) EVP_PKEY_CTX_free(ctx); if (out) BIO_free_all(out); BIO_free(in); if (pass) OPENSSL_free(pass); return ret; }
static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, char *queryfile, char *ca_path, char *ca_file, char *untrusted) { TS_VERIFY_CTX *ctx = NULL; BIO *input = NULL; TS_REQ *request = NULL; int ret = 0; if (data != NULL || digest != NULL) { if (!(ctx = TS_VERIFY_CTX_new())) goto err; ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER; if (data != NULL) { ctx->flags |= TS_VFY_DATA; if (!(ctx->data = BIO_new_file(data, "rb"))) goto err; } else if (digest != NULL) { long imprint_len; ctx->flags |= TS_VFY_IMPRINT; if (!(ctx->imprint = string_to_hex(digest, &imprint_len))) { BIO_printf(bio_err, "invalid digest string\n"); goto err; } ctx->imprint_len = imprint_len; } } else if (queryfile != NULL) { /* The request has just to be read, decoded and converted to a verify context object. */ if (!(input = BIO_new_file(queryfile, "rb"))) goto err; if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err; if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err; } else return NULL; /* Add the signature verification flag and arguments. */ ctx->flags |= TS_VFY_SIGNATURE; /* Initialising the X509_STORE object. */ if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err; /* Loading untrusted certificates. */ if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) goto err; ret = 1; err: if (!ret) { TS_VERIFY_CTX_free(ctx); ctx = NULL; } BIO_free_all(input); TS_REQ_free(request); return ctx; }
static int reply_command(CONF *conf, char *section, char *engine, char *queryfile, char *passin, char *inkey, char *signer, char *chain, const char *policy, char *in, int token_in, char *out, int token_out, int text) { int ret = 0; TS_RESP *response = NULL; BIO *in_bio = NULL; BIO *query_bio = NULL; BIO *inkey_bio = NULL; BIO *signer_bio = NULL; BIO *out_bio = NULL; /* Build response object either from response or query. */ if (in != NULL) { if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; if (token_in) { /* We have a ContentInfo (PKCS7) object, add 'granted' status info around it. */ response = read_PKCS7(in_bio); } else { /* We have a ready-made TS_RESP object. */ response = d2i_TS_RESP_bio(in_bio, NULL); } } else { response = create_response(conf, section, engine, queryfile, passin, inkey, signer, chain, policy); if (response) BIO_printf(bio_err, "Response has been generated.\n"); else BIO_printf(bio_err, "Response is not generated.\n"); } if (response == NULL) goto end; /* Write response either in ASN.1 or text format. */ if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) goto end; if (text) { /* Text output. */ if (token_out) { TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end; } else { if (!TS_RESP_print_bio(out_bio, response)) goto end; } } else { /* ASN.1 DER output. */ if (token_out) { PKCS7 *token = TS_RESP_get_token(response); if (!i2d_PKCS7_bio(out_bio, token)) goto end; } else { if (!i2d_TS_RESP_bio(out_bio, response)) goto end; } } ret = 1; end: ERR_print_errors(bio_err); /* Clean up. */ BIO_free_all(in_bio); BIO_free_all(query_bio); BIO_free_all(inkey_bio); BIO_free_all(signer_bio); BIO_free_all(out_bio); TS_RESP_free(response); return ret; }
int genpkey_main(int argc, char **argv) { char **args, *outfile = NULL; char *passarg = NULL; BIO *in = NULL, *out = NULL; const EVP_CIPHER *cipher = NULL; int outformat; int text = 0; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *pass = NULL; int badarg = 0; int ret = 1, rv; int do_param = 0; if (single_execution) { if (pledge("stdio rpath wpath cpath tty", NULL) == -1) { perror("pledge"); exit(1); } } outformat = FORMAT_PEM; args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp(*args, "-pass")) { if (!args[1]) goto bad; passarg = *(++args); } else if (!strcmp(*args, "-paramfile")) { if (!args[1]) goto bad; args++; if (do_param == 1) goto bad; if (!init_keygen_file(bio_err, &ctx, *args)) goto end; } else if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (strcmp(*args, "-algorithm") == 0) { if (!args[1]) goto bad; if (!init_gen_str(bio_err, &ctx, *(++args), do_param)) goto end; } else if (strcmp(*args, "-pkeyopt") == 0) { if (!args[1]) goto bad; if (!ctx) { BIO_puts(bio_err, "No keytype specified\n"); goto bad; } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) { BIO_puts(bio_err, "parameter setting error\n"); ERR_print_errors(bio_err); goto end; } } else if (strcmp(*args, "-genparam") == 0) { if (ctx) goto bad; do_param = 1; } else if (strcmp(*args, "-text") == 0) text = 1; else { cipher = EVP_get_cipherbyname(*args + 1); if (!cipher) { BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1); badarg = 1; } if (do_param == 1) badarg = 1; } args++; } if (!ctx) badarg = 1; if (badarg) { bad: BIO_printf(bio_err, "Usage: genpkey [options]\n"); BIO_printf(bio_err, "where options may be\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-outform X output format (DER or PEM)\n"); BIO_printf(bio_err, "-pass arg output file pass phrase source\n"); BIO_printf(bio_err, "-<cipher> use cipher <cipher> to encrypt the key\n"); BIO_printf(bio_err, "-paramfile file parameters file\n"); BIO_printf(bio_err, "-algorithm alg the public key algorithm\n"); BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n" " to value <value>\n"); BIO_printf(bio_err, "-genparam generate parameters, not key\n"); BIO_printf(bio_err, "-text print the in text\n"); BIO_printf(bio_err, "NB: options order may be important! See the manual page.\n"); goto end; } if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) { BIO_puts(bio_err, "Error getting password\n"); goto end; } if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } EVP_PKEY_CTX_set_cb(ctx, genpkey_cb); EVP_PKEY_CTX_set_app_data(ctx, bio_err); if (do_param) { if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { BIO_puts(bio_err, "Error generating parameters\n"); ERR_print_errors(bio_err); goto end; } } else { if (EVP_PKEY_keygen(ctx, &pkey) <= 0) { BIO_puts(bio_err, "Error generating key\n"); ERR_print_errors(bio_err); goto end; } } if (do_param) rv = PEM_write_bio_Parameters(out, pkey); else if (outformat == FORMAT_PEM) rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass); else if (outformat == FORMAT_ASN1) rv = i2d_PrivateKey_bio(out, pkey); else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } if (rv <= 0) { BIO_puts(bio_err, "Error writing key\n"); ERR_print_errors(bio_err); } if (text) { if (do_param) rv = EVP_PKEY_print_params(out, pkey, 0, NULL); else rv = EVP_PKEY_print_private(out, pkey, 0, NULL); if (rv <= 0) { BIO_puts(bio_err, "Error printing key\n"); ERR_print_errors(bio_err); } } ret = 0; end: if (pkey) EVP_PKEY_free(pkey); if (ctx) EVP_PKEY_CTX_free(ctx); if (out) BIO_free_all(out); BIO_free(in); free(pass); 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; const char *CAfile = NULL, *CApath = NULL, *prog = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *inrand = NULL; char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL; char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL; OPTION_CHOICE o; int noCApath = 0, noCAfile = 0; 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; const char *mime_eol = "\n"; 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_PDS, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PDS, &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_CRLFEOL: flags |= PKCS7_CRLFEOL; mime_eol = "\r\n"; 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 argument 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_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; 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 (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, "recipient certificate file"); if (cert == NULL) goto end; sk_X509_push(encerts, cert); cert = NULL; argv++; } } if (certfile) { if (!load_certs(certfile, &other, FORMAT_PEM, NULL, "certificate file")) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if ((recip = load_cert(recipfile, FORMAT_PEM, "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, noCAfile, noCApath)) == 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, "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%s", to, mime_eol); if (from) BIO_printf(out, "From: %s%s", from, mime_eol); if (subject) BIO_printf(out, "Subject: %s%s", subject, mime_eol); 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); release_engine(e); BIO_free(in); BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); return (ret); }
int pkeyparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; EVP_PKEY *pkey = NULL; int ret = 1; if (single_execution) { if (pledge("stdio cpath wpath rpath", NULL) == -1) { perror("pledge"); exit(1); } } memset(&pkeyparam_config, 0, sizeof(pkeyparam_config)); if (options_parse(argc, argv, pkeyparam_options, NULL, NULL) != 0) { pkeyparam_usage(); return (1); } if (pkeyparam_config.infile) { if (!(in = BIO_new_file(pkeyparam_config.infile, "r"))) { BIO_printf(bio_err, "Can't open input file %s\n", pkeyparam_config.infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (pkeyparam_config.outfile) { if (!(out = BIO_new_file(pkeyparam_config.outfile, "w"))) { BIO_printf(bio_err, "Can't open output file %s\n", pkeyparam_config.outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); } 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 (!pkeyparam_config.noout) PEM_write_bio_Parameters(out, pkey); if (pkeyparam_config.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 main(int argc, char **argv) { BIO *in = NULL, *out = NULL, *tbio = NULL; X509 *scert = NULL, *scert2 = NULL; EVP_PKEY *skey = NULL, *skey2 = NULL; PKCS7 *p7 = NULL; int ret = 1; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); tbio = BIO_new_file("signer.pem", "r"); if (!tbio) goto err; scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); BIO_reset(tbio); skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); BIO_free(tbio); tbio = BIO_new_file("signer2.pem", "r"); if (!tbio) goto err; scert2 = PEM_read_bio_X509(tbio, NULL, 0, NULL); BIO_reset(tbio); skey2 = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); if (!scert2 || !skey2) goto err; in = BIO_new_file("sign.txt", "r"); if (!in) goto err; p7 = PKCS7_sign(NULL, NULL, NULL, in, PKCS7_STREAM | PKCS7_PARTIAL); if (!p7) goto err; /* Add each signer in turn */ if (!PKCS7_sign_add_signer(p7, scert, skey, NULL, 0)) goto err; if (!PKCS7_sign_add_signer(p7, scert2, skey2, NULL, 0)) goto err; out = BIO_new_file("smout.txt", "w"); if (!out) goto err; /* NB: content included and finalized by SMIME_write_PKCS7 */ if (!SMIME_write_PKCS7(out, p7, in, PKCS7_STREAM)) goto err; ret = 0; err: if (ret) { fprintf(stderr, "Error Signing Data\n"); ERR_print_errors_fp(stderr); } PKCS7_free(p7); X509_free(scert); EVP_PKEY_free(skey); X509_free(scert2); EVP_PKEY_free(skey2); BIO_free(in); BIO_free(out); BIO_free(tbio); return ret; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; char *infile=NULL, *outfile=NULL, *keyname = NULL; char *certfile=NULL; BIO *in=NULL, *out = NULL; char **args; char *name = NULL; char *csp_name = NULL; PKCS12 *p12 = NULL; char pass[50], macpass[50]; int export_cert = 0; int options = 0; int chain = 0; int badarg = 0; int iter = PKCS12_DEFAULT_ITER; int maciter = PKCS12_DEFAULT_ITER; int twopass = 0; int keytype = 0; int cert_pbe; int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; int ret = 1; int macver = 1; int noprompt = 0; STACK *canames = NULL; char *cpass = NULL, *mpass = NULL; char *passargin = NULL, *passargout = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL; char *inrand = NULL; char *CApath = NULL, *CAfile = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif apps_startup(); #ifdef OPENSSL_FIPS if (FIPS_mode()) cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; else #endif cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; enc = EVP_des_ede3_cbc(); if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; args = argv + 1; while (*args) { if (*args[0] == '-') { if (!strcmp (*args, "-nokeys")) options |= NOKEYS; else if (!strcmp (*args, "-keyex")) keytype = KEY_EX; else if (!strcmp (*args, "-keysig")) keytype = KEY_SIG; else if (!strcmp (*args, "-nocerts")) options |= NOCERTS; else if (!strcmp (*args, "-clcerts")) options |= CLCERTS; else if (!strcmp (*args, "-cacerts")) options |= CACERTS; else if (!strcmp (*args, "-noout")) options |= (NOKEYS|NOCERTS); else if (!strcmp (*args, "-info")) options |= INFO; else if (!strcmp (*args, "-chain")) chain = 1; else if (!strcmp (*args, "-twopass")) twopass = 1; else if (!strcmp (*args, "-nomacver")) macver = 0; else if (!strcmp (*args, "-descert")) cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; else if (!strcmp (*args, "-export")) export_cert = 1; else if (!strcmp (*args, "-des")) enc=EVP_des_cbc(); #ifndef OPENSSL_NO_IDEA else if (!strcmp (*args, "-idea")) enc=EVP_idea_cbc(); #endif else if (!strcmp (*args, "-des3")) enc = EVP_des_ede3_cbc(); #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) enc=EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) enc=EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) enc=EVP_aes_256_cbc(); #endif else if (!strcmp (*args, "-noiter")) iter = 1; else if (!strcmp (*args, "-maciter")) maciter = PKCS12_DEFAULT_ITER; else if (!strcmp (*args, "-nomaciter")) maciter = 1; else if (!strcmp (*args, "-nodes")) enc=NULL; else if (!strcmp (*args, "-certpbe")) { if (args[1]) { args++; cert_pbe=OBJ_txt2nid(*args); if(cert_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-keypbe")) { if (args[1]) { args++; key_pbe=OBJ_txt2nid(*args); if(key_pbe == NID_undef) { BIO_printf(bio_err, "Unknown PBE algorithm %s\n", *args); badarg = 1; } } else badarg = 1; } else if (!strcmp (*args, "-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyname = *args; } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-name")) { if (args[1]) { args++; name = *args; } else badarg = 1; } else if (!strcmp (*args, "-CSP")) { if (args[1]) { args++; csp_name = *args; } else badarg = 1; } else if (!strcmp (*args, "-caname")) { if (args[1]) { args++; if (!canames) canames = sk_new_null(); sk_push(canames, *args); } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp(*args,"-passout")) { if (args[1]) { args++; passargout = *args; } else badarg = 1; } else if (!strcmp (*args, "-password")) { if (args[1]) { args++; passarg = *args; noprompt = 1; } else badarg = 1; } else if (!strcmp(*args,"-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp(*args,"-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; #ifndef OPENSSL_NO_ENGINE } else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; #endif } else badarg = 1; } else badarg = 1; args++; } if (badarg) { BIO_printf (bio_err, "Usage: pkcs12 [options]\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-export output PKCS12 file\n"); BIO_printf (bio_err, "-chain add certificate chain\n"); BIO_printf (bio_err, "-inkey file private key if not infile\n"); BIO_printf (bio_err, "-certfile f add all certs in f\n"); BIO_printf (bio_err, "-CApath arg - PEM format directory of CA's\n"); BIO_printf (bio_err, "-CAfile arg - PEM format file of CA's\n"); BIO_printf (bio_err, "-name \"name\" use name as friendly name\n"); BIO_printf (bio_err, "-caname \"nm\" use nm as CA friendly name (can be used more than once).\n"); BIO_printf (bio_err, "-in infile input filename\n"); BIO_printf (bio_err, "-out outfile output filename\n"); BIO_printf (bio_err, "-noout don't output anything, just verify.\n"); BIO_printf (bio_err, "-nomacver don't verify MAC.\n"); BIO_printf (bio_err, "-nocerts don't output certificates.\n"); BIO_printf (bio_err, "-clcerts only output client certificates.\n"); BIO_printf (bio_err, "-cacerts only output CA certificates.\n"); BIO_printf (bio_err, "-nokeys don't output private keys.\n"); BIO_printf (bio_err, "-info give info about PKCS#12 structure.\n"); BIO_printf (bio_err, "-des encrypt private keys with DES\n"); BIO_printf (bio_err, "-des3 encrypt private keys with triple DES (default)\n"); #ifndef OPENSSL_NO_IDEA BIO_printf (bio_err, "-idea encrypt private keys with idea\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif BIO_printf (bio_err, "-nodes don't encrypt private keys\n"); BIO_printf (bio_err, "-noiter don't use encryption iteration\n"); BIO_printf (bio_err, "-maciter use MAC iteration\n"); BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n"); BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n"); BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n"); BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n"); BIO_printf (bio_err, "-keyex set MS key exchange type\n"); BIO_printf (bio_err, "-keysig set MS key signature type\n"); BIO_printf (bio_err, "-password p set import/export password source\n"); BIO_printf (bio_err, "-passin p input file pass phrase source\n"); BIO_printf (bio_err, "-passout p output file pass phrase source\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if(passarg) { if(export_cert) passargout = passarg; else passargin = passarg; } if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if(!cpass) { if(export_cert) cpass = passout; else cpass = passin; } if(cpass) { mpass = cpass; noprompt = 1; } else { cpass = pass; mpass = macpass; } if(export_cert || inrand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ERR_load_crypto_strings(); #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read files"); #endif if (!infile) in = BIO_new_fp(stdin, BIO_NOCLOSE); else in = BIO_new_file(infile, "rb"); if (!in) { BIO_printf(bio_err, "Error opening input file %s\n", infile ? infile : "<stdin>"); perror (infile); goto end; } #if 0 if (certfile) { if(!(certsin = BIO_new_file(certfile, "r"))) { BIO_printf(bio_err, "Can't open certificate file %s\n", certfile); perror (certfile); goto end; } } if (keyname) { if(!(inkey = BIO_new_file(keyname, "r"))) { BIO_printf(bio_err, "Can't key certificate file %s\n", keyname); perror (keyname); goto end; } } #endif #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("write files"); #endif if (!outfile) { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else out = BIO_new_file(outfile, "wb"); if (!out) { BIO_printf(bio_err, "Error opening output file %s\n", outfile ? outfile : "<stdout>"); perror (outfile); goto end; } if (twopass) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read MAC password"); #endif if(EVP_read_pw_string (macpass, sizeof macpass, "Enter MAC Password:"******"Can't read Password\n"); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif } if (export_cert) { EVP_PKEY *key = NULL; STACK_OF(PKCS12_SAFEBAG) *bags = NULL; STACK_OF(PKCS7) *safes = NULL; PKCS12_SAFEBAG *bag = NULL; PKCS8_PRIV_KEY_INFO *p8 = NULL; PKCS7 *authsafe = NULL; X509 *ucert = NULL; STACK_OF(X509) *certs=NULL; char *catmp = NULL; int i; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; #ifdef CRYPTO_MDEBUG CRYPTO_push_info("process -export_cert"); CRYPTO_push_info("reading private key"); #endif key = load_key(bio_err, keyname ? keyname : infile, FORMAT_PEM, 1, passin, e, "private key"); if (!key) { goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from input"); #endif /* Load in all certs in input file */ if(!(certs = load_certs(bio_err, infile, FORMAT_PEM, NULL, e, "certificates"))) { goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from input 2"); #endif for(i = 0; i < sk_X509_num(certs); i++) { ucert = sk_X509_value(certs, i); if(X509_check_private_key(ucert, key)) { X509_digest(ucert, EVP_sha1(), keyid, &keyidlen); break; } } if(!keyidlen) { ucert = NULL; BIO_printf(bio_err, "No certificate matches private key\n"); goto export_end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("reading certs from certfile"); #endif bags = sk_PKCS12_SAFEBAG_new_null (); /* Add any more certificates asked for */ if (certfile) { STACK_OF(X509) *morecerts=NULL; if(!(morecerts = load_certs(bio_err, certfile, FORMAT_PEM, NULL, e, "certificates from certfile"))) { goto export_end; } while(sk_X509_num(morecerts) > 0) { sk_X509_push(certs, sk_X509_shift(morecerts)); } sk_X509_free(morecerts); } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building chain"); #endif /* If chaining get chain from user cert */ if (chain) { int vret; STACK_OF(X509) *chain2; X509_STORE *store = X509_STORE_new(); if (!store) { BIO_printf (bio_err, "Memory allocation error\n"); goto export_end; } if (!X509_STORE_load_locations(store, CAfile, CApath)) X509_STORE_set_default_paths (store); vret = get_cert_chain (ucert, store, &chain2); X509_STORE_free(store); if (!vret) { /* Exclude verified certificate */ for (i = 1; i < sk_X509_num (chain2) ; i++) sk_X509_push(certs, sk_X509_value (chain2, i)); /* Free first certificate */ X509_free(sk_X509_value(chain2, 0)); sk_X509_free(chain2); } else { BIO_printf (bio_err, "Error %s getting chain.\n", X509_verify_cert_error_string(vret)); goto export_end; } } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building bags"); #endif /* We now have loads of certificates: include them all */ for(i = 0; i < sk_X509_num(certs); i++) { X509 *cert = NULL; cert = sk_X509_value(certs, i); bag = PKCS12_x5092certbag(cert); /* If it matches private key set id */ if(cert == ucert) { if(name) PKCS12_add_friendlyname(bag, name, -1); PKCS12_add_localkeyid(bag, keyid, keyidlen); } else if((catmp = sk_shift(canames))) PKCS12_add_friendlyname(bag, catmp, -1); sk_PKCS12_SAFEBAG_push(bags, bag); } sk_X509_pop_free(certs, X509_free); certs = NULL; #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("encrypting bags"); #endif if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Export Password:"******"Can't read Password\n"); goto export_end; } if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); /* Turn certbags into encrypted authsafe */ authsafe = PKCS12_pack_p7encdata(cert_pbe, cpass, -1, NULL, 0, iter, bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; if (!authsafe) { ERR_print_errors (bio_err); goto export_end; } safes = sk_PKCS7_new_null (); sk_PKCS7_push (safes, authsafe); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building shrouded key bag"); #endif /* Make a shrouded key bag */ p8 = EVP_PKEY2PKCS8 (key); if(keytype) PKCS8_add_keyusage(p8, keytype); bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8); PKCS8_PRIV_KEY_INFO_free(p8); p8 = NULL; if (name) PKCS12_add_friendlyname (bag, name, -1); if(csp_name) PKCS12_add_CSPName_asc(bag, csp_name, -1); PKCS12_add_localkeyid (bag, keyid, keyidlen); bags = sk_PKCS12_SAFEBAG_new_null(); sk_PKCS12_SAFEBAG_push (bags, bag); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("encrypting shrouded key bag"); #endif /* Turn it into unencrypted safe bag */ authsafe = PKCS12_pack_p7data (bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = NULL; sk_PKCS7_push (safes, authsafe); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("building pkcs12"); #endif p12 = PKCS12_init(NID_pkcs7_data); PKCS12_pack_authsafes(p12, safes); sk_PKCS7_pop_free(safes, PKCS7_free); safes = NULL; PKCS12_set_mac (p12, mpass, -1, NULL, 0, maciter, NULL); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_push_info("writing pkcs12"); #endif i2d_PKCS12_bio (out, p12); ret = 0; export_end: #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); CRYPTO_pop_info(); CRYPTO_push_info("process -export_cert: freeing"); #endif if (key) EVP_PKEY_free(key); if (certs) sk_X509_pop_free(certs, X509_free); if (safes) sk_PKCS7_pop_free(safes, PKCS7_free); if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif goto end; } if (!(p12 = d2i_PKCS12_bio (in, NULL))) { ERR_print_errors(bio_err); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_push_info("read import password"); #endif if(!noprompt && EVP_read_pw_string(pass, sizeof pass, "Enter Import Password:"******"Can't read Password\n"); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif if (!twopass) BUF_strlcpy(macpass, pass, sizeof macpass); if (options & INFO) BIO_printf (bio_err, "MAC Iteration %ld\n", p12->mac->iter ? ASN1_INTEGER_get (p12->mac->iter) : 1); if(macver) { #ifdef CRYPTO_MDEBUG CRYPTO_push_info("verify MAC"); #endif /* If we enter empty password try no password first */ if(!mpass[0] && PKCS12_verify_mac(p12, NULL, 0)) { /* If mac and crypto pass the same set it to NULL too */ if(!twopass) cpass = NULL; } else if (!PKCS12_verify_mac(p12, mpass, -1)) { BIO_printf (bio_err, "Mac verify error: invalid password?\n"); ERR_print_errors (bio_err); goto end; } BIO_printf (bio_err, "MAC verified OK\n"); #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif } #ifdef CRYPTO_MDEBUG CRYPTO_push_info("output keys and certificates"); #endif if (!dump_certs_keys_p12 (out, p12, cpass, -1, options, passout)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors (bio_err); goto end; } #ifdef CRYPTO_MDEBUG CRYPTO_pop_info(); #endif ret = 0; end: if (p12) PKCS12_free(p12); if(export_cert || inrand) app_RAND_write_file(NULL, bio_err); #ifdef CRYPTO_MDEBUG CRYPTO_remove_all_info(); #endif BIO_free(in); BIO_free_all(out); if (canames) sk_free(canames); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); OPENSSL_EXIT(ret); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL; char *signerfile = NULL, *recipfile = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; const EVP_CIPHER *cipher = NULL; PKCS7 *p7 = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; int badarg = 0; int flags = PKCS7_DETACHED; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-pk7out")) operation = SMIME_PK7OUT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif else if (!strcmp (*args, "-text")) flags |= PKCS7_TEXT; else if (!strcmp (*args, "-nointern")) flags |= PKCS7_NOINTERN; else if (!strcmp (*args, "-noverify")) flags |= PKCS7_NOVERIFY; else if (!strcmp (*args, "-nochain")) flags |= PKCS7_NOCHAIN; else if (!strcmp (*args, "-nocerts")) flags |= PKCS7_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= PKCS7_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~PKCS7_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= PKCS7_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; else if (!strcmp (*args, "-nooldmime")) flags |= PKCS7_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= PKCS7_CRLFEOL; else if (!strcmp(*args,"-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; } #endif else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp (*args, "-to")) { if (args[1]) { args++; to = *args; } else badarg = 1; } else if (!strcmp (*args, "-from")) { if (args[1]) { args++; from = *args; } else badarg = 1; } else if (!strcmp (*args, "-subject")) { if (args[1]) { args++; subject = *args; } else badarg = 1; } else if (!strcmp (*args, "-signer")) { if (args[1]) { args++; signerfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-recip")) { if (args[1]) { args++; recipfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-keyform")) { if (args[1]) { args++; keyform = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-content")) { if (args[1]) { args++; contfile = *args; } else badarg = 1; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else badarg = 1; args++; } if (operation == SMIME_SIGN) { if (!signerfile) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile) { BIO_printf(bio_err, "No recipient certificate and key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-pk7out output PKCS#7 structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (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_SIGN) flags &= ~PKCS7_DETACHED; if (operation & SMIME_OP) { if (flags & PKCS7_BINARY) inmode = "rb"; if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & PKCS7_BINARY) outmode = "wb"; if (informat == FORMAT_ASN1) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_RC2 cipher = EVP_rc2_40_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message is already printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args); #endif goto end; } sk_X509_push(encerts, cert); cert = NULL; args++; } } if (signerfile && (operation == SMIME_SIGN)) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL, e, "signer certificate"))) { #if 0 /* An appropri message has already been printed */ BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile); #endif goto end; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { #if 0 /* An appropriate message has already been printed */ BIO_printf(bio_err, "Can't read certificate file %s\n", certfile); #endif ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message has alrady been printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile); #endif 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(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (operation == SMIME_VERIFY) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb_func(store, smime_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_ENCRYPT) p7 = PKCS7_encrypt(encerts, in, cipher, flags); else if (operation == SMIME_SIGN) { /* If detached data and SMIME output enable partial * signing. */ if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) flags |= PKCS7_STREAM; p7 = PKCS7_sign(signer, key, other, in, flags); /* Don't need to rewind for partial signing */ if (!(flags & PKCS7_STREAM) && (BIO_reset(in) != 0)) { BIO_printf(bio_err, "Can't rewind input file\n"); goto end; } } else { 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"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); 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) SMIME_write_PKCS7(out, p7, in, flags); else if (outformat == FORMAT_PEM) PEM_write_bio_PKCS7(out,p7); else if (outformat == FORMAT_ASN1) i2d_PKCS7_bio(out,p7); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } } ret = 0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); 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); if (passin) OPENSSL_free(passin); return (ret); }
static TS_RESP *create_response(CONF *conf, const char *section, char *engine, char *queryfile, char *passin, char *inkey, char *signer, char *chain, const char *policy) { int ret = 0; TS_RESP *response = NULL; BIO *query_bio = NULL; TS_RESP_CTX *resp_ctx = NULL; if (!(query_bio = BIO_new_file(queryfile, "rb"))) goto end; /* Getting TSA configuration section. */ if (!(section = TS_CONF_get_tsa_section(conf, section))) goto end; /* Setting up response generation context. */ if (!(resp_ctx = TS_RESP_CTX_new())) goto end; /* Setting serial number provider callback. */ if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end; #ifndef OPENSSL_NO_ENGINE /* Setting default OpenSSL engine. */ if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end; #endif /* Setting TSA signer certificate. */ if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end; /* Setting TSA signer certificate chain. */ if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end; /* Setting TSA signer private key. */ if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx)) goto end; /* Setting default policy OID. */ if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end; /* Setting acceptable policy OIDs. */ if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end; /* Setting the acceptable one-way hash algorithms. */ if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end; /* Setting guaranteed time stamp accuracy. */ if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end; /* Setting the precision of the time. */ if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx)) goto end; /* Setting the ordering flaf if requested. */ if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end; /* Setting the TSA name required flag if requested. */ if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end; /* Setting the ESS cert id chain flag if requested. */ if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end; /* Creating the response. */ if (!(response = TS_RESP_create_response(resp_ctx, query_bio))) goto end; ret = 1; end: if (!ret) { TS_RESP_free(response); response = NULL; } TS_RESP_CTX_free(resp_ctx); BIO_free_all(query_bio); return response; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; BIO *in = NULL, *out = NULL; char *infile = NULL, *outfile = NULL; # ifndef OPENSSL_NO_ENGINE char *engine = NULL; # endif char *keyfile = NULL; char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; int keyform = FORMAT_PEM; char need_priv = 0, badarg = 0, rev = 0; char hexdump = 0, asn1parse = 0; X509 *x; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; char *passargin = NULL, *passin = NULL; int rsa_inlen, rsa_outlen = 0; int keysize; int ret = 1; argc--; argv++; if (!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); pad = RSA_PKCS1_PADDING; while (argc >= 1) { if (!strcmp(*argv, "-in")) { if (--argc < 1) badarg = 1; else infile = *(++argv); } else if (!strcmp(*argv, "-out")) { if (--argc < 1) badarg = 1; else outfile = *(++argv); } else if (!strcmp(*argv, "-inkey")) { if (--argc < 1) badarg = 1; else keyfile = *(++argv); } else if (!strcmp(*argv, "-passin")) { if (--argc < 1) badarg = 1; else passargin = *(++argv); } else if (strcmp(*argv, "-keyform") == 0) { if (--argc < 1) badarg = 1; else keyform = str2fmt(*(++argv)); # ifndef OPENSSL_NO_ENGINE } else if (!strcmp(*argv, "-engine")) { if (--argc < 1) badarg = 1; else engine = *(++argv); # endif } else if (!strcmp(*argv, "-pubin")) { key_type = KEY_PUBKEY; } else if (!strcmp(*argv, "-certin")) { key_type = KEY_CERT; } else if (!strcmp(*argv, "-asn1parse")) asn1parse = 1; else if (!strcmp(*argv, "-hexdump")) hexdump = 1; else if (!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; else if (!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; else if (!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; else if (!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; else if (!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING; else if (!strcmp(*argv, "-sign")) { rsa_mode = RSA_SIGN; need_priv = 1; } else if (!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; else if (!strcmp(*argv, "-rev")) rev = 1; else if (!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; else if (!strcmp(*argv, "-decrypt")) { rsa_mode = RSA_DECRYPT; need_priv = 1; } else badarg = 1; if (badarg) { usage(); goto end; } argc--; argv++; } if (need_priv && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } # ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); # endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } /* FIXME: seed PRNG only if needed */ app_RAND_load_file(NULL, bio_err, 0); switch (key_type) { case KEY_PRIVKEY: pkey = load_key(bio_err, keyfile, keyform, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, e, "Public Key"); break; case KEY_CERT: x = load_cert(bio_err, keyfile, keyform, 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; } if (infile) { if (!(in = BIO_new_file(infile, "rb"))) { BIO_printf(bio_err, "Error Reading Input File\n"); ERR_print_errors(bio_err); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Error Reading Output File\n"); ERR_print_errors(bio_err); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); # ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } # endif } keysize = RSA_size(rsa); rsa_in = OPENSSL_malloc(keysize * 2); rsa_out = OPENSSL_malloc(keysize); /* 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"); exit(1); } 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); if (rsa_in) OPENSSL_free(rsa_in); if (rsa_out) OPENSSL_free(rsa_out); if (passin) OPENSSL_free(passin); return ret; }
static EVP_PKEY *tpm_engine_load_key(ENGINE *e, const char *key_id, UI_METHOD *ui, void *cb_data) { ASN1_OCTET_STRING *blobstr; TSS_HKEY hKey; TSS_RESULT result; UINT32 authusage; RSA *rsa; EVP_PKEY *pkey; BIO *bf; DBG("%s", __FUNCTION__); if (!key_id) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_PASSED_NULL_PARAMETER); return NULL; } if (!tpm_load_srk(ui, cb_data)) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_SRK_LOAD_FAILED); return NULL; } if ((bf = BIO_new_file(key_id, "r")) == NULL) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_FILE_NOT_FOUND); return NULL; } blobstr = PEM_ASN1_read_bio((void *)d2i_ASN1_OCTET_STRING, "TSS KEY BLOB", bf, NULL, NULL, NULL); if (!blobstr) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_FILE_READ_FAILED); BIO_free(bf); return NULL; } BIO_free(bf); DBG("Loading blob of size: %d", blobstr->length); if ((result = Tspi_Context_LoadKeyByBlob(hContext, hSRK, blobstr->length, blobstr->data, &hKey))) { TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } ASN1_OCTET_STRING_free(blobstr); if ((result = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &authusage))) { Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } if (authusage) { TSS_HPOLICY hPolicy; BYTE *auth; if ((auth = calloc(1, 128)) == NULL) { Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); return NULL; } if (!tpm_engine_get_auth(ui, (char *)auth, 128, "TPM Key Password: ", cb_data)) { Tspi_Context_CloseObject(hContext, hKey); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } if ((result = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, TSS_POLICY_USAGE, &hPolicy))) { Tspi_Context_CloseObject(hContext, hKey); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return 0; } if ((result = Tspi_Policy_AssignToObject(hPolicy, hKey))) { Tspi_Context_CloseObject(hContext, hKey); Tspi_Context_CloseObject(hContext, hPolicy); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return 0; } if ((result = Tspi_Policy_SetSecret(hPolicy, TSS_SECRET_MODE_PLAIN, strlen((char *)auth), auth))) { Tspi_Context_CloseObject(hContext, hKey); Tspi_Context_CloseObject(hContext, hPolicy); free(auth); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return 0; } free(auth); } /* create the new objects to return */ if ((pkey = EVP_PKEY_new()) == NULL) { Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); return NULL; } pkey->type = EVP_PKEY_RSA; if ((rsa = RSA_new()) == NULL) { EVP_PKEY_free(pkey); Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, ERR_R_MALLOC_FAILURE); return NULL; } rsa->meth = &tpm_rsa; /* call our local init function here */ rsa->meth->init(rsa); pkey->pkey.rsa = rsa; if (!fill_out_rsa_object(rsa, hKey)) { EVP_PKEY_free(pkey); RSA_free(rsa); Tspi_Context_CloseObject(hContext, hKey); TSSerr(TPM_F_TPM_ENGINE_LOAD_KEY, TPM_R_REQUEST_FAILED); return NULL; } EVP_PKEY_assign_RSA(pkey, rsa); return pkey; }
// Save the RSA key as a PKCS#8 file int save_rsa_pkcs8(char* out_path, char* file_pin, key_material_t* pkey) { RSA* rsa = NULL; EVP_PKEY* ossl_pkey = NULL; PKCS8_PRIV_KEY_INFO* p8inf = NULL; BIO* out = NULL; X509_SIG* p8 = NULL; int result = 0; // See if the key material was found. if ( pkey[TAG_MODULUS].size <= 0 || pkey[TAG_PUBEXP].size <= 0 || pkey[TAG_PRIVEXP].size <= 0 || pkey[TAG_PRIME1].size <= 0 || pkey[TAG_PRIME2].size <= 0 || pkey[TAG_EXP1].size <= 0 || pkey[TAG_EXP2].size <= 0 || pkey[TAG_COEFF].size <= 0 ) { fprintf(stderr, "ERROR: Some parts of the key material is missing in the input file.\n"); return 1; } rsa = RSA_new(); rsa->p = BN_bin2bn((unsigned char*)pkey[TAG_PRIME1].big, pkey[TAG_PRIME1].size, NULL); rsa->q = BN_bin2bn((unsigned char*)pkey[TAG_PRIME2].big, pkey[TAG_PRIME2].size, NULL); rsa->d = BN_bin2bn((unsigned char*)pkey[TAG_PRIVEXP].big, pkey[TAG_PRIVEXP].size, NULL); rsa->n = BN_bin2bn((unsigned char*)pkey[TAG_MODULUS].big, pkey[TAG_MODULUS].size, NULL); rsa->e = BN_bin2bn((unsigned char*)pkey[TAG_PUBEXP].big, pkey[TAG_PUBEXP].size, NULL); rsa->dmp1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP1].big, pkey[TAG_EXP1].size, NULL); rsa->dmq1 = BN_bin2bn((unsigned char*)pkey[TAG_EXP2].big, pkey[TAG_EXP2].size, NULL); rsa->iqmp = BN_bin2bn((unsigned char*)pkey[TAG_COEFF].big, pkey[TAG_COEFF].size, NULL); ossl_pkey = EVP_PKEY_new(); // Convert RSA to EVP_PKEY if (!EVP_PKEY_set1_RSA(ossl_pkey, rsa)) { fprintf(stderr, "ERROR: Could not convert RSA key to EVP_PKEY.\n"); RSA_free(rsa); EVP_PKEY_free(ossl_pkey); return 1; } RSA_free(rsa); // Convert EVP_PKEY to PKCS#8 if (!(p8inf = EVP_PKEY2PKCS8(ossl_pkey))) { fprintf(stderr, "ERROR: Could not convert EVP_PKEY to PKCS#8.\n"); EVP_PKEY_free(ossl_pkey); return 1; } EVP_PKEY_free(ossl_pkey); // Open output file if (!(out = BIO_new_file (out_path, "wb"))) { fprintf(stderr, "ERROR: Could not open the output file.\n"); PKCS8_PRIV_KEY_INFO_free(p8inf); return 1; } // Write to disk if (file_pin == NULL) { PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); printf("The key has been written to %s\n", out_path); } else { // Encrypt p8 if (!(p8 = PKCS8_encrypt(NID_pbeWithMD5AndDES_CBC, NULL, file_pin, strlen(file_pin), NULL, 0, PKCS12_DEFAULT_ITER, p8inf))) { fprintf(stderr, "ERROR: Could not encrypt the PKCS#8 file\n"); result = 1; } else { PEM_write_bio_PKCS8(out, p8); X509_SIG_free(p8); printf("The key has been written to %s\n", out_path); } } PKCS8_PRIV_KEY_INFO_free(p8inf); BIO_free_all(out); return result; }
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; 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_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 (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, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT); 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 (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_sha256(); 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 main(int argc, char **argv) { BIO* in=NULL; BIO* out=NULL; char * outfile = NULL; char * infile = NULL ; int tabLength=100; char *binaryptr; char* mimetype; char* mimetypeaccept=NULL; char* contenttype; char** pp; unsigned char* hostporturl = NULL; binaryptr=(char*)malloc(tabLength); BIO * p12bio ; char **args = argv + 1; unsigned char * serverurl; sslctxparm p; char *response; p.verbose = 0; CURLcode res; struct curl_slist * headers=NULL; p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE); curl_global_init(CURL_GLOBAL_DEFAULT); /* we need some more for the P12 decoding */ OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); ERR_load_crypto_strings(); int badarg=0; while (*args && *args[0] == '-') { if (!strcmp (*args, "-in")) { if (args[1]) { infile=*(++args); } else badarg=1; } else if (!strcmp (*args, "-out")) { if (args[1]) { outfile=*(++args); } else badarg=1; } else if (!strcmp (*args, "-p12")) { if (args[1]) { p.p12file = *(++args); } else badarg=1; } else if (strcmp(*args,"-envpass") == 0) { if (args[1]) { p.pst = getenv(*(++args)); } else badarg=1; } else if (strcmp(*args,"-connect") == 0) { if (args[1]) { hostporturl = *(++args); } else badarg=1; } else if (strcmp(*args,"-mimetype") == 0) { if (args[1]) { mimetype = *(++args); } else badarg=1; } else if (strcmp(*args,"-acceptmime") == 0) { if (args[1]) { mimetypeaccept = *(++args); } else badarg=1; } else if (strcmp(*args,"-accesstype") == 0) { if (args[1]) { if ((p.accesstype = OBJ_obj2nid(OBJ_txt2obj(*++args,0))) == 0) badarg=1; } else badarg=1; } else if (strcmp(*args,"-verbose") == 0) { p.verbose++; } else badarg=1; args++; } if (mimetype==NULL || mimetypeaccept == NULL) badarg = 1; if (badarg) { for (pp=curlx_usage; (*pp != NULL); pp++) BIO_printf(p.errorbio,"%s\n",*pp); BIO_printf(p.errorbio,"\n"); goto err; } /* set input */ if ((in=BIO_new(BIO_s_file())) == NULL) { BIO_printf(p.errorbio, "Error setting input bio\n"); goto err; } else if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE|BIO_FP_TEXT); else if (BIO_read_filename(in,infile) <= 0) { BIO_printf(p.errorbio, "Error opening input file %s\n", infile); BIO_free(in); goto err; } /* set output */ if ((out=BIO_new(BIO_s_file())) == NULL) { BIO_printf(p.errorbio, "Error setting output bio.\n"); goto err; } else if (outfile == NULL) BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); else if (BIO_write_filename(out,outfile) <= 0) { BIO_printf(p.errorbio, "Error opening output file %s\n", outfile); BIO_free(out); goto err; } p.errorbio = BIO_new_fp (stderr, BIO_NOCLOSE); if (!(p.curl = curl_easy_init())) { BIO_printf(p.errorbio, "Cannot init curl lib\n"); goto err; } if (!(p12bio = BIO_new_file(p.p12file , "rb"))) { BIO_printf(p.errorbio, "Error opening P12 file %s\n", p.p12file); goto err; } if (!(p.p12 = d2i_PKCS12_bio (p12bio, NULL))) { BIO_printf(p.errorbio, "Cannot decode P12 structure %s\n", p.p12file); goto err; } p.ca= NULL; if (!(PKCS12_parse (p.p12, p.pst, &(p.pkey), &(p.usercert), &(p.ca) ) )) { BIO_printf(p.errorbio,"Invalid P12 structure in %s\n", p.p12file); goto err; } if (sk_X509_num(p.ca) <= 0) { BIO_printf(p.errorbio,"No trustworthy CA given.%s\n", p.p12file); goto err; } if (p.verbose > 1) X509_print_ex(p.errorbio,p.usercert,0,0); /* determine URL to go */ if (hostporturl) { serverurl=(char*) malloc(9+strlen(hostporturl)); sprintf(serverurl,"https://%s",hostporturl); } else if (p.accesstype != 0) { /* see whether we can find an AIA or SIA for a given access type */ if (!(serverurl = my_get_ext(p.usercert,p.accesstype,NID_info_access))) { BIO_printf(p.errorbio,"no service URL in user cert " "cherching in others certificats\n"); int j=0; int find=0; for (j=0;j<sk_X509_num(p.ca);j++) { if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype, NID_info_access))) break; if ((serverurl = my_get_ext(sk_X509_value(p.ca,j),p.accesstype, NID_sinfo_access))) break; } } } if (!serverurl) { BIO_printf(p.errorbio, "no service URL in certificats," " check '-accesstype (AD_DVCS | ad_timestamping)'" " or use '-connect'\n"); goto err; } if (p.verbose) BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl); curl_easy_setopt(p.curl, CURLOPT_URL, serverurl); /* Now specify the POST binary data */ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,tabLength); /* pass our list of custom made headers */ contenttype=(char*) malloc(15+strlen(mimetype)); sprintf(contenttype,"Content-type: %s",mimetype); headers = curl_slist_append(headers,contenttype); curl_easy_setopt(p.curl, CURLOPT_HTTPHEADER, headers); if (p.verbose) BIO_printf(p.errorbio, "Service URL: <%s>\n", serverurl); { FILE *outfp; BIO_get_fp(out,&outfp); curl_easy_setopt(p.curl, CURLOPT_FILE,outfp); } res = curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun) ; if (res != CURLE_OK) BIO_printf(p.errorbio,"%d %s=%d %d\n", __LINE__, "CURLOPT_SSL_CTX_FUNCTION",CURLOPT_SSL_CTX_FUNCTION,res); curl_easy_setopt(p.curl, CURLOPT_SSL_CTX_DATA, &p); { int lu; int i=0; while ((lu = BIO_read (in,&binaryptr[i],tabLength-i)) >0 ) { i+=lu; if (i== tabLength) { tabLength+=100; binaryptr=(char*)realloc(binaryptr,tabLength); /* should be more careful */ } } tabLength = i; } /* Now specify the POST binary data */ curl_easy_setopt(p.curl, CURLOPT_POSTFIELDS, binaryptr); curl_easy_setopt(p.curl, CURLOPT_POSTFIELDSIZE,tabLength); /* Perform the request, res will get the return code */ BIO_printf(p.errorbio,"%d %s %d\n", __LINE__, "curl_easy_perform", res = curl_easy_perform(p.curl)); { int result =curl_easy_getinfo(p.curl,CURLINFO_CONTENT_TYPE,&response); if( mimetypeaccept && p.verbose) if(!strcmp(mimetypeaccept,response)) BIO_printf(p.errorbio,"the response has a correct mimetype : %s\n", response); else BIO_printf(p.errorbio,"the reponse doesn\'t has an acceptable " "mime type, it is %s instead of %s\n", response,mimetypeaccept); } /*** code d'erreur si accept mime ***, egalement code return HTTP != 200 ***/ /* free the header list*/ curl_slist_free_all(headers); /* always cleanup */ curl_easy_cleanup(p.curl); BIO_free(in); BIO_free(out); return (EXIT_SUCCESS); err: BIO_printf(p.errorbio,"error"); exit(1); }
void LFNetConfigLoader::retrieveConfig() { this->notifyStatus("Loading OpenSSL stuff ..."); OpenSSL_add_all_algorithms(); ERR_load_BIO_strings(); ERR_load_crypto_strings(); this->notifyStatus("Generating private key ..."); BIGNUM* e = BN_new(); BN_set_word(e, RSA_F4); RSA* key = RSA_new(); RSA_generate_key_ex(key, 4096, e, NULL); this->notifyStatus("Saving private key ..."); BIO* privateKey = BIO_new_file((_configLocation + "/private.key").toLocal8Bit().data(), "w"); PEM_write_bio_RSAPrivateKey(privateKey, key, NULL, NULL, 0, NULL, NULL); BIO_free(privateKey); this->notifyStatus("Generating csr ..."); EVP_PKEY* pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, key); X509_NAME* name = X509_NAME_new(); X509_NAME_add_entry_by_txt(name, "O", MBSTRING_UTF8, (unsigned char*)"LF-Net", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8, (unsigned char*)"VPN", -1, -1, 0); X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (unsigned char*)(_username.toUpper() + "_" + _computerName.toUpper()).toUtf8().data(), -1, -1, 0); X509_REQ* req = X509_REQ_new(); X509_REQ_set_pubkey(req, pkey); X509_REQ_set_subject_name(req, name); X509_REQ_set_version(req, 1); X509_REQ_sign(req, pkey, EVP_sha512()); BIO* request = BIO_new(BIO_s_mem()); PEM_write_bio_X509_REQ(request, req); BUF_MEM* requestData; BIO_get_mem_ptr(request, &requestData); this->notifyStatus("Request certificate using generated csr ..."); QNetworkAccessManager *mgr = new QNetworkAccessManager(this); connect(mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(certificateRequestFinished(QNetworkReply*))); connect(mgr, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*))); QNetworkRequest netRequest(QUrl("https://mokoscha.lf-net.org/request_certificate")); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain"); mgr->post(netRequest, QByteArray(requestData->data, requestData->length)); this->notifyStatus("Cleaning up temporary data ..."); BIO_free(request); X509_REQ_free(req); X509_NAME_free(name); EVP_PKEY_free(pkey); BN_free(e); this->notifyStatus("Waiting for certificate ..."); }
BOOL tls_accept(rdpTls* tls, BIO* underlying, rdpSettings *settings) { long options = 0; BIO *bio; RSA *rsa; X509 *x509; /** * SSL_OP_NO_SSLv2: * * We only want SSLv3 and TLSv1, so disable SSLv2. * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. */ options |= SSL_OP_NO_SSLv2; /** * SSL_OP_NO_COMPRESSION: * * The Microsoft RDP server does not advertise support * for TLS compression, but alternative servers may support it. * This was observed between early versions of the FreeRDP server * and the FreeRDP client, and caused major performance issues, * which is why we're disabling it. */ #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #endif /** * SSL_OP_TLS_BLOCK_PADDING_BUG: * * The Microsoft RDP server does *not* support TLS padding. * It absolutely needs to be disabled otherwise it won't work. */ options |= SSL_OP_TLS_BLOCK_PADDING_BUG; /** * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: * * Just like TLS padding, the Microsoft RDP server does not * support empty fragments. This needs to be disabled. */ options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (!tls_prepare(tls, underlying, SSLv23_server_method(), options, FALSE)) return FALSE; if (settings->PrivateKeyFile) { bio = BIO_new_file(settings->PrivateKeyFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for private key %s", settings->PrivateKeyFile); return FALSE; } } else if (settings->PrivateKeyContent) { bio = BIO_new_mem_buf(settings->PrivateKeyContent, strlen(settings->PrivateKeyContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for private key"); return FALSE; } } else { WLog_ERR(TAG, "no private key defined"); return FALSE; } rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!rsa) { WLog_ERR(TAG, "invalid private key"); return FALSE; } if (SSL_use_RSAPrivateKey(tls->ssl, rsa) <= 0) { WLog_ERR(TAG, "SSL_CTX_use_RSAPrivateKey_file failed"); RSA_free(rsa); return FALSE; } if (settings->CertificateFile) { bio = BIO_new_file(settings->CertificateFile, "rb+"); if (!bio) { WLog_ERR(TAG, "BIO_new_file failed for certificate %s", settings->CertificateFile); return FALSE; } } else if (settings->CertificateContent) { bio = BIO_new_mem_buf(settings->CertificateContent, strlen(settings->CertificateContent)); if (!bio) { WLog_ERR(TAG, "BIO_new_mem_buf failed for certificate"); return FALSE; } } else { WLog_ERR(TAG, "no certificate defined"); return FALSE; } x509 = PEM_read_bio_X509(bio, NULL, NULL, 0); BIO_free(bio); if (!x509) { WLog_ERR(TAG, "invalid certificate"); return FALSE; } if (SSL_use_certificate(tls->ssl, x509) <= 0) { WLog_ERR(TAG, "SSL_use_certificate_file failed"); X509_free(x509); return FALSE; } #ifndef OPENSSL_NO_TLSEXT /** * The Microsoft iOS clients eventually send a null or even double null * terminated hostname in the SNI TLS extension! * If the length indicator does not equal the hostname strlen OpenSSL * will abort (see openssl:ssl/t1_lib.c). * Here is a tcpdump segment of Microsoft Remote Desktop Client Version * 8.1.7 running on an iPhone 4 with iOS 7.1.2 showing the transmitted * SNI hostname TLV blob when connection to server "abcd": * 00 name_type 0x00 (host_name) * 00 06 length_in_bytes 0x0006 * 61 62 63 64 00 00 host_name "abcd\0\0" * * Currently the only (runtime) workaround is setting an openssl tls * extension debug callback that sets the SSL context's servername_done * to 1 which effectively disables the parsing of that extension type. */ SSL_set_tlsext_debug_callback(tls->ssl, tls_openssl_tlsext_debug_callback); #endif return tls_do_handshake(tls, FALSE) > 0; }
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) { int st; BIO* bp; EVP_PKEY* pk; int pktype; _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Computing public key from private key file: %s", privatekey); bp = BIO_new_file(privatekey, "r"); if(bp == NULL) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key from private key " "file: Unable to open private key file"); } BIO_reset(bp); pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase); BIO_free(bp); if(pk == NULL) { return _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key file: " "Wrong passphrase or invalid/unrecognized " "private key file format"); } #ifdef HAVE_OPAQUE_STRUCTS pktype = EVP_PKEY_id(pk); #else pktype = pk->type; #endif switch(pktype) { case EVP_PKEY_RSA : st = gen_publickey_from_rsa_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #if LIBSSH2_DSA case EVP_PKEY_DSA : st = gen_publickey_from_dsa_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif /* LIBSSH_DSA */ #if LIBSSH2_ECDSA case EVP_PKEY_EC : st = gen_publickey_from_ec_evp( session, method, method_len, pubkeydata, pubkeydata_len, pk); break; #endif default : st = _libssh2_error(session, LIBSSH2_ERROR_FILE, "Unable to extract public key " "from private key file: " "Unsupported private key file format"); break; } EVP_PKEY_free(pk); return st; }
int main(int argv, char** args) { if(argv < 2) { printf("podales za malo argumentow( argument 1 - plik podpisywany\n"); exit(1); } // inicjalizacja: int n; MD5_CTX md5_ctx; unsigned char* signature_bufor; unsigned char* binary_key; unsigned char hash_bufor[128]; unsigned char hash[16]; const unsigned char *p; BIO *in; char error_buf[122]; int error; printf("tworzenie struktury dsa... "); RSA* rsa = NULL;// = NULL; //DSA_new(); // inicjalizacja struktury dsa error = ERR_get_error(); if(error)printf("wystapil blad nr %d\n",error); else printf("OK\n"); // odczyt pliku z kluczem prywatnym printf("otwarcie pliku z kluczem prywatnym... "); in = BIO_new_file("priv_key.rsa", "rb"); if(!in) printf("wystaplil blad w otwieraniu pliku\n"); else printf("OK\n"); int key_size = fileSize(in); printf("rozmiar otworzonego pliku: %d\n",key_size); printf("odczyt klucza z pliku priv_key.rsa... "); binary_key = OPENSSL_malloc(key_size); BIO_read(in, binary_key, key_size); int i; // printf("tak wyglada otwarty klucz: "); // printf("\n"); for(i = 0 ; i < key_size ; ++i) printf("%c",binary_key[i]); printf("\n"); error = ERR_get_error(); if(error)printf("wystapil blad nr %d\n",error); else printf("OK\n"); printf("tworzenie struktury rsa na podstawie klucza...OK\n"); p = binary_key; d2i_RSAPrivateKey(&rsa, &p, key_size); if(rsa == NULL) printf("blad w tworzeniu struktury dsa\n"); BIO_free(in); // tworzenie hashu pliku z wiadomoscia printf("otwarcie pliku z wiadomoscia... "); in = BIO_new_file(args[1],"r"); if(!in) printf("wystaplil blad w otwieraniu pliku\n"); else printf("OK\n"); int file_size = fileSize(in); printf("rozmiar otworzonego pliku: %d\n",file_size); printf("tworzenie hashu pliku z wiadomoscia... "); MD5_Init(&md5_ctx); while ((n = BIO_read(in, hash_bufor, sizeof(hash_bufor)))>0) MD5_Update(&md5_ctx, hash_bufor, n); MD5_Final(hash, &md5_ctx); printf("OK\n"); printf("tak wyglada hash pliku:\n"); for(n = 0; n < sizeof(hash); n++) printf("%02x ", hash[n]); printf("\n"); // podpisywanie pliku printf("podpisywanie pliku... "); signature_bufor = OPENSSL_malloc(RSA_size(rsa)); //(unsigned char*)malloc(DSA_size(dsa)); int signature_size; // printf("wielkosc hashu: %d\n",sizeof(hash_md5)); RSA_sign(NID_md5, hash, sizeof(hash), signature_bufor, &signature_size, rsa); error = ERR_get_error(); if(error)printf("wystapil blad nr %d\n",error); else printf("OK\n"); printf("rozmiar sygnatury: %d\n",signature_size); printf("tworzenie pliku z podpisem... "); BIO* out = BIO_new_file("signature","wb"); BIO_write(out,signature_bufor,signature_size); if(!in) printf("wystaplil blad w otwieraniu pliku\n"); else printf("OK\n"); // sprzatamy printf("zwalnianie pamieci po strukturze dsa... "); RSA_free(rsa); // czyscimy pamiec po strukturze dsa error = ERR_get_error(); if(error)printf("wystapil blad nr %d\n",error); else printf("OK\n"); return 0; }
static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, char *queryfile, char *CApath, char *CAfile, char *untrusted, X509_VERIFY_PARAM *vpm) { TS_VERIFY_CTX *ctx = NULL; BIO *input = NULL; TS_REQ *request = NULL; int ret = 0; int f = 0; if (data != NULL || digest != NULL) { if ((ctx = TS_VERIFY_CTX_new()) == NULL) goto err; f = TS_VFY_VERSION | TS_VFY_SIGNER; if (data != NULL) { f |= TS_VFY_DATA; if (TS_VERIFY_CTX_set_data(ctx, BIO_new_file(data, "rb")) == NULL) goto err; } else if (digest != NULL) { long imprint_len; unsigned char *hexstr = string_to_hex(digest, &imprint_len); f |= TS_VFY_IMPRINT; if (TS_VERIFY_CTX_set_imprint(ctx, hexstr, imprint_len) == NULL) { BIO_printf(bio_err, "invalid digest string\n"); goto err; } } } else if (queryfile != NULL) { if ((input = BIO_new_file(queryfile, "rb")) == NULL) goto err; if ((request = d2i_TS_REQ_bio(input, NULL)) == NULL) goto err; if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL) goto err; } else return NULL; /* Add the signature verification flag and arguments. */ TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE); /* Initialising the X509_STORE object. */ if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm)) == NULL) goto err; /* Loading untrusted certificates. */ if (untrusted && TS_VERIFY_CTS_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL) goto err; ret = 1; err: if (!ret) { TS_VERIFY_CTX_free(ctx); ctx = NULL; } BIO_free_all(input); TS_REQ_free(request); return ctx; }
int MAIN(int argc, char **argv) { char **args, *infile = NULL, *outfile = NULL; BIO *in = NULL, *out = NULL; int text = 0, noout = 0; EVP_PKEY *pkey=NULL; int badarg = 0; #ifndef OPENSSL_NO_ENGINE ENGINE *e = NULL; char *engine=NULL; #endif int ret = 1; if (bio_err == NULL) bio_err = BIO_new_fp (OPENSSL_TYPE__FILE_STDERR, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); args = argv + 1; while (!badarg && *args && *args[0] == '-') { if (!TINYCLR_SSL_STRCMP (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!TINYCLR_SSL_STRCMP (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } #ifndef OPENSSL_NO_ENGINE else if (TINYCLR_SSL_STRCMP(*args,"-engine") == 0) { if (!args[1]) goto bad; engine= *(++args); } #endif else if (TINYCLR_SSL_STRCMP(*args,"-text") == 0) text=1; else if (TINYCLR_SSL_STRCMP(*args,"-noout") == 0) noout=1; args++; } if (badarg) { #ifndef OPENSSL_NO_ENGINE bad: #endif BIO_printf(bio_err, "Usage pkeyparam [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-in file input file\n"); BIO_printf(bio_err, "-out file output file\n"); BIO_printf(bio_err, "-text print parameters as text\n"); BIO_printf(bio_err, "-noout don't output encoded parameters\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif return 1; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (infile) { if (!(in = BIO_new_file (infile, "r"))) { BIO_printf(bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp (OPENSSL_TYPE__FILE_STDIN, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file (outfile, "w"))) { BIO_printf(bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp (OPENSSL_TYPE__FILE_STDOUT, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } 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 ocsp_main(int argc, char **argv) { char **args; char *host = NULL, *port = NULL, *path = "/"; char *reqin = NULL, *respin = NULL; char *reqout = NULL, *respout = NULL; char *signfile = NULL, *keyfile = NULL; char *rsignfile = NULL, *rkeyfile = NULL; char *outfile = NULL; int add_nonce = 1, noverify = 0, use_ssl = -1; STACK_OF(CONF_VALUE) * headers = NULL; OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; OCSP_BASICRESP *bs = NULL; X509 *issuer = NULL, *cert = NULL; X509 *signer = NULL, *rsigner = NULL; EVP_PKEY *key = NULL, *rkey = NULL; BIO *acbio = NULL, *cbio = NULL; BIO *derbio = NULL; BIO *out = NULL; int req_timeout = -1; int req_text = 0, resp_text = 0; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; char *CAfile = NULL, *CApath = NULL; X509_STORE *store = NULL; STACK_OF(X509) * sign_other = NULL, *verify_other = NULL, *rother = NULL; char *sign_certfile = NULL, *verify_certfile = NULL, *rcertfile = NULL; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; int ret = 1; int accept_count = -1; int badarg = 0; int i; int ignore_err = 0; STACK_OF(OPENSSL_STRING) * reqnames = NULL; STACK_OF(OCSP_CERTID) * ids = NULL; X509 *rca_cert = NULL; char *ridx_filename = NULL; char *rca_filename = NULL; CA_DB *rdb = NULL; int nmin = 0, ndays = -1; const EVP_MD *cert_id_md = NULL; const char *errstr = NULL; args = argv + 1; reqnames = sk_OPENSSL_STRING_new_null(); ids = sk_OCSP_CERTID_new_null(); while (!badarg && *args && *args[0] == '-') { if (!strcmp(*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-timeout")) { if (args[1]) { args++; req_timeout = strtonum(*args, 0, INT_MAX, &errstr); if (errstr) { BIO_printf(bio_err, "Illegal timeout value %s: %s\n", *args, errstr); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-url")) { if (args[1]) { args++; if (!OCSP_parse_url(*args, &host, &port, &path, &use_ssl)) { BIO_printf(bio_err, "Error parsing URL\n"); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-host")) { if (args[1]) { args++; host = *args; } else badarg = 1; } else if (!strcmp(*args, "-port")) { if (args[1]) { args++; port = *args; } else badarg = 1; } else if (!strcmp(*args, "-header")) { if (args[1] && args[2]) { if (!X509V3_add_value(args[1], args[2], &headers)) goto end; args += 2; } else badarg = 1; } else if (!strcmp(*args, "-ignore_err")) ignore_err = 1; else if (!strcmp(*args, "-noverify")) noverify = 1; else if (!strcmp(*args, "-nonce")) add_nonce = 2; else if (!strcmp(*args, "-no_nonce")) add_nonce = 0; else if (!strcmp(*args, "-resp_no_certs")) rflags |= OCSP_NOCERTS; else if (!strcmp(*args, "-resp_key_id")) rflags |= OCSP_RESPID_KEY; else if (!strcmp(*args, "-no_certs")) sign_flags |= OCSP_NOCERTS; else if (!strcmp(*args, "-no_signature_verify")) verify_flags |= OCSP_NOSIGS; else if (!strcmp(*args, "-no_cert_verify")) verify_flags |= OCSP_NOVERIFY; else if (!strcmp(*args, "-no_chain")) verify_flags |= OCSP_NOCHAIN; else if (!strcmp(*args, "-no_cert_checks")) verify_flags |= OCSP_NOCHECKS; else if (!strcmp(*args, "-no_explicit")) verify_flags |= OCSP_NOEXPLICIT; else if (!strcmp(*args, "-trust_other")) verify_flags |= OCSP_TRUSTOTHER; else if (!strcmp(*args, "-no_intern")) verify_flags |= OCSP_NOINTERN; else if (!strcmp(*args, "-text")) { req_text = 1; resp_text = 1; } else if (!strcmp(*args, "-req_text")) req_text = 1; else if (!strcmp(*args, "-resp_text")) resp_text = 1; else if (!strcmp(*args, "-reqin")) { if (args[1]) { args++; reqin = *args; } else badarg = 1; } else if (!strcmp(*args, "-respin")) { if (args[1]) { args++; respin = *args; } else badarg = 1; } else if (!strcmp(*args, "-signer")) { if (args[1]) { args++; signfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-VAfile")) { if (args[1]) { args++; verify_certfile = *args; verify_flags |= OCSP_TRUSTOTHER; } else badarg = 1; } else if (!strcmp(*args, "-sign_other")) { if (args[1]) { args++; sign_certfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-verify_other")) { if (args[1]) { args++; verify_certfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp(*args, "-validity_period")) { if (args[1]) { args++; nsec = strtonum(*args, 0, LONG_MAX, &errstr); if (errstr) { BIO_printf(bio_err, "Illegal validity period %s: %s\n", *args, errstr); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-status_age")) { if (args[1]) { args++; maxage = strtonum(*args, 0, LONG_MAX, &errstr); if (errstr) { BIO_printf(bio_err, "Illegal validity age %s: %s\n", *args, errstr); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-signkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-reqout")) { if (args[1]) { args++; reqout = *args; } else badarg = 1; } else if (!strcmp(*args, "-respout")) { if (args[1]) { args++; respout = *args; } else badarg = 1; } else if (!strcmp(*args, "-path")) { if (args[1]) { args++; path = *args; } else badarg = 1; } else if (!strcmp(*args, "-issuer")) { if (args[1]) { args++; X509_free(issuer); issuer = load_cert(bio_err, *args, FORMAT_PEM, NULL, "issuer certificate"); if (!issuer) goto end; } else badarg = 1; } else if (!strcmp(*args, "-cert")) { if (args[1]) { args++; X509_free(cert); cert = load_cert(bio_err, *args, FORMAT_PEM, NULL, "certificate"); if (!cert) goto end; if (!cert_id_md) cert_id_md = EVP_sha1(); if (!add_ocsp_cert(&req, cert, cert_id_md, issuer, ids)) goto end; if (!sk_OPENSSL_STRING_push(reqnames, *args)) goto end; } else badarg = 1; } else if (!strcmp(*args, "-serial")) { if (args[1]) { args++; if (!cert_id_md) cert_id_md = EVP_sha1(); if (!add_ocsp_serial(&req, *args, cert_id_md, issuer, ids)) goto end; if (!sk_OPENSSL_STRING_push(reqnames, *args)) goto end; } else badarg = 1; } else if (!strcmp(*args, "-index")) { if (args[1]) { args++; ridx_filename = *args; } else badarg = 1; } else if (!strcmp(*args, "-CA")) { if (args[1]) { args++; rca_filename = *args; } else badarg = 1; } else if (!strcmp(*args, "-nmin")) { if (args[1]) { args++; nmin = strtonum(*args, 0, INT_MAX, &errstr); if (errstr) { BIO_printf(bio_err, "Illegal update period %s: %s\n", *args, errstr); badarg = 1; } } if (ndays == -1) ndays = 0; else badarg = 1; } else if (!strcmp(*args, "-nrequest")) { if (args[1]) { args++; accept_count = strtonum(*args, 0, INT_MAX, &errstr); if (errstr) { BIO_printf(bio_err, "Illegal accept count %s: %s\n", *args, errstr); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-ndays")) { if (args[1]) { args++; ndays = strtonum(*args, 0, INT_MAX, &errstr); if (errstr) { BIO_printf(bio_err, "Illegal update period %s: %s\n", *args, errstr); badarg = 1; } } else badarg = 1; } else if (!strcmp(*args, "-rsigner")) { if (args[1]) { args++; rsignfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-rkey")) { if (args[1]) { args++; rkeyfile = *args; } else badarg = 1; } else if (!strcmp(*args, "-rother")) { if (args[1]) { args++; rcertfile = *args; } else badarg = 1; } else if ((cert_id_md = EVP_get_digestbyname((*args) + 1)) == NULL) { badarg = 1; } args++; } /* Have we anything to do? */ if (!req && !reqin && !respin && !(port && ridx_filename)) badarg = 1; if (badarg) { BIO_printf(bio_err, "OCSP utility\n"); BIO_printf(bio_err, "Usage ocsp [options]\n"); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, "-out file output filename\n"); BIO_printf(bio_err, "-issuer file issuer certificate\n"); BIO_printf(bio_err, "-cert file certificate to check\n"); BIO_printf(bio_err, "-serial n serial number to check\n"); BIO_printf(bio_err, "-signer file certificate to sign OCSP request with\n"); BIO_printf(bio_err, "-signkey file private key to sign OCSP request with\n"); BIO_printf(bio_err, "-sign_other file additional certificates to include in signed request\n"); BIO_printf(bio_err, "-no_certs don't include any certificates in signed request\n"); BIO_printf(bio_err, "-req_text print text form of request\n"); BIO_printf(bio_err, "-resp_text print text form of response\n"); BIO_printf(bio_err, "-text print text form of request and response\n"); BIO_printf(bio_err, "-reqout file write DER encoded OCSP request to \"file\"\n"); BIO_printf(bio_err, "-respout file write DER encoded OCSP reponse to \"file\"\n"); BIO_printf(bio_err, "-reqin file read DER encoded OCSP request from \"file\"\n"); BIO_printf(bio_err, "-respin file read DER encoded OCSP reponse from \"file\"\n"); BIO_printf(bio_err, "-nonce add OCSP nonce to request\n"); BIO_printf(bio_err, "-no_nonce don't add OCSP nonce to request\n"); BIO_printf(bio_err, "-url URL OCSP responder URL\n"); BIO_printf(bio_err, "-host host:n send OCSP request to host on port n\n"); BIO_printf(bio_err, "-path path to use in OCSP request\n"); BIO_printf(bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf(bio_err, "-CAfile file trusted certificates file\n"); BIO_printf(bio_err, "-VAfile file validator certificates file\n"); BIO_printf(bio_err, "-validity_period n maximum validity discrepancy in seconds\n"); BIO_printf(bio_err, "-status_age n maximum status age in seconds\n"); BIO_printf(bio_err, "-noverify don't verify response at all\n"); BIO_printf(bio_err, "-verify_other file additional certificates to search for signer\n"); BIO_printf(bio_err, "-trust_other don't verify additional certificates\n"); BIO_printf(bio_err, "-no_intern don't search certificates contained in response for signer\n"); BIO_printf(bio_err, "-no_signature_verify don't check signature on response\n"); BIO_printf(bio_err, "-no_cert_verify don't check signing certificate\n"); BIO_printf(bio_err, "-no_chain don't chain verify response\n"); BIO_printf(bio_err, "-no_cert_checks don't do additional checks on signing certificate\n"); BIO_printf(bio_err, "-port num port to run responder on\n"); BIO_printf(bio_err, "-index file certificate status index file\n"); BIO_printf(bio_err, "-CA file CA certificate\n"); BIO_printf(bio_err, "-rsigner file responder certificate to sign responses with\n"); BIO_printf(bio_err, "-rkey file responder key to sign responses with\n"); BIO_printf(bio_err, "-rother file other certificates to include in response\n"); BIO_printf(bio_err, "-resp_no_certs don't include any certificates in response\n"); BIO_printf(bio_err, "-nmin n number of minutes before next update\n"); BIO_printf(bio_err, "-ndays n number of days before next update\n"); BIO_printf(bio_err, "-resp_key_id identify reponse by signing certificate key ID\n"); BIO_printf(bio_err, "-nrequest n number of requests to accept (default unlimited)\n"); BIO_printf(bio_err, "-<dgst alg> use specified digest in the request\n"); goto end; } if (outfile) out = BIO_new_file(outfile, "w"); else out = BIO_new_fp(stdout, BIO_NOCLOSE); if (!out) { BIO_printf(bio_err, "Error opening output file\n"); goto end; } if (!req && (add_nonce != 2)) add_nonce = 0; if (!req && reqin) { derbio = BIO_new_file(reqin, "rb"); if (!derbio) { BIO_printf(bio_err, "Error Opening OCSP request file\n"); 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(bio_err, rsignfile, FORMAT_PEM, NULL, "responder certificate"); if (!rsigner) { BIO_printf(bio_err, "Error loading responder certificate\n"); goto end; } rca_cert = load_cert(bio_err, rca_filename, FORMAT_PEM, NULL, "CA certificate"); if (rcertfile) { rother = load_certs(bio_err, rcertfile, FORMAT_PEM, NULL, "responder other certificates"); if (!rother) goto end; } rkey = load_key(bio_err, rkeyfile, FORMAT_PEM, 0, 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(bio_err, signfile, FORMAT_PEM, NULL, "signer certificate"); if (!signer) { BIO_printf(bio_err, "Error loading signer certificate\n"); goto end; } if (sign_certfile) { sign_other = load_certs(bio_err, sign_certfile, FORMAT_PEM, NULL, "signer certificates"); if (!sign_other) goto end; } key = load_key(bio_err, keyfile, FORMAT_PEM, 0, 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_new_file(reqout, "wb"); if (!derbio) { BIO_printf(bio_err, "Error opening file %s\n", reqout); 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) { i = make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey, rother, rflags, nmin, ndays); if (cbio) send_ocsp_response(cbio, resp); } else if (host) { resp = process_responder(bio_err, req, host, path, port, use_ssl, headers, req_timeout); if (!resp) goto end; } else if (respin) { derbio = BIO_new_file(respin, "rb"); if (!derbio) { BIO_printf(bio_err, "Error Opening OCSP response file\n"); 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_new_file(respout, "wb"); if (!derbio) { BIO_printf(bio_err, "Error opening file %s\n", respout); 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) accept_count--; /* Redo if more connections needed */ if (accept_count) { BIO_free_all(cbio); cbio = NULL; OCSP_REQUEST_free(req); req = NULL; OCSP_RESPONSE_free(resp); resp = NULL; goto redo_accept; } goto end; } if (!store) store = setup_verify(bio_err, CAfile, CApath); if (!store) goto end; if (verify_certfile) { verify_other = load_certs(bio_err, verify_certfile, FORMAT_PEM, 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; } 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"); goto end; } } i = OCSP_basic_verify(bs, verify_other, store, verify_flags); if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); if (i <= 0) { BIO_printf(bio_err, "Response Verify Failure\n"); ERR_print_errors(bio_err); } else BIO_printf(bio_err, "Response verify OK\n"); } if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) goto end; ret = 0; end: ERR_print_errors(bio_err); X509_free(signer); X509_STORE_free(store); EVP_PKEY_free(key); EVP_PKEY_free(rkey); X509_free(issuer); 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); if (use_ssl != -1) { free(host); free(port); free(path); } return (ret); }
static TS_RESP *create_response(CONF *conf, const char *section, char *engine, char *queryfile, char *passin, char *inkey, const EVP_MD *md, char *signer, char *chain, const char *policy) { int ret = 0; TS_RESP *response = NULL; BIO *query_bio = NULL; TS_RESP_CTX *resp_ctx = NULL; if ((query_bio = BIO_new_file(queryfile, "rb")) == NULL) goto end; if ((section = TS_CONF_get_tsa_section(conf, section)) == NULL) goto end; if ((resp_ctx = TS_RESP_CTX_new()) == NULL) goto end; if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end; # ifndef OPENSSL_NO_ENGINE if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end; # endif if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end; if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end; if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx)) goto end; if (md) { if (!TS_RESP_CTX_set_signer_digest(resp_ctx, md)) goto end; } else if (!TS_CONF_set_signer_digest(conf, section, NULL, resp_ctx)) { goto end; } if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end; if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end; if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end; if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end; if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx)) goto end; if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end; if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end; if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end; if ((response = TS_RESP_create_response(resp_ctx, query_bio)) == NULL) goto end; ret = 1; end: if (!ret) { TS_RESP_free(response); response = NULL; } TS_RESP_CTX_free(resp_ctx); BIO_free_all(query_bio); return response; }
int main(int argc, char **argv) { BIO *in = NULL, *out = NULL, *tbio = NULL; X509 *scert = NULL; EVP_PKEY *skey = NULL; CMS_ContentInfo *cms = NULL; int ret = 1; /* For simple S/MIME signing use CMS_DETACHED. * On OpenSSL 0.9.9 only: * for streaming detached set CMS_DETACHED|CMS_STREAM * for streaming non-detached set CMS_STREAM */ int flags = CMS_DETACHED|CMS_STREAM; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* Read in signer certificate and private key */ tbio = BIO_new_file("signer.pem", "r"); if (!tbio) goto err; scert = PEM_read_bio_X509(tbio, NULL, 0, NULL); BIO_reset(tbio); skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL); if (!scert || !skey) goto err; /* Open content being signed */ in = BIO_new_file("sign.txt", "r"); if (!in) goto err; /* Sign content */ cms = CMS_sign(scert, skey, NULL, in, flags); if (!cms) goto err; out = BIO_new_file("smout.txt", "w"); if (!out) goto err; if (!(flags & CMS_STREAM)) BIO_reset(in); /* Write out S/MIME message */ if (!SMIME_write_CMS(out, cms, in, flags)) goto err; ret = 0; err: if (ret) { fprintf(stderr, "Error Signing Data\n"); ERR_print_errors_fp(stderr); } if (cms) CMS_ContentInfo_free(cms); if (scert) X509_free(scert); if (skey) EVP_PKEY_free(skey); if (in) BIO_free(in); if (out) BIO_free(out); if (tbio) BIO_free(tbio); return ret; }