In apps/apps.c, one can set up an engine with setup_engine().
However, we freed the structural reference immediately, which means
that for engines that don't already have a structural reference
somewhere else (because it's a built in engine), we end up returning
an invalid reference.
Instead, the function release_engine() is added, and called at the end
of the routines that call setup_engine().
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1643)
(cherry picked from commit
dd1abd4462e4e4fa84b8f8de2ec70375f9b0e191)
}
BIO_printf(bio_err, "engine \"%s\" set.\n", ENGINE_get_id(e));
-
- /* Free our "structural" reference. */
- ENGINE_free(e);
}
return e;
}
#endif
+void release_engine(ENGINE *e)
+{
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ /* Free our "structural" reference. */
+ ENGINE_free(e);
+#endif
+}
+
static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
{
const char *n;
# else
ENGINE *setup_engine(const char *engine, int debug);
# endif
+void release_engine(ENGINE *e);
# ifndef OPENSSL_NO_OCSP
OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
const char *host, const char *path,
X509_CRL_free(crl);
NCONF_free(conf);
NCONF_free(extconf);
+ release_engine(e);
return (ret);
}
EVP_PKEY_free(key);
CMS_ContentInfo_free(cms);
CMS_ContentInfo_free(rcms);
+ release_engine(e);
BIO_free(rctin);
BIO_free(in);
BIO_free(indata);
sk_OPENSSL_STRING_free(macopts);
OPENSSL_free(sigbuf);
BIO_free(bmd);
+ release_engine(e);
return (ret);
}
BIO *in = NULL, *out = NULL;
DH *dh = NULL;
char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
+ ENGINE *e = NULL;
#ifndef OPENSSL_NO_DSA
int dsaparam = 0;
#endif
outfile = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
case OPT_CHECK:
check = 1;
BIO_free(in);
BIO_free_all(out);
DH_free(dh);
+ release_engine(e);
return (ret);
}
end:
BIO_free_all(out);
DSA_free(dsa);
+ release_engine(e);
OPENSSL_free(passin);
OPENSSL_free(passout);
return (ret);
int dsaparam_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
DSA *dsa = NULL;
BIO *in = NULL, *out = NULL;
BN_GENCB *cb = NULL;
outfile = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
case OPT_TIMEBOMB:
# ifdef GENCB_TEST
BIO_free(in);
BIO_free_all(out);
DSA_free(dsa);
+ release_engine(e);
return (ret);
}
BIO_free(in);
BIO_free_all(out);
EC_KEY_free(eckey);
+ release_engine(e);
OPENSSL_free(passin);
OPENSSL_free(passout);
return (ret);
int ecparam_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
BIGNUM *ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL;
BIO *in = NULL, *out = NULL;
need_rand = 1;
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
}
}
BN_free(ec_order);
BN_free(ec_cofactor);
OPENSSL_free(buffer);
+ EC_GROUP_free(group);
+ release_engine(e);
BIO_free(in);
BIO_free_all(out);
- EC_GROUP_free(group);
return (ret);
}
{
static char buf[128];
static const char magic[] = "Salted__";
+ ENGINE *e = NULL;
BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio =
NULL, *wbio = NULL;
EVP_CIPHER_CTX *ctx = NULL;
passarg = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
case OPT_D:
enc = 0;
#ifdef ZLIB
BIO_free(bzl);
#endif
+ release_engine(e);
OPENSSL_free(pass);
return (ret);
}
int gendsa_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
BIO *out = NULL, *in = NULL;
DSA *dsa = NULL;
const EVP_CIPHER *enc = NULL;
passoutarg = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
BIO_free(in);
BIO_free_all(out);
DSA_free(dsa);
+ release_engine(e);
OPENSSL_free(passout);
return (ret);
}
EVP_PKEY_CTX_free(ctx);
BIO_free_all(out);
BIO_free(in);
+ release_engine(e);
OPENSSL_free(pass);
-
return ret;
}
BN_GENCB_free(cb);
RSA_free(rsa);
BIO_free_all(out);
+ release_engine(eng);
OPENSSL_free(passout);
if (ret != 0)
ERR_print_errors(bio_err);
PKCS12_free(p12);
if (export_cert || inrand)
app_RAND_write_file(NULL);
+ release_engine(e);
BIO_free(in);
BIO_free_all(out);
sk_OPENSSL_STRING_free(canames);
int pkcs7_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
PKCS7 *p7 = NULL;
BIO *in = NULL, *out = NULL;
int informat = FORMAT_PEM, outformat = FORMAT_PEM;
print_certs = 1;
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
}
}
ret = 0;
end:
PKCS7_free(p7);
+ release_engine(e);
BIO_free(in);
BIO_free_all(out);
return (ret);
X509_SIG_free(p8);
PKCS8_PRIV_KEY_INFO_free(p8inf);
EVP_PKEY_free(pkey);
+ release_engine(e);
BIO_free_all(out);
BIO_free(in);
OPENSSL_free(passin);
end:
EVP_PKEY_free(pkey);
+ release_engine(e);
BIO_free_all(out);
BIO_free(in);
OPENSSL_free(passin);
int pkeyparam_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
BIO *in = NULL, *out = NULL;
EVP_PKEY *pkey = NULL;
int text = 0, noout = 0, ret = 1;
outfile = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
case OPT_TEXT:
text = 1;
end:
EVP_PKEY_free(pkey);
+ release_engine(e);
BIO_free_all(out);
BIO_free(in);
end:
EVP_PKEY_CTX_free(ctx);
+ release_engine(e);
BIO_free(in);
BIO_free_all(out);
OPENSSL_free(buf_in);
int rand_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
BIO *out = NULL;
char *inrand = NULL, *outfile = NULL, *prog;
OPTION_CHOICE o;
outfile = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
end:
if (ret != 0)
ERR_print_errors(bio_err);
+ release_engine(e);
BIO_free_all(out);
return (ret);
}
X509_REQ_free(req);
X509_free(x509ss);
ASN1_INTEGER_free(serial);
+ release_engine(e);
if (passin != nofree_passin)
OPENSSL_free(passin);
if (passout != nofree_passout)
} else
ret = 0;
end:
+ release_engine(e);
BIO_free_all(out);
RSA_free(rsa);
OPENSSL_free(passin);
BIO_write(out, rsa_out, rsa_outlen);
end:
RSA_free(rsa);
+ release_engine(e);
BIO_free(in);
BIO_free_all(out);
OPENSSL_free(rsa_in);
OPENSSL_clear_free(cbuf, BUFSIZZ);
OPENSSL_clear_free(sbuf, BUFSIZZ);
OPENSSL_clear_free(mbuf, BUFSIZZ);
+ release_engine(e);
BIO_free(bio_c_out);
bio_c_out = NULL;
BIO_free(bio_c_msg);
ssl_excert_free(exc);
sk_OPENSSL_STRING_free(ssl_args);
SSL_CONF_CTX_free(cctx);
+ release_engine(engine);
BIO_free(bio_s_out);
bio_s_out = NULL;
BIO_free(bio_s_msg);
X509_free(signer);
EVP_PKEY_free(key);
PKCS7_free(p7);
+ release_engine(e);
BIO_free(in);
BIO_free(indata);
BIO_free_all(out);
int speed_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
loopargs_t *loopargs = NULL;
int async_init = 0;
int loopargs_len = 0;
#endif
/* Initialize the engine after the fork */
- (void)setup_engine(engine_id, 0);
+ e = setup_engine(engine_id, 0);
/* No parameters; turn on everything. */
if ((argc == 0) && !doit[D_EVP]) {
ASYNC_cleanup_thread();
}
OPENSSL_free(loopargs);
+ release_engine(e);
return (ret);
}
NETSCAPE_SPKI_free(spki);
BIO_free_all(out);
EVP_PKEY_free(pkey);
+ release_engine(e);
OPENSSL_free(passin);
return (ret);
}
int srp_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
CA_DB *db = NULL;
CONF *conf = NULL;
int gNindex = -1, maxgN = -1, ret = 1, errors = 0, verbose = 0, i;
passoutarg = opt_arg();
break;
case OPT_ENGINE:
- (void)setup_engine(opt_arg(), 0);
+ e = setup_engine(opt_arg(), 0);
break;
}
}
app_RAND_write_file(randfile);
NCONF_free(conf);
free_index(db);
+ release_engine(e);
return (ret);
}
#endif
int verify_main(int argc, char **argv)
{
+ ENGINE *e = NULL;
STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
STACK_OF(X509_CRL) *crls = NULL;
X509_STORE *store = NULL;
crl_download = 1;
break;
case OPT_ENGINE:
- if (setup_engine(opt_arg(), 0) == NULL) {
+ if ((e = setup_engine(opt_arg(), 0)) == NULL) {
/* Failure message already displayed */
goto end;
}
sk_X509_pop_free(untrusted, X509_free);
sk_X509_pop_free(trusted, X509_free);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
+ release_engine(e);
return (ret < 0 ? 2 : ret);
}
sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
ASN1_OBJECT_free(objtmp);
+ release_engine(e);
OPENSSL_free(passin);
return (ret);
}