CDS-88: Add security parameters to keyring meta (#5)

* CDS-88: Add security parameters to keyring meta

* CDS-88: Rename security_parameters in config to new_key_security_parameters

* CDS-88: Refactor security_parameters encoding/decoding

* CDS-88: Rename
This commit is contained in:
ndiezel0 2019-07-05 17:26:04 +03:00 committed by GitHub
parent 6114ce6a0e
commit a92c0a6687
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 174 additions and 22 deletions

View File

@ -40,11 +40,19 @@
-define(KEY_BYTESIZE, 32). -define(KEY_BYTESIZE, 32).
-define(FORMAT_VERSION, 1). -define(FORMAT_VERSION, 1).
-define(DEFAULT_SEC_PARAMS, #{
deduplication_hash_opts => #{
n => 16384,
r => 8,
p => 1
}
}).
%% %%
-spec new() -> keyring(). -spec new() -> keyring().
new() -> new() ->
SecurityParameters = application:get_env(kds, new_key_security_parameters, ?DEFAULT_SEC_PARAMS),
#{ #{
data => #{ data => #{
keys => #{0 => kds_crypto:key()} keys => #{0 => kds_crypto:key()}
@ -54,7 +62,8 @@ new() ->
version => 1, version => 1,
keys => #{ keys => #{
0 => #{ 0 => #{
retired => false retired => false,
security_parameters => SecurityParameters
} }
} }
} }
@ -63,6 +72,7 @@ new() ->
-spec rotate(keyring()) -> keyring(). -spec rotate(keyring()) -> keyring().
rotate(#{data := #{keys := Keys}, meta := #{current_key_id := CurrentKeyId, version := Version, keys := KeysMeta}}) -> rotate(#{data := #{keys := Keys}, meta := #{current_key_id := CurrentKeyId, version := Version, keys := KeysMeta}}) ->
MaxKeyId = lists:max(maps:keys(Keys)), MaxKeyId = lists:max(maps:keys(Keys)),
SecurityParameters = application:get_env(kds, new_key_security_parameters, ?DEFAULT_SEC_PARAMS),
NewMaxKeyId = MaxKeyId + 1, NewMaxKeyId = MaxKeyId + 1,
#{ #{
data => #{ data => #{
@ -71,7 +81,7 @@ rotate(#{data := #{keys := Keys}, meta := #{current_key_id := CurrentKeyId, vers
meta => #{ meta => #{
current_key_id => CurrentKeyId, current_key_id => CurrentKeyId,
version => Version + 1, version => Version + 1,
keys => KeysMeta#{NewMaxKeyId => #{retired => false}} keys => KeysMeta#{NewMaxKeyId => #{retired => false, security_parameters => SecurityParameters}}
} }
}. }.

View File

@ -7,8 +7,10 @@
-export([update_meta/2]). -export([update_meta/2]).
-export([decode_keyring_meta_diff/1]). -export([decode_keyring_meta_diff/1]).
-export([decode_keyring_meta/1]). -export([decode_keyring_meta/1]).
-export([decode_security_parameters/1]).
-export([encode_keyring_meta_diff/1]). -export([encode_keyring_meta_diff/1]).
-export([encode_keyring_meta/1]). -export([encode_keyring_meta/1]).
-export([encode_security_parameters/1]).
-export_type([keyring_meta/0]). -export_type([keyring_meta/0]).
-export_type([keyring_meta_diff/0]). -export_type([keyring_meta_diff/0]).
@ -23,21 +25,33 @@
-type keyring_meta_diff() :: #{ -type keyring_meta_diff() :: #{
current_key_id => non_neg_integer() | undefined, current_key_id => non_neg_integer() | undefined,
keys => #{ keys => #{
key_id() => key_meta() key_id() => key_meta_diff()
} | undefined } | undefined
}. }.
-type key_meta() :: #{ -type key_meta() :: #{
retired := boolean(),
security_parameters := security_parameters()
}.
-type key_meta_diff() :: #{
retired := boolean() retired := boolean()
}. }.
-type security_parameters() :: #{
deduplication_hash_opts := #{
n := pos_integer(),
r := pos_integer(),
p := pos_integer()
}
}.
-type key_id() :: kds_keyring:key_id(). -type key_id() :: kds_keyring:key_id().
-type encoded_keyring_meta() :: #'KeyringMeta'{}. -type encoded_keyring_meta() :: #'KeyringMeta'{}.
-type encoded_keyring_meta_diff() :: #'KeyringMetaDiff'{}. -type encoded_keyring_meta_diff() :: #'KeyringMetaDiff'{}.
-type encoded_security_parameters() :: #'SecurityParameters'{}.
-spec get_default_keyring_meta(kds_keyring:keyring_data()) -> keyring_meta(). -spec get_default_keyring_meta(kds_keyring:keyring_data()) -> keyring_meta().
get_default_keyring_meta(KeyringData) -> get_default_keyring_meta(KeyringData) ->
Keys = maps:get(keys, KeyringData), Keys = maps:get(keys, KeyringData),
CurrentKeyId = lists:max(maps:keys(Keys)), CurrentKeyId = lists:max(maps:keys(Keys)),
KeysMeta = maps:map(fun (_KeyId, _Key) -> #{retired => false} end, Keys), KeysMeta = maps:map(fun(_KeyId, _Key) -> #{retired => false} end, Keys),
#{current_key_id => CurrentKeyId, version => 1, keys => KeysMeta}. #{current_key_id => CurrentKeyId, version => 1, keys => KeysMeta}.
-spec update_meta(keyring_meta(), keyring_meta_diff()) -> keyring_meta(). -spec update_meta(keyring_meta(), keyring_meta_diff()) -> keyring_meta().
@ -73,7 +87,7 @@ decode_keyring_meta_diff(#'KeyringMetaDiff'{
current_key_id = CurrentKeyId, current_key_id = CurrentKeyId,
keys_meta = KeysMeta keys_meta = KeysMeta
}) -> }) ->
DecodedKeysMeta = decode_keys_meta(KeysMeta), DecodedKeysMeta = decode_keys_meta_diff(KeysMeta),
#{current_key_id => CurrentKeyId, keys => DecodedKeysMeta}. #{current_key_id => CurrentKeyId, keys => DecodedKeysMeta}.
-spec decode_keyring_meta(encoded_keyring_meta()) -> keyring_meta(). -spec decode_keyring_meta(encoded_keyring_meta()) -> keyring_meta().
@ -84,21 +98,44 @@ decode_keyring_meta(#'KeyringMeta'{
DecodedKeysMeta = decode_keys_meta(KeysMeta), DecodedKeysMeta = decode_keys_meta(KeysMeta),
#{current_key_id => CurrentKeyId, version => 1, keys => DecodedKeysMeta}. #{current_key_id => CurrentKeyId, version => 1, keys => DecodedKeysMeta}.
decode_keys_meta(undefined) -> decode_keys_meta_diff(undefined) ->
undefined; undefined;
decode_keys_meta(KeysMeta) -> decode_keys_meta_diff(KeysMetaDiff) ->
maps:fold( maps:fold(
fun (K, #'KeyMeta'{retired = Retired}, Acc) -> fun(K, #'KeyMetaDiff'{retired = Retired}, Acc) ->
Acc#{K => #{retired => Retired}} Acc#{K => #{retired => Retired}}
end, end,
#{}, #{},
KeysMetaDiff).
decode_keys_meta(KeysMeta) ->
maps:fold(
fun(K,
#'KeyMeta'{
retired = Retired,
security_parameters = SecurityParameters
},
Acc) ->
Acc#{K => #{
retired => Retired,
security_parameters => decode_security_parameters(SecurityParameters)
}}
end,
#{},
KeysMeta). KeysMeta).
-spec decode_security_parameters(encoded_security_parameters()) -> security_parameters().
decode_security_parameters(#'SecurityParameters'{deduplication_hash_opts = HashOpts}) ->
#{deduplication_hash_opts => decode_scrypt_opts(HashOpts)}.
decode_scrypt_opts(#'ScryptOptions'{n = N, r = R, p = P}) ->
#{n => N, r => R, p => P}.
-spec encode_keyring_meta_diff(keyring_meta_diff()) -> encoded_keyring_meta_diff(). -spec encode_keyring_meta_diff(keyring_meta_diff()) -> encoded_keyring_meta_diff().
encode_keyring_meta_diff(KeyringMetaDiff) -> encode_keyring_meta_diff(KeyringMetaDiff) ->
#'KeyringMetaDiff'{ #'KeyringMetaDiff'{
current_key_id = maps:get(current_key_id, KeyringMetaDiff, undefined), current_key_id = maps:get(current_key_id, KeyringMetaDiff, undefined),
keys_meta = encode_keys_meta(maps:get(keys, KeyringMetaDiff, undefined)) keys_meta = encode_keys_meta_diff(maps:get(keys, KeyringMetaDiff, undefined))
}. }.
-spec encode_keyring_meta(keyring_meta() | undefined) -> encoded_keyring_meta(). -spec encode_keyring_meta(keyring_meta() | undefined) -> encoded_keyring_meta().
@ -111,14 +148,39 @@ encode_keyring_meta(#{
EncodedKeysMeta = encode_keys_meta(KeysMeta), EncodedKeysMeta = encode_keys_meta(KeysMeta),
#'KeyringMeta'{current_key_id = CurrentKeyId, keys_meta = EncodedKeysMeta}. #'KeyringMeta'{current_key_id = CurrentKeyId, keys_meta = EncodedKeysMeta}.
encode_keys_meta_diff(undefined) ->
undefined;
encode_keys_meta_diff(KeysMetaDiff) ->
maps:fold(
fun(K, #{retired := Retired}, Acc) ->
Acc#{K => #'KeyMetaDiff'{retired = Retired}}
end,
#{},
KeysMetaDiff
).
encode_keys_meta(undefined) -> encode_keys_meta(undefined) ->
undefined; undefined;
encode_keys_meta(KeysMeta) -> encode_keys_meta(KeysMeta) ->
maps:fold( maps:fold(
fun (K, #{retired := Retired}, Acc) -> fun(K,
Acc#{K => #'KeyMeta'{retired = Retired}} #{
retired := Retired,
security_parameters := SecurityParameters
},
Acc) ->
Acc#{K => #'KeyMeta'{
retired = Retired,
security_parameters = encode_security_parameters(SecurityParameters)
}}
end, end,
#{}, #{},
KeysMeta KeysMeta
). ).
-spec encode_security_parameters(security_parameters()) -> encoded_security_parameters().
encode_security_parameters(#{deduplication_hash_opts := ScryptOpts}) ->
#'SecurityParameters'{deduplication_hash_opts = encode_scrypt_opts(ScryptOpts)}.
encode_scrypt_opts(#{n := N, r := R, p := P}) ->
#'ScryptOptions'{n = N, r = R, p = P}.

View File

@ -128,10 +128,28 @@ decode_encrypted_keyring(#{
decode_number_key_map(Map) -> decode_number_key_map(Map) ->
maps:fold( maps:fold(
fun (K, #{<<"retired">> := Retired}, Acc) -> fun (K,
#{
<<"retired">> := Retired,
<<"security_parameters">> := #{
<<"deduplication_hash_opts">> := #{
<<"n">> := ScryptN,
<<"r">> := ScryptR,
<<"p">> := ScryptP
}
}
},
Acc) ->
Acc#{ Acc#{
binary_to_integer(K) => #{ binary_to_integer(K) => #{
retired => Retired retired => Retired,
security_parameters => #{
deduplication_hash_opts => #{
n => ScryptN,
r => ScryptR,
p => ScryptP
}
}
} }
} }
end, end,

View File

@ -47,11 +47,15 @@ encode_keyring(#{
encode_keys(Keys, KeysMeta) -> encode_keys(Keys, KeysMeta) ->
maps:fold( maps:fold(
fun(K, V, Acc) -> fun(K, V, Acc) ->
#{retired := Retired} = maps:get(K, KeysMeta), #{
retired := Retired,
security_parameters := SecurityParameters
} = maps:get(K, KeysMeta),
Acc#{K => #'Key'{ Acc#{K => #'Key'{
data = V, data = V,
meta = #'KeyMeta'{ meta = #'KeyMeta'{
retired = Retired retired = Retired,
security_parameters = kds_keyring_meta:encode_security_parameters(SecurityParameters)
} }
}} }}
end, end,

View File

@ -55,6 +55,13 @@ start_clear(Config) ->
{fail_if_no_peer_cert, true} {fail_if_no_peer_cert, true}
] ]
}}, }},
{new_key_security_parameters, #{
deduplication_hash_opts => #{
n => 16384,
r => 8,
p => 1
}
}},
{protocol_opts, #{ {protocol_opts, #{
request_timeout => 60000 request_timeout => 60000
}}, }},

View File

@ -412,8 +412,16 @@ decode_keys(Keys) ->
decode_keys_meta(Keys) -> decode_keys_meta(Keys) ->
maps:fold( maps:fold(
fun (K, #'Key'{meta = #'KeyMeta'{retired = Retired}}, Acc) -> fun(K,
Acc#{K => #{retired => Retired}} #'Key'{meta = #'KeyMeta'{
retired = Retired,
security_parameters = SecurityParameters
}},
Acc) ->
Acc#{K => #{
retired => Retired,
security_parametes => kds_keyring_meta:decode_security_parameters(SecurityParameters)
}}
end, end,
#{}, #{},
Keys Keys

View File

@ -91,14 +91,50 @@ init_check_meta(C) ->
rotate_check_meta(C) -> rotate_check_meta(C) ->
_ = ?assertMatch( _ = ?assertMatch(
#{keys := #{0 := #{retired := false}}}, #{keys := #{
0 := #{
retired := false,
security_parameters := #{
deduplication_hash_opts := #{
n := 16384,
r := 8,
p := 1
}
}
}
}},
kds_keyring_client:get_keyring_meta(root_url(C)) kds_keyring_client:get_keyring_meta(root_url(C))
), ),
ok = application:set_env(kds, new_key_security_parameters, #{
deduplication_hash_opts => #{
n => 16384,
r => 7,
p => 1
}
}),
_ = kds_ct_keyring:rotate(C), _ = kds_ct_keyring:rotate(C),
_ = ?assertMatch( _ = ?assertMatch(
#{keys := #{ #{keys := #{
0 := #{retired := false}, 0 := #{
1 := #{retired := false} retired := false,
security_parameters := #{
deduplication_hash_opts := #{
n := 16384,
r := 8,
p := 1
}
}
},
1 := #{
retired := false,
security_parameters := #{
deduplication_hash_opts := #{
n := 16384,
r := 7,
p := 1
}
}
}
}}, }},
kds_keyring_client:get_keyring_meta(root_url(C)) kds_keyring_client:get_keyring_meta(root_url(C))
). ).

View File

@ -16,6 +16,13 @@
{protocol_opts, #{ {protocol_opts, #{
request_timeout => 60000 request_timeout => 60000
}}, }},
{new_key_security_parameters, #{
deduplication_hash_opts => #{
n => 16384,
r => 8,
p => 1
}
}},
{shutdown_timeout, 0}, {shutdown_timeout, 0},
{keyring_storage, kds_keyring_storage_file}, {keyring_storage, kds_keyring_storage_file},
{keyring_storage_opts, #{ {keyring_storage_opts, #{

View File

@ -4,7 +4,7 @@
{<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1},
{<<"cds_proto">>, {<<"cds_proto">>,
{git,"git@github.com:rbkmoney/cds-proto.git", {git,"git@github.com:rbkmoney/cds-proto.git",
{ref,"a8828869fcc3acbf382b8d4914665f5ef3c19a57"}}, {ref,"f8a5e834b46a2cb261ff753132837df8e8681d1a"}},
0}, 0},
{<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.5.1">>},2},
{<<"cg_mon">>, {<<"cg_mon">>,