+ if (kdfalg != NULL) {
+ if (kdflen == 0) {
+ BIO_printf(bio_err,
+ "%s: no KDF length given (-kdflen parameter).\n", prog);
+ goto opthelp;
+ }
+ } else if (inkey == NULL) {
+ BIO_printf(bio_err,
+ "%s: no private key given (-inkey parameter).\n", prog);
+ goto opthelp;
+ } else if (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE) {
+ BIO_printf(bio_err,
+ "%s: no peer key given (-peerkey parameter).\n", prog);
+ goto opthelp;
+ }
+
+ if (rawin) {
+ if ((mctx = EVP_MD_CTX_new()) == NULL) {
+ BIO_printf(bio_err, "Error: out of memory\n");
+ goto end;
+ }
+ }
+ ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
+ passinarg, pkey_op, e, engine_impl, rawin, &pkey,
+ mctx, digestname, libctx, app_get0_propq());
+ if (ctx == NULL) {
+ BIO_printf(bio_err, "%s: Error initializing context\n", prog);
+ goto end;
+ }
+ if (peerkey != NULL && !setup_peer(ctx, peerform, peerkey, e)) {
+ BIO_printf(bio_err, "%s: Error setting up peer key\n", prog);
+ goto end;
+ }
+ if (pkeyopts != NULL) {
+ int num = sk_OPENSSL_STRING_num(pkeyopts);
+ int i;
+
+ for (i = 0; i < num; ++i) {
+ const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i);
+
+ if (pkey_ctrl_string(ctx, opt) <= 0) {
+ BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",
+ prog, opt);
+ goto end;
+ }
+ }
+ }
+ if (pkeyopts_passin != NULL) {
+ int num = sk_OPENSSL_STRING_num(pkeyopts_passin);
+ int i;
+
+ for (i = 0; i < num; i++) {
+ char *opt = sk_OPENSSL_STRING_value(pkeyopts_passin, i);
+ char *passin = strchr(opt, ':');
+ char *passwd;
+
+ if (passin == NULL) {
+ /* Get password interactively */
+ char passwd_buf[4096];
+ int r;
+
+ BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt);
+ r = EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1,
+ passwd_buf, 0);
+ if (r < 0) {
+ if (r == -2)
+ BIO_puts(bio_err, "user abort\n");
+ else
+ BIO_puts(bio_err, "entry failed\n");
+ goto end;
+ }
+ passwd = OPENSSL_strdup(passwd_buf);
+ if (passwd == NULL) {
+ BIO_puts(bio_err, "out of memory\n");
+ goto end;
+ }
+ } else {
+ /* Get password as a passin argument: First split option name
+ * and passphrase argument into two strings */
+ *passin = 0;
+ passin++;
+ if (app_passwd(passin, NULL, &passwd, NULL) == 0) {
+ BIO_printf(bio_err, "failed to get '%s'\n", opt);
+ goto end;
+ }
+ }
+
+ if (EVP_PKEY_CTX_ctrl_str(ctx, opt, passwd) <= 0) {
+ BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",
+ prog, opt);
+ goto end;
+ }
+ OPENSSL_free(passwd);
+ }
+ }
+
+ if (sigfile != NULL && (pkey_op != EVP_PKEY_OP_VERIFY)) {