Beispiel #1
0
        private static SignalsEnum EntryPointDET(KernelDatabaseBase database, KernelRequest kernel1Request, CardQ cardQManager, Stopwatch sw)
        {
            database.UpdateWithDETData(kernel1Request.InputData);

            bool    missingPDOLData            = false;
            TLV     _9f38                      = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList                   = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);
            DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);

            foreach (TLV tlv in pdolList)
            {
                if (database.IsEmpty(tlv.Tag.TagLable))
                {
                    missingPDOLData = true;
                    dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                }
            }
            dataNeeded.UpdateDB();

            if (missingPDOLData)
            {
                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }

            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));

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

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
        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);
                    }
                }
            }
        }
Beispiel #3
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));
        }
Beispiel #5
0
        private static SignalsEnum EntryPointRA(KernelDatabaseBase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager,
                                                Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager,
                                                Func <string, KernelDatabaseBase, KernelQ, CardQ, Stopwatch, PublicKeyCertificateManager, CardExceptionManager, SignalsEnum> ReadRecordCompleteCallback)
        {
            byte sfi;
            bool signedFlag;

            if (!cardResponse.ApduResponse.Succeeded)
            {
                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));
            }

            if (database.ActiveAFL.Value.Entries[0].OfflineDataAuthenticationRecordLength > 0)
            {
                signedFlag = true;
            }
            else
            {
                signedFlag = false;
            }

            sfi = database.ActiveAFL.Value.Entries[0].SFI;
            database.ActiveAFL.Value.Entries.RemoveAt(0);

            if (database.ActiveAFL.Value.Entries.Count == 0)
            {
                database.NextCommandEnum = NextCommandEnum.NONE;
            }
            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;
            }

            bool parsingResult;

            if (sfi <= 10)
            {
                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;
            }

            if (!parsingResult)
            {
                if (database.NextCommandEnum == NextCommandEnum.NONE)
                {
                    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));
                }
                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");
            }

            TLVList cdols = responseTags.FindAll(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag);

            if (cdols.Count > 0)
            {
                TLVList cdolList = TLV.DeserializeChildrenWithNoV(cdols.GetFirst().Value, 0);
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                foreach (TLV tlv in cdolList)
                {
                    if (database.IsEmpty(tlv.Tag.TagLable))
                    {
                        dataNeeded.Value.Tags.Add(tlv.Tag.TagLable);
                    }
                }
                dataNeeded.UpdateDB();
            }

            Do434(database, signedFlag, sfi, cardResponse, responseTags);

            return(ReadRecordCompleteCallback("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, publicKeyCertificateManager, cardExceptionManager));
            //return State_4_5_6_CommonProcessing.DoCommonProcessing("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, publicKeyCertificateManager);
        }
Beispiel #6
0
        private static SignalsEnum EntryPointACT(KernelDatabaseBase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            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);
                    }
                }
            }

            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();

            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            cvmr.UpdateDB();

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            tvr.UpdateDB();

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            _9f33.UpdateDB();

            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();
            }

            bool MissingPDOLDataFlag = false;

            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();

            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));
            }

            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);
            }

            dataNeeded.UpdateDB();

            if (MissingPDOLDataFlag)
            {
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();

                sw.Restart();
                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
Beispiel #7
0
        public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, TornTransactionLogManager tornTransactionLogManager)
        {
            #region 456.1
            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            #endregion
            {
                #region 456.2
                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 456.3
                if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)
                #endregion
                {
                    #region 456.4
                    CommonRoutines.PostDEK(database, qManager);
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                    database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                    #endregion
                }
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }
            else
            {
                if (database.NextCommandEnum == NextCommandEnum.GET_DATA)
                {
                    return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE);
                }
                else
                {
                    #region 456.5
                    if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag))
                    #endregion
                    {
                        DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                        #region 456.6
                        dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag);
                        #endregion
                        dataNeeded.UpdateDB();

                        return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw));
                    }
                    else
                    {
                        #region 456.11
                        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 456.7
                            return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw));

                            #endregion
                        }
                    }
                }
            }

            #region 456.12
            if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag))
            #endregion
            {
                #region 456.13
                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 456.14
            long aa   = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value);
            long rctl = database.ReaderContactlessTransactionLismit;
            if (aa > rctl)
            #endregion
            {
                #region 456.15
                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 456.16
            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag)))
            #endregion
            {
                #region 456.17
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.N_A,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_MISSING,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 456.18
            IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
            if (ids.Value.IsRead)
            #endregion
            {
                #region 456.19
                string dsid      = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value);
                string pan       = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value);
                string seqNumber = "00";
                if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))
                {
                    seqNumber = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value);
                }
                string concat = pan + seqNumber;
                if (concat.Length % 2 != 0)
                {
                    concat = "0" + concat;
                }
                if (concat.Length < 16)
                {
                    concat.PadLeft(16, '0');
                }
                if (dsid != concat)
                #endregion
                {
                    #region 456.20.1,456.20.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.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
            }

            #region 456.21
            TLVList toRemove2 = new TLVList();
            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));
                    }
                }
                toRemove2.AddToList(tlv);
            }

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

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

            #region 456.24
            if (database.ODAStatus == 0x80)
            #endregion
            {
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                #region 456.25
                if (!(
                        database.IsNotEmpty(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN.Tag) &&
                        database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag)
                        ))
                {
                    tvr.Value.ICCDataMissing = true;
                    tvr.Value.CDAFailed      = true;
                }

                if (database.PublicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null)
                {
                    tvr.Value.CDAFailed = true;
                }


                #endregion

                #region 456.26
                bool test = false;
                TLV  aip  = null;
                if (database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag))
                {
                    TLV     sdal = database.Get(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN);
                    TLVList list = TLV.DeserializeChildrenWithNoLV(sdal.Value, 0);
                    if (list.Count == 1)
                    {
                        aip = list.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                        if (aip != null)
                        {
                            test = true;
                        }
                    }
                }

                if (test == false)
                {
                    #region 456.27.1 - 456.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.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                #endregion

                #region 456.28
                int length = database.StaticDataToBeAuthenticated.Serialize().Length;
                if (2048 - length >= aip.Value.Length)
                {
                    database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN));
                }
                else
                {
                    tvr.Value.CDAFailed = true;
                }
                #endregion
                tvr.UpdateDB();
            }

            #region 456.30
            long cvmrl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value);
            if (aa > cvmrl)
            #endregion
            {
                #region 456.31
                CommonRoutines.UpdateOutcomeParameterSet(database, true);
                #endregion

                #region 456.32
                database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_CVM_REQUIRED_DF8118_KRN2).Value[0];
                #endregion
            }
            else
            {
                #region 456.33
                database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_NO_CVM_REQUIRED_DF8119_KRN2).Value[0];
                #endregion
            }

            #region 456.34
            SignalsEnum se = PreGenACBalanceReading_7_1.PreGenACBalanceReading(database, qManager, cardQManager);
            if (se != SignalsEnum.NONE)
            {
                return(se);
            }
            #endregion

            #region 456.35
            ProcessingRestrictions_7_7.ProcessingRestrictions(database);
            #endregion

            #region 456.35
            CVMSelection_7_5.CVMSelection(database,
                                          new Func <bool>(() =>
            {
                return(new KERNEL_CONFIGURATION_DF811B_KRN2(database).Value.OnDeviceCardholderVerificationSupported);
            }));
            #endregion

            #region 456.36
            long rcfl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_FLOOR_LIMIT_DF8123_KRN2).Value);
            if (aa > rcfl)
            #endregion
            {
                #region 456.38
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.TransactionExceedsFloorLimit = true;
                tvr.UpdateDB();
                #endregion
            }

            #region 456.39
            database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database);
            #endregion

            //#region support for Refunds pg 177
            //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];
            //if (transactionType == (byte)TransactionTypeEnum.Refund)
            //{
            //    database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC;
            //    database.ODAStatus = 0x00; //dont request CDA in first gen ac
            //}
            //#endregion


            #region 456.42
            if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag))
            #endregion
            {
                #region 456.50
                TLV tlvRemoved            = database.TagsToWriteBeforeGenACYet.GetFirstAndRemoveFromList();
                EMVPutDataRequest request = new EMVPutDataRequest(tlvRemoved);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_BEFORE_GEN_AC);

                #endregion
            }
            else
            {
                TORN_RECORD_FF8101_KRN2 foundTTL = null;
                #region 456.43
                uint mnttl = Formatting.ConvertToInt32(database.GetDefault(EMVTagsEnum.MAX_NUMBER_OF_TORN_TRANSACTION_LOG_RECORDS_DF811D_KRN2).Value);
                if (database.IsNotEmpty(EMVTagsEnum.DRDOL_9F51_KRN2.Tag) && mnttl != 0)
                #endregion
                {
                    #region 456.44
                    foreach (TORN_RECORD_FF8101_KRN2 tlv in tornTransactionLogManager.TornTransactionLogs)
                    {
                        if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))
                        {
                            if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) &&
                                (Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value)))
                            {
                                foundTTL = tlv;
                            }
                        }
                        else
                        {
                            if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) &&
                                (tlv.Children.IsNotPresent(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)))
                            {
                                foundTTL = tlv;
                            }
                        }
                    }
                    #endregion
                    if (foundTTL == null)
                    {
                        #region 456.45
                        EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager);
                        cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                        return(SignalsEnum.WAITING_FOR_GEN_AC_1);

                        #endregion
                    }
                    else
                    {
                        #region 456.47
                        database.TornTempRecord = foundTTL;
                        #endregion

                        #region 456.48
                        database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2).Value = database.TornTempRecord.Children.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2.Tag).Value;
                        EMVRecoverACRequest requestRecover = new EMVRecoverACRequest(database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2));
                        cardQManager.EnqueueToInput(new CardRequest(requestRecover, CardinterfaceServiceRequestEnum.ADPU));
                        return(SignalsEnum.WAITING_FOR_RECOVER_AC);

                        #endregion
                    }
                }
                else
                {
                    #region 456.45
                    EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager);
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    return(SignalsEnum.WAITING_FOR_GEN_AC_1);

                    #endregion
                }
            }
        }
        private static SignalsEnum ProcessNextCVM(KernelDatabase database, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN      cvl = new CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN(database);
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            bool goToNextCVM = false;

            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
            {
                if (cvr.Value.GetCVMResult() == CVMResult.Failed)
                {
                    goToNextCVM = true;
                }
            }
            else
            {
                //if a previously run CVM failed then state returns here and we try the next CVM
                if (cvr.Value.GetCVMResult() != CVMResult.Success)
                {
                    goToNextCVM = true;
                }
            }

            if (goToNextCVM && database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count)
            {
                //if previous cvm was offline pin, check pin try counter
                if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper)
                {
                    TLV pinTryCounterTLV = database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN);
                    if (pinTryCounterTLV != null)
                    {
                        ushort pinTryCounter = Formatting.ConvertToInt16(pinTryCounterTLV.Value);
                        if (pinTryCounter > 1) //at this point the pin try counter on the card is 0, we are always 1 behind
                        {
                            qManager.EnqueueToOutput(new KernelPinResponse());
                            return(SignalsEnum.WAITING_FOR_PIN_RESPONSE);
                        }
                    }
                }

                #region Book 3 Section 10.5
                CVMSelection_7_5.CVMSelection(database, new Func <bool>(() => { return(true); }));
                cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);//update after calling cvm selection
                #endregion

                if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC ||
                    cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper ||
                    cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline)
                {
                    qManager.EnqueueToOutput(new KernelPinResponse());
                    return(SignalsEnum.WAITING_FOR_PIN_RESPONSE);
                }

                if (cvr.Value.GetCVMResult() == CVMResult.Failed)
                {
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }
            }

            if (cvr.Value.GetCVMPerformed() != CVMCode.NoCVMDone)
            {
                TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                tsi.Value.CardholderVerificationWasPerformed = true;
                tsi.UpdateDB();
            }

            #region Book 3 Section 10.6
            //Terminal Risk Management
            TLV lcol = database.Get(EMVTagsEnum.LOWER_CONSECUTIVE_OFFLINE_LIMIT_9F14_KRN);
            TLV ucol = database.Get(EMVTagsEnum.UPPER_CONSECUTIVE_OFFLINE_LIMIT_9F23_KRN);
            if (lcol != null && ucol != null)
            {
                EMVGetDataRequest requestATC           = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag));
                EMVGetDataRequest requestLastOnlineATC = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag));
                cardQManager.EnqueueToInput(new CardRequest(requestATC, CardinterfaceServiceRequestEnum.ADPU));
                cardQManager.EnqueueToInput(new CardRequest(requestLastOnlineATC, CardinterfaceServiceRequestEnum.ADPU));
            }

            //Get Floor Limit Data
            if (database.IsEmpty(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag))
            {
                DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                dataNeeded.Value.Tags.Add(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag);
                dataNeeded.UpdateDB();
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
            }

            qManager.EnqueueToOutput(new KernelTRMResponse());
            return(SignalsEnum.WAITING_FOR_TERMINAL_RISK_MANAGEMENT);

            #endregion
        }