summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Avdey <eiri@eiri.ca>2020-04-16 14:50:55 -0300
committerEric Avdey <eiri@eiri.ca>2020-04-17 00:09:43 -0300
commit80d75e8e2a41023fac10ff8f5c689d4a5eb564cd (patch)
treecab29f96689619c1eabd1f977ffa2695ffb8e140
parenta76694cc6b56a2bce8f4e40340f7f6fac184c9a5 (diff)
downloadcouchdb-80d75e8e2a41023fac10ff8f5c689d4a5eb564cd.tar.gz
Return error if can't unwrap a key
-rw-r--r--src/aegis/src/aegis_key_cache.erl28
-rw-r--r--src/aegis/test/aegis_key_cache_test.erl31
2 files changed, 54 insertions, 5 deletions
diff --git a/src/aegis/src/aegis_key_cache.erl b/src/aegis/src/aegis_key_cache.erl
index 9e4ba2fd4..aac946c0e 100644
--- a/src/aegis/src/aegis_key_cache.erl
+++ b/src/aegis/src/aegis_key_cache.erl
@@ -196,6 +196,22 @@ maybe_spawn_worker(St, From, Action, #{aegis := WrappedKey} = Db, Key, Value) ->
end.
+maybe_reply(St, Ref, {key, {error, WrappedKey, Error}}) ->
+ #{
+ waiters := Waiters
+ } = St,
+
+ Reply = {error, Error},
+
+ NewSt = case dict:take(WrappedKey, Waiters) of
+ {WaitList, Waiters1} ->
+ [ gen_server:reply(From, Reply) || #{from := From} <- WaitList ],
+ St#{waiters := Waiters1};
+ error ->
+ St
+ end,
+ maybe_reply(NewSt, Ref, Reply);
+
maybe_reply(#{clients := Clients} = St, Ref, Resp) ->
case dict:take(Ref, Clients) of
{From, Clients1} ->
@@ -224,16 +240,18 @@ get_wrapped_key(#{} = _Db) ->
unwrap_key(#{aegis := WrappedKey} = _Db) ->
process_flag(sensitive, true),
try
- %% this could be atom fail, throw error is so !!
- DbKey = aegis_keywrap:key_unwrap(?ROOT_KEY, WrappedKey),
- {ok, DbKey, WrappedKey}
+ case aegis_keywrap:key_unwrap(?ROOT_KEY, WrappedKey) of
+ fail ->
+ error(decryption_failed);
+ DbKey ->
+ {ok, DbKey, WrappedKey}
+ end
of
Resp ->
exit({key, Resp})
catch
_:Error ->
- %% FIXME! add tag key and WrappedKey so we can respond to Waiters
- exit({error, Error})
+ exit({key, {error, WrappedKey, Error}})
end.
diff --git a/src/aegis/test/aegis_key_cache_test.erl b/src/aegis/test/aegis_key_cache_test.erl
index e18eb34f0..f9b189412 100644
--- a/src/aegis/test/aegis_key_cache_test.erl
+++ b/src/aegis/test/aegis_key_cache_test.erl
@@ -93,6 +93,7 @@ test_decrypt() ->
?assertEqual(1, meck:num_calls(aegis_keywrap, key_unwrap, 2)),
?assertEqual(12, meck:num_calls(aegis, decrypt, 4)).
+
test_multibase() ->
?assertEqual(0, meck:num_calls(aegis_keywrap, key_unwrap, 2)),
?assertEqual(0, meck:num_calls(aegis, encrypt, 4)),
@@ -111,3 +112,33 @@ test_multibase() ->
?assertEqual(12, meck:num_calls(aegis_keywrap, key_unwrap, 2)),
?assertEqual(120, meck:num_calls(aegis, encrypt, 4)),
?assertEqual(120, meck:num_calls(aegis, decrypt, 4)).
+
+
+
+error_test_() ->
+ {
+ foreach,
+ fun() ->
+ Ctx = setup(),
+ ok = meck:delete(aegis_keywrap, key_unwrap, 2),
+ ok = meck:expect(aegis_keywrap, key_unwrap, 2, fail),
+ Ctx
+ end,
+ fun teardown/1,
+ [
+ {"return error when unwrap fail on encrypt",
+ {timeout, ?TIMEOUT, fun test_encrypt_error/0}},
+ {"return error when unwrap fail on decrypt",
+ {timeout, ?TIMEOUT, fun test_decrypt_error/0}}
+ ]
+ }.
+
+
+test_encrypt_error() ->
+ Reply = gen_server:call(?SERVER, {encrypt, ?DB, <<1:64>>, ?VALUE}),
+ ?assertEqual({error, decryption_failed}, Reply).
+
+
+test_decrypt_error() ->
+ Reply = gen_server:call(?SERVER, {decrypt, ?DB, <<1:64>>, ?VALUE}),
+ ?assertEqual({error, decryption_failed}, Reply).