+ 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_STRING_num(macopts); i++)
+ {
+ macopt = sk_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 (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, e, sigkey);
+ else
+ r = EVP_DigestSignInit(mctx, &pctx, md, e, 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_STRING_num(sigopts); i++)
+ {
+ sigopt = sk_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;
+ }
+ }
+ }
+ }