From bc05d3dd6313855639e75ce06179f84f8439e725 Mon Sep 17 00:00:00 2001 From: ndiezel0 Date: Tue, 16 Jul 2019 17:13:26 +0300 Subject: [PATCH] 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 --- apps/kds/src/kds.erl | 4 +- .../kds_keyring_management_thrift_handler.erl | 132 +++++++++-------- apps/kds/src/kds_keyring_meta.erl | 32 ++--- .../kds_keyring_storage_thrift_handler.erl | 21 ++- apps/kds/src/kds_woody_client.erl | 2 +- apps/kds/src/kds_woody_event_handler.erl | 74 ++++++++++ apps/kds/test/kds_ct_utils.erl | 21 +++ apps/kds/test/kds_keyring_client.erl | 133 ++++++++++-------- config/sys.config | 3 +- doc/keyring.md | 20 +-- rebar.lock | 2 +- 11 files changed, 292 insertions(+), 152 deletions(-) create mode 100644 apps/kds/src/kds_woody_event_handler.erl diff --git a/apps/kds/src/kds.erl b/apps/kds/src/kds.erl index 0327909..966999a 100644 --- a/apps/kds/src/kds.erl +++ b/apps/kds/src/kds.erl @@ -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, #{}), diff --git a/apps/kds/src/kds_keyring_management_thrift_handler.erl b/apps/kds/src/kds_keyring_management_thrift_handler.erl index 0bc1f5c..77180ae 100644 --- a/apps/kds/src/kds_keyring_management_thrift_handler.erl +++ b/apps/kds/src/kds_keyring_management_thrift_handler.erl @@ -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). diff --git a/apps/kds/src/kds_keyring_meta.erl b/apps/kds/src/kds_keyring_meta.erl index 848135a..1f40c68 100644 --- a/apps/kds/src/kds_keyring_meta.erl +++ b/apps/kds/src/kds_keyring_meta.erl @@ -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}. diff --git a/apps/kds/src/kds_keyring_storage_thrift_handler.erl b/apps/kds/src/kds_keyring_storage_thrift_handler.erl index e30c500..50ed24a 100644 --- a/apps/kds/src/kds_keyring_storage_thrift_handler.erl +++ b/apps/kds/src/kds_keyring_storage_thrift_handler.erl @@ -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) } diff --git a/apps/kds/src/kds_woody_client.erl b/apps/kds/src/kds_woody_client.erl index 69239af..46c7232 100644 --- a/apps/kds/src/kds_woody_client.erl +++ b/apps/kds/src/kds_woody_client.erl @@ -27,7 +27,7 @@ call(ServiceCode, Function, Args, RootUrl, ExtraOpts) -> Path = genlib:to_binary(kds_thrift_services:path(ServiceCode)), CallOpts = maps:merge(ExtraOpts, #{ url => <>, - event_handler => scoper_woody_event_handler + event_handler => kds_woody_event_handler }), case woody_client:call(Request, CallOpts) of {ok, Result} -> diff --git a/apps/kds/src/kds_woody_event_handler.erl b/apps/kds/src/kds_woody_event_handler.erl new file mode 100644 index 0000000..009e996 --- /dev/null +++ b/apps/kds/src/kds_woody_event_handler.erl @@ -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. diff --git a/apps/kds/test/kds_ct_utils.erl b/apps/kds/test/kds_ct_utils.erl index 374c37e..9183a7c 100644 --- a/apps/kds/test/kds_ct_utils.erl +++ b/apps/kds/test/kds_ct_utils.erl @@ -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}, diff --git a/apps/kds/test/kds_keyring_client.erl b/apps/kds/test/kds_keyring_client.erl index d8f7b9f..a9cb1e8 100644 --- a/apps/kds/test/kds_keyring_client.erl +++ b/apps/kds/test/kds_keyring_client.erl @@ -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 }}, diff --git a/config/sys.config b/config/sys.config index 6ca2f8d..fa5cc6d 100644 --- a/config/sys.config +++ b/config/sys.config @@ -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 ] }} }} diff --git a/doc/keyring.md b/doc/keyring.md index 506ae29..5945e70 100644 --- a/doc/keyring.md +++ b/doc/keyring.md @@ -81,7 +81,7 @@ EC ключ для криптоподписи: ```bash $ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring StartInit '' + KeyringManagement StartInit '' ``` `threshold` - количество фрагментов мастер-ключа, которое нужно для его востановление @@ -111,7 +111,7 @@ $ echo "" | \ step crypto jws sign - --key ec.json | \ woorl -s cds_proto/proto/kds.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring ValidateInit '""' '"'"$(cat -)"'"' + KeyringManagement ValidateInit '{"id":"","signed_share":"'"$(cat -)"'"}' ``` `EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа @@ -142,7 +142,7 @@ $ echo "" | \ ```bash $ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring StartUnlock + KeyringManagement StartUnlock ``` ### Подтверждение @@ -156,7 +156,7 @@ $ echo "" | \ step crypto jws sign - --key ec.json | \ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring ConfirmUnlock '""' '"'"$(cat -)"'"' + KeyringManagement ConfirmUnlock '{"id":"","signed_share":"'"$(cat -)"'"}' ``` `EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа @@ -186,7 +186,7 @@ $ echo "" | \ ```bash $ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring StartRotate + KeyringManagement StartRotate ``` ### Подтверждение @@ -200,7 +200,7 @@ $ echo "" | \ step crypto jws sign - --key ec.json | \ woorl -s cds_proto/proto/kds.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring ConfirmRotate '""' '"'"$(cat -)"'"' + KeyringManagement ConfirmRotate '{"id":"","signed_share":"'"$(cat -)"'"}' ``` `EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа @@ -241,7 +241,7 @@ $ echo "" | \ ```bash $ woorl -s cds_proto/proto/kds.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring StartRekey '' + KeyringManagement StartRekey '' ``` `threshold` - количество фрагментов мастер-ключа, которое нужно для его востановление @@ -257,7 +257,7 @@ $ echo "" | \ step crypto jws sign - --key ec.json | \ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring ConfirmRekey '""' '"'"$(cat -)"'"' + KeyringManagement ConfirmRekey '{"id":"","signed_share":"'"$(cat -)"'"}' ``` `EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа @@ -271,7 +271,7 @@ $ echo "" | \ ```bash $ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring StartRekeyValidation + KeyringManagement StartRekeyValidation ``` Пример получаемых фрагментов: @@ -297,7 +297,7 @@ $ echo "" | \ step crypto jws sign - --key ec.json | \ woorl -s cds_proto/proto/keyring.thrift \ 'http://kds:8022/v2/keyring' \ - Keyring ValidateRekey '""' '"'"$(cat -)"'"' + KeyringManagement ValidateRekey '{"id":"","signed_share":"'"$(cat -)"'"}' ``` `EncodedMasterKeyShare` - полученный зашифрованный фрагмент мастер-ключа diff --git a/rebar.lock b/rebar.lock index a1cc120..d507fe8 100644 --- a/rebar.lock +++ b/rebar.lock @@ -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">>,