예제 #1
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.STATUS_BYTES, L3Enum.NOT_SET));
            }

            SignalsEnum result = ProcessGenACCommand(database, cardResponse, qManager, cardQManager, sw, publicKeyCertificateManager, emvSelectApplicationResponse);

            TLV _72 = database.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN);

            if (_72 != null)
            {
                database.ScriptsToRunAfterGenAC = CardActionAnalysis.BuildScriptList(_72);
                if (database.ScriptsToRunAfterGenAC.Count > 0)
                {
                    //post first script
                    TLV firstScript = database.ScriptsToRunAfterGenAC.GetFirstAndRemoveFromList();
                    EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest();
                    scriptRequest.Deserialize(firstScript.Value);
                    cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU));
                    return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING);
                }
            }

            return(result);
        }
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            if (database.IsScriptProcessingBeforeGenACInProgress)
            {
                if (cardResponse.ApduResponse.SW1 != 0x90 && cardResponse.ApduResponse.SW1 != 0x62 && cardResponse.ApduResponse.SW1 != 0x63)
                {
                    TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                    tvr.Value.ScriptProcessingFailedBeforeFinalGENERATEAC = true;
                    tvr.UpdateDB();
                    database.IsScriptProcessingBeforeGenACInProgress = false;
                    return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));
                }

                if (database.ScriptsToRunBeforeGenAC.Count == 0)
                {
                    database.IsScriptProcessingBeforeGenACInProgress = false;
                    return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse, true));
                }

                TLV firstScript = database.ScriptsToRunBeforeGenAC.GetFirstAndRemoveFromList();
                EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest();
                scriptRequest.Deserialize(firstScript.Value);
                cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING);
            }
            else
            {
                if (cardResponse.ApduResponse.SW1 != 0x90 && cardResponse.ApduResponse.SW1 != 0x62 && cardResponse.ApduResponse.SW1 != 0x63)
                {
                    TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                    tvr.Value.ScriptProcessingFailedAfterFinalGENERATEAC = true;
                    tvr.UpdateDB();
                    //update emv data to return with this updated value
                    if (database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) != null)
                    {
                        database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2).Children.RemoveFromList(database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag));
                        database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2).Children.AddToList(TLV.Create(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag, database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN).Value));
                    }
                    return(SignalsEnum.STOP);
                }
                if (database.ScriptsToRunAfterGenAC.Count == 0)
                {
                    return(SignalsEnum.STOP);
                }

                TLV firstScript = database.ScriptsToRunAfterGenAC.GetFirstAndRemoveFromList();
                EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest();
                scriptRequest.Deserialize(firstScript.Value);
                cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING);
            }
        }
예제 #3
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.IssuerAuthenticationFailed = true;
                tvr.UpdateDB();
            }
            else
            {
                TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                tsi.Value.IssuerAuthenticationWasPerformed = true;
                tsi.UpdateDB();
            }

            //EMVExternalAuthenticateResponse response = cardResponse.ApduResponse as EMVExternalAuthenticateResponse;

            //if scripts need to be run before gen ac, do now
            return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));
        }
        private static SignalsEnum EntryPointOnline(KernelDatabase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            KernelOnlineRequest response = (KernelOnlineRequest)kernel1Request;

            //check if approved or not or unable to go online
            if (response.OnlineApprovalStatus == KernelOnlineResponseType.UnableToGoOnline)
            {
                //if unable to go online, check what action to take using TAC/IAC default,
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                ulong tvrAsNumber = Formatting.ConvertToInt64(tvr.Value.Value);
                ulong tacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_DEFAULT_DF8120_KRN2).Value);
                if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN.Tag))
                {
                    ulong iacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN).Value);
                    if (!(
                            ((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0)
                        )
                    {
                        database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC;
                    }
                    else
                    {
                        database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC;
                    }
                }
                else
                {
                    if (!((tacAsNumber & tvrAsNumber) == 0))
                    {
                        database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC;
                    }
                    else
                    {
                        database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC;
                    }
                }
                //what should these be set to in this case?
                database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag));
                database.AddToList(TLV.Create(EMVTagsEnum.AUTHORISATION_RESPONSE_CODE_8A_KRN.Tag));
            }
            else
            {
                if (response.OnlineApprovalStatus == KernelOnlineResponseType.Approve)
                {
                    database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC;
                }
                else
                {
                    database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC;
                }
                database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag));
                database.AddToList(response.InputData.Get(EMVTagsEnum.AUTHORISATION_RESPONSE_CODE_8A_KRN.Tag));
                if (response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN.Tag) != null)
                {
                    database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN.Tag));
                }
                if (response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN.Tag) != null)
                {
                    database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN.Tag));
                }
            }

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);

            if (aip.Value.IssuerAuthenticationIsSupported && response.OnlineApprovalStatus != KernelOnlineResponseType.UnableToGoOnline)
            {
                TLV _91 = response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag);
                EMVExternalAuthenticateRequest request = new EMVExternalAuthenticateRequest(_91.Value);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_EXTERNAL_AUTHENTICATE);
            }
            else
            {
                //if scripts need to be run before gen ac, do now
                return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));
            }
        }
        private static SignalsEnum EntryPointTRM(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager, KernelQ qManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN  tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);

            tsi.Value.TerminalRiskmanagementWasPerformed = true;
            tsi.UpdateDB();

            //The state works as follows:
            //State_5_WaitingForCVMProcessing ends by possibly adding 2 messages to the card q
            //and 1 or 2 messages in the terminal q (get floor limit (optional) and do trm)
            //the card messages are processed by this state first, then the get floor limit by DEK if it
            //was in the q and then this method

            //Random Transaction Selection determined by terminal, not kernel
            //Terminal can also force transaction online
            //EMVTagsEnum.MAXIMUM_TARGET_PERCENTAGE_TO_BE_USED_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN
            //EMVTagsEnum.THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN
            //EMVTagsEnum.MAXIMUM_TARGET_PERCENTAGE_TO_BE_USED_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN

            switch (((KernelTRMRequest)kernel1Request).KernelTRMRequestType)
            {
            case KernelTRMRequestType.GoOnlineForRandomSelection:
                tvr.Value.TransactionSelectedRandomlyForOnlineProcessing = true;
                tvr.UpdateDB();
                break;

            case KernelTRMRequestType.GoOnline:
                tvr.Value.MerchantForcedTransactionOnline = true;
                tvr.UpdateDB();
                break;
            }

            //Floor limit check done by kernel, no need for it to be done by terminal
            if (database.IsNotEmpty(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag))
            {
                long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                long fl = Formatting.BcdToLong(database.Get(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN).Value);
                if (aa > fl)
                {
                    tvr.Value.TransactionExceedsFloorLimit = true;
                    tvr.UpdateDB();
                }
            }

            //Velocity Check
            TLV lcol   = database.Get(EMVTagsEnum.LOWER_CONSECUTIVE_OFFLINE_LIMIT_9F14_KRN);
            TLV ucol   = database.Get(EMVTagsEnum.UPPER_CONSECUTIVE_OFFLINE_LIMIT_9F23_KRN);
            TLV atcTLV = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag);
            TLV lastOnlineATCRegisterTLV = database.Get(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag);

            bool doVelocity = false;

            if (lcol != null && ucol != null)
            {
                if (database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) != null &&
                    database.Get(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag) != null)
                {
                    if (Formatting.ConvertToInt32(atcTLV.Value) >
                        Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value))
                    {
                        doVelocity = true;
                    }
                    else
                    {
                        // Set both the ‘Lower consecutive offline limit exceeded’ and the ‘Upper consecutive offline limit exceeded’ bits in the TVR to 1.
                        // Not set the ‘New card’ indicator in the TVR unless the Last Online ATC Register is returned and equals zero.
                        // End velocity checking for this transaction
                        tvr.Value.LowerConsecutiveOfflineLimitExceeded = true;
                        tvr.Value.UpperConsecutiveOfflineLimitExceeded = true;

                        if (lastOnlineATCRegisterTLV != null)
                        {
                            if (Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value) == 0)
                            {
                                tvr.Value.NewCard = true;
                            }
                        }
                        tvr.UpdateDB();
                    }
                }
            }
            if (doVelocity == true)
            {
                uint atc     = Formatting.ConvertToInt32(atcTLV.Value);
                uint lastATC = Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value);

                uint atcDiff = atc - lastATC;
                uint lcolInt = Formatting.ConvertToInt32(lcol.Value);
                uint ucolInt = Formatting.ConvertToInt32(ucol.Value);
                if (atcDiff > lcolInt)
                {
                    //set ‘Lower consecutive offline limit exceeded’ bit in the TVR to 1
                    tvr.Value.LowerConsecutiveOfflineLimitExceeded = true;
                    if (atcDiff > ucolInt)
                    {
                        //set the ‘Upper consecutive offline limit exceeded’ bit in the TVR to 1.
                        tvr.Value.UpperConsecutiveOfflineLimitExceeded = true;
                    }
                }
                if (lastATC == 0)
                {
                    //set ‘New card’ bit in the TVR to 1.
                    tvr.Value.NewCard = true;
                }
                tvr.UpdateDB();
            }

            #region Book 3 Section 10.7
            //Terminal Action Analysis of kernel 2 being used
            database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database);
            #endregion

            #region Book 3 Section 10.8
            //Card Action Analysis
            return(CardActionAnalysis.InitiateCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));

            #endregion
        }