diff options
author | Eric Avdey <eiri@eiri.ca> | 2020-03-25 01:10:36 -0300 |
---|---|---|
committer | Eric Avdey <eiri@eiri.ca> | 2020-04-07 02:37:10 -0300 |
commit | e60987469250e908eb93d8d0286cef2fa83c31e1 (patch) | |
tree | 6c532bb9a2222dd1f486ed4c54d27a55b5ae235c | |
parent | 8ac9b6bf6fb6ed0bc91735c3de8ae392a10f3ad6 (diff) | |
download | couchdb-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.erl | 46 | ||||
-rw-r--r-- | src/fabric/src/fabric2_fdb.erl | 29 |
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) -> |