Initialize pkcs11 engine only once

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
This commit is contained in:
Jakub Jelen
2022-08-24 15:47:47 +02:00
parent f721ee847b
commit 0800618f32
3 changed files with 50 additions and 24 deletions

View File

@@ -223,5 +223,8 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
size_t requested_len); size_t requested_len);
int secure_memcmp(const void *s1, const void *s2, size_t n); int secure_memcmp(const void *s1, const void *s2, size_t n);
#ifdef HAVE_LIBCRYPTO
ENGINE *pki_get_engine(void);
#endif /* HAVE_LIBCRYPTO */
#endif /* _CRYPTO_H_ */ #endif /* _CRYPTO_H_ */

View File

@@ -85,6 +85,8 @@
static int libcrypto_initialized = 0; static int libcrypto_initialized = 0;
static ENGINE *engine = NULL;
void ssh_reseed(void){ void ssh_reseed(void){
#ifndef _WIN32 #ifndef _WIN32
struct timeval tv; struct timeval tv;
@@ -93,6 +95,36 @@ void ssh_reseed(void){
#endif #endif
} }
ENGINE *pki_get_engine(void)
{
int ok;
if (engine == NULL) {
ENGINE_load_builtin_engines();
engine = ENGINE_by_id("pkcs11");
if (engine == NULL) {
SSH_LOG(SSH_LOG_WARN,
"Could not load the engine: %s",
ERR_error_string(ERR_get_error(), NULL));
return NULL;
}
SSH_LOG(SSH_LOG_INFO, "Engine loaded successfully");
ok = ENGINE_init(engine);
if (!ok) {
SSH_LOG(SSH_LOG_WARN,
"Could not initialize the engine: %s",
ERR_error_string(ERR_get_error(), NULL));
ENGINE_free(engine);
return NULL;
}
SSH_LOG(SSH_LOG_INFO, "Engine init success");
}
return engine;
}
#ifdef HAVE_OPENSSL_ECC #ifdef HAVE_OPENSSL_ECC
static const EVP_MD *nid_to_evpmd(int nid) static const EVP_MD *nid_to_evpmd(int nid)
{ {
@@ -1393,6 +1425,17 @@ void ssh_crypto_finalize(void)
return; return;
} }
/* TODO this should finalize engine if it was started, but during atexit calls,
* we are crashing. AFAIK this is related to the dlopened pkcs11 modules calling
* the crypto cleanups earlier. */
#if 0
if (engine != NULL) {
ENGINE_finish(engine);
ENGINE_free(engine);
engine = NULL;
}
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
ENGINE_cleanup(); ENGINE_cleanup();
EVP_cleanup(); EVP_cleanup();

View File

@@ -3461,29 +3461,13 @@ int pki_uri_import(const char *uri_name,
#endif #endif
ssh_key key = NULL; ssh_key key = NULL;
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN; enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
int ok;
ENGINE_load_builtin_engines(); /* Do the init only once */
engine = pki_get_engine();
engine = ENGINE_by_id("pkcs11");
if (engine == NULL) { if (engine == NULL) {
SSH_LOG(SSH_LOG_WARN, SSH_LOG(SSH_LOG_WARN, "Failed to initialize engine");
"Could not load the engine: %s", goto fail;
ERR_error_string(ERR_get_error(),NULL));
return SSH_ERROR;
} }
SSH_LOG(SSH_LOG_INFO, "Engine loaded successfully");
ok = ENGINE_init(engine);
if (!ok) {
SSH_LOG(SSH_LOG_WARN,
"Could not initialize the engine: %s",
ERR_error_string(ERR_get_error(),NULL));
ENGINE_free(engine);
return SSH_ERROR;
}
SSH_LOG(SSH_LOG_INFO, "Engine init success");
switch (key_type) { switch (key_type) {
case SSH_KEY_PRIVATE: case SSH_KEY_PRIVATE:
@@ -3593,14 +3577,10 @@ int pki_uri_import(const char *uri_name,
#endif #endif
*nkey = key; *nkey = key;
ENGINE_finish(engine);
ENGINE_free(engine);
return SSH_OK; return SSH_OK;
fail: fail:
ENGINE_finish(engine);
ENGINE_free(engine);
EVP_PKEY_free(pkey); EVP_PKEY_free(pkey);
ssh_key_free(key); ssh_key_free(key);
#if OPENSSL_VERSION_NUMBER < 0x30000000L #if OPENSSL_VERSION_NUMBER < 0x30000000L