CDS-92: Filter sensitive meta in logs (#7)

* CDS-92: Filter logs from sensitive meta

* CDS-92: Make filter content dependant

* CDS-92: Bump cds_proto and doc

* CDS-92: Add GetKeyring filtering

* CDS-92: Make filter whitelist instead of whitelist

* CDS-92: Move filter_keys to filter

* CDS-92: Skip filtering for internal woody errors

* CDS-92: Update JOSE regex

* CDS-92: Upgrade cds_proto

* CDS-92: Add system errors to whitelist

* CDS-92: Add try catch to thrift handlers

* CDS-92: Review fix

* CDS-92: Review fixes
This commit is contained in:
ndiezel0 2019-07-16 17:13:26 +03:00 committed by GitHub
parent 2e8698bbf3
commit bc05d3dd63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 292 additions and 152 deletions

View File

@ -41,7 +41,7 @@ init([]) ->
handlers => [
kds_thrift_services:http_handler(keyring_management)
],
event_handler => scoper_woody_event_handler,
event_handler => kds_woody_event_handler,
ip => IP,
port => genlib_app:env(?MODULE, management_port, 8022),
transport_opts => genlib_app:env(?MODULE, management_transport_opts, #{}),
@ -56,7 +56,7 @@ init([]) ->
handlers => [
kds_thrift_services:http_handler(keyring_storage)
],
event_handler => scoper_woody_event_handler,
event_handler => kds_woody_event_handler,
ip => IP,
port => genlib_app:env(?MODULE, storage_port, 8023),
transport_opts => genlib_app:env(?MODULE, storage_transport_opts, #{}),

View File

@ -6,7 +6,7 @@
%% woody_server_thrift_handler callbacks
-export([handle_function/4]).
-type encrypted_masterkey_share() :: #'EncryptedMasterKeyShare' {}.
-type encrypted_masterkey_share() :: #'cds_EncryptedMasterKeyShare' {}.
%%
%% woody_server_thrift_handler callbacks
@ -18,7 +18,18 @@
handle_function(OperationID, Args, Context, Opts) ->
scoper:scope(
keyring_management,
fun() -> handle_function_(OperationID, Args, Context, Opts) end
fun() ->
try
handle_function_(OperationID, Args, Context, Opts)
catch
throw:Exception ->
throw(Exception);
error:{woody_error, _} = WoodyError:Stacktrace ->
erlang:raise(error, WoodyError, Stacktrace);
Class:_Exception:Stacktrace ->
erlang:raise(Class, '***', Stacktrace)
end
end
).
handle_function_('StartInit', [Threshold], _Context, _Opts) ->
@ -27,116 +38,120 @@ handle_function_('StartInit', [Threshold], _Context, _Opts) ->
{ok, encode_encrypted_shares(EncryptedMasterKeyShares)}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
invalid_args ->
raise(#'InvalidArguments'{})
raise(#'cds_InvalidArguments'{})
end;
handle_function_('ValidateInit', [ShareholderId, Share], _Context, _Opts) ->
handle_function_('ValidateInit', [SignedShare], _Context, _Opts) ->
{ShareholderId, Share} = decode_signed_share(SignedShare),
VerifiedShare = verify_signed_share(ShareholderId, Share, 'ValidateInit'),
try kds_keyring_manager:validate_init(ShareholderId, VerifiedShare) of
{more, More} ->
{ok, {more_keys_needed, More}};
ok ->
{ok, {success, #'Success'{}}}
{ok, {success, #'cds_Success'{}}}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
{operation_aborted, Reason} ->
raise(#'OperationAborted'{reason = atom_to_binary(Reason, utf8)})
raise(#'cds_OperationAborted'{reason = atom_to_binary(Reason, utf8)})
end;
handle_function_('CancelInit', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:cancel_init()} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status})
raise(#'cds_InvalidStatus'{status = Status})
end;
handle_function_('Lock', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:lock()} catch
{invalid_status, locked} ->
{ok, ok};
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status})
raise(#'cds_InvalidStatus'{status = Status})
end;
handle_function_('StartUnlock', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:start_unlock()} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity})
raise(#'cds_InvalidActivity'{activity = Activity})
end;
handle_function_('ConfirmUnlock', [ShareholderId, Share], _Context, _Opts) ->
handle_function_('ConfirmUnlock', [SignedShare], _Context, _Opts) ->
{ShareholderId, Share} = decode_signed_share(SignedShare),
VerifiedShare = verify_signed_share(ShareholderId, Share, 'ConfirmUnlock'),
try kds_keyring_manager:confirm_unlock(ShareholderId, VerifiedShare) of
{more, More} ->
{ok, {more_keys_needed, More}};
ok ->
{ok, {success, #'Success'{}}}
{ok, {success, #'cds_Success'{}}}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
{operation_aborted, Reason} ->
raise(#'OperationAborted'{reason = atom_to_binary(Reason, utf8)})
raise(#'cds_OperationAborted'{reason = atom_to_binary(Reason, utf8)})
end;
handle_function_('CancelUnlock', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:cancel_unlock()} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status})
raise(#'cds_InvalidStatus'{status = Status})
end;
handle_function_('StartRotate', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:start_rotate()} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity})
raise(#'cds_InvalidActivity'{activity = Activity})
end;
handle_function_('ConfirmRotate', [ShareholderId, Share], _Context, _Opts) ->
handle_function_('ConfirmRotate', [SignedShare], _Context, _Opts) ->
{ShareholderId, Share} = decode_signed_share(SignedShare),
VerifiedShare = verify_signed_share(ShareholderId, Share, 'ConfirmRotate'),
try kds_keyring_manager:confirm_rotate(ShareholderId, VerifiedShare) of
{more, More} ->
{ok, {more_keys_needed, More}};
ok ->
{ok, {success, #'Success'{}}}
{ok, {success, #'cds_Success'{}}}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
{operation_aborted, Reason} ->
raise(#'OperationAborted'{reason = atom_to_binary(Reason, utf8)})
raise(#'cds_OperationAborted'{reason = atom_to_binary(Reason, utf8)})
end;
handle_function_('CancelRotate', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:cancel_rotate()} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status})
raise(#'cds_InvalidStatus'{status = Status})
end;
handle_function_('StartRekey', [Threshold], _Context, _Opts) ->
try {ok, kds_keyring_manager:start_rekey(Threshold)} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
invalid_args ->
raise(#'InvalidArguments'{})
raise(#'cds_InvalidArguments'{})
end;
handle_function_('ConfirmRekey', [ShareholderId, Share], _Context, _Opts) ->
handle_function_('ConfirmRekey', [SignedShare], _Context, _Opts) ->
{ShareholderId, Share} = decode_signed_share(SignedShare),
VerifiedShare = verify_signed_share(ShareholderId, Share, 'ConfirmRekey'),
try kds_keyring_manager:confirm_rekey(ShareholderId, VerifiedShare) of
{more, More} ->
{ok, {more_keys_needed, More}};
ok ->
{ok, {success, #'Success'{}}}
{ok, {success, #'cds_Success'{}}}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
{operation_aborted, Reason} ->
raise(#'OperationAborted'{reason = atom_to_binary(Reason, utf8)})
raise(#'cds_OperationAborted'{reason = atom_to_binary(Reason, utf8)})
end;
handle_function_('StartRekeyValidation', [], _Context, _Opts) ->
try kds_keyring_manager:start_validate_rekey() of
@ -144,29 +159,30 @@ handle_function_('StartRekeyValidation', [], _Context, _Opts) ->
{ok, encode_encrypted_shares(EncryptedMasterKeyShares)}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity})
raise(#'cds_InvalidActivity'{activity = Activity})
end;
handle_function_('ValidateRekey', [ShareholderId, Share], _Context, _Opts) ->
handle_function_('ValidateRekey', [SignedShare], _Context, _Opts) ->
{ShareholderId, Share} = decode_signed_share(SignedShare),
VerifiedShare = verify_signed_share(ShareholderId, Share, 'ValidateRekey'),
try kds_keyring_manager:validate_rekey(ShareholderId, VerifiedShare) of
{more, More} ->
{ok, {more_keys_needed, More}};
ok ->
{ok, {success, #'Success'{}}}
{ok, {success, #'cds_Success'{}}}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{invalid_activity, Activity} ->
raise(#'InvalidActivity'{activity = Activity});
raise(#'cds_InvalidActivity'{activity = Activity});
{operation_aborted, Reason} ->
raise(#'OperationAborted'{reason = atom_to_binary(Reason, utf8)})
raise(#'cds_OperationAborted'{reason = atom_to_binary(Reason, utf8)})
end;
handle_function_('CancelRekey', [], _Context, _Opts) ->
try {ok, kds_keyring_manager:cancel_rekey()} catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status})
raise(#'cds_InvalidStatus'{status = Status})
end;
handle_function_('GetState', [], _Context, _Opts) ->
@ -184,9 +200,9 @@ handle_function_('UpdateKeyringMeta', [KeyringMeta], _Context, _Opts) ->
{ok, ok}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status});
raise(#'cds_InvalidStatus'{status = Status});
{validation_failed, Reason} ->
raise(#'InvalidKeyringMeta'{reason = erlang:atom_to_binary(Reason, utf8)})
raise(#'cds_InvalidKeyringMeta'{reason = erlang:atom_to_binary(Reason, utf8)})
end;
handle_function_('GetKeyringMeta', [], _Context, _Opts) ->
KeyringMeta = kds_keyring_manager:get_meta(),
@ -207,7 +223,7 @@ encode_encrypted_share(#{
owner := Owner,
encrypted_share := EncryptedShare
}) ->
#'EncryptedMasterKeyShare' {
#'cds_EncryptedMasterKeyShare' {
id = Id,
owner = Owner,
encrypted_share = EncryptedShare
@ -227,12 +243,12 @@ verify_signed_share(ShareholderId, SignedShare, OperationId) ->
{error, failed_to_verify} ->
_ = logger:info("Shareholder ~w failed verification of operation ~w",
[ShareholderId, OperationId]),
raise(#'VerificationFailed'{})
raise(#'cds_VerificationFailed'{})
end;
{error, not_found} ->
_ = logger:info("Shareholder ~w failed verification of operation ~w",
[ShareholderId, OperationId]),
raise(#'VerificationFailed'{})
raise(#'cds_VerificationFailed'{})
end.
encode_state(#{
@ -261,25 +277,25 @@ encode_state(#{
}
}
}) ->
#'KeyringState'{
#'cds_KeyringState'{
status = Status,
activities = #'ActivitiesState'{
initialization = #'InitializationState'{
activities = #'cds_ActivitiesState'{
initialization = #'cds_InitializationState'{
phase = InitPhase,
lifetime = InitLifetime,
validation_shares = InitValShares
},
rotation = #'RotationState'{
rotation = #'cds_RotationState'{
phase = RotatePhase,
lifetime = RotateLifetime,
confirmation_shares = RotateConShares
},
unlock = #'UnlockState'{
unlock = #'cds_UnlockState'{
phase = UnlockPhase,
lifetime = UnlockLifetime,
confirmation_shares = UnlockConShares
},
rekeying = #'RekeyingState'{
rekeying = #'cds_RekeyingState'{
phase = RekeyPhase,
lifetime = RekeyLifetime,
confirmation_shares = RekeyConShares,
@ -288,6 +304,12 @@ encode_state(#{
}
}.
decode_signed_share(#'cds_SignedMasterKeyShare'{
id = ShareholderId,
signed_share = Share
}) ->
{ShareholderId, Share}.
-spec raise(_) -> no_return().
raise(Exception) ->
woody_error:raise(business, Exception).

View File

@ -43,9 +43,9 @@
}
}.
-type key_id() :: kds_keyring:key_id().
-type encoded_keyring_meta() :: #'KeyringMeta'{}.
-type encoded_keyring_meta_diff() :: #'KeyringMetaDiff'{}.
-type encoded_security_parameters() :: #'SecurityParameters'{}.
-type encoded_keyring_meta() :: #'cds_KeyringMeta'{}.
-type encoded_keyring_meta_diff() :: #'cds_KeyringMetaDiff'{}.
-type encoded_security_parameters() :: #'cds_SecurityParameters'{}.
-spec get_default_keyring_meta(kds_keyring:keyring_data()) -> keyring_meta().
get_default_keyring_meta(KeyringData) ->
@ -83,7 +83,7 @@ update_current_key_id(_OldCurrentKeyId, NewCurrentKeyId) ->
NewCurrentKeyId.
-spec decode_keyring_meta_diff(encoded_keyring_meta_diff()) -> keyring_meta_diff().
decode_keyring_meta_diff(#'KeyringMetaDiff'{
decode_keyring_meta_diff(#'cds_KeyringMetaDiff'{
current_key_id = CurrentKeyId,
keys_meta = KeysMeta
}) ->
@ -91,7 +91,7 @@ decode_keyring_meta_diff(#'KeyringMetaDiff'{
#{current_key_id => CurrentKeyId, keys => DecodedKeysMeta}.
-spec decode_keyring_meta(encoded_keyring_meta()) -> keyring_meta().
decode_keyring_meta(#'KeyringMeta'{
decode_keyring_meta(#'cds_KeyringMeta'{
current_key_id = CurrentKeyId,
keys_meta = KeysMeta
}) ->
@ -102,7 +102,7 @@ decode_keys_meta_diff(undefined) ->
undefined;
decode_keys_meta_diff(KeysMetaDiff) ->
maps:fold(
fun(K, #'KeyMetaDiff'{retired = Retired}, Acc) ->
fun(K, #'cds_KeyMetaDiff'{retired = Retired}, Acc) ->
Acc#{K => #{retired => Retired}}
end,
#{},
@ -111,7 +111,7 @@ decode_keys_meta_diff(KeysMetaDiff) ->
decode_keys_meta(KeysMeta) ->
maps:fold(
fun(K,
#'KeyMeta'{
#'cds_KeyMeta'{
retired = Retired,
security_parameters = SecurityParameters
},
@ -125,35 +125,35 @@ decode_keys_meta(KeysMeta) ->
KeysMeta).
-spec decode_security_parameters(encoded_security_parameters()) -> security_parameters().
decode_security_parameters(#'SecurityParameters'{deduplication_hash_opts = HashOpts}) ->
decode_security_parameters(#'cds_SecurityParameters'{deduplication_hash_opts = HashOpts}) ->
#{deduplication_hash_opts => decode_scrypt_opts(HashOpts)}.
decode_scrypt_opts(#'ScryptOptions'{n = N, r = R, p = P}) ->
decode_scrypt_opts(#'cds_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().
encode_keyring_meta_diff(KeyringMetaDiff) ->
#'KeyringMetaDiff'{
#'cds_KeyringMetaDiff'{
current_key_id = maps:get(current_key_id, KeyringMetaDiff, undefined),
keys_meta = encode_keys_meta_diff(maps:get(keys, KeyringMetaDiff, undefined))
}.
-spec encode_keyring_meta(keyring_meta() | undefined) -> encoded_keyring_meta().
encode_keyring_meta(undefined) ->
#'KeyringMeta'{current_key_id = 0, keys_meta = #{}};
#'cds_KeyringMeta'{current_key_id = 0, keys_meta = #{}};
encode_keyring_meta(#{
current_key_id := CurrentKeyId,
keys := KeysMeta
}) ->
EncodedKeysMeta = encode_keys_meta(KeysMeta),
#'KeyringMeta'{current_key_id = CurrentKeyId, keys_meta = EncodedKeysMeta}.
#'cds_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}}
Acc#{K => #'cds_KeyMetaDiff'{retired = Retired}}
end,
#{},
KeysMetaDiff
@ -169,7 +169,7 @@ encode_keys_meta(KeysMeta) ->
security_parameters := SecurityParameters
},
Acc) ->
Acc#{K => #'KeyMeta'{
Acc#{K => #'cds_KeyMeta'{
retired = Retired,
security_parameters = encode_security_parameters(SecurityParameters)
}}
@ -180,7 +180,7 @@ encode_keys_meta(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)}.
#'cds_SecurityParameters'{deduplication_hash_opts = encode_scrypt_opts(ScryptOpts)}.
encode_scrypt_opts(#{n := N, r := R, p := P}) ->
#'ScryptOptions'{n = N, r = R, p = P}.
#'cds_ScryptOptions'{n = N, r = R, p = P}.

View File

@ -16,7 +16,18 @@
handle_function(OperationID, Args, Context, Opts) ->
scoper:scope(
keyring_storage,
fun() -> handle_function_(OperationID, Args, Context, Opts) end
fun() ->
try
handle_function_(OperationID, Args, Context, Opts)
catch
throw:Exception ->
throw(Exception);
error:{woody_error, _} = WoodyError:Stacktrace ->
erlang:raise(error, WoodyError, Stacktrace);
Class:_Exception:Stacktrace ->
erlang:raise(Class, '***', Stacktrace)
end
end
).
handle_function_('GetKeyring', [], _Context, _Opts) ->
@ -25,7 +36,7 @@ handle_function_('GetKeyring', [], _Context, _Opts) ->
{ok, encode_keyring(Keyring)}
catch
{invalid_status, Status} ->
raise(#'InvalidStatus'{status = Status})
raise(#'cds_InvalidStatus'{status = Status})
end.
encode_keyring(#{
@ -38,7 +49,7 @@ encode_keyring(#{
keys := KeysMeta
}
}) ->
#'Keyring'{
#'cds_Keyring'{
version = Version,
current_key_id = CurrentKeyId,
keys = encode_keys(Keys, KeysMeta)
@ -51,9 +62,9 @@ encode_keys(Keys, KeysMeta) ->
retired := Retired,
security_parameters := SecurityParameters
} = maps:get(K, KeysMeta),
Acc#{K => #'Key'{
Acc#{K => #'cds_Key'{
data = V,
meta = #'KeyMeta'{
meta = #'cds_KeyMeta'{
retired = Retired,
security_parameters = kds_keyring_meta:encode_security_parameters(SecurityParameters)
}

View File

@ -27,7 +27,7 @@ call(ServiceCode, Function, Args, RootUrl, ExtraOpts) ->
Path = genlib:to_binary(kds_thrift_services:path(ServiceCode)),
CallOpts = maps:merge(ExtraOpts, #{
url => <<RootUrl/binary, Path/binary>>,
event_handler => scoper_woody_event_handler
event_handler => kds_woody_event_handler
}),
case woody_client:call(Request, CallOpts) of
{ok, Result} ->

View File

@ -0,0 +1,74 @@
-module(kds_woody_event_handler).
-behaviour(woody_event_handler).
-include_lib("cds_proto/include/cds_proto_keyring_thrift.hrl").
-include_lib("woody/src/woody_defs.hrl").
%% woody_event_handler behaviour callbacks
-export([handle_event/4]).
%%
%% woody_event_handler behaviour callbacks
%%
-spec handle_event(Event, RpcId, Meta, Opts) ->
ok
when
Event :: woody_event_handler:event(),
RpcId :: woody:rpc_id() | undefined,
Meta :: woody_event_handler:event_meta(),
Opts :: woody:options().
handle_event(?EV_INTERNAL_ERROR, RpcID, RawMeta, Opts) ->
RawMetaWithoutReason = RawMeta#{reason => <<"***">>},
scoper_woody_event_handler:handle_event(?EV_INTERNAL_ERROR, RpcID, RawMetaWithoutReason, Opts);
handle_event(Event, RpcID, RawMeta, Opts) ->
FilteredMeta = filter_meta(RawMeta),
scoper_woody_event_handler:handle_event(Event, RpcID, FilteredMeta, Opts).
filter_meta(RawMeta) ->
case RawMeta of
#{result := Result} ->
RawMeta#{result => filter_result(Result)};
#{args := Args} ->
RawMeta#{args => filter_args(Args)};
_ ->
RawMeta
end.
filter_result({ok, Result}) -> {ok, filter(Result)};
filter_result({system, SystemError}) -> {system, filter(SystemError)};
filter_result({exception, Exception}) -> {exception, filter(Exception)};
filter_result(Result) -> filter(Result).
filter_args(Args) -> filter(Args).
filter(L) when is_list(L) -> [filter(E) || E <- L];
filter(M) when is_map(M) -> maps:map(fun (_K, V) -> filter(V) end, M);
filter({internal, Error, Details} = V) when is_atom(Error) and is_binary(Details) -> V;
filter({external, Error, Details} = V) when is_atom(Error) and is_binary(Details) -> V;
filter(#'cds_EncryptedMasterKeyShare'{} = EncryptedMasterKeyShare) ->
EncryptedMasterKeyShare#'cds_EncryptedMasterKeyShare'{encrypted_share = <<"***">>};
filter(#'cds_SignedMasterKeyShare'{} = SignedShare) ->
SignedShare#'cds_SignedMasterKeyShare'{signed_share = <<"***">>};
filter(#'cds_Keyring'{keys = Keys} = Keyring) ->
Keyring#'cds_Keyring'{keys = filter(Keys)};
filter(#'cds_Key'{} = Key) ->
Key#'cds_Key'{data = <<"***">>};
filter(V) when is_integer(V) -> V;
filter(ok) -> ok;
filter({success, #'cds_Success'{}} = V) -> V;
filter({more_keys_needed, D} = V) when is_integer(D) -> V;
filter(#'cds_KeyringState'{} = V) -> V;
filter(#'cds_KeyringMeta'{} = V) -> V;
filter(#'cds_KeyringMetaDiff'{} = V) -> V;
filter(#'cds_InvalidStatus'{} = V) -> V;
filter(#'cds_InvalidActivity'{} = V) -> V;
filter(#'cds_InvalidKeyringMeta'{} = V) -> V;
filter(#'cds_InvalidArguments'{} = V) -> V;
filter(#'cds_VerificationFailed'{} = V) -> V;
filter(#'cds_OperationAborted'{} = V) -> V.

View File

@ -34,9 +34,30 @@ start_clear(Config) ->
ServerCertFile = filename:join(config(data_dir, Config), "server.pem"),
ClientCertFile = filename:join(config(data_dir, Config), "client.pem"),
Apps =
genlib_app:start_application_with(kernel, [
{logger_sasl_compatible, false},
{logger_level, debug},
{logger, [
{handler, default, logger_std_h, #{
formatter => {logger_logstash_formatter, #{
message_redaction_regex_list => [
"[0-9]{12,19}", %% pan
"[0-9]{2}.[0-9]{2,4}", %% expiration date
"[0-9]{3,4}", %% cvv
"^ey[JI]([a-zA-Z0-9_-]*.?){1,6}" %% JWS and JWE compact representation
]
}}
}}
]}
]) ++
genlib_app:start_application_with(scoper, [
{storage, scoper_storage_logger}
]) ++
genlib_app:start_application_with(os_mon, [
{start_disksup, false},
{start_memsup, false},
{start_cpu_sup, false}
]) ++
genlib_app:start_application_with(kds, [
{ip, IP},
{management_port, ManagementPort},

View File

@ -42,11 +42,11 @@ start_init(Threshold, RootUrl) ->
EncryptedShares ->
decode_encrypted_shares(EncryptedShares)
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'InvalidArguments'{reason = Reason} ->
#'cds_InvalidArguments'{reason = Reason} ->
{error, {invalid_arguments, Reason}}
end.
@ -57,19 +57,20 @@ start_init(Threshold, RootUrl) ->
{error, verification_failed} |
{error, {invalid_arguments, binary()}}.
validate_init(ShareholderId, Share, RootUrl) ->
try kds_woody_client:call(keyring_management, 'ValidateInit', [ShareholderId, Share], RootUrl) of
{success, #'Success'{}} ->
SignedShare = encode_signed_share(ShareholderId, Share),
try kds_woody_client:call(keyring_management, 'ValidateInit', [SignedShare], RootUrl) of
{success, #'cds_Success'{}} ->
ok;
{more_keys_needed, More} ->
{more_keys_needed, More}
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'VerificationFailed'{} ->
#'cds_VerificationFailed'{} ->
{error, verification_failed};
#'OperationAborted'{reason = Reason} ->
#'cds_OperationAborted'{reason = Reason} ->
{error, {operation_aborted, Reason}}
end.
@ -79,9 +80,9 @@ validate_init(ShareholderId, Share, RootUrl) ->
{error, {invalid_activity, {initialization, kds_keyring_initializer:state()}}}.
cancel_init(RootUrl) ->
try kds_woody_client:call(keyring_management, 'CancelInit', [], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}}
end.
@ -91,9 +92,9 @@ cancel_init(RootUrl) ->
{error, {invalid_activity, {unlock, kds_keyring_unlocker:state()}}}.
start_unlock(RootUrl) ->
try kds_woody_client:call(keyring_management, 'StartUnlock', [], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}}
end.
@ -104,19 +105,20 @@ start_unlock(RootUrl) ->
{error, verification_failed} |
{error, {operation_aborted, binary()}}.
confirm_unlock(ShareholderId, Share, RootUrl) ->
try kds_woody_client:call(keyring_management, 'ConfirmUnlock', [ShareholderId, Share], RootUrl) of
{success, #'Success'{}} ->
SignedShare = encode_signed_share(ShareholderId, Share),
try kds_woody_client:call(keyring_management, 'ConfirmUnlock', [SignedShare], RootUrl) of
{success, #'cds_Success'{}} ->
ok;
{more_keys_needed, More} ->
{more_keys_needed, More}
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'VerificationFailed'{} ->
#'cds_VerificationFailed'{} ->
{error, verification_failed};
#'OperationAborted'{reason = Reason} ->
#'cds_OperationAborted'{reason = Reason} ->
{error, {operation_aborted, Reason}}
end.
@ -125,7 +127,7 @@ confirm_unlock(ShareholderId, Share, RootUrl) ->
{error, {invalid_status, kds_keyring_manager:state()}}.
cancel_unlock(RootUrl) ->
try kds_woody_client:call(keyring_management, 'CancelUnlock', [], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}}
end.
@ -134,7 +136,7 @@ cancel_unlock(RootUrl) ->
{error, {invalid_status, kds_keyring_manager:state()}}.
lock(RootUrl) ->
try kds_woody_client:call(keyring_management, 'Lock', [], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}}
end.
@ -144,9 +146,9 @@ lock(RootUrl) ->
{error, {invalid_activity, {rotation, kds_keyring_rotator:state()}}}.
start_rotate(RootUrl) ->
try kds_woody_client:call(keyring_management, 'StartRotate', [], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}}
end.
@ -157,19 +159,20 @@ start_rotate(RootUrl) ->
{error, verification_failed} |
{error, {operation_aborted, binary()}}.
confirm_rotate(ShareholderId, Share, RootUrl) ->
try kds_woody_client:call(keyring_management, 'ConfirmRotate', [ShareholderId, Share], RootUrl) of
{success, #'Success'{}} ->
SignedShare = encode_signed_share(ShareholderId, Share),
try kds_woody_client:call(keyring_management, 'ConfirmRotate', [SignedShare], RootUrl) of
{success, #'cds_Success'{}} ->
ok;
{more_keys_needed, More} ->
{more_keys_needed, More}
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'VerificationFailed'{} ->
#'cds_VerificationFailed'{} ->
{error, verification_failed};
#'OperationAborted'{reason = Reason} ->
#'cds_OperationAborted'{reason = Reason} ->
{error, {operation_aborted, Reason}}
end.
@ -178,7 +181,7 @@ confirm_rotate(ShareholderId, Share, RootUrl) ->
{error, {invalid_status, kds_keyring_manager:state()}}.
cancel_rotate(RootUrl) ->
try kds_woody_client:call(keyring_management, 'CancelRotate', [], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}}
end.
@ -189,11 +192,11 @@ cancel_rotate(RootUrl) ->
{error, {invalid_arguments, binary()}}.
start_rekey(Threshold, RootUrl) ->
try kds_woody_client:call(keyring_management, 'StartRekey', [Threshold], RootUrl) catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'InvalidArguments'{reason = Reason} ->
#'cds_InvalidArguments'{reason = Reason} ->
{error, {invalid_arguments, Reason}}
end.
@ -204,19 +207,20 @@ start_rekey(Threshold, RootUrl) ->
{error, verification_failed} |
{error, {operation_aborted, binary()}}.
confirm_rekey(ShareholderId, Share, RootUrl) ->
try kds_woody_client:call(keyring_management, 'ConfirmRekey', [ShareholderId, Share], RootUrl) of
{success, #'Success'{}} ->
SignedShare = encode_signed_share(ShareholderId, Share),
try kds_woody_client:call(keyring_management, 'ConfirmRekey', [SignedShare], RootUrl) of
{success, #'cds_Success'{}} ->
ok;
{more_keys_needed, More} ->
{more_keys_needed, More}
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'VerificationFailed'{} ->
#'cds_VerificationFailed'{} ->
{error, verification_failed};
#'OperationAborted'{reason = Reason} ->
#'cds_OperationAborted'{reason = Reason} ->
{error, {operation_aborted, Reason}}
end.
@ -229,9 +233,9 @@ start_rekey_validation(RootUrl) ->
EncryptedShares ->
decode_encrypted_shares(EncryptedShares)
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}}
end.
@ -242,19 +246,20 @@ start_rekey_validation(RootUrl) ->
{error, verification_failed} |
{error, {operation_aborted, binary()}}.
validate_rekey(ShareholderId, Share, RootUrl) ->
try kds_woody_client:call(keyring_management, 'ValidateRekey', [ShareholderId, Share], RootUrl) of
{success, #'Success'{}} ->
SignedShare = encode_signed_share(ShareholderId, Share),
try kds_woody_client:call(keyring_management, 'ValidateRekey', [SignedShare], RootUrl) of
{success, #'cds_Success'{}} ->
ok;
{more_keys_needed, More} ->
{more_keys_needed, More}
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}};
#'InvalidActivity'{activity = Activity} ->
#'cds_InvalidActivity'{activity = Activity} ->
{error, {invalid_activity, Activity}};
#'VerificationFailed'{} ->
#'cds_VerificationFailed'{} ->
{error, verification_failed};
#'OperationAborted'{reason = Reason} ->
#'cds_OperationAborted'{reason = Reason} ->
{error, {operation_aborted, Reason}}
end.
@ -264,7 +269,7 @@ validate_rekey(ShareholderId, Share, RootUrl) ->
cancel_rekey(RootUrl) ->
try kds_woody_client:call(keyring_management, 'CancelRekey', [], RootUrl)
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}}
end.
@ -282,9 +287,9 @@ update_keyring_meta(KeyringMeta, RootUrl) ->
EncodedMeta = kds_keyring_meta:encode_keyring_meta_diff(KeyringMeta),
kds_woody_client:call(keyring_management, 'UpdateKeyringMeta', [EncodedMeta], RootUrl)
catch
#'InvalidKeyringMeta'{reason = Reason} ->
#'cds_InvalidKeyringMeta'{reason = Reason} ->
{error, {invalid_keyring_meta, Reason}};
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}}
end.
@ -308,29 +313,35 @@ get_keyring(RootUrl, SSLOptions) ->
Keyring ->
decode_keyring(Keyring)
catch
#'InvalidStatus'{status = Status} ->
#'cds_InvalidStatus'{status = Status} ->
{error, {invalid_status, Status}}
end.
decode_state(#'KeyringState'{
encode_signed_share(ShareholderId, Share) ->
#'cds_SignedMasterKeyShare'{
id = ShareholderId,
signed_share = Share
}.
decode_state(#'cds_KeyringState'{
status = Status,
activities = #'ActivitiesState'{
initialization = #'InitializationState'{
activities = #'cds_ActivitiesState'{
initialization = #'cds_InitializationState'{
phase = InitPhase,
lifetime = InitLifetime,
validation_shares = InitValShares
},
unlock = #'UnlockState'{
unlock = #'cds_UnlockState'{
phase = UnlockPhase,
lifetime = UnlockLifetime,
confirmation_shares = UnlockConShares
},
rotation = #'RotationState'{
rotation = #'cds_RotationState'{
phase = RotatePhase,
lifetime = RotateLifetime,
confirmation_shares = RotateConShares
},
rekeying = #'RekeyingState'{
rekeying = #'cds_RekeyingState'{
phase = RekeyPhase,
lifetime = RekeyLifetime,
confirmation_shares = RekeyConShares,
@ -374,7 +385,7 @@ decode_encrypted_shares(EncryptedMasterKeyShares) ->
-spec decode_encrypted_share(encrypted_masterkey_share()) ->
kds_keysharing:encrypted_master_key_share().
decode_encrypted_share(#'EncryptedMasterKeyShare' {
decode_encrypted_share(#'cds_EncryptedMasterKeyShare' {
id = Id,
owner = Owner,
encrypted_share = EncryptedShare
@ -385,7 +396,7 @@ decode_encrypted_share(#'EncryptedMasterKeyShare' {
encrypted_share => EncryptedShare
}.
decode_keyring(#'Keyring'{
decode_keyring(#'cds_Keyring'{
version = Version,
current_key_id = CurrentKeyId,
keys = Keys
@ -403,7 +414,7 @@ decode_keyring(#'Keyring'{
decode_keys(Keys) ->
maps:fold(
fun (K, #'Key'{data = KeyData}, Acc) ->
fun (K, #'cds_Key'{data = KeyData}, Acc) ->
Acc#{K => KeyData}
end,
#{},
@ -413,7 +424,7 @@ decode_keys(Keys) ->
decode_keys_meta(Keys) ->
maps:fold(
fun(K,
#'Key'{meta = #'KeyMeta'{
#'cds_Key'{meta = #'cds_KeyMeta'{
retired = Retired,
security_parameters = SecurityParameters
}},

View File

@ -76,7 +76,8 @@
message_redaction_regex_list => [
"[0-9]{12,19}", %% pan
"[0-9]{2}.[0-9]{2,4}", %% expiration date
"[0-9]{3,4}" %% cvv
"[0-9]{3,4}", %% cvv
"^ey[JI]([a-zA-Z0-9_-]*.?){1,6}" %% JWS and JWE compact representation
]
}}
}}

View File

@ -81,7 +81,7 @@ EC ключ для криптоподписи:
```bash
$ woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring StartInit '<insert threshold here>'
KeyringManagement StartInit '<insert threshold here>'
```
`threshold` - количество фрагментов мастер-ключа, которое нужно для его востановление
@ -111,7 +111,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
step crypto jws sign - --key ec.json | \
woorl -s cds_proto/proto/kds.thrift \
'http://kds:8022/v2/keyring' \
Keyring ValidateInit '"<insert id, ex. ndiezel>"' '"'"$(cat -)"'"'
KeyringManagement ValidateInit '{"id":"<insert id, ex. ndiezel>","signed_share":"'"$(cat -)"'"}'
```
`EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа
@ -142,7 +142,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
```bash
$ woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring StartUnlock
KeyringManagement StartUnlock
```
### Подтверждение
@ -156,7 +156,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
step crypto jws sign - --key ec.json | \
woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring ConfirmUnlock '"<insert id, ex. ndiezel>"' '"'"$(cat -)"'"'
KeyringManagement ConfirmUnlock '{"id":"<insert id, ex. ndiezel>","signed_share":"'"$(cat -)"'"}'
```
`EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа
@ -186,7 +186,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
```bash
$ woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring StartRotate
KeyringManagement StartRotate
```
### Подтверждение
@ -200,7 +200,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
step crypto jws sign - --key ec.json | \
woorl -s cds_proto/proto/kds.thrift \
'http://kds:8022/v2/keyring' \
Keyring ConfirmRotate '"<insert id, ex. ndiezel>"' '"'"$(cat -)"'"'
KeyringManagement ConfirmRotate '{"id":"<insert id, ex. ndiezel>","signed_share":"'"$(cat -)"'"}'
```
`EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа
@ -241,7 +241,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
```bash
$ woorl -s cds_proto/proto/kds.thrift \
'http://kds:8022/v2/keyring' \
Keyring StartRekey '<insert threshold here>'
KeyringManagement StartRekey '<insert threshold here>'
```
`threshold` - количество фрагментов мастер-ключа, которое нужно для его востановление
@ -257,7 +257,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
step crypto jws sign - --key ec.json | \
woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring ConfirmRekey '"<insert id, ex. ndiezel>"' '"'"$(cat -)"'"'
KeyringManagement ConfirmRekey '{"id":"<insert id, ex. ndiezel>","signed_share":"'"$(cat -)"'"}'
```
`EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа
@ -271,7 +271,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
```bash
$ woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring StartRekeyValidation
KeyringManagement StartRekeyValidation
```
Пример получаемых фрагментов:
@ -297,7 +297,7 @@ $ echo "<insert EncryptedMasterKeyShare here>" | \
step crypto jws sign - --key ec.json | \
woorl -s cds_proto/proto/keyring.thrift \
'http://kds:8022/v2/keyring' \
Keyring ValidateRekey '"<insert id, ex. ndiezel>"' '"'"$(cat -)"'"'
KeyringManagement ValidateRekey '{"id":"<insert id, ex. ndiezel>","signed_share":"'"$(cat -)"'"}'
```
`EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа

View File

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