% Copyright (c) 2025 Onomondo ApS & sysmocom - s.f.m.c. GmbH. All rights reserved. % % SPDX-License-Identifier: AGPL-3.0-only % % Author: Philipp Maier / sysmocom - s.f.m.c. GmbH -module(esipa_asn1_handler_utils). -export([handle_euiccPackageResult/3]). transactionId_from_euiccPackageResult(EuiccPackageResult) -> case EuiccPackageResult of {euiccPackageResultSigned, EuiccPackageResultSigned} -> EuiccPackageResultDataSigned = maps:get( euiccPackageResultDataSigned, EuiccPackageResultSigned ), maps:get(transactionId, EuiccPackageResultDataSigned); {euiccPackageErrorSigned, EuiccPackageErrorSigned} -> EuiccPackageErrorDataSigned = maps:get( euiccPackageErrorDataSigned, EuiccPackageErrorSigned ), maps:get(transactionId, EuiccPackageErrorDataSigned); _ -> none end. process_euiccPackageResult(Pid, EuiccPackageResult, EsipaReq, TransactionId) -> WorkBind = fun(Map) -> case maps:is_key(transactionId, Map) of true -> mnesia_db:work_bind(Pid, maps:get(transactionId, Map)); _ -> ok end end, CheckCounterValue = fun(Map) -> {EidValue, _, _} = mnesia_db:work_pickup(Pid, TransactionId), CounterValueIpad = maps:get(counterValue, Map), {ok, CounterValueEim} = mnesia_db:euicc_param_get(EidValue, counterValue), case CounterValueIpad of CounterValueEim -> ok; _ -> logger:error( "invalid euiccPackageResultSigned, counterValue mismatch: CounterValueIpad=~p, CounterValueEim=~p~n", [CounterValueIpad, CounterValueEim] ), error end end, Outcome = case EuiccPackageResult of {euiccPackageResultSigned, EuiccPackageResultSigned} -> EuiccPackageResultDataSigned = maps:get( euiccPackageResultDataSigned, EuiccPackageResultSigned ), WorkBind(EuiccPackageResultDataSigned), case CheckCounterValue(EuiccPackageResultDataSigned) of ok -> esipa_rest_utils:euiccPackageResultDataSigned_to_outcome( EuiccPackageResultDataSigned ); _ -> [{[{euiccPackageErrorCode, counterValueMismatch}]}] end; {euiccPackageErrorSigned, EuiccPackageErrorSigned} -> EuiccPackageErrorDataSigned = maps:get( euiccPackageErrorDataSigned, EuiccPackageErrorSigned ), WorkBind(EuiccPackageErrorDataSigned), EuiccPackageErrorCode = maps:get( euiccPackageErrorCode, EuiccPackageErrorDataSigned ), case CheckCounterValue(EuiccPackageErrorDataSigned) of ok -> [{[{euiccPackageErrorCode, EuiccPackageErrorCode}]}]; _ -> [{[{euiccPackageErrorCode, counterValueMismatch}]}] end; {euiccPackageErrorUnsigned, _} -> [{[{euiccPackageErrorCode, undefinedError}]}] end, mnesia_db:work_finish(Pid, Outcome, EsipaReq). % Handle an EuiccPackageResult, this includes everything from the handling of the work items in mnesia_db, down to % signature checks and the generation of an appropriate outcome for the REST API. handle_euiccPackageResult(Pid, EuiccPackageResult, EsipaReq) -> TransactionId = transactionId_from_euiccPackageResult(EuiccPackageResult), {EidValue, _, _} = mnesia_db:work_pickup(Pid, TransactionId), case crypto_utils:verify_euiccPackageResultSigned(EuiccPackageResult, EidValue) of ok -> process_euiccPackageResult(Pid, EuiccPackageResult, EsipaReq, TransactionId); _ -> mnesia_db:work_finish( Pid, [{[{procedureError, euiccSignatureInvalid}]}], EsipaReq ) end.