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 has registered at least one cipher or digest
algorithm method, and therefore gets a functional reference through the
ENGINE_set_default() call), 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().
Originally, the ENGINE API wasn't designed for this to happen, an
engine had to register at least one algorithm method, and was
especially expected to register the algorithms corresponding to the
key types that could be stored and hidden in hardware. However, it
turns out that some engines will not register those algorithms with
the ENGINE_set_{algo}, ENGINE_set_cipher or ENGINE_set_digest
functions, as they only want the methods to be used for keys, not as
general crypto accelerator methods. That may cause ENGINE_set_default()
to do nothing, and no functional reference is therefore made, leading
to a premature deallocation of the engine and it thereby becoming
unavailable when trying to fetch a key.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1644)
}
BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e));
+ }
+ return e;
+}
+void release_engine(ENGINE *e)
+{
+ if (e != NULL)
/* Free our "structural" reference. */
ENGINE_free(e);
- }
- return e;
}
#endif
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
# ifndef OPENSSL_NO_ENGINE
ENGINE *setup_engine(BIO *err, const char *engine, int debug);
+void release_engine(ENGINE *e);
# endif
# ifndef OPENSSL_NO_OCSP
X509_CRL_free(crl);
NCONF_free(conf);
NCONF_free(extconf);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
OBJ_cleanup();
apps_shutdown();
OPENSSL_EXIT(ret);
EVP_PKEY_free(key);
CMS_ContentInfo_free(cms);
CMS_ContentInfo_free(rcms);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
BIO_free(rctin);
BIO_free(in);
BIO_free(indata);
OPENSSL_free(sigbuf);
if (bmd != NULL)
BIO_free(bmd);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
apps_shutdown();
OPENSSL_EXIT(err);
}
char *inrand = NULL;
# ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
+ ENGINE *e = NULL;
# endif
int num = 0, g = 0;
ERR_load_crypto_strings();
# ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
# endif
if (g && !num)
BIO_free_all(out);
if (dh != NULL)
DH_free(dh);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
apps_shutdown();
OPENSSL_EXIT(ret);
}
BIO_free_all(out);
if (dsa != NULL)
DSA_free(dsa);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
if (passin)
OPENSSL_free(passin);
if (passout)
int need_rand = 0;
# ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
+ ENGINE *e = NULL;
# endif
# ifdef GENCB_TEST
int timebomb = 0;
}
# ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
# endif
if (need_rand) {
BIO_free_all(out);
if (dsa != NULL)
DSA_free(dsa);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
apps_shutdown();
OPENSSL_EXIT(ret);
}
int informat, outformat, text = 0, noout = 0;
int pubin = 0, pubout = 0, param_out = 0;
char *infile, *outfile, *prog, *engine;
+# ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = NULL;
+# endif
char *passargin = NULL, *passargout = NULL;
char *passin = NULL, *passout = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
ERR_load_crypto_strings();
# ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
# endif
if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
BIO_free_all(out);
if (eckey)
EC_KEY_free(eckey);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
if (passin)
OPENSSL_free(passin);
if (passout)
BIO *in = NULL, *out = NULL;
int informat, outformat, noout = 0, C = 0, ret = 1;
char *engine = NULL;
+# ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = NULL;
+# endif
BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
*ec_gen = NULL, *ec_order = NULL, *ec_cofactor = NULL;
}
# ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
# endif
if (list_curves) {
BN_free(ec_cofactor);
if (buffer)
OPENSSL_free(buffer);
+ if (group != NULL)
+ EC_GROUP_free(group);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
if (in != NULL)
BIO_free(in);
if (out != NULL)
BIO_free_all(out);
- if (group != NULL)
- EC_GROUP_free(group);
apps_shutdown();
OPENSSL_EXIT(ret);
}
char pname[PROG_NAME_SIZE + 1];
#ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
+ ENGINE *e = NULL;
#endif
const EVP_MD *dgst = NULL;
int non_fips_allow = 0;
}
#ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
#endif
if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) {
#ifdef ZLIB
if (bzl != NULL)
BIO_free(bzl);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
#endif
if (pass)
OPENSSL_free(pass);
const EVP_CIPHER *enc = NULL;
# ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
+ ENGINE *e = NULL;
# endif
apps_startup();
goto end;
}
# ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
# endif
if (!app_passwd(bio_err, NULL, passargout, NULL, &passout)) {
BIO_free_all(out);
if (dsa != NULL)
DSA_free(dsa);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
if (passout)
OPENSSL_free(passout);
apps_shutdown();
if (out)
BIO_free_all(out);
BIO_free(in);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (pass)
OPENSSL_free(pass);
-
return ret;
}
RSA_free(rsa);
if (out)
BIO_free_all(out);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
if (passout)
OPENSSL_free(passout);
if (ret != 0)
app_RAND_write_file(NULL, bio_err);
# ifdef CRYPTO_MDEBUG
CRYPTO_remove_all_info();
+# endif
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
# endif
BIO_free(in);
BIO_free_all(out);
int ret = 1;
#ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
+ ENGINE *e = NULL;
#endif
apps_startup();
ERR_load_crypto_strings();
#ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
#endif
in = BIO_new(BIO_s_file());
end:
if (p7 != NULL)
PKCS7_free(p7);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (in != NULL)
BIO_free(in);
if (out != NULL)
X509_SIG_free(p8);
PKCS8_PRIV_KEY_INFO_free(p8inf);
EVP_PKEY_free(pkey);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
BIO_free_all(out);
BIO_free(in);
if (passin)
end:
EVP_PKEY_free(pkey);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
BIO_free_all(out);
BIO_free(in);
if (passin)
int badarg = 0;
#ifndef OPENSSL_NO_ENGINE
char *engine = NULL;
+ ENGINE *e = NULL;
#endif
int ret = 1;
return 1;
}
#ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
#endif
if (infile) {
end:
EVP_PKEY_free(pkey);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
BIO_free_all(out);
BIO_free(in);
end:
if (ctx)
EVP_PKEY_CTX_free(ctx);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
BIO_free(in);
BIO_free_all(out);
if (buf_in != NULL)
BIO *out = NULL;
int num = -1;
#ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = NULL;
char *engine = NULL;
#endif
goto err;
}
#ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
#endif
app_RAND_load_file(NULL, bio_err, (inrand != NULL));
err:
ERR_print_errors(bio_err);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (out)
BIO_free_all(out);
apps_shutdown();
X509_REQ_free(req);
X509_free(x509ss);
ASN1_INTEGER_free(serial);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (passargin && passin)
OPENSSL_free(passin);
if (passargout && passout)
} else
ret = 0;
end:
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
if (out != NULL)
BIO_free_all(out);
if (rsa != NULL)
BIO_write(out, rsa_out, rsa_outlen);
end:
RSA_free(rsa);
+# ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+# endif
BIO_free(in);
BIO_free_all(out);
if (rsa_in)
OPENSSL_cleanse(mbuf, BUFSIZZ);
OPENSSL_free(mbuf);
}
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (bio_c_out != NULL) {
BIO_free(bio_c_out);
bio_c_out = NULL;
#ifndef OPENSSL_NO_JPAKE
if (jpake_secret && psk_key)
OPENSSL_free(psk_key);
+#endif
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
#endif
if (bio_s_out != NULL) {
BIO_free(bio_s_out);
X509_free(signer);
EVP_PKEY_free(key);
PKCS7_free(p7);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
BIO_free(in);
BIO_free(indata);
BIO_free_all(out);
int MAIN(int argc, char **argv)
{
+# ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = NULL;
+#endif
unsigned char *buf = NULL, *buf2 = NULL;
int mret = 1;
long count = 0, save_count = 0;
BIO_printf(bio_err, "no engine given\n");
goto end;
}
- setup_engine(bio_err, *argv, 0);
+ e = setup_engine(bio_err, *argv, 0);
/*
* j will be increased again further down. We just don't want
* speed to confuse an engine with an algorithm, especially when
}
# endif
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
apps_shutdown();
OPENSSL_EXIT(mret);
}
BIO_free(in);
BIO_free_all(out);
EVP_PKEY_free(pkey);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (passin)
OPENSSL_free(passin);
apps_shutdown();
long errorline = -1;
char *randfile = NULL;
# ifndef OPENSSL_NO_ENGINE
+ ENGINE *e = NULL;
char *engine = NULL;
# endif
char *tofree = NULL;
ERR_load_crypto_strings();
# ifndef OPENSSL_NO_ENGINE
- setup_engine(bio_err, engine, 0);
+ e = setup_engine(bio_err, engine, 0);
# endif
if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) {
if (db)
free_index(db);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
OBJ_cleanup();
apps_shutdown();
OPENSSL_EXIT(ret);
sk_X509_pop_free(untrusted, X509_free);
sk_X509_pop_free(trusted, X509_free);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
apps_shutdown();
OPENSSL_EXIT(ret < 0 ? 2 : ret);
}
ASN1_INTEGER_free(sno);
sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
+#ifndef OPENSSL_NO_ENGINE
+ if (e != NULL)
+ release_engine(e);
+#endif
if (passin)
OPENSSL_free(passin);
apps_shutdown();