Пример #1
0
        public static SignalsEnum Execute(
            KernelDatabaseBase database,
            KernelQ qManager,
            CardQ cardQManager
            )
        {
            if (qManager.GetOutputQCount() > 0) //there is a pending request to the terminal
            {
                KernelRequest kernel1Request = qManager.DequeueFromInput(false);
                switch (kernel1Request.KernelTerminalReaderServiceRequestEnum)
                {
                case KernelTerminalReaderServiceRequestEnum.STOP:
                    return(EntryPointSTOP(database, qManager));

                default:
                    throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_3_WaitingForGPOResponse:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum));
                }
            }
            else
            {
                CardResponse cardResponse = cardQManager.DequeueFromOutput(false);
                switch (cardResponse.CardInterfaceServiceResponseEnum)
                {
                case CardInterfaceServiceResponseEnum.RA:
                    return(EntryPointRA(database, qManager));

                case CardInterfaceServiceResponseEnum.L1RSP:
                    return(EntryPointL1RSP(database, qManager, cardResponse));

                default:
                    throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_3_WaitingForGPOResponse:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), cardResponse.CardInterfaceServiceResponseEnum));
                }
            }
        }
        public static SignalsEnum Execute(
            KernelDatabase database,
            KernelQ qManager,
            CardQ cardQManager,
            Stopwatch sw)
        {
            if (qManager.GetOutputQCount() > 0) //there is a pending request to the terminal
            {
                KernelRequest kernel1Request = qManager.DequeueFromInput(false);
                switch (kernel1Request.KernelTerminalReaderServiceRequestEnum)
                {
                case KernelTerminalReaderServiceRequestEnum.STOP:
                    return(EntryPointSTOP(database, qManager));

                case KernelTerminalReaderServiceRequestEnum.DET:
                    return(EntryPointDET(database, kernel1Request));

                default:
                    throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_5_WaitingForCVMProcessing:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum));
                }
            }
            else
            {
                return(ProcessNextCVM(database, qManager, cardQManager, sw));
            }
        }
Пример #3
0
        public static SignalsEnum Execute(
            Kernel2Database database,
            KernelQ qManager,
            CardQ cardQManager,
            TornTransactionLogManager tornTransactionLogManager,
            Stopwatch sw)
        {
            if (qManager.GetInputQCount() == 0)
            {
                throw new EMVProtocolException("Execute_1_Idle: Kernel Input Q empty");
            }

            KernelRequest kernel2Request = qManager.DequeueFromInput(false);

            switch (kernel2Request.KernelTerminalReaderServiceRequestEnum)
            {
            case KernelTerminalReaderServiceRequestEnum.STOP:
                return(EntryPointSTOP(database, qManager));

            case KernelTerminalReaderServiceRequestEnum.CLEAN:
                return(EntryPointCLEAN(database, kernel2Request, qManager, tornTransactionLogManager));

            case KernelTerminalReaderServiceRequestEnum.ACT:
                return(EntryPointACT(database, kernel2Request, qManager, cardQManager, sw));

            default:
                throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in Execute_1_Idle:" + Enum.GetName(typeof(KernelTerminalReaderServiceRequestEnum), kernel2Request.KernelTerminalReaderServiceRequestEnum));
            }
        }
        public static SignalsEnum DoOnlineProcess(KernelDatabaseBase database, CardQ cardQManager)
        {
            #region 3.5.1.1
            TLV tvr = database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN);
            if (tvr == null)
            {
                tvr = TLV.Create(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00 });
                database.AddToList(tvr);
            }
            TLV    cdol1            = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN);
            byte[] cdol1RelatedData = CommonRoutines.PackRelatedDataTag(database, cdol1);

            EMVGenerateACRequest request = new EMVGenerateACRequest(cdol1RelatedData);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            return(SignalsEnum.WAITING_FOR_GEN_AC_1);

            #endregion
        }
        public static SignalsEnum Execute(
            KernelDatabase database,
            KernelQ qManager,
            CardQ cardQManager,
            EMVSelectApplicationResponse emvSelectApplicationResponse,
            Stopwatch sw)
        {
            if (cardQManager.GetInputQCount() > 0) //there is a pending request to the card
            {
                CardResponse cardResponse = cardQManager.DequeueFromOutput(false);
                switch (cardResponse.CardInterfaceServiceResponseEnum)
                {
                case CardInterfaceServiceResponseEnum.RA:
                    return(EntryPointRA(database, cardResponse, qManager, cardQManager, sw));

                case CardInterfaceServiceResponseEnum.L1RSP:
                    return(EntryPointL1RSP(database, cardResponse, qManager));

                default:
                    throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_6_WaitingForTerminalRiskManagement:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), cardResponse.CardInterfaceServiceResponseEnum));
                }
            }
            else
            {
                KernelRequest kernel1Request = qManager.DequeueFromInput(false);
                switch (kernel1Request.KernelTerminalReaderServiceRequestEnum)
                {
                case KernelTerminalReaderServiceRequestEnum.STOP:
                    return(EntryPointSTOP(database, qManager));

                case KernelTerminalReaderServiceRequestEnum.DET:
                    return(EntryPointDET(database, kernel1Request));

                case KernelTerminalReaderServiceRequestEnum.TRM:
                    return(EntryPointTRM(database, kernel1Request, cardQManager, qManager, emvSelectApplicationResponse));

                default:
                    throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_6_WaitingForTerminalRiskManagement:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum));
                }
            }
        }
        public static SignalsEnum DoOfflineProcess(KernelDatabaseBase database, CardQ cardQManager)
        {
            #region 3.4.1.1 and 3.4.1.2
            TLV    ddol = database.Get(EMVTagsEnum.DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST_DDOL_9F49_KRN);
            byte[] ddolRelatedData;
            if (ddol == null)
            {
                TLV unpred = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN);
                unpred.Val.PackValue(unpred.Val.GetLength());
                ddolRelatedData = unpred.Value;
            }
            else
            {
                ddolRelatedData = CommonRoutines.PackRelatedDataTag(database, ddol);
            }
            EMVInternalAuthenticateRequest request = new EMVInternalAuthenticateRequest(ddolRelatedData);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE);

            #endregion
        }
Пример #7
0
        public static SignalsEnum Execute(
            KernelDatabaseBase database,
            KernelQ qManager,
            CardQ cardQManager,
            Stopwatch sw,
            PublicKeyCertificateManager publicKeyCertificateManager,
            CardExceptionManager cardExceptionManager,
            Func <string, KernelDatabaseBase, KernelQ, CardQ, Stopwatch, PublicKeyCertificateManager, CardExceptionManager, SignalsEnum> ReadRecordCompleteCallback)
        {
            if (qManager.GetOutputQCount() > 0) //there is a pending request to the terminal
            {
                KernelRequest kernel1Request = qManager.DequeueFromInput(false);
                switch (kernel1Request.KernelTerminalReaderServiceRequestEnum)
                {
                case KernelTerminalReaderServiceRequestEnum.STOP:
                    return(EntryPointSTOP(database, qManager));

                case KernelTerminalReaderServiceRequestEnum.DET:
                    return(EntryPointDET(database, kernel1Request));

                default:
                    throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_3_WaitingForGPOResponse:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum));
                }
            }
            else
            {
                CardResponse cardResponse = cardQManager.DequeueFromOutput(false);
                switch (cardResponse.CardInterfaceServiceResponseEnum)
                {
                case CardInterfaceServiceResponseEnum.RA:
                    return(EntryPointRA(database, cardResponse, qManager, cardQManager, sw, publicKeyCertificateManager, cardExceptionManager, ReadRecordCompleteCallback));

                case CardInterfaceServiceResponseEnum.L1RSP:
                    return(EntryPointL1RSP(database, cardResponse, qManager));

                default:
                    throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_3_WaitingForGPOResponse:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), cardResponse.CardInterfaceServiceResponseEnum));
                }
            }
        }
        public static SignalsEnum Execute(
            Kernel2Database database,
            KernelQ qManager,
            CardQ cardQManager,
            TornTransactionLogManager tornTransactionLogManager,
            PublicKeyCertificateManager publicKeyCertificateManager,
            Stopwatch sw)
        {
            if (qManager.GetOutputQCount() > 0) //there is a pending request to the terminal
            {
                KernelRequest kernel1Request = qManager.DequeueFromInput(false);
                switch (kernel1Request.KernelTerminalReaderServiceRequestEnum)
                {
                case KernelTerminalReaderServiceRequestEnum.STOP:
                    return(EntryPointSTOP(database, qManager));

                case KernelTerminalReaderServiceRequestEnum.DET:
                    return(EntryPointDET(database, kernel1Request));

                default:
                    throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_11_WaitingForGenACResponse_2:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum));
                }
            }
            else
            {
                CardResponse cardResponse = cardQManager.DequeueFromOutput(false);
                switch (cardResponse.CardInterfaceServiceResponseEnum)
                {
                case CardInterfaceServiceResponseEnum.RA:
                    return(EntryPointRA(database, cardResponse, qManager, cardQManager, tornTransactionLogManager, sw, publicKeyCertificateManager));

                case CardInterfaceServiceResponseEnum.L1RSP:
                    return(EntryPointL1RSP(database, cardResponse, qManager, tornTransactionLogManager));

                default:
                    throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_11_WaitingForGenACResponse_2:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), cardResponse.CardInterfaceServiceResponseEnum));
                }
            }
        }
Пример #9
0
        public static SignalsEnum Execute(
            KernelDatabaseBase database,
            KernelQ qManager,
            CardQ cardQManager,
            Stopwatch sw)
        {
            KernelRequest kernel1Request = qManager.DequeueFromInput(false);

            switch (kernel1Request.KernelTerminalReaderServiceRequestEnum)
            {
            case KernelTerminalReaderServiceRequestEnum.STOP:
                return(EntryPointSTOP(database, qManager));

            case KernelTerminalReaderServiceRequestEnum.TIMEOUT:
                return(EntryPointTIMEOUT(database, qManager));

            case KernelTerminalReaderServiceRequestEnum.DET:
                return(EntryPointDET(database, kernel1Request, cardQManager, sw));

            default:
                throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in Execute_1_Idle:" + Enum.GetName(typeof(KernelTerminalReaderServiceRequestEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum));
            }
        }
        public static SignalsEnum Execute(
            Kernel2Database database,
            KernelQ qManager,
            CardQ cardQManager,
            Stopwatch sw)
        {
            KernelRequest kernel2Request = qManager.DequeueFromInput(false);

            switch (kernel2Request.KernelTerminalReaderServiceRequestEnum)
            {
            case KernelTerminalReaderServiceRequestEnum.STOP:
                return(EntryPointSTOP(database, qManager));

            case KernelTerminalReaderServiceRequestEnum.TIMEOUT:
                return(EntryPointTIMEOUT(database, qManager));

            case KernelTerminalReaderServiceRequestEnum.DET:
                return(EntryPointDET(database, kernel2Request, qManager, cardQManager, sw));

            default:
                throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_8_WaitingForMagStripeFirstWriteFlag:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel2Request.KernelTerminalReaderServiceRequestEnum));
            }
        }
Пример #11
0
 private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
 {
     //no signal should be received from card here
     throw new EMVProtocolException("Invalid state in State_5a_WaitingForGetPinReponse");
 }
Пример #12
0
        private static SignalsEnum EntryPointRA(Kernel1Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));
            }

            bool parsingResult = false;
            EMVInternalAuthenticateResponse response = cardResponse.ApduResponse as EMVInternalAuthenticateResponse;

            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                database.AddToList(response.GetTLVSignedApplicationData());
            }

            if (!parsingResult)
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.PARSING_ERROR,
                                                  L3Enum.NOT_SET));
            }

            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag)))
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_MISSING,
                                                  L3Enum.NOT_SET));
            }

            TLV  cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN);
            byte cid    = cidTLV.Value[0];

            cid = (byte)(cid >> 6);
            if (cid == (byte)ACTypeEnum.ARQC)
            {
                #region 3.10.3.1
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.PROCESSING_ERROR,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_ERROR,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 3.6.1.1
            CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true);
            #endregion


            #region 3.8.1.1
            bool ddaPassed = K3.State_3_4_CommonProcessing.DoOfflineAuth(database, qManager, publicKeyCertificateManager);
            #endregion
            if (!ddaPassed)
            {
                #region 3.10.3.1
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.PROCESSING_ERROR,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_ERROR,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            if (cid == (byte)ACTypeEnum.TC)
            {
                #region 3.9.2
                CommonRoutines.CreateEMVDataRecord(database);
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.APPROVED,
                                                  KernelStatusEnum.READY_TO_READ,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.APPROVED,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.N_A,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.NOT_SET,
                                                  L3Enum.NOT_SET,
                                                  ValueQualifierEnum.NONE,
                                                  null,
                                                  null,
                                                  false,
                                                  KernelCVMEnum.N_A));

                #endregion
            }

            //declined
            CommonRoutines.CreateEMVDiscretionaryData(database);
            return(CommonRoutines.PostOutcome(database, qManager,
                                              KernelMessageidentifierEnum.DECLINED,
                                              KernelStatusEnum.READY_TO_READ,
                                              null,
                                              Kernel2OutcomeStatusEnum.DECLINED,
                                              Kernel2StartEnum.N_A,
                                              true,
                                              KernelMessageidentifierEnum.N_A,
                                              L1Enum.NOT_SET,
                                              null,
                                              L2Enum.NOT_SET,
                                              L3Enum.NOT_SET,
                                              ValueQualifierEnum.NONE,
                                              null,
                                              null,
                                              false,
                                              KernelCVMEnum.N_A));
        }
Пример #13
0
        private static SignalsEnum ProcessGenACCommand(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            //remove values stored during 1st gen ac
            database.RemoveFromList(database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag));
            database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag));
            database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag));
            database.RemoveFromList(database.Get(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag));
            //will only exist if CDA was perfomred after 1st gen ac
            database.RemoveFromList(database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag));

            bool parsingResult = false;

            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                EMVGenerateACResponse response = cardResponse.ApduResponse as EMVGenerateACResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80)
                {
                    if (cardResponse.ApduResponse.ResponseData.Length < 11 ||
                        cardResponse.ApduResponse.ResponseData.Length > 43 ||
                        database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) ||
                        database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) ||
                        database.IsNotEmpty(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag) ||
                        (cardResponse.ApduResponse.ResponseData.Length > 11 &&
                         database.IsNotEmpty(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag))
                        )
                    {
                        parsingResult = false;
                    }
                    else
                    {
                        byte[] responseBuffer = new byte[cardResponse.ApduResponse.ResponseData.Length - 2];
                        Array.Copy(cardResponse.ApduResponse.ResponseData, 2, responseBuffer, 0, responseBuffer.Length);
                        database.AddToList(TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag, new byte[] { responseBuffer[0] }));
                        database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag, new byte[] { responseBuffer[1], responseBuffer[2] }));

                        byte[] ac = new byte[8];
                        Array.Copy(responseBuffer, 3, ac, 0, 8);
                        database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag, ac));
                        if (responseBuffer.Length > 11)
                        {
                            byte[] iad = new byte[responseBuffer.Length - 11];
                            Array.Copy(responseBuffer, 11, iad, 0, iad.Length);
                            database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag, iad));
                        }
                        parsingResult = true;
                    }
                }
            }

            if (!parsingResult)
            {
                return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
            }

            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag)))
            {
                return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
            }

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);
            TERMINAL_VERIFICATION_RESULTS_95_KRN   tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcp = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database);

            if (!
                (((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40 && rcp.Value.ACTypeEnum == ACTypeEnum.TC) ||
                 ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80 && (rcp.Value.ACTypeEnum == ACTypeEnum.TC || rcp.Value.ACTypeEnum == ACTypeEnum.ARQC)) ||
                 ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00))
                )
            {
                return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
            }

            if (aip.Value.CDASupported && tc.Value.CDACapable)
            {
                string  aid                 = emvSelectApplicationResponse.GetDFName();
                string  rid                 = aid.Substring(0, 10);
                RIDEnum ridEnum             = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid);
                CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);

                if (capk == null)
                {
                    tvr.Value.CDAFailed = true;
                    tvr.UpdateDB();
                }

                if (database.IsNotEmpty(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag))
                {
                    State_7_10_CommonProcessing.DoCDA(database, qManager, capk, cardQManager, cardResponse, emvSelectApplicationResponse, false);
                }
                else
                {
                    tvr.Value.CDAFailed = true;
                    tvr.UpdateDB();
                }
            }
            return(State_7_10_CommonProcessing.EndOnTCorAAC(database, qManager, cardQManager));
        }
Пример #14
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);
        }
        internal static SignalsEnum PostGenACBalanceReading(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager)
        {
            APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);

            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag) &&
                  aci.Value.SupportForBalanceReading))
            {
                return(SignalsEnum.NONE);
            }

            if (!database.IsPresent(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2.Tag))
            {
                return(SignalsEnum.NONE);
            }

            EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.OFFLINE_ACCUMULATOR_BALANCE_9F50_KRN2.Tag));

            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));

            SignalsEnum result = SignalsEnum.WAITING_FOR_POST_GEN_AC_BALANCE;

            while (result == SignalsEnum.WAITING_FOR_POST_GEN_AC_BALANCE)
            {
                CardResponse cardResponse = cardQManager.DequeueFromOutput(false);
                result = State_17_WaitingForPostGenACBalance_7_4.Execute_State_17_WaitingForPostGenACBalance(database, qManager, cardQManager);
            }

            return(result);
        }
Пример #16
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.SELECT_NEXT,
                                                  Kernel2StartEnum.C,
                                                  null,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET, cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));
            }

            bool parsingResult = false;
            EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse;

            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80)
                {
                    //if (cardResponse.ApduResponse.ResponseData.Length < 6 ||
                    //    ((cardResponse.ApduResponse.ResponseData.Length - 2) % 4 != 0) ||
                    //        database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag) ||
                    //        database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag))
                    //{
                    //    parsingResult = false;
                    //}
                    //else
                    //{
                    foreach (TLV tlv in response.GetResponseTags())
                    {
                        parsingResult = database.ParseAndStoreCardResponse(tlv);
                        if (!parsingResult)
                        {
                            break;
                        }
                    }
                    //}
                }
            }

            if (!parsingResult)
            {
                return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
            }
            else
            {
                if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) &&
                    database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag))
                {
                    return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
                }
                else
                {
                    return(DoEMVMode(database, qManager, cardQManager, cardResponse, sw));
                }
            }
        }
Пример #17
0
        private static SignalsEnum DoEMVMode(KernelDatabase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse, Stopwatch sw)
        {
            TLV aflRaw = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN);

            byte[] kcValCheck = new byte[4];
            Array.Copy(aflRaw.Value, 0, kcValCheck, 0, kcValCheck.Length);
            //if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100")
            //{
            //    byte[] activeAFLBytes = new byte[aflRaw.Value.Length - 4];
            //    Array.Copy(aflRaw.Value, 4, activeAFLBytes, 0, activeAFLBytes.Length);

            //    List<byte[]> bytes = new List<byte[]>
            //    {
            //        new byte[] { (byte)activeAFLBytes.Length },
            //        activeAFLBytes
            //    };
            //    database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);
            //}
            //else
            //{
            List <byte[]> bytes = new List <byte[]>
            {
                new byte[] { (byte)aflRaw.Value.Length },
                aflRaw.Value
            };

            database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);
            //}

            return(DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, cardResponse));
        }
        internal static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag))
            {
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                #region 78.2
                dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag);
                #endregion
                dataNeeded.UpdateDB();

                return(Do78_3(source, database, qManager, sw));
            }
            else
            {
                #region 78.7
                if (database.IsPresent(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag) &&
                    database.Get(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2).Value[0] == 0x00)
                #endregion
                {
                    #region 78.3
                    return(Do78_3(source, database, qManager, sw));

                    #endregion
                }
                else
                {
                    #region 78.8
                    if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag))
                    #endregion
                    {
                        #region 78.9
                        CommonRoutines.CreateEMVDiscretionaryData(database);
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT));

                        #endregion
                    }
                    #region 78.10
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    #endregion
                    {
                        #region 78.11
                        CommonRoutines.CreateEMVDiscretionaryData(database);
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET));

                        #endregion
                    }

                    #region 78.12
                    foreach (TLV tlv in database.TagsToReadYet)
                    {
                        if (database.IsPresent(tlv.Tag.TagLable))
                        {
                            database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                        }
                        else
                        if (database.IsKnown(tlv.Tag.TagLable))
                        {
                            database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(tlv.Tag.TagLable));
                        }

                        database.TagsToReadYet.RemoveFromList(tlv);
                    }
                    #endregion

                    #region 78.13
                    if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag))
                    #endregion
                    {
                        #region 78.14
                        CommonRoutines.PostDEK(database, qManager);
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                        database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                        #endregion
                    }

                    #region 78.15
                    //The 8-nUN most significant digits must be set to zero
                    TLV rNN = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2);
                    if (rNN == null)
                    {
                        database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2.Tag));
                        rNN = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2);
                    }
                    rNN.Value = Formatting.GetRandomNumberNumeric(8 - database.NUN);
                    #endregion

                    #region 78.16
                    APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
                    if (aip.Value.OnDeviceCardholderVerificationIsSupported)
                    #endregion
                    {
                        #region 78.19
                        if (aa > rctl)
                        #endregion
                        {
                            #region 78.20
                            byte msi = database.Get(EMVTagsEnum.MOBILE_SUPPORT_INDICATOR_9F7E_KRN2).Value[0];
                            msi = (byte)(msi | 0x02);
                            database.Get(EMVTagsEnum.MOBILE_SUPPORT_INDICATOR_9F7E_KRN2).Value[0] = msi;
                            #endregion
                        }

                        #region 78.21
                        EMVComputeCryptographicChecksumRequest request = new EMVComputeCryptographicChecksumRequest(CommonRoutines.PackUdolRelatedDataTag(database));
                        #endregion

                        #region 78.22
                        cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                        #endregion

                        return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_2);
                    }
                    else
                    {
                        #region 78.17
                        EMVComputeCryptographicChecksumRequest request = new EMVComputeCryptographicChecksumRequest(CommonRoutines.PackUdolRelatedDataTag(database));
                        #endregion

                        #region 78.17
                        cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                        #endregion

                        return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_1);
                    }
                }
            }
        }
Пример #19
0
        /*
         * S1.1, S1.7 - S1.23
         */
        private static SignalsEnum EntryPointACT(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            #region S1.7
            foreach (TLV tlv in kernel1Request.InputData)
            {
                if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)
                {
                    if (!database.ParseAndStoreCardResponse(tlv))
                    {
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
                    }
                }
                else
                {
                    if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT))
                    {
                        database.AddToList(tlv);
                    }
                }
            }

            if (database.IsNotEmpty(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN.Tag))
            {
                byte[] languagePrefFromCard       = database.Get(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN).Value;
                byte[] languagePrefFromCardPadded = new byte[8]; //will be padded with trailing 0's
                Array.Copy(languagePrefFromCard, languagePrefFromCardPadded, languagePrefFromCard.Length);
                CommonRoutines.UpdateUserInterfaceRequestData(database, languagePrefFromCardPadded);
            }

            #region S1.8
            if (database.IsNotPresent(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag) || database.IsEmpty(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag))
            {
                return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));
            }
            #endregion

            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
            {
                APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aciVal = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                if (aciVal.Value.SupportForFieldOffDetection)
                {
                    byte[] holdTimeValue = database.GetDefault(EMVTagsEnum.HOLD_TIME_VALUE_DF8130_KRN2).Value;
                    CommonRoutines.UpdateOutcomeParameterSet(database, holdTimeValue[0]);
                }
            }
            #endregion

            #region S1.9
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);
            cvmr.UpdateDB();

            database.ACType = new DS_AC_TYPE_DF8108_KRN2(database);
            database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC;

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            tvr.UpdateDB();

            database.ODAStatus = 0x00;

            database.AddToList(TLV.Create(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2.Tag, new byte[] { 0x00 }));

            //CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2 df8117 = new CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2(database);
            //SECURITY_CAPABILITY_DF811F_KRN2 df811f = new SECURITY_CAPABILITY_DF811F_KRN2(database);

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);
            //_9f33.Value.SetCardDataInputCapabilityValue(df8117);
            //_9f33.Value.SetSecurityCapabilityValue(df811f);
            _9f33.UpdateDB();

            database.StaticDataToBeAuthenticated.Initialize();

            database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00 }));
            database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber();

            //REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpv = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2();
            //rcpv.Value.ACTypeEnum = ACTypeEnum.TC;
            //rcpv.UpdateDB();
            #endregion

            #region S1.10
            database.Initialize(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag);

            DATA_NEEDED_DF8106_KRN2  dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
            DATA_TO_SEND_FF8104_KRN2 dataToSend = new DATA_TO_SEND_FF8104_KRN2(database);

            database.TagsToReadYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2.Tag))
            {
                database.TagsToReadYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2).Children);
            }
            else
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2);
                dataNeeded.UpdateDB();
            }
            #endregion

            #region S1.11
            bool MissingPDOLDataFlag = false;
            #endregion

            #region S1.12
            TLV     _9f38    = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);
            foreach (TLV tlv in pdolList)
            {
                if (database.IsEmpty(tlv.Tag.TagLable))
                {
                    MissingPDOLDataFlag = true;
                    dataNeeded.Value.AddTag(tlv.Tag.TagLable);
                }
            }
            dataNeeded.UpdateDB();

            #region S1.13 and S1.14
            if (!MissingPDOLDataFlag)
            {
                database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag);
                CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList);
                EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            }
            #endregion

            #endregion

            #region S1.15
            TLVList toRemove = new TLVList();
            foreach (TLV tlv in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(tlv.Tag.TagLable))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                    toRemove.AddToList(tlv);
                }
            }

            foreach (TLV tlv in toRemove)
            {
                database.TagsToReadYet.RemoveFromList(tlv);
            }
            #endregion

            #region S1.16
            database.Initialize(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2.Tag);
            database.Initialize(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2.Tag);
            database.Initialize(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag);

            database.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2).Value                 = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value          = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value  = new byte[] { 0x00 };
            database.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2).Value = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };

            database.TagsToWriteAfterGenACYet.Initialize();
            database.TagsToWriteBeforeGenACYet.Initialize();

            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            {
                database.TagsToWriteBeforeGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2).Children);
            }
            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            {
                database.TagsToWriteAfterGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2).Children);
            }

            if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2);
            }
            if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            {
                dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2);
            }

            dataNeeded.UpdateDB();
            #endregion

            #region S1.17
            if (database.IsNotEmpty(EMVTagsEnum.DSVN_TERM_DF810D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2.Tag))
            {
                #region S1.18
                if (database.IsPresent(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2));
                }
                else
                {
                    TLV dsid = TLV.Create(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag);
                    dsid.Val.PackValue(EMVTagsEnum.DS_ID_9F5E_KRN2.DataFormatter.GetMaxLength());
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(dsid);
                }

                if (database.IsPresent(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2));
                }
                else
                {
                    TLV aci = TLV.Create(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag);
                    aci.Val.PackValue(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.DataFormatter.GetMaxLength());
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(aci);
                }
                #endregion

                #region S1.19
                if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag))
                {
                    APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                    if ((aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_1 || aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_2) &&
                        database.IsNotEmpty(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag))
                    {
                        #region S1.20
                        IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                        ids.Value.IsRead = true;
                        ids.UpdateDB();
                        #endregion
                    }
                }
                #endregion
            }
            #endregion

            #region S1.21
            if (MissingPDOLDataFlag)
            {
                #region S1.22
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion

                #region S1.23
                sw.Restart();
                #endregion

                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }
            #endregion

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
        /*
         * S4.3
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw)
        {
            bool signedFlag;
            byte sfi;

            #region 4.9
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 4.10
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 4.11
            if (database.ActiveAFL.Value.Entries[0].OfflineDataAuthenticationRecordLength > 0)
            #endregion
            {
                #region 4.12
                signedFlag = true;
                #endregion
            }
            else
            {
                #region 4.13
                signedFlag = false;
                #endregion
            }

            #region 4.14
            sfi = database.ActiveAFL.Value.Entries[0].SFI;
            database.ActiveAFL.Value.Entries.RemoveAt(0);
            #endregion

            #region 4.15
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();
            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }
            #endregion
            if (database.ActiveTag != null)
            {
                #region 4.16 - 4.19
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
                #endregion
            }
            else
            {
                #region 4.19
                if (database.ActiveAFL.Value.Entries.Count == 0)
                #endregion
                {
                    #region 4.20
                    database.NextCommandEnum = NextCommandEnum.NONE;
                    #endregion
                }
                else
                {
                    #region 4.21 - 4.23
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    database.NextCommandEnum = NextCommandEnum.READ_RECORD;
                    #endregion
                }
            }

            bool parsingResult;
            #region 4.24
            if (sfi <= 10)
            #endregion
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70)
                {
                    parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData);
                }
                else
                {
                    parsingResult = false;
                }
            }
            else //Processing of records in proprietary files is beyond the scope of thisspecification
            {
                parsingResult = false;
            }

            #region 4.25
            if (!parsingResult)
            #endregion
            {
                #region 4.26
                if (database.NextCommandEnum == NextCommandEnum.NONE)
                #endregion
                {
                    #region 4.27.1 - 4.27.2
                    CommonRoutines.CreateEMVDiscretionaryData(database);
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.NOT_READY,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.PARSING_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    return(SignalsEnum.TEMINATE_ON_NEXT_RA);
                }
            }

            TLVList responseTags;
            if (cardResponse.ApduResponse is EMVReadRecordResponse)
            {
                responseTags = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags();
            }
            else if (cardResponse.ApduResponse is EMVGetDataResponse)
            {
                responseTags = (cardResponse.ApduResponse as EMVGetDataResponse).GetResponseTags();
            }
            else
            {
                throw new EMVProtocolException("Invalid card response in State4");
            }

            #region 4.28
            TLVList cdols = responseTags.FindAll(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag);
            if (cdols.Count > 0)
            #endregion
            {
                TLVList cdolList = TLV.DeserializeChildrenWithNoV(cdols.GetFirst().Value, 0);
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                #region 4.29
                foreach (TLV tlv in cdolList)
                {
                    if (database.IsEmpty(tlv.Tag.TagLable))
                    {
                        dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                    }
                }
                dataNeeded.UpdateDB();
                #endregion
            }

            #region 4.30
            TLVList dsdols = responseTags.FindAll(EMVTagsEnum.DSDOL_9F5B_KRN2.Tag);
            if (dsdols.Count > 0)
            #endregion
            {
                #region 4.31
                IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                if (ids.Value.IsRead)
                #endregion
                {
                    #region 4.32
                    if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) && new DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2(database).Value.LockedSlot)
                    #endregion
                    {
                        DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                        #region 4.33
                        foreach (TLV tlv in dsdols.GetFirst().Children)
                        {
                            if (database.IsEmpty(tlv.Tag.TagLable))
                            {
                                dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                            }
                        }
                        dataNeeded.UpdateDB();
                        #endregion
                    }
                    else
                    {
                        #region 4.34
                        Do434(database, signedFlag, sfi, cardResponse, responseTags);
                        #endregion
                    }
                }
                else
                {
                    #region 4.34
                    Do434(database, signedFlag, sfi, cardResponse, responseTags);
                    #endregion
                }
            }
            else
            {
                #region 4.34
                Do434(database, signedFlag, sfi, cardResponse, responseTags);
                #endregion
            }

            return(State_4_5_6_CommonProcessing.DoCommonProcessing("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, tornTransactionLogManager));
        }
Пример #21
0
        /*
         * 14.6
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager)
        {
            #region 14.9
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 14.10
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.STATUS_BYTES, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            #region 14.11
            bool parsingResult = false;
            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                EMVComputeCryptographicChecksumResponse response = cardResponse.ApduResponse as EMVComputeCryptographicChecksumResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                parsingResult = false;
            }
            #endregion

            #region 14.12
            if (!parsingResult)
            #endregion
            {
                #region 14.13
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            #region 14.12.1
            CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true);
            #endregion

            #region 14.14
            if (database.IsEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) ||
                database.IsEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag))
            #endregion
            {
                #region 14.17
                CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET);
                return(DoInvalidResponse(database, qManager));

                #endregion
            }

            long nUN = 0;
            #region 14.15
            if (database.IsNotEmpty(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2.Tag))
            #endregion
            {
                #region 14.16
                if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag) &&
                    (database.IsNotPresent(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag) ||
                     database.IsEmpty(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag)))
                #endregion
                {
                    #region 14.17
                    CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET);
                    return(DoInvalidResponse(database, qManager));

                    #endregion
                }

                #region 14.20
                byte pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1];
                #endregion
                if ((pcii & 0x10) == 0x10)   //OD-CVM verification successful
                {
                    #region 14.24
                    nUN = (nUN + 5) % 10;
                    #endregion
                }
                else
                {
                    #region 14.21
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    #endregion
                    {
                        #region 14.21.1
                        CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET);
                        return(DoInvalidResponse(database, qManager));

                        #endregion
                    }
                    else
                    {
                        #region 14.25
                        nUN = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value);
                        #endregion
                    }
                }

                #region 14.25.1
                database.FailedMSCntr = 0;
                #endregion

                #region 14.26
                TRACK_2_DATA_9F6B_KRN2 t2d = new TRACK_2_DATA_9F6B_KRN2(database);
                ushort t2 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK2_9F67_KRN2).Value);

                TLV       PCVC3_TRACK2_9F65_KRN2       = database.Get(EMVTagsEnum.PCVC3_TRACK2_9F65_KRN2);
                MagBitmap bitmapPCVC3_TRACK2_9F65_KRN2 = new MagBitmap(PCVC3_TRACK2_9F65_KRN2.Value);

                TLV    CVC3_TRACK2_9F61_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2);
                ushort cvc3T2AsShort         = Formatting.ConvertToInt16(CVC3_TRACK2_9F61_KRN2.Value.Reverse().ToArray());

                string q2LeastSigDigits = Convert.ToString(cvc3T2AsShort);
                q2LeastSigDigits            = q2LeastSigDigits.Substring(q2LeastSigDigits.Length - bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount);
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPCVC3_TRACK2_9F65_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), q2LeastSigDigits, bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount, true), false);

                TLV       PUNATC_TRACK2_9F66_KRN2       = database.Get(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2);
                MagBitmap bitmapPUNATC_TRACK2_9F66_KRN2 = new MagBitmap(PUNATC_TRACK2_9F66_KRN2.Value);
                uint      unpredInt    = Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2).Value.Reverse().ToArray());
                string    unpredString = Convert.ToString(unpredInt);
                unpredString = unpredString.Substring(unpredString.Length - database.NUN);
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), unpredString, database.NUN, true), false);

                if (t2 != 0)
                {
                    TLV    APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN);
                    uint   atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray());
                    string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort);
                    atcAsShortLeastSigDigits    = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t2);
                    t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t2, false), false);
                }
                #endregion

                #region 14.27
                StringBuilder dd = new StringBuilder(Formatting.BcdToString(t2d.Value.DiscretionaryData));
                dd[dd.Length - 1]           = Convert.ToString(nUN)[0];
                t2d.Value.DiscretionaryData = Formatting.StringToBcd(dd.ToString(), false);
                #endregion

                t2d.Serialize(); //reserialize in case the length of discretionary data changed
                t2d.UpdateDB();

                #region 14.28
                if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag))
                #endregion
                {
                    #region 14.29
                    TRACK_1_DATA_56_KRN2 t1d = new TRACK_1_DATA_56_KRN2(database);
                    ushort t1 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK1_9F64_KRN2).Value);

                    TLV       PCVC3_TRACK1_9F62_KRN2       = database.Get(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2);
                    MagBitmap bitmapPCVC3_TRACK1_9F62_KRN2 = new MagBitmap(PCVC3_TRACK1_9F62_KRN2.Value);

                    TLV    CVC3_TRACK1_9F60_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2);
                    ushort cvc3T1AsShort         = Formatting.ConvertToInt16(CVC3_TRACK1_9F60_KRN2.Value.Reverse().ToArray());

                    string q1LeastSigDigits = Convert.ToString(cvc3T1AsShort);
                    q1LeastSigDigits            = q1LeastSigDigits.Substring(q1LeastSigDigits.Length - bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount);
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPCVC3_TRACK1_9F62_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), q1LeastSigDigits, bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount, true));

                    TLV       PUNATC_TRACK1_9F63_KRN2       = database.Get(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2);
                    MagBitmap bitmapPUNATC_TRACK1_9F63_KRN2 = new MagBitmap(PUNATC_TRACK1_9F63_KRN2.Value);
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), unpredString, database.NUN, true));

                    if (t2 != 0)
                    {
                        TLV    APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN);
                        uint   atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray());
                        string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort);
                        atcAsShortLeastSigDigits    = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t1);
                        t2d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t1, false));
                    }
                    #endregion

                    #region 14.30
                    StringBuilder dd1 = new StringBuilder(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData));
                    dd1[dd1.Length - 1]         = Convert.ToString(nUN)[0];
                    t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(dd1.ToString());
                    #endregion

                    t1d.Serialize(); //reserialize in case the length of discretionary data changed
                    t1d.UpdateDB();
                }

                #region 14.32
                Kernel2OutcomeStatusEnum k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST;
                KernelCVMEnum            cvmEnum         = KernelCVMEnum.N_A;
                bool receipt = false;

                pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1];
                if ((pcii & 0x10) == 0x10)   //OD-CVM verification successful
                #endregion
                {
                    #region 14.34
                    cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED;
                    long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
                    long rctl = database.ReaderContactlessTransactionLismit;
                    if (aa > rctl)
                    {
                        receipt = true;
                    }
                    #endregion
                }
                else
                {
                    #region 14.33
                    cvmEnum = KernelCVMEnum.NO_CVM;
                    #endregion
                }
                CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                CommonRoutines.CreateMSDataRecord(database);
                return(CommonRoutines.PostOutcomeOnly(database, qManager, k2OutcomeStatus, cvmEnum, receipt));
            }
            else
            {
                #region 14.19.1
                if (((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x00030F) != 0x000000)
                #endregion
                {
                    KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED;
                    KernelStatusEnum            k2Status            = KernelStatusEnum.READY_TO_READ;
                    byte[] holdTime = new byte[] { 0x00, 0x00, 0x00 };

                    #region 14.22
                    PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = (PHONE_MESSAGE_TABLE_DF8131_KRN2)database.GetDefault(EMVTagsEnum.PHONE_MESSAGE_TABLE_DF8131_KRN2);
                    foreach (PhoneMessageTableEntry_DF8131 entry in pmt.Value.Entries)
                    {
                        int pcii     = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value);
                        int pciMask  = (int)Formatting.ConvertToInt32(entry.PCIIMask);
                        int pciValue = (int)Formatting.ConvertToInt32(entry.PCIIValue);
                        if ((pciMask & pcii) == pciValue)
                        {
                            k2MessageIdentifier = entry.MessageIdentifier;
                            k2Status            = entry.Status;
                            holdTime            = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;
                            break;
                        }
                    }
                    #endregion

                    #region 14.21.1
                    int waitTime = ((2 ^ database.FailedMSCntr) * 300);
                    Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait();
                    #endregion

                    #region 14.21.2
                    database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5);
                    #endregion

                    #region 14.23
                    CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                    CommonRoutines.CreateMSDataRecord(database);

                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      k2MessageIdentifier,
                                                      k2Status,
                                                      holdTime,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.B,
                                                      false,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    #region 14.19.2.1
                    int waitTime = ((2 ^ database.FailedMSCntr) * 300);
                    Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait();
                    #endregion
                    #region 14.19.2.2
                    database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5);
                    #endregion

                    #region 14.19.3
                    CommonRoutines.CreateMSDiscretionaryDataRecord(database);
                    CommonRoutines.CreateMSDataRecord(database);

                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.DECLINED,
                                                      KernelStatusEnum.NOT_READY,
                                                      database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.N_A,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.NOT_SET,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
            }
        }
Пример #22
0
        private static SignalsEnum EntryPointPIN(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            //store the pin
            database.AddToList(kernel1Request.InputData.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag));
            string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);

            //online pin
            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
            {
                PinProcessing.VerifyOnlinePin(pin, tvr, cvr);
                return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
            }

            //offline pin
            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper ||
                cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper)
            {
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN.Tag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GET_PIN_TRY_COUNTER);
            }

            throw new EMVProtocolException("Invalid cvr in State_5a_WaitingForGetPinReponse");
        }
        /*
         * 15.2
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw)
        {
            #region 15.5
            if (cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 15.6
                if (database.TagsToWriteAfterGenACYet.Count != 0)
                #endregion
                {
                    #region 15.7
                    TLV tagToPut = database.TagsToWriteAfterGenACYet.GetFirstAndRemoveFromList();
                    EMVPutDataRequest requestPutData = new EMVPutDataRequest(tagToPut);
                    #endregion
                    #region 15.8
                    cardQManager.EnqueueToInput(new CardRequest(requestPutData, CardinterfaceServiceRequestEnum.ADPU));
                    return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_AFTER_GEN_AC);

                    #endregion
                }
                else
                {
                    #region 15.9
                    byte pgacps = database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value[0];
                    pgacps = (byte)(pgacps | 0x80);
                    database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value[0] = pgacps;
                    #endregion
                }
            }

            return(DoCommon(database, cardResponse, qManager));
        }
        public static SignalsEnum DoNOCDA9_10_30(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse)
        {
            #region 9_10.30
            if (!database.IsPresent(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag))
            #endregion
            {
                #region 9_10.31
                return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));

                #endregion
            }
            else
            {
                #region 9_10.32
                REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcp = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database);
                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00)
                #endregion
                {
                    #region 9_10.33
                    IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                    if (ids.Value.IsRead)
                    #endregion
                    {
                        #region 9_10.37
                        return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));

                        #endregion
                    }
                    else
                    {
                        #region 9_10.35
                        if (rcp.Value.ACTypeEnum == ACTypeEnum.AAC)
                        #endregion
                        {
                            #region 9_10.36
                            if (rcp.Value.CDASignatureRequested)
                            #endregion
                            {
                                #region 9_10.37
                                return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));

                                #endregion
                            }
                            else
                            {
                                return(DoPart_E(database, qManager, cardQManager));
                            }
                        }
                        else
                        {
                            return(DoPart_E(database, qManager, cardQManager));
                        }
                    }
                }
                else
                {
                    #region 9_10.34
                    if (rcp.Value.CDASignatureRequested)
                    #endregion
                    {
                        #region 9_10.37
                        return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));

                        #endregion
                    }
                    else
                    {
                        #region 9_10.38
                        TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                        if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                        #endregion
                        {
                            #region 9_10.39
                            Do9_10__39(database);
                            #endregion
                        }
                        return(DoPart_E(database, qManager, cardQManager));
                    }
                }
            }
        }
Пример #25
0
        private static SignalsEnum DoCommonProcessing(string source, KernelDatabase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse)
        {
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();

            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }

            if (database.ActiveTag != null)
            {
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
            }
            else
            {
                if (database.ActiveAFL == null)
                {
                    return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));
                }
                else
                {
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    database.NextCommandEnum = NextCommandEnum.READ_RECORD;
                }
            }

            TLVList dataToSend = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children;

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
        }
        public static SignalsEnum DoCDA9_10_1(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse)
        {
            CAPublicKeyCertificate capk = publicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);

            if (capk == null)
            {
                #region 9_10.1
                return(DoPart_F(database, qManager, cardResponse));

                #endregion
            }
            else
            {
                #region 9_10.2
                IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                if (ids.Value.IsRead)
                #endregion
                {
                    bool successIDSRead = false;
                    #region 9_10.2.2
                    if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                    #endregion
                    {
                        #region 9_10.3.1
                        successIDSRead = VerifySDAD_Summaries_CheckRelayData_9_10__3_1(database, capk, cardResponse);
                        #endregion
                    }
                    else
                    {
                        #region 9_10.3
                        successIDSRead = VerifySDAD_Summaries_9_10__3(database, capk, cardResponse);
                        #endregion
                    }
                    #region 9_10.3.5
                    if (!successIDSRead)
                    #endregion
                    {
                        return(DoPart_F(database, qManager, cardResponse));
                    }
                    else
                    {
                        #region 9_10.8
                        string dbds1 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2).Value);
                        if (!database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2.Tag))
                        #endregion
                        {
                            #region 9_10.9
                            return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));

                            #endregion
                        }

                        #region 9_10.10
                        string dbds2 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2).Value);
                        if (dbds1 != dbds2)
                        #endregion
                        {
                            #region 9_10.11
                            return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.IDS_READ_ERROR, L3Enum.NOT_SET));

                            #endregion
                        }

                        #region 9_10.12
                        byte dsss = database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0];
                        dsss = (byte)(dsss | 0x80); //set succesful read
                        database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss;
                        #endregion

                        #region 9_10.13
                        if (!ids.Value.IsWrite)
                        #endregion
                        {
                            #region 9_10.70
                            return(DoPart_E(database, qManager, cardQManager));

                            #endregion
                        }
                        else
                        {
                            #region 9_10.14
                            if (!database.IsPresent(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2.Tag))
                            #endregion
                            {
                                #region 9_10.15
                                return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));

                                #endregion
                            }
                            else
                            {
                                #region 9_10.16
                                string dbds3 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2).Value);
                                if (dbds2 == dbds3)
                                #endregion
                                {
                                    #region 9_10.18
                                    byte dsodsifr = database.Get(EMVTagsEnum.DS_ODS_INFO_FOR_READER_DF810A_KRN2).Value[0];
                                    if ((dsodsifr & 0x02) == 0x02) //stop if write set
                                    #endregion
                                    {
                                        #region 9_10.19
                                        return(DoInvalidResponsePart_D(database, qManager, L1Enum.NOT_SET, L2Enum.IDS_WRITE_ERROR, L3Enum.NOT_SET));

                                        #endregion
                                    }
                                    else
                                    {
                                        return(DoPart_E(database, qManager, cardQManager));
                                    }
                                }
                                else
                                {
                                    #region 9_10.17
                                    dsss = (byte)(dsss | 0x40); //set succesful write
                                    database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss;
                                    return(DoPart_E(database, qManager, cardQManager));

                                    #endregion
                                }
                            }
                        }
                    }
                }
                else
                {
                    bool successIDSNotRead = false;
                    #region 9_10.2.1
                    if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                    #endregion
                    {
                        #region 9_10.4.1
                        successIDSNotRead = VerifySDAD_CheckRelayData_9_10__4_1(database, capk, cardResponse);
                        #endregion
                    }
                    else
                    {
                        #region 9_10.4
                        successIDSNotRead = VerifySDAD_9_10__4(database, capk, cardResponse);
                        #endregion
                    }
                    #region 9_10.6
                    if (!successIDSNotRead)
                    #endregion
                    {
                        return(DoPart_F(database, qManager, cardResponse));
                    }
                    else
                    {
                        return(DoPart_E(database, qManager, cardQManager));
                    }
                }
            }
        }
Пример #27
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 DoPart_E(Kernel2Database database, KernelQ qManager, CardQ cardQManager)
        {
            #region 9_10.70
            CommonRoutines.CreateEMVDataRecord(database);

            Kernel2OutcomeStatusEnum    k2OutcomeStatus     = Kernel2OutcomeStatusEnum.N_A;
            Kernel2StartEnum            k2StartStatus       = Kernel2StartEnum.N_A;
            KernelStatusEnum            k2Status            = KernelStatusEnum.N_A;
            KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.N_A;
            byte[]             holdTime           = new byte[] { 0x00, 0x00, 0x00 };
            ValueQualifierEnum valueQualifierEnum = ValueQualifierEnum.NONE;
            KernelCVMEnum      cvmEnum            = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database).Value.CVM;
            byte[]             currencyCode       = new byte[2];
            byte[]             valueQualifier     = new byte[6];
            bool uiRequestOnOutcomePresent;

            #endregion

            #region 9_10.71
            if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) &&
                ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x0000030F) != 0x00000000)
            #endregion
            {
                #region 9_10.72
                k2OutcomeStatus = Kernel2OutcomeStatusEnum.END_APPLICATION;
                k2StartStatus   = Kernel2StartEnum.B;
                #endregion

                #region 9_10.73
                PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = new PHONE_MESSAGE_TABLE_DF8131_KRN2(database.GetDefault(EMVTagsEnum.PHONE_MESSAGE_TABLE_DF8131_KRN2));
                foreach (PhoneMessageTableEntry_DF8131 entry in pmt.Value.Entries)
                {
                    int pcii     = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value);
                    int pciMask  = (int)Formatting.ConvertToInt32(entry.PCIIMask);
                    int pciValue = (int)Formatting.ConvertToInt32(entry.PCIIValue);
                    if ((pciMask & pcii) == pciValue)
                    {
                        k2MessageIdentifier = entry.MessageIdentifier;
                        k2Status            = entry.Status;
                        holdTime            = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;
                        break;
                    }
                }
                #endregion
            }
            else
            {
                string tt = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value);
                #region 9_10.74
                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40)
                #endregion
                {
                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.APPROVED;
                }
                else
                {
                    if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80)
                    {
                        k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST;
                    }
                    else
                    {
                        /*
                         * Check if Transaction Type indicates a cash transaction (cash
                         * withdrawal or cash disbursement) or a purchase transaction (purchase
                         * or purchase with cashback).
                         */
                        if (tt == "01" || tt == "17" || tt == "00" || tt == "09")
                        {
                            if (database.IsNotEmpty(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2.Tag))
                            {
                                THIRD_PARTY_DATA_9F6E_KRN      tpd = new THIRD_PARTY_DATA_9F6E_KRN(database);
                                TERMINAL_CAPABILITIES_9F33_KRN tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);
                                ushort uid = Formatting.ConvertToInt16(tpd.Value.UniqueIdentifier);
                                ushort dt  = Formatting.ConvertToInt16(tpd.Value.DeviceType);
                                if ((uid & 0x8000) == 0x0000 && dt != 0x3030 || tc.Value.ICWithContactsCapable)
                                {
                                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.DECLINED;
                                }
                                else
                                {
                                    k2OutcomeStatus = Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE;
                                }
                            }
                            else
                            {
                                k2OutcomeStatus = Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE;
                            }
                        }
                        else
                        {
                            k2OutcomeStatus = Kernel2OutcomeStatusEnum.END_APPLICATION;
                        }
                    }
                }

                #region 9_10.75
                k2Status = KernelStatusEnum.NOT_READY;

                if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40)
                {
                    holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;

                    if (database.IsNotEmpty(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2.Tag))
                    {
                        valueQualifierEnum = ValueQualifierEnum.BALANCE;
                        valueQualifier     = database.Get(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2).Value;
                        if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN.Tag))
                        {
                            currencyCode = database.Get(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN).Value;
                        }
                    }

                    if (cvmEnum == KernelCVMEnum.OBTAIN_SIGNATURE)
                    {
                        k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED_SIGN;
                    }
                    else
                    {
                        k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED;
                    }
                }
                else
                {
                    if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80)
                    {
                        holdTime            = new byte[] { 0x00, 0x00, 0x00 };
                        k2MessageIdentifier = KernelMessageidentifierEnum.AUTHORISING_PLEASE_WAIT;
                    }
                    else
                    {
                        if (tt == "01" || tt == "17" || tt == "00" || tt == "09")
                        {
                            holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value;


                            if (database.IsNotEmpty(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2.Tag))
                            {
                                THIRD_PARTY_DATA_9F6E_KRN      tpd = new THIRD_PARTY_DATA_9F6E_KRN(database);
                                TERMINAL_CAPABILITIES_9F33_KRN tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);
                                ushort uid = Formatting.ConvertToInt16(tpd.Value.UniqueIdentifier);
                                ushort dt  = Formatting.ConvertToInt16(tpd.Value.DeviceType);
                                if ((uid & 0x8000) == 0x0000 && dt != 0x3030 || tc.Value.ICWithContactsCapable)
                                {
                                    k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED;
                                }
                                else
                                {
                                    k2MessageIdentifier = KernelMessageidentifierEnum.INSERT_CARD;
                                }
                            }
                            else
                            {
                                k2MessageIdentifier = KernelMessageidentifierEnum.INSERT_CARD;
                            }
                        }
                        else
                        {
                            holdTime            = new byte[] { 0x00, 0x00, 0x00 };
                            k2MessageIdentifier = KernelMessageidentifierEnum.CLEAR_DISPLAY;
                        }
                    }
                }

                #endregion
            }

            #region 9_10.76
            if (database.IsNotEmpty(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag))
            #endregion
            {
                #region 9_10.77
                TLV tagToPut = database.TagsToWriteAfterGenACYet.GetFirstAndRemoveFromList();
                EMVPutDataRequest request = new EMVPutDataRequest(tagToPut);
                #endregion
                #region 9_10.78
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_AFTER_GEN_AC);

                #endregion
            }

            CommonRoutines.CreateEMVDiscretionaryData(database);

            #region 9_10.78.1
            if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) &&
                ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x0000030F) != 0x00000000)
            #endregion
            {
                #region 9_10.79
                CommonRoutines.PostUIOnly(database, qManager, k2MessageIdentifier, k2Status, true, holdTime);
                #endregion

                #region 9_10.80
                uiRequestOnOutcomePresent = false;
                k2Status = KernelStatusEnum.READY_TO_READ;
                holdTime = new byte[] { 0x00, 0x00, 0x00 };
                #endregion
            }
            else
            {
                #region 9_10.81
                uiRequestOnOutcomePresent = true;
                #endregion
            }
            return(CommonRoutines.PostOutcome(database, qManager,
                                              k2MessageIdentifier,
                                              k2Status,
                                              holdTime,
                                              k2OutcomeStatus,
                                              k2StartStatus,
                                              uiRequestOnOutcomePresent,
                                              KernelMessageidentifierEnum.N_A,
                                              L1Enum.NOT_SET,
                                              null,
                                              L2Enum.NOT_SET,
                                              L3Enum.NOT_SET,
                                              valueQualifierEnum,
                                              valueQualifier,
                                              currencyCode,
                                              false,
                                              cvmEnum));
        }
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            EMVGetDataResponse response = (EMVGetDataResponse)cardResponse.ApduResponse;

            if (!response.Succeeded)
            {
                cvr.Value.CVMResult = 0x01;//failed
                cvr.UpdateDB();
                return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
            }

            //store the pin try counter value
            database.AddToList(response.GetResponseTag());
            int pinTryCounter = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN).Value);

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper)
            {
                string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);
                if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr))
                {
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }
                //fire off get challenge command
                EMVGetChallengeRequest request = new EMVGetChallengeRequest();
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GET_CHALLENGE);
            }

            if (cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper)
            {
                string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);
                if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr))
                {
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }

                byte[] pinData = PinProcessing.BuildPlainTextPinBlock(pin);

                //fire off verify for plain text pin
                EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Plaintext_PIN, pinData);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));

                return(SignalsEnum.WAITING_FOR_VERIFY);
            }

            throw new EMVProtocolException("Invalid cvr in State_5b_WaitingForGetPinTryCounter");
        }
        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);
            }
        }