From 5b51f9d9875750f27f2fa8a75f22e0fcb9a6bec0 Mon Sep 17 00:00:00 2001 From: Lars Thorsen Date: Wed, 15 Aug 2018 12:26:44 +0200 Subject: Updated the engine load functionality - engine_load/3/4 can be called multiple times for same engine if it allows it (eg doesn't contain global data) - ensure_engine_loaded/2/3 is new functions that guarantees that the engine is just loaded once by adding it to OpenSSL internal engine list and check that before loading. - ensure_engine_unloaded/1/2 is new functions that is used to unload engines loaded with ensure_engine_loaded (remove it from OpenSSL internal engine list and then unload). - new utility functions engine_by_id/1, engine_add/1, engine_remove/1, engine_get_id/1 and engine_get_name/1 --- lib/crypto/test/engine_SUITE.erl | 280 ++++++++++++++++++++++++++++++++++----- 1 file changed, 244 insertions(+), 36 deletions(-) (limited to 'lib/crypto/test/engine_SUITE.erl') diff --git a/lib/crypto/test/engine_SUITE.erl b/lib/crypto/test/engine_SUITE.erl index f410542f72..891eaff23b 100644 --- a/lib/crypto/test/engine_SUITE.erl +++ b/lib/crypto/test/engine_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2017-2017. All Rights Reserved. +%% Copyright Ericsson AB 2017-2018. 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. @@ -39,6 +39,10 @@ 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, bad_arguments, unknown_engine, pre_command_fail_bad_value, @@ -46,6 +50,7 @@ all() -> failed_engine_init, ctrl_cmd_string, ctrl_cmd_string_optional, + ensure_load, {group, engine_stored_key} ]. @@ -95,7 +100,7 @@ init_per_group(engine_stored_key, Config) -> {error, notexist} -> {skip, "OTP Test engine not found"}; {error, notsup} -> - {skip, "Engine not supported on this OpenSSL version"}; + {skip, "Engine not supported on this SSL version"}; {error, bad_engine_id} -> {skip, "Dynamic Engine not supported"}; Other -> @@ -130,11 +135,12 @@ get_all_possible_methods() -> get_all_possible_methods(Config) when is_list(Config) -> try List = crypto:engine_get_all_methods(), + true = erlang:is_list(List), ct:log("crypto:engine_get_all_methods() -> ~p\n", [List]), ok catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end. engine_load_all_methods()-> @@ -147,13 +153,12 @@ engine_load_all_methods(Config) when is_list(Config) -> {error, notexist} -> {skip, "OTP Test engine not found"}; {ok, Engine} -> - try + 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}, - {<<"ID">>, <<"MD5">>}, <<"LOAD">>], []) of {ok, E} -> @@ -179,7 +184,7 @@ engine_load_all_methods(Config) when is_list(Config) -> end catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end end. @@ -193,21 +198,20 @@ engine_load_some_methods(Config) when is_list(Config) -> {error, notexist} -> {skip, "OTP Test engine not found"}; {ok, Engine} -> - try + 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>>, EngineMethods = crypto:engine_get_all_methods() -- - [engine_method_dh,engine_method_rand, + [engine_method_dh, engine_method_rand, engine_method_ciphers, engine_method_store, engine_method_pkey_meths, engine_method_pkey_asn1_meths], case crypto:engine_load(<<"dynamic">>, [{<<"SO_PATH">>, Engine}, - {<<"ID">>, <<"MD5">>}, <<"LOAD">>], [], EngineMethods) of - {ok, E} -> + {ok, E} -> case crypto:hash(md5, "Don't panic") of Md5Hash1 -> ct:fail(fail_to_load_engine_still_original); @@ -230,7 +234,168 @@ engine_load_some_methods(Config) when is_list(Config) -> end catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} + 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."}]. + +engine_list(Config) when is_list(Config) -> + case crypto:get_test_engine() of + {error, notexist} -> + {skip, "OTP Test engine not found"}; + {ok, Engine} -> + try + EngineList0 = crypto:engine_list(), + case crypto:engine_load(<<"dynamic">>, + [{<<"SO_PATH">>, Engine}, + <<"LOAD">>], + []) of + {ok, E} -> + EngineList0 = crypto:engine_list(), + ok = crypto:engine_add(E), + [<<"MD5">>] = lists:subtract(crypto:engine_list(), EngineList0), + ok = crypto:engine_remove(E), + EngineList0 = crypto:engine_list(), + ok = crypto:engine_unload(E); + {error, bad_engine_id} -> + {skip, "Dynamic Engine not supported"} + end + catch + error:notsup -> + {skip, "Engine not supported on this SSL version"} + end + end. + +get_id_and_name()-> + [{doc, "Test fetching id and name from an engine."}]. + +get_id_and_name(Config) when is_list(Config) -> + case crypto:get_test_engine() of + {error, notexist} -> + {skip, "OTP Test engine not found"}; + {ok, Engine} -> + try + case crypto:engine_load(<<"dynamic">>, + [{<<"SO_PATH">>, Engine}, + <<"LOAD">>], + []) of + {ok, E} -> + <<"MD5">> = crypto:engine_get_id(E), + <<"MD5 test engine">> = crypto:engine_get_name(E), + ok = crypto:engine_unload(E); + {error, bad_engine_id} -> + {skip, "Dynamic Engine not supported"} + end + catch + error:notsup -> + {skip, "Engine not supported on this SSL version"} + end + end. + +engine_by_id()-> + [{doc, "Test fetching a new reference the the engine when the" + "engine id is added to the SSL engine list."}]. + +engine_by_id(Config) when is_list(Config) -> + case crypto:get_test_engine() of + {error, notexist} -> + {skip, "OTP Test engine not found"}; + {ok, Engine} -> + try + case crypto:engine_load(<<"dynamic">>, + [{<<"SO_PATH">>, Engine}, + <<"LOAD">>], + []) of + {ok, E} -> + case crypto:engine_by_id(<<"MD5">>) of + {error,bad_engine_id} -> + ok; + {ok, _} -> + ct:fail(fail_engine_found) + end, + ok = crypto:engine_add(E), + {ok, _E1} = crypto:engine_by_id(<<"MD5">>), + ok = crypto:engine_remove(E), + ok = crypto:engine_unload(E); + {error, bad_engine_id} -> + {skip, "Dynamic Engine not supported"} + end + catch + error:notsup -> + {skip, "Engine not supported on this SSL version"} end end. @@ -244,7 +409,7 @@ bad_arguments(Config) when is_list(Config) -> {error, notexist} -> {skip, "OTP Test engine not found"}; {ok, Engine} -> - try + try try crypto:engine_load(fail_engine, [], []) catch @@ -274,7 +439,7 @@ bad_arguments(Config) when is_list(Config) -> end catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end end. @@ -287,7 +452,7 @@ unknown_engine(Config) when is_list(Config) -> ok catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end. pre_command_fail_bad_value() -> @@ -309,7 +474,7 @@ pre_command_fail_bad_value(Config) when is_list(Config) -> end catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end. pre_command_fail_bad_key() -> @@ -332,9 +497,9 @@ pre_command_fail_bad_key(Config) when is_list(Config) -> {skip, "Dynamic Engine not supported"} end end - catch + catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end. failed_engine_init()-> @@ -350,18 +515,20 @@ failed_engine_init(Config) when is_list(Config) -> [{<<"SO_PATH">>, Engine}, {<<"ID">>, <<"MD5">>}], []) of - {error, add_engine_failed} -> + {error, engine_init_failed} -> ok; {error, bad_engine_id} -> {skip, "Dynamic Engine not supported"} end end - catch + catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} + {skip, "Engine not supported on this SSL version"} end. +%%------------------------------------------------------------------------- +%% Test the optional flag in ctrl comands ctrl_cmd_string()-> [{doc, "Test that a not known optional ctrl comand do not fail"}]. ctrl_cmd_string(Config) when is_list(Config) -> @@ -375,22 +542,22 @@ ctrl_cmd_string(Config) when is_list(Config) -> {<<"ID">>, <<"MD5">>}, <<"LOAD">>], []) of - {ok, E} -> + {ok, E} -> case crypto:engine_ctrl_cmd_string(E, <<"TEST">>, <<"17">>) of ok -> ct:fail(fail_ctrl_cmd_should_fail); - {error,ctrl_cmd_failed} -> + {error,ctrl_cmd_failed} -> ok end, - ok = crypto:engine_unload(E); + ok = crypto:engine_unload(E); {error, bad_engine_id} -> {skip, "Dynamic Engine not supported"} end end - catch + catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} - end. + {skip, "Engine not supported on this SSL version"} + end. ctrl_cmd_string_optional()-> [{doc, "Test that a not known optional ctrl comand do not fail"}]. @@ -405,22 +572,63 @@ ctrl_cmd_string_optional(Config) when is_list(Config) -> {<<"ID">>, <<"MD5">>}, <<"LOAD">>], []) of - {ok, E} -> + {ok, E} -> case crypto:engine_ctrl_cmd_string(E, <<"TEST">>, <<"17">>, true) of ok -> ok; - _ -> + _ -> ct:fail(fail_ctrl_cmd_string) end, - ok = crypto:engine_unload(E); + ok = crypto:engine_unload(E); {error, bad_engine_id} -> {skip, "Dynamic Engine not supported"} end end - catch + catch error:notsup -> - {skip, "Engine not supported on this OpenSSL version"} - end. + {skip, "Engine not supported on this SSL version"} + end. + +ensure_load()-> + [{doc, "Test the special ensure load function."}]. + +ensure_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:ensure_engine_loaded(<<"MD5">>, Engine) of + {ok, E} -> + {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(E), + 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. %%%---------------------------------------------------------------- %%% Pub/priv key storage tests. Thoose are for testing the crypto.erl @@ -465,7 +673,7 @@ sign_verify_rsa_pwd_bad_pwd(Config) -> _ -> {fail, "PWD prot pubkey sign succeded with no pwd!"} catch error:badarg -> ok - end. + end. priv_encrypt_pub_decrypt_rsa(Config) -> Priv = #{engine => engine_ref(Config), @@ -538,7 +746,7 @@ get_pub_from_priv_key_rsa_pwd_no_pwd(Config) -> {skip, "RSA not supported"}; {error, Error} -> {fail, {wrong_error,Error}}; - Pub -> + Pub -> ct:log("rsa Pub = ~p",[Pub]), {fail, "PWD prot pubkey fetch succeded although no pwd!"} end. @@ -554,7 +762,7 @@ get_pub_from_priv_key_rsa_pwd_bad_pwd(Config) -> {skip, "RSA not supported"}; {error, Error} -> {fail, {wrong_error,Error}}; - Pub -> + Pub -> ct:log("rsa Pub = ~p",[Pub]), {fail, "PWD prot pubkey fetch succeded with bad pwd!"} end. @@ -588,7 +796,7 @@ get_pub_from_priv_key_ecdsa(Config) -> ct:log("ecdsa Pub = ~p",[Pub]), sign_verify(ecdsa, sha, Priv, Pub) end. - + %%%================================================================ %%% Help for engine_stored_pub_priv_keys* test cases %%% -- cgit v1.2.3