summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Thorsen <lars@erlang.org>2022-05-12 15:37:48 +0200
committerLars Thorsen <lars@erlang.org>2022-05-12 15:37:48 +0200
commit4bf325feb5885056ad3315d9a0316b652613b3d9 (patch)
tree8e8f50779be88077ab3cb2b5270267a558e7a06e
parent660596b107b62fbfd1ff028a9e46bb822484c2be (diff)
parentb7c1f7b4b746b47073df4ffcf1cb1965ec291214 (diff)
downloaderlang-4bf325feb5885056ad3315d9a0316b652613b3d9.tar.gz
Merge branch 'maint'
-rw-r--r--lib/crypto/c_src/crypto.c11
-rw-r--r--lib/crypto/c_src/engine.c775
-rw-r--r--lib/crypto/c_src/engine.h7
-rw-r--r--lib/crypto/src/crypto.erl93
-rw-r--r--lib/crypto/test/engine_SUITE.erl145
5 files changed, 661 insertions, 370 deletions
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index 042d122f53..ed8cf15f02 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -129,7 +129,9 @@ static ErlNifFunc nif_funcs[] = {
{"engine_get_next_nif", 1, engine_get_next_nif, 0},
{"engine_get_id_nif", 1, engine_get_id_nif, 0},
{"engine_get_name_nif", 1, engine_get_name_nif, 0},
- {"engine_get_all_methods_nif", 0, engine_get_all_methods_nif, 0}
+ {"engine_get_all_methods_nif", 0, engine_get_all_methods_nif, 0},
+ {"ensure_engine_loaded_nif", 3, ensure_engine_loaded_nif, 0},
+ {"ensure_engine_unloaded_nif", 2, ensure_engine_unloaded_nif, 0}
};
#ifdef HAS_3_0_API
@@ -213,6 +215,9 @@ static int initialize(ErlNifEnv* env, ERL_NIF_TERM load_info)
if (!init_engine_ctx(env)) {
return __LINE__;
}
+ if (!create_engine_mutex(env)) {
+ return __LINE__;
+ }
#ifdef HAS_3_0_API
prov_cnt = 0;
@@ -327,8 +332,10 @@ static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data,
static void unload(ErlNifEnv* env, void* priv_data)
{
- if (--library_refc == 0)
+ if (--library_refc == 0) {
cleanup_algorithms_types(env);
+ destroy_engine_mutex(env);
+ }
#ifdef HAS_3_0_API
while (prov_cnt>0)
diff --git a/lib/crypto/c_src/engine.c b/lib/crypto/c_src/engine.c
index 1ad8fd698a..6f223ee05a 100644
--- a/lib/crypto/c_src/engine.c
+++ b/lib/crypto/c_src/engine.c
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2021. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2022. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,8 +31,8 @@ struct engine_ctx {
#define ERROR_Atom(Env, ReasonString) ERROR_Term((Env), enif_make_atom((Env),(ReasonString)))
static ErlNifResourceType* engine_ctx_rtype;
+static ErlNifMutex *ensure_engine_loaded_mtx = NULL;
-static int get_engine_load_cmd_list(ErlNifEnv* env, const ERL_NIF_TERM term, char **cmds, int i);
static int zero_terminate(ErlNifBinary bin, char **buf);
static void engine_ctx_dtor(ErlNifEnv* env, struct engine_ctx* ctx) {
@@ -117,11 +117,281 @@ int init_engine_ctx(ErlNifEnv *env) {
PRINTF_ERR0("CRYPTO: Could not open resource type 'ENGINE_CTX'");
return 0;
}
+
#endif
return 1;
}
+int create_engine_mutex(ErlNifEnv *env) {
+#ifdef HAS_ENGINE_SUPPORT
+
+ if (!ensure_engine_loaded_mtx && ((ensure_engine_loaded_mtx = enif_mutex_create("crypto.ensure_engine_loaded")) == NULL)) {
+ PRINTF_ERR0("CRYPTO: Could not create mutex 'crypto.ensure_engine_loaded'");
+ return 0;
+ }
+
+#endif
+ return 1;
+}
+
+void destroy_engine_mutex(ErlNifEnv *env) {
+#ifdef HAS_ENGINE_SUPPORT
+
+ enif_mutex_destroy(ensure_engine_loaded_mtx);
+ ensure_engine_loaded_mtx = NULL;
+
+#endif
+}
+
+#ifdef HAS_ENGINE_SUPPORT
+static int get_engine_load_cmd_list(ErlNifEnv* env, const ERL_NIF_TERM term, char **cmds, int i)
+{
+ ERL_NIF_TERM head, tail;
+ const ERL_NIF_TERM *tmp_tuple;
+ ErlNifBinary tmpbin;
+ int arity;
+ char *tuple1 = NULL, *tuple2 = NULL;
+
+ if (enif_is_empty_list(env, term)) {
+ cmds[i] = NULL;
+ return 0;
+ }
+
+ if (!enif_get_list_cell(env, term, &head, &tail))
+ goto err;
+ if (!enif_get_tuple(env, head, &arity, &tmp_tuple))
+ goto err;
+ if (arity != 2)
+ goto err;
+ if (!enif_inspect_binary(env, tmp_tuple[0], &tmpbin))
+ goto err;
+
+ if ((tuple1 = enif_alloc(tmpbin.size + 1)) == NULL)
+ goto err;
+
+ (void) memcpy(tuple1, tmpbin.data, tmpbin.size);
+ tuple1[tmpbin.size] = '\0';
+ cmds[i] = tuple1;
+ i++;
+
+ if (!enif_inspect_binary(env, tmp_tuple[1], &tmpbin))
+ goto err;
+
+ if (tmpbin.size == 0) {
+ cmds[i] = NULL;
+ } else {
+ if ((tuple2 = enif_alloc(tmpbin.size + 1)) == NULL)
+ goto err;
+ (void) memcpy(tuple2, tmpbin.data, tmpbin.size);
+ tuple2[tmpbin.size] = '\0';
+ cmds[i] = tuple2;
+ }
+ i++;
+ return get_engine_load_cmd_list(env, tail, cmds, i);
+
+ err:
+ if (tuple1 != NULL) {
+ i--;
+ enif_free(tuple1);
+ }
+ cmds[i] = NULL;
+ return -1;
+}
+
+static int get_engine_method_list(ErlNifEnv* env, const ERL_NIF_TERM term, unsigned int *methods, int i)
+{
+ ERL_NIF_TERM head, tail;
+ unsigned int method;
+
+ if (enif_is_empty_list(env, term)) {
+ return 0;
+ }
+
+ if (!enif_get_list_cell(env, term, &head, &tail))
+ goto err;
+
+ if (!enif_get_uint(env, head, &method))
+ goto err;
+
+ methods[i] = method;
+
+ i++;
+ return get_engine_method_list(env, tail, methods, i);
+
+ err:
+ return -1;
+}
+
+static int register_method(ENGINE *engine, unsigned int method)
+{
+ int ret = 0;
+
+ switch(method)
+ {
+#ifdef ENGINE_METHOD_RSA
+ case ENGINE_METHOD_RSA:
+ ret = ENGINE_register_RSA(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_DSA
+ case ENGINE_METHOD_DSA:
+ ret = ENGINE_register_DSA(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_DH
+ case ENGINE_METHOD_DH:
+ ret = ENGINE_register_DH(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_RAND
+ case ENGINE_METHOD_RAND:
+ ret = ENGINE_register_RAND(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_ECDH
+ case ENGINE_METHOD_ECDH:
+ ret = ENGINE_register_ECDH(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_ECDSA
+ case ENGINE_METHOD_ECDSA:
+ ret = ENGINE_register_ECDSA(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_STORE
+ case ENGINE_METHOD_STORE:
+ ret = ENGINE_register_STORE(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_CIPHERS
+ case ENGINE_METHOD_CIPHERS:
+ ret = ENGINE_register_ciphers(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_DIGESTS
+ case ENGINE_METHOD_DIGESTS:
+ ret = ENGINE_register_digests(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_PKEY_METHS
+ case ENGINE_METHOD_PKEY_METHS:
+ ret = ENGINE_register_pkey_meths(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_PKEY_ASN1_METHS
+ case ENGINE_METHOD_PKEY_ASN1_METHS:
+ ret = ENGINE_register_pkey_asn1_meths(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_EC
+ case ENGINE_METHOD_EC:
+ ret = ENGINE_register_EC(engine);
+ break;
+#endif
+ default:
+ return -1;
+ }
+
+ return ret;
+}
+
+static void unregister_method(ENGINE *engine, unsigned int method)
+{
+
+ switch(method)
+ {
+#ifdef ENGINE_METHOD_RSA
+ case ENGINE_METHOD_RSA:
+ ENGINE_unregister_RSA(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_DSA
+ case ENGINE_METHOD_DSA:
+ ENGINE_unregister_DSA(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_DH
+ case ENGINE_METHOD_DH:
+ ENGINE_unregister_DH(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_RAND
+ case ENGINE_METHOD_RAND:
+ ENGINE_unregister_RAND(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_ECDH
+ case ENGINE_METHOD_ECDH:
+ ENGINE_unregister_ECDH(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_ECDSA
+ case ENGINE_METHOD_ECDSA:
+ ENGINE_unregister_ECDSA(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_STORE
+ case ENGINE_METHOD_STORE:
+ ENGINE_unregister_STORE(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_CIPHERS
+ case ENGINE_METHOD_CIPHERS:
+ ENGINE_unregister_ciphers(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_DIGESTS
+ case ENGINE_METHOD_DIGESTS:
+ ENGINE_unregister_digests(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_PKEY_METHS
+ case ENGINE_METHOD_PKEY_METHS:
+ ENGINE_unregister_pkey_meths(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_PKEY_ASN1_METHS
+ case ENGINE_METHOD_PKEY_ASN1_METHS:
+ ENGINE_unregister_pkey_asn1_meths(engine);
+ break;
+#endif
+#ifdef ENGINE_METHOD_EC
+ case ENGINE_METHOD_EC:
+ ENGINE_unregister_EC(engine);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return;
+}
+
+static int register_engine_methods(ENGINE *engine, unsigned int methods_len, unsigned int *methods)
+{
+ unsigned int i;
+ int ret;
+
+ for(i = 0; i < methods_len; i++)
+ if((ret = register_method(engine, methods[i])) != 1)
+ return ret;
+
+ return 1;
+}
+
+static void unregister_engine_methods(ENGINE *engine, unsigned int methods_len, unsigned int *methods)
+{
+ unsigned int i;
+
+ for(i = 0; i < methods_len; i++)
+ unregister_method(engine, methods[i]);
+
+ return;
+}
+
+#endif /* HAS_ENGINE_SUPPORT */
+
ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (EngineId) */
#ifdef HAS_ENGINE_SUPPORT
@@ -131,9 +401,10 @@ ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ENGINE *engine;
struct engine_ctx *ctx = NULL;
- // Get Engine Id
+ /* Get Arguments */
ASSERT(argc == 1);
+ /* EngineId */
if (!enif_inspect_binary(env, argv[0], &engine_id_bin))
goto bad_arg;
@@ -142,6 +413,7 @@ ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
(void) memcpy(engine_id, engine_id_bin.data, engine_id_bin.size);
engine_id[engine_id_bin.size] = '\0';
+
if ((engine = ENGINE_by_id(engine_id)) == NULL) {
PRINTF_ERR0("engine_by_id_nif Leaved: {error, bad_engine_id}");
ret = ERROR_Atom(env, "bad_engine_id");
@@ -181,9 +453,10 @@ ERL_NIF_TERM engine_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
#ifdef HAS_ENGINE_SUPPORT
struct engine_ctx *ctx;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 1);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx))
goto bad_arg;
@@ -224,6 +497,7 @@ ERL_NIF_TERM engine_free_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]
else {
ASSERT(!ctx->is_functional);
}
+
return atom_ok;
bad_arg:
@@ -257,15 +531,16 @@ ERL_NIF_TERM engine_ctrl_cmd_strings_nif(ErlNifEnv* env, int argc, const ERL_NIF
int optional = 0;
int cmds_loaded = 0;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 3);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
|| !ctx->engine)
goto bad_arg;
PRINTF_ERR1("Engine Id: %s\r\n", ENGINE_get_id(ctx->engine));
- // Get Command List
+ /* Command List */
if (!enif_get_list_length(env, argv[1], &cmds_len))
goto bad_arg;
@@ -326,9 +601,10 @@ ERL_NIF_TERM engine_add_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
#ifdef HAS_ENGINE_SUPPORT
struct engine_ctx *ctx;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 1);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
|| !ctx->engine)
goto bad_arg;
@@ -354,9 +630,10 @@ ERL_NIF_TERM engine_remove_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
#ifdef HAS_ENGINE_SUPPORT
struct engine_ctx *ctx;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 1);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
|| !ctx->engine)
goto bad_arg;
@@ -382,91 +659,26 @@ ERL_NIF_TERM engine_register_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
struct engine_ctx *ctx;
unsigned int method;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 2);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
|| !ctx->engine)
goto bad_arg;
if (!enif_get_uint(env, argv[1], &method))
goto bad_arg;
- switch(method)
+ switch(register_method(ctx->engine, method))
{
-#ifdef ENGINE_METHOD_RSA
- case ENGINE_METHOD_RSA:
- if (!ENGINE_register_RSA(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_DSA
- case ENGINE_METHOD_DSA:
- if (!ENGINE_register_DSA(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_DH
- case ENGINE_METHOD_DH:
- if (!ENGINE_register_DH(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_RAND
- case ENGINE_METHOD_RAND:
- if (!ENGINE_register_RAND(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_ECDH
- case ENGINE_METHOD_ECDH:
- if (!ENGINE_register_ECDH(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_ECDSA
- case ENGINE_METHOD_ECDSA:
- if (!ENGINE_register_ECDSA(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_STORE
- case ENGINE_METHOD_STORE:
- if (!ENGINE_register_STORE(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_CIPHERS
- case ENGINE_METHOD_CIPHERS:
- if (!ENGINE_register_ciphers(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_DIGESTS
- case ENGINE_METHOD_DIGESTS:
- if (!ENGINE_register_digests(ctx->engine))
- goto failed;
- break;
-#endif
-#ifdef ENGINE_METHOD_PKEY_METHS
- case ENGINE_METHOD_PKEY_METHS:
- if (!ENGINE_register_pkey_meths(ctx->engine))
- goto failed;
+ case 1:
break;
-#endif
-#ifdef ENGINE_METHOD_PKEY_ASN1_METHS
- case ENGINE_METHOD_PKEY_ASN1_METHS:
- if (!ENGINE_register_pkey_asn1_meths(ctx->engine))
- goto failed;
+ case 0:
+ goto failed;
break;
-#endif
-#ifdef ENGINE_METHOD_EC
- case ENGINE_METHOD_EC:
- if (!ENGINE_register_EC(ctx->engine))
- goto failed;
+ case -1:
+ goto not_supported;
break;
-#endif
- default:
- return ERROR_Atom(env, "engine_method_not_supported");
}
return atom_ok;
@@ -477,6 +689,9 @@ ERL_NIF_TERM engine_register_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
failed:
return ERROR_Atom(env, "register_engine_failed");
+ not_supported:
+ return ERROR_Atom(env, "engine_method_not_supported");
+
#else
return atom_notsup;
#endif
@@ -488,80 +703,17 @@ ERL_NIF_TERM engine_unregister_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
struct engine_ctx *ctx;
unsigned int method;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 2);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
|| !ctx->engine)
goto bad_arg;
if (!enif_get_uint(env, argv[1], &method))
goto bad_arg;
- switch(method)
- {
-#ifdef ENGINE_METHOD_RSA
- case ENGINE_METHOD_RSA:
- ENGINE_unregister_RSA(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_DSA
- case ENGINE_METHOD_DSA:
- ENGINE_unregister_DSA(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_DH
- case ENGINE_METHOD_DH:
- ENGINE_unregister_DH(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_RAND
- case ENGINE_METHOD_RAND:
- ENGINE_unregister_RAND(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_ECDH
- case ENGINE_METHOD_ECDH:
- ENGINE_unregister_ECDH(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_ECDSA
- case ENGINE_METHOD_ECDSA:
- ENGINE_unregister_ECDSA(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_STORE
- case ENGINE_METHOD_STORE:
- ENGINE_unregister_STORE(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_CIPHERS
- case ENGINE_METHOD_CIPHERS:
- ENGINE_unregister_ciphers(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_DIGESTS
- case ENGINE_METHOD_DIGESTS:
- ENGINE_unregister_digests(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_PKEY_METHS
- case ENGINE_METHOD_PKEY_METHS:
- ENGINE_unregister_pkey_meths(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_PKEY_ASN1_METHS
- case ENGINE_METHOD_PKEY_ASN1_METHS:
- ENGINE_unregister_pkey_asn1_meths(ctx->engine);
- break;
-#endif
-#ifdef ENGINE_METHOD_EC
- case ENGINE_METHOD_EC:
- ENGINE_unregister_EC(ctx->engine);
- break;
-#endif
- default:
- break;
- }
+ unregister_method(ctx->engine, method);
return atom_ok;
@@ -621,9 +773,10 @@ ERL_NIF_TERM engine_get_next_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
ErlNifBinary engine_bin;
struct engine_ctx *ctx, *next_ctx = NULL;
- // Get Engine
+ /* Get Arguments */
ASSERT(argc == 1);
+ /* Engine */
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
|| !ctx->engine)
goto bad_arg;
@@ -674,7 +827,7 @@ ERL_NIF_TERM engine_get_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
size_t size;
struct engine_ctx *ctx = NULL;
- // Get Engine
+ // Get arguments
ASSERT(argc == 1);
if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
@@ -744,62 +897,6 @@ ERL_NIF_TERM engine_get_name_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
#endif
}
-#ifdef HAS_ENGINE_SUPPORT
-static int get_engine_load_cmd_list(ErlNifEnv* env, const ERL_NIF_TERM term, char **cmds, int i)
-{
- ERL_NIF_TERM head, tail;
- const ERL_NIF_TERM *tmp_tuple;
- ErlNifBinary tmpbin;
- int arity;
- char *tuple1 = NULL, *tuple2 = NULL;
-
- if (enif_is_empty_list(env, term)) {
- cmds[i] = NULL;
- return 0;
- }
-
- if (!enif_get_list_cell(env, term, &head, &tail))
- goto err;
- if (!enif_get_tuple(env, head, &arity, &tmp_tuple))
- goto err;
- if (arity != 2)
- goto err;
- if (!enif_inspect_binary(env, tmp_tuple[0], &tmpbin))
- goto err;
-
- if ((tuple1 = enif_alloc(tmpbin.size + 1)) == NULL)
- goto err;
-
- (void) memcpy(tuple1, tmpbin.data, tmpbin.size);
- tuple1[tmpbin.size] = '\0';
- cmds[i] = tuple1;
- i++;
-
- if (!enif_inspect_binary(env, tmp_tuple[1], &tmpbin))
- goto err;
-
- if (tmpbin.size == 0) {
- cmds[i] = NULL;
- } else {
- if ((tuple2 = enif_alloc(tmpbin.size + 1)) == NULL)
- goto err;
- (void) memcpy(tuple2, tmpbin.data, tmpbin.size);
- tuple2[tmpbin.size] = '\0';
- cmds[i] = tuple2;
- }
- i++;
- return get_engine_load_cmd_list(env, tail, cmds, i);
-
- err:
- if (tuple1 != NULL) {
- i--;
- enif_free(tuple1);
- }
- cmds[i] = NULL;
- return -1;
-}
-#endif /* HAS_ENGINE_SUPPORT */
-
ERL_NIF_TERM engine_get_all_methods_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* () */
#ifdef HAS_ENGINE_SUPPORT
@@ -850,3 +947,271 @@ ERL_NIF_TERM engine_get_all_methods_nif(ErlNifEnv* env, int argc, const ERL_NIF_
return atom_notsup;
#endif
}
+
+ERL_NIF_TERM ensure_engine_loaded_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (EngineId, LibPath, MethodList) */
+#ifdef HAS_ENGINE_SUPPORT
+ ERL_NIF_TERM ret, result;
+ ErlNifBinary engine_id_bin,
+ library_path_bin;
+ char *engine_id = NULL,
+ *library_path = NULL;
+ unsigned int methods_len = 0;
+ unsigned int *methods = NULL;
+ int is_locked = 0;
+
+ ENGINE *engine = NULL;
+ struct engine_ctx *ctx = NULL;
+
+ /* Get Arguments */
+ ASSERT(argc == 3);
+ enif_fprintf(stderr, "ensure_engine_loaded_nif ENTER\n\n");
+
+ /* EngineId */
+ if (!enif_inspect_binary(env, argv[0], &engine_id_bin))
+ goto bad_arg;
+
+ if ((engine_id = enif_alloc(engine_id_bin.size+1)) == NULL)
+ goto bad_arg;
+
+ (void) memcpy(engine_id, engine_id_bin.data, engine_id_bin.size);
+ engine_id[engine_id_bin.size] = '\0';
+
+ /* LibPath */
+ if (!enif_inspect_binary(env, argv[1], &library_path_bin))
+ goto bad_arg;
+
+ if ((library_path = enif_alloc(library_path_bin.size+1)) == NULL)
+ goto bad_arg;
+
+ (void) memcpy(library_path, library_path_bin.data, library_path_bin.size);
+ library_path[library_path_bin.size] = '\0';
+
+ /* Method List */
+ if (!enif_get_list_length(env, argv[2], &methods_len))
+ goto bad_arg;
+ if (methods_len > UINT_MAX - 1)
+ goto bad_arg;
+ if ((size_t)methods_len > SIZE_MAX / sizeof(unsigned int))
+ goto bad_arg;
+ if ((methods = enif_alloc((methods_len) * sizeof(unsigned int))) == NULL)
+ goto bad_arg;
+ if (get_engine_method_list(env, argv[2], methods, 0))
+ goto bad_arg;
+
+ /* Loading Engine */
+ enif_mutex_lock(ensure_engine_loaded_mtx);
+ is_locked = 1;
+
+ if ((engine = ENGINE_by_id(engine_id)) != NULL)
+ {
+ enif_fprintf(stderr, "ensure_engine_loaded_nif ENGINE ALREADY LOADED\n\n");
+
+ PRINTF_ERR0("Engine already loaded, get a reference\r\n");
+ /* Get structural reference to already loaded engine */
+ if ((ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx))) == NULL) {
+ ret = enif_make_badarg(env);
+ goto err;
+ }
+ ctx->engine = engine;
+ ctx->is_functional = 0;
+ ctx->id = engine_id;
+ /* ctx now owns engine_id */
+ engine_id = NULL;
+
+ result = enif_make_resource(env, ctx);
+ ret = enif_make_tuple2(env, atom_ok, result);
+ goto done;
+
+ } else {
+ enif_fprintf(stderr, "ensure_engine_loaded_nif LOAD ENGINE\n\n");
+ PRINTF_ERR0("Load engine\r\n");
+ /* Load dynamic engine */
+ ENGINE_load_dynamic();
+ if ((engine = ENGINE_by_id("dynamic")) == NULL) {
+ PRINTF_ERR0("ensure_engine_loaded_nif; couldn't get the dynamic engine");
+ ret = ERROR_Atom(env, "bad_engine_id");
+ goto done;
+ }
+
+ /* Use dynamic engine to load the real engine */
+ /* From this point an ENGINE_free() is done on failure */
+ if(!ENGINE_ctrl_cmd_string(engine, "SO_PATH", library_path, 0)) {
+ PRINTF_ERR1("Cmd: SO_PATH:%s\r\n", library_path);
+ ret = ERROR_Atom(env, "ctrl_cmd_failed");
+ goto err;
+ }
+ if(!ENGINE_ctrl_cmd_string(engine, "ID", engine_id, 0)) {
+ PRINTF_ERR1("Cmd: ID:%s\r\n", engine_id);
+ ret = ERROR_Atom(env, "ctrl_cmd_failed");
+ goto err;
+ }
+ if(!ENGINE_ctrl_cmd_string(engine, "LOAD", NULL, 0)) {
+ PRINTF_ERR0("Cmd: LOAD:(NULL)\r\n");
+ ret = ERROR_Atom(env, "ctrl_cmd_failed");
+ goto err;
+ }
+
+ /* Add engine to OpenSSls internal list */
+ if(!ENGINE_add(engine)) {
+ ret = ERROR_Atom(env, "add_engine_failed");
+ goto err;
+ }
+
+ enif_fprintf(stderr, "ENGINE_init called!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ /* Init engine and get functional reference */
+ if (!ENGINE_init(engine)) {
+ ret = ERROR_Atom(env, "engine_init_failed");
+ goto err;
+ }
+
+ /* From this point an ENGINE_finish() is done on failure */
+ /* Register the methods that the engine handles */
+ switch(register_engine_methods(engine, methods_len, methods)) {
+ case 1:
+ break;
+ case 0:
+ ret = ERROR_Atom(env, "register_engine_failed");
+ ENGINE_finish(engine);
+ goto done;
+ break;
+ case -1:
+ ret = ERROR_Atom(env, "engine_method_not_supported");
+ ENGINE_finish(engine);
+ goto done;
+ break;
+ }
+
+ if ((ctx = enif_alloc_resource(engine_ctx_rtype, sizeof(struct engine_ctx))) == NULL) {
+ ret = enif_make_badarg(env);
+ ENGINE_finish(engine);
+ goto done;
+ }
+ ctx->engine = engine;
+ ctx->is_functional = 1;
+ ctx->id = engine_id;
+ /* ctx now owns engine_id */
+ engine_id = NULL;
+
+ result = enif_make_resource(env, ctx);
+ ret = enif_make_tuple2(env, atom_ok, result);
+ goto done;
+ }
+
+ bad_arg:
+ ret = enif_make_badarg(env);
+
+ err:
+ if(engine)
+ ENGINE_free(engine);
+
+ done:
+
+ enif_free(library_path);
+
+ if(is_locked) {
+ enif_mutex_unlock(ensure_engine_loaded_mtx);
+ is_locked = 0;
+ }
+
+ if (methods != NULL)
+ enif_free(methods);
+ if (engine_id)
+ enif_free(engine_id);
+ if (ctx)
+ enif_release_resource(ctx);
+ enif_fprintf(stderr, "ensure_engine_loaded_nif LEAVING\n\n");
+
+ return ret;
+
+#else
+ return atom_notsup;
+#endif
+}
+
+ERL_NIF_TERM ensure_engine_unloaded_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{/* (Engine, MethodList) */
+#ifdef HAS_ENGINE_SUPPORT
+ ERL_NIF_TERM ret;
+ struct engine_ctx *ctx;
+ unsigned int methods_len = 0;
+ unsigned int *methods = NULL;
+ int is_locked = 0;
+ ENGINE *tmp_engine = NULL;
+ const char *tmp_engine_id;
+
+ /* Get Arguments */
+ ASSERT(argc == 2);
+ enif_fprintf(stderr, "ensure_engine_unloaded_nif ENTER\n\n");
+
+ /* Engine */
+ if (!enif_get_resource(env, argv[0], engine_ctx_rtype, (void**)&ctx)
+ || !ctx->engine)
+ goto bad_arg;
+
+ /* Method List */
+ if (!enif_get_list_length(env, argv[1], &methods_len))
+ goto bad_arg;
+ if (methods_len > UINT_MAX - 1)
+ goto bad_arg;
+ if ((size_t)methods_len > SIZE_MAX / sizeof(unsigned int))
+ goto bad_arg;
+ if ((methods = enif_alloc((methods_len) * sizeof(unsigned int))) == NULL)
+ goto bad_arg;
+ if (get_engine_method_list(env, argv[1], methods, 0))
+ goto bad_arg;
+
+ /* Unloading Engine */
+ enif_mutex_lock(ensure_engine_loaded_mtx);
+ is_locked = 1;
+
+ /* Remove functional reference */
+ if(ctx->is_functional) {
+ enif_fprintf(stderr, "ensure_engine_unloaded_nif REMOVE FUNCTIONAL\n\n");
+
+ /* Remove engine from OpenSSls internal list if existing */
+ if((tmp_engine_id = ENGINE_get_id(ctx->engine)) != NULL)
+ if ((tmp_engine = ENGINE_by_id(tmp_engine_id)) != NULL) {
+ enif_fprintf(stderr, "ensure_engine_unloaded_nif REMOVE TAG\n\n");
+ ENGINE_free(tmp_engine);
+ if(!ENGINE_remove(ctx->engine)) {
+ ret = ERROR_Atom(env, "remove_engine_failed");
+ goto done;
+ }
+ }
+ /* Register the methods that the engine handles */
+ unregister_engine_methods(ctx->engine, methods_len, methods);
+
+ if (!ENGINE_finish(ctx->engine))
+ goto err;
+ ctx->is_functional = 0;
+ }
+
+ /* Remove structural reference */
+ enif_fprintf(stderr, "ensure_engine_unloaded_nif REMOVE STRUCTURAL\n\n");
+ if (!ENGINE_free(ctx->engine))
+ goto err;
+ ctx->engine = NULL;
+
+ ret = atom_ok;
+ goto done;
+
+ bad_arg:
+ err:
+ ret = enif_make_badarg(env);
+
+ done:
+
+ enif_free(methods);
+
+ if(is_locked) {
+ enif_mutex_unlock(ensure_engine_loaded_mtx);
+ is_locked = 0;
+ }
+ enif_fprintf(stderr, "ensure_engine_unloaded_nif LEAVING\n\n");
+ return ret;
+
+#else
+ return atom_notsup;
+#endif
+}
diff --git a/lib/crypto/c_src/engine.h b/lib/crypto/c_src/engine.h
index 4a2eed9672..f6a5a2921b 100644
--- a/lib/crypto/c_src/engine.h
+++ b/lib/crypto/c_src/engine.h
@@ -1,7 +1,7 @@
/*
* %CopyrightBegin%
*
- * Copyright Ericsson AB 2010-2018. All Rights Reserved.
+ * Copyright Ericsson AB 2010-2022. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,8 @@ char *get_key_password(ErlNifEnv *env, ERL_NIF_TERM key);
#endif /* HAS_ENGINE_SUPPORT */
int init_engine_ctx(ErlNifEnv *env);
+int create_engine_mutex(ErlNifEnv *env);
+void destroy_engine_mutex(ErlNifEnv *env);
ERL_NIF_TERM engine_by_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM engine_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
@@ -45,5 +47,6 @@ ERL_NIF_TERM engine_get_next_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
ERL_NIF_TERM engine_get_id_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM engine_get_name_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM engine_get_all_methods_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-
+ERL_NIF_TERM ensure_engine_loaded_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM ensure_engine_unloaded_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
#endif /* E_ENGINE_H__ */
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 6365961b0e..f2e2f28ce0 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -838,9 +838,9 @@ cipher_info(Type) ->
-opaque crypto_state() :: reference() .
--type crypto_opts() :: boolean()
+-type crypto_opts() :: boolean()
| [ crypto_opt() ] .
--type crypto_opt() :: {encrypt,boolean()}
+-type crypto_opt() :: {encrypt,boolean()}
| {padding, padding()} .
-type padding() :: cryptolib_padding() | otp_padding().
-type cryptolib_padding() :: none | pkcs_padding .
@@ -1906,8 +1906,8 @@ engine_unload(Engine, EngineMethods) ->
%% Release the reference from engine_by_id_nif
ok = engine_nif_wrapper(engine_free_nif(Engine))
catch
- throw:Error ->
- Error
+ throw:Error ->
+ Error
end.
%%----------------------------------------------------------------------
@@ -2024,7 +2024,8 @@ engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
-spec ensure_engine_loaded(EngineId, LibPath) ->
Result when EngineId :: unicode:chardata(),
LibPath :: unicode:chardata(),
- Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
+ Result :: {ok, Engine::engine_ref()} |
+ {error, Reason::term()}.
ensure_engine_loaded(EngineId, LibPath) ->
ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()).
@@ -2036,55 +2037,20 @@ ensure_engine_loaded(EngineId, LibPath) ->
Result when EngineId :: unicode:chardata(),
LibPath :: unicode:chardata(),
EngineMethods :: [engine_method_type()],
- Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
-ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
- try
- List = crypto:engine_list(),
- case lists:member(EngineId, List) of
- true ->
- notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)));
- false ->
- ok = notsup_to_error(engine_load_dynamic_nif()),
- case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(<<"dynamic">>))) of
- {ok, Engine} ->
- PreCommands = [{<<"SO_PATH">>, ensure_bin_chardata(LibPath)},
- {<<"ID">>, ensure_bin_chardata(EngineId)},
- <<"LOAD">>],
- ensure_engine_loaded_1(Engine, PreCommands, EngineMethods);
- {error, Error1} ->
- {error, Error1}
- end
- end
- catch
- throw:Error2 ->
- Error2
- end.
-
-ensure_engine_loaded_1(Engine, PreCmds, Methods) ->
- try
- ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
- ok = engine_nif_wrapper(engine_add_nif(Engine)),
- ok = engine_nif_wrapper(engine_init_nif(Engine)),
- ensure_engine_loaded_2(Engine, Methods),
- {ok, Engine}
- catch
- throw:Error ->
- %% The engine couldn't initialise, release the structural reference
- ok = engine_free_nif(Engine),
- throw(Error)
+ Result :: {ok, Engine::engine_ref()} |
+ {error, Reason::term()}.
+ensure_engine_loaded(EngineId, LibPath, Methods) ->
+ ConvertedMethods = [engine_method_atom_to_int(Method) ||
+ Method <- Methods],
+ case notsup_to_error(ensure_engine_loaded_nif(ensure_bin_chardata(EngineId),
+ ensure_bin_chardata(LibPath),
+ ConvertedMethods)) of
+ {ok, Engine} ->
+ {ok, Engine};
+ {error, Error1} ->
+ {error, Error1}
end.
-ensure_engine_loaded_2(Engine, Methods) ->
- try
- [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
- Method <- Methods],
- ok
- catch
- throw:Error ->
- %% The engine registration failed, release the functional reference
- ok = engine_free_nif(Engine),
- throw(Error)
- end.
%%----------------------------------------------------------------------
%% Function: ensure_engine_unloaded/1
%%----------------------------------------------------------------------
@@ -2100,19 +2066,14 @@ ensure_engine_unloaded(Engine) ->
Result when Engine :: engine_ref(),
EngineMethods :: [engine_method_type()],
Result :: ok | {error, Reason::term()}.
-ensure_engine_unloaded(Engine, EngineMethods) ->
- List = crypto:engine_list(),
- EngineId = crypto:engine_get_id(Engine),
- case lists:member(EngineId, List) of
- true ->
- case engine_remove(Engine) of
- ok ->
- engine_unload(Engine, EngineMethods);
- {error, Error} ->
- {error, Error}
- end;
- false ->
- engine_unload(Engine, EngineMethods)
+ensure_engine_unloaded(Engine, Methods) ->
+ ConvertedMethods = [engine_method_atom_to_int(Method) ||
+ Method <- Methods],
+ case notsup_to_error(ensure_engine_unloaded_nif(Engine, ConvertedMethods)) of
+ ok ->
+ ok;
+ {error, Error1} ->
+ {error, Error1}
end.
@@ -2524,6 +2485,8 @@ engine_get_next_nif(_Engine) -> ?nif_stub.
engine_get_id_nif(_Engine) -> ?nif_stub.
engine_get_name_nif(_Engine) -> ?nif_stub.
engine_get_all_methods_nif() -> ?nif_stub.
+ensure_engine_loaded_nif(_EngineId, _LibPath, _EngineMethods) -> ?nif_stub.
+ensure_engine_unloaded_nif(_Engine, _EngineMethods) -> ?nif_stub.
%%--------------------------------------------------------------------
%% Engine internals
diff --git a/lib/crypto/test/engine_SUITE.erl b/lib/crypto/test/engine_SUITE.erl
index 7da6e4e7fb..29803950fc 100644
--- a/lib/crypto/test/engine_SUITE.erl
+++ b/lib/crypto/test/engine_SUITE.erl
@@ -39,8 +39,6 @@
engine_load_all_methods/1,
engine_load_some_methods/0,
engine_load_some_methods/1,
- multiple_engine_load/0,
- multiple_engine_load/1,
engine_list/0,
engine_list/1,
get_id_and_name/0,
@@ -94,7 +92,6 @@ all() ->
get_all_possible_methods,
engine_load_all_methods,
engine_load_some_methods,
- multiple_engine_load,
engine_list,
get_id_and_name,
engine_by_id,
@@ -353,77 +350,6 @@ engine_load_some_methods(Config) when is_list(Config) ->
end
end.
-multiple_engine_load()->
- [{doc, "Use a dummy md5 engine that does not implement md5"
- "but rather returns a static binary to test that crypto:engine_load "
- "functions works when called multiple times."}].
-
-multiple_engine_load(Config) when is_list(Config) ->
- case crypto:get_test_engine() of
- {error, notexist} ->
- {skip, "OTP Test engine not found"};
- {ok, Engine} ->
- try
- Md5Hash1 = <<106,30,3,246,166,222,229,158,244,217,241,179,50,232,107,109>>,
- Md5Hash1 = crypto:hash(md5, "Don't panic"),
- Md5Hash2 = <<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15>>,
- case crypto:engine_load(<<"dynamic">>,
- [{<<"SO_PATH">>, Engine},
- <<"LOAD">>],
- []) of
- {ok, E} ->
- {ok, E1} = crypto:engine_load(<<"dynamic">>,
- [{<<"SO_PATH">>, Engine},
- <<"LOAD">>],
- []),
- {ok, E2} = crypto:engine_load(<<"dynamic">>,
- [{<<"SO_PATH">>, Engine},
- <<"LOAD">>],
- []),
- case crypto:hash(md5, "Don't panic") of
- Md5Hash1 ->
- ct:fail(fail_to_load_still_original_engine);
- Md5Hash2 ->
- ok;
- _ ->
- ct:fail(fail_to_load_engine)
- end,
- ok = crypto:engine_unload(E2),
- case crypto:hash(md5, "Don't panic") of
- Md5Hash1 ->
- ct:fail(fail_to_load_still_original_engine);
- Md5Hash2 ->
- ok;
- _ ->
- ct:fail(fail_to_load_engine)
- end,
- ok = crypto:engine_unload(E),
- case crypto:hash(md5, "Don't panic") of
- Md5Hash1 ->
- ct:fail(fail_to_load_still_original_engine);
- Md5Hash2 ->
- ok;
- _ ->
- ct:fail(fail_to_load_engine)
- end,
- ok = crypto:engine_unload(E1),
- case crypto:hash(md5, "Don't panic") of
- Md5Hash2 ->
- ct:fail(fail_to_unload_still_test_engine);
- Md5Hash1 ->
- ok;
- _ ->
- ct:fail(fail_to_unload_engine)
- end;
- {error, bad_engine_id} ->
- {skip, "Dynamic Engine not supported"}
- end
- catch
- error:notsup ->
- {skip, "Engine not supported on this SSL version"}
- end
- end.
-
engine_list()->
[{doc, "Test add and remove engine ID to the SSL internal engine list."}].
@@ -720,6 +646,7 @@ ctrl_cmd_string_optional(Config) when is_list(Config) ->
{skip, "Engine not supported on this SSL version"}
end.
+%%-------------------------------------------------------------------------
ensure_load()->
[{doc, "Test the special ensure load function."}].
@@ -733,8 +660,8 @@ ensure_load(Config) when is_list(Config) ->
Md5Hash1 = crypto:hash(md5, "Don't panic"),
Md5Hash2 = <<0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15>>,
case crypto:ensure_engine_loaded(<<"MD5">>, Engine) of
- {ok, E1} ->
- {ok, E2} = crypto:ensure_engine_loaded(<<"MD5">>, Engine),
+ {ok, E} ->
+
case crypto:hash(md5, "Don't panic") of
Md5Hash1 ->
ct:fail(fail_to_load_still_original_engine);
@@ -744,50 +671,76 @@ ensure_load(Config) when is_list(Config) ->
ct:fail(fail_to_load_engine)
end,
- {ok, E3} = crypto:engine_by_id(<<"MD5">>),
-
- ok = crypto:ensure_engine_unloaded(E3),
+ {ok, E1} = crypto:ensure_engine_loaded(<<"MD5">>, Engine),
case crypto:hash(md5, "Don't panic") of
Md5Hash1 ->
+ ct:fail(fail_to_load_still_original_engine);
+ Md5Hash2 ->
ok;
+ _ ->
+ ct:fail(fail_to_load_engine)
+ end,
+
+ ok = crypto:ensure_engine_unloaded(E1),
+ case crypto:hash(md5, "Don't panic") of
+ Md5Hash1 ->
+ ct:fail(fail_test_engine_unloaded);
Md5Hash2 ->
- ct:fail(fail_to_unload_still_test_engine);
+ ok;
_ ->
- ct:fail(load_engine)
+ ct:fail(fail_to_unload_engine)
end,
- %% ToDo: Why doesn't this work?
- %% {ok, E4} = crypto:ensure_engine_loaded(<<"MD5">>, Engine),
- %% case crypto:hash(md5, "Don't panic") of
- %% Md5Hash1 ->
- %% ct:fail(fail_to_load_still_original_engine);
- %% Md5Hash2 ->
- %% ok;
- %% _ ->
- %% ct:fail(fail_to_load_engine)
- %% end,
+ {ok, E2} = crypto:ensure_engine_loaded(<<"MD5">>, Engine),
+ case crypto:hash(md5, "Don't panic") of
+ Md5Hash1 ->
+ ct:fail(fail_test_engine_not_loaded);
+ Md5Hash2 ->
+ ok;
+ _ ->
+ ct:fail(fail_to_load_engine)
+ end,
+ ok = crypto:ensure_engine_unloaded(E2),
- ok = crypto:ensure_engine_unloaded(E1),
+ {ok, E3} = crypto:ensure_engine_loaded(<<"MD5">>, Engine),
+ case crypto:hash(md5, "Don't panic") of
+ Md5Hash1 ->
+ ct:fail(fail_test_engine_not_loaded);
+ Md5Hash2 ->
+ ok;
+ _ ->
+ ct:fail(fail_to_load_engine)
+ end,
+
+ ok = crypto:ensure_engine_unloaded(E),
case crypto:hash(md5, "Don't panic") of
+ Md5Hash1 ->
+ ok;
Md5Hash2 ->
ct:fail(fail_to_unload_still_test_engine);
+ _ ->
+ ct:fail(fail_to_unload_engine)
+ end,
+
+ ok = crypto:ensure_engine_unloaded(E3),
+ case crypto:hash(md5, "Don't panic") of
Md5Hash1 ->
- ok = crypto:ensure_engine_unloaded(E2),
- %% ok = crypto:ensure_engine_unloaded(E4);
ok;
+ Md5Hash2 ->
+ ct:fail(fail_to_unload_still_test_engine);
_ ->
ct:fail(fail_to_unload_engine)
end;
+
{error, bad_engine_id} ->
{skip, "Dynamic Engine not supported"}
end
catch
error:notsup ->
- {skip, "Engine not supported on this SSL version"}
+ {skip, "Engine not supported on this SSL version"}
end
end.
-
%%%----------------------------------------------------------------
%%% Pub/priv key storage tests. Those are for testing the crypto.erl
%%% support for using priv/pub keys stored in an engine.