If we take a look at any ENGINE_load_XXX function, we find that they all has similar structure:
ENGINE *toadd = engine_XXX(); if(!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); My question is: why we need call ENGINE_free(toadd) ?? Somewhere inside it calls EVP_PKEY_asn1_free(), which besides everything else desroy all AMETH structures, created during engine initialization via EVP_PKEY_asn1_set_* . So, let's consider following example: CRYPTO_malloc_init(); ERR_load_crypto_strings(); ENGINE_load_builtin_engines(); e = ENGINE_by_id("XXX"); ENGINE_set_default(e, ENGINE_METHOD_ALL); OpenSSL_add_all_algorithms(); OpenSSL_add_ssl_algorithms(); EVP_PKEY *signing_key = ENGINE_load_private_key(e, NULL, NULL, NULL); // bla-bla-bla... And, if in engine load priv func we write something like EVP_PKEY *pkey = EVP_PKEY_new(); pkey->ameth = ENGINE_get_pkey_asn1_meth(eng, NID_id_SOME_NID); it's not gonna work, because all ASN1 structures, carefully created by engine via calls to EVP_PKEY_asn1_set_* are invalid and possibly corrupted at this moment. Is it a design issue, or provided example is invalid (but it taken from openssl sources, hm...)?