summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Avdey <eiri@eiri.ca>2020-03-25 01:10:36 -0300
committerEric Avdey <eiri@eiri.ca>2020-04-07 02:37:10 -0300
commite60987469250e908eb93d8d0286cef2fa83c31e1 (patch)
tree6c532bb9a2222dd1f486ed4c54d27a55b5ae235c
parent8ac9b6bf6fb6ed0bc91735c3de8ae392a10f3ad6 (diff)
downloadcouchdb-e60987469250e908eb93d8d0286cef2fa83c31e1.tar.gz
Revert from using update counter back to doc revs for key derivation
This reverts commit 8f9a988c875973a530806be492cb731b55bf7d12.
-rw-r--r--src/fabric/src/fabric2_encryption.erl46
-rw-r--r--src/fabric/src/fabric2_fdb.erl29
2 files changed, 33 insertions, 42 deletions
diff --git a/src/fabric/src/fabric2_encryption.erl b/src/fabric/src/fabric2_encryption.erl
index c440c3d59..95d470f10 100644
--- a/src/fabric/src/fabric2_encryption.erl
+++ b/src/fabric/src/fabric2_encryption.erl
@@ -54,24 +54,22 @@ get_wrapped_kek(DbName) when is_binary(DbName) ->
end.
-encode(WrappedKEK, DbName, DocId, UpdateCounter, DocBody)
+encode(WrappedKEK, DbName, DocId, DocRev, DocBody)
when is_binary(WrappedKEK),
is_binary(DbName),
is_binary(DocId),
- is_integer(UpdateCounter), UpdateCounter > 0,
+ is_binary(DocRev),
is_binary(DocBody) ->
- gen_server:call(?MODULE,
- {encode, WrappedKEK, DbName, DocId, UpdateCounter, DocBody}).
+ gen_server:call(?MODULE, {encode, WrappedKEK, DbName, DocId, DocRev, DocBody}).
-decode(WrappedKEK, DbName, DocId, UpdateCounter, DocBody)
+decode(WrappedKEK, DbName, DocId, DocRev, DocBody)
when is_binary(WrappedKEK),
is_binary(DbName),
is_binary(DocId),
- is_integer(UpdateCounter), UpdateCounter > 0,
+ is_binary(DocRev),
is_binary(DocBody) ->
- gen_server:call(?MODULE,
- {decode, WrappedKEK, DbName, DocId, UpdateCounter, DocBody}).
+ gen_server:call(?MODULE, {decode, WrappedKEK, DbName, DocId, DocRev, DocBody}).
@@ -97,8 +95,7 @@ handle_call({get_wrapped_kek, DbName}, _From, #{cache := Cache} = St) ->
true = ets:insert(Cache, {WrappedKEK, KEK}),
{reply, {ok, WrappedKEK}, St};
-handle_call({encode, WrappedKEK, DbName, DocId, UpdateCounter, DocBody},
- From, St) ->
+handle_call({encode, WrappedKEK, DbName, DocId, DocRev, DocBody}, From, St) ->
#{
iid := InstanceId,
cache := Cache,
@@ -107,15 +104,14 @@ handle_call({encode, WrappedKEK, DbName, DocId, UpdateCounter, DocBody},
{ok, KEK} = unwrap_kek(Cache, WrappedKEK),
{Pid, _Ref} = erlang:spawn_monitor(?MODULE,
- do_encode, [KEK, InstanceId, DbName, DocId, UpdateCounter, DocBody]),
+ do_encode, [KEK, InstanceId, DbName, DocId, DocRev, DocBody]),
NewSt = St#{
waiters := dict:store(Pid, From, Waiters)
},
{noreply, NewSt};
-handle_call({decode, WrappedKEK, DbName, DocId, UpdateCounter, Encoded},
- From, St) ->
+handle_call({decode, WrappedKEK, DbName, DocId, DocRev, Encoded}, From, St) ->
#{
iid := InstanceId,
cache := Cache,
@@ -124,7 +120,7 @@ handle_call({decode, WrappedKEK, DbName, DocId, UpdateCounter, Encoded},
{ok, KEK} = unwrap_kek(Cache, WrappedKEK),
{Pid, _Ref} = erlang:spawn_monitor(?MODULE,
- do_decode, [KEK, InstanceId, DbName, DocId, UpdateCounter, Encoded]),
+ do_decode, [KEK, InstanceId, DbName, DocId, DocRev, Encoded]),
NewSt = St#{
waiters := dict:store(Pid, From, Waiters)
@@ -167,10 +163,10 @@ init_st() ->
}}.
-do_encode(KEK, InstanceId, DbName, DocId, UpdateCounter, DocBody) ->
+do_encode(KEK, InstanceId, DbName, DocId, DocRev, DocBody) ->
try
{ok, AAD} = get_aad(InstanceId, DbName),
- {ok, DEK} = get_dek(KEK, DocId, UpdateCounter),
+ {ok, DEK} = get_dek(KEK, DocId, DocRev),
{CipherText, CipherTag} = crypto:block_encrypt(
aes_gcm, DEK, <<0:96>>, {AAD, DocBody, 16}),
<<CipherTag/binary, CipherText/binary>>
@@ -183,11 +179,11 @@ do_encode(KEK, InstanceId, DbName, DocId, UpdateCounter, DocBody) ->
end.
-do_decode(KEK, InstanceId, DbName, DocId, UpdateCounter, Encoded) ->
+do_decode(KEK, InstanceId, DbName, DocId, DocRev, Encoded) ->
try
<<CipherTag:16/binary, CipherText/binary>> = Encoded,
{ok, AAD} = get_aad(InstanceId, DbName),
- {ok, DEK} = get_dek(KEK, DocId, UpdateCounter),
+ {ok, DEK} = get_dek(KEK, DocId, DocRev),
crypto:block_decrypt(
aes_gcm, DEK, <<0:96>>, {AAD, CipherText, CipherTag})
of
@@ -203,8 +199,8 @@ get_aad(InstanceId, DbName) when is_binary(InstanceId), is_binary(DbName) ->
{ok, <<InstanceId/binary, 0:8, DbName/binary>>}.
-get_dek(KEK, DocId, UpdateCounter) when bit_size(KEK) == 256 ->
- Context = <<DocId/binary, 0:8, (integer_to_binary(UpdateCounter))/binary>>,
+get_dek(KEK, DocId, DocRev) when bit_size(KEK) == 256 ->
+ Context = <<DocId/binary, 0:8, DocRev/binary>>,
PlainText = <<1:16, ?LABEL, 0:8, Context/binary, 256:16>>,
<<_:256>> = DEK = crypto:hmac(sha256, KEK, PlainText),
{ok, DEK}.
@@ -228,24 +224,24 @@ unwrap_kek(Cache, WrappedKEK) ->
get_dek_test() ->
KEK = crypto:strong_rand_bytes(32),
- {ok, DEK} = get_dek(KEK, <<"0001">>, 1),
+ {ok, DEK} = get_dek(KEK, <<"0001">>, <<"1-abcdefgh">>),
?assertNotEqual(KEK, DEK),
?assertEqual(32, byte_size(DEK)).
encode_decode_test() ->
KEK = crypto:strong_rand_bytes(32),
- {IId, DbName, DocId, UpdateCounter, DocBody}
- = {<<"dev">>, <<"db">>, <<"0001">>, 1, <<"[ohai]">>},
+ {IId, DbName, DocId, DocRev, DocBody}
+ = {<<"dev">>, <<"db">>, <<"0001">>, <<"1-abcdefgh">>, <<"[ohai]">>},
{ok, EncResult} = try
- do_encode(KEK, IId, DbName, DocId, UpdateCounter, DocBody)
+ do_encode(KEK, IId, DbName, DocId, DocRev, DocBody)
catch
exit:ER -> ER
end,
?assertNotEqual(DocBody, EncResult),
{ok, DecResult} = try
- do_decode(KEK, IId, DbName, DocId, UpdateCounter, EncResult)
+ do_decode(KEK, IId, DbName, DocId, DocRev, EncResult)
catch
exit:DR -> DR
end,
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index 3ecf4769b..0f00bf0eb 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -207,7 +207,6 @@ create(#{} = Db0, Options) ->
{?DB_STATS, <<"doc_del_count">>, ?uint2bin(0)},
{?DB_STATS, <<"doc_design_count">>, ?uint2bin(0)},
{?DB_STATS, <<"doc_local_count">>, ?uint2bin(0)},
- {?DB_STATS, <<"update_count">>, ?uint2bin(1)},
{?DB_STATS, <<"sizes">>, <<"external">>, ?uint2bin(2)},
{?DB_STATS, <<"sizes">>, <<"views">>, ?uint2bin(0)}
],
@@ -849,7 +848,6 @@ write_doc(#{} = Db0, Doc, NewWinner0, OldWinner, ToUpdate, ToRemove) ->
AddSize = sum_add_rev_sizes([NewWinner | ToUpdate]),
RemSize = sum_rem_rev_sizes(ToRemove),
incr_stat(Db, <<"sizes">>, <<"external">>, AddSize - RemSize),
- incr_stat(Db, <<"update_count">>, 1),
ok.
@@ -1377,20 +1375,18 @@ doc_to_fdb(Db, #doc{} = Doc) ->
DiskAtts = lists:map(fun couch_att:to_disk_term/1, Atts),
- ValueTerm = case WrappedKEK of
+ Value = case WrappedKEK of
false ->
- {Body, DiskAtts, Deleted};
+ term_to_binary({Body, DiskAtts, Deleted}, [{minor_version, 1}]);
_ ->
- UpdateCounter = get_stat(Db, <<"update_count">>),
+ BinRev = couch_doc:rev_to_str({Start, Rev}),
BinBody = term_to_binary(Body,
[{compressed, 0}, {minor_version, 1}]),
{ok, Encoded} = fabric2_encryption:encode(
- WrappedKEK, DbName, Id, UpdateCounter, BinBody),
- {UpdateCounter, Encoded, DiskAtts, Deleted}
+ WrappedKEK, DbName, Id, BinRev, BinBody),
+ term_to_binary({Encoded, DiskAtts, Deleted}, [{minor_version, 1}])
end,
- Value = term_to_binary(ValueTerm, [{minor_version, 1}]),
-
Chunks = chunkify_binary(Value),
{Rows, _} = lists:mapfoldl(fun(Chunk, ChunkId) ->
@@ -1404,24 +1400,23 @@ doc_to_fdb(Db, #doc{} = Doc) ->
fdb_to_doc(_Db, _DocId, _Pos, _Path, []) ->
{not_found, missing};
-fdb_to_doc(Db, DocId, Pos, Path, BinRows) when is_list(BinRows) ->
+fdb_to_doc(Db, DocId, Pos, [Rev | _] = Path, BinRows) when is_list(BinRows) ->
#{
name := DbName,
wrapped_kek := WrappedKEK
} = Db,
Bin = iolist_to_binary(BinRows),
- ValueTerm = binary_to_term(Bin, [safe]),
+ {Encoded, DiskAtts, Deleted} = binary_to_term(Bin, [safe]),
- {Body, DiskAtts, Deleted} = case WrappedKEK of
+ Body = case WrappedKEK of
false ->
- ValueTerm;
+ Encoded;
_ ->
- {UpdateCounter, Encoded, DiskAtts0, Deleted0} = ValueTerm,
+ BinRev = couch_doc:rev_to_str({Pos, Rev}),
{ok, BinBody} = fabric2_encryption:decode(
- WrappedKEK, DbName, DocId, UpdateCounter, Encoded),
- Body0 = binary_to_term(BinBody, [safe]),
- {Body0, DiskAtts0, Deleted0}
+ WrappedKEK, DbName, DocId, BinRev, Encoded),
+ binary_to_term(BinBody, [safe])
end,
Atts = lists:map(fun(Att) ->