Exemplo n.º 1
0
        public static SignalsEnum Initiate2ndCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse, bool entryFromScriptProcessingCompleted = false)
        {
            if (!entryFromScriptProcessingCompleted)
            {
                //check if scripts need to be run
                TLV _71 = database.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN);
                if (_71 != null)
                {
                    ((KernelDatabase)database).ScriptsToRunBeforeGenAC = BuildScriptList(_71);
                    if (((KernelDatabase)database).ScriptsToRunBeforeGenAC.Count > 0)
                    {
                        ((KernelDatabase)database).IsScriptProcessingBeforeGenACInProgress = true;
                        //post first script
                        TLV firstScript = ((KernelDatabase)database).ScriptsToRunBeforeGenAC.GetFirstAndRemoveFromList();
                        EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest();
                        scriptRequest.Deserialize(firstScript.Value);
                        cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU));
                        return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING);
                    }
                }
            }

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

            //section 6.5.5 in Book 3
            TLV cdol2 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_2_CDOL2_8D_KRN);

            byte[] cdol2Data = CommonRoutines.PackRelatedDataTag(database, cdol2);

            REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database);

            rcpST.Value.ACTypeEnum = GetDSACType(database);
            if (aip.Value.CDASupported && tc.Value.CDACapable)
            {
                rcpST.Value.CDASignatureRequested = true;
            }
            else
            {
                rcpST.Value.CDASignatureRequested = false;
            }
            rcpST.UpdateDB();

            EMVGenerateACRequest request = new EMVGenerateACRequest(cdol2Data, null, rcpST);

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

            return(SignalsEnum.WAITING_FOR_GEN_AC_2);
        }
        private static EMVGenerateACRequest DoGAC22_26(KernelDatabaseBase database)
        {
            #region GAC.22
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            KERNEL_CONFIGURATION_DF811B_KRN2       kc  = new KERNEL_CONFIGURATION_DF811B_KRN2(database);
            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported)
            #endregion
            {
                #region GAC.23
                SetDSACType(database, ACTypeEnum.AAC);
                #endregion
            }

            return(DoGAC26(database));
        }
Exemplo n.º 3
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);
        }
        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);
                    }
                }
            }
        }
Exemplo n.º 5
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));
        }
        private static SignalsEnum EntryPointOnline(KernelDatabase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            KernelOnlineRequest response = (KernelOnlineRequest)kernel1Request;

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

            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);

            if (aip.Value.IssuerAuthenticationIsSupported && response.OnlineApprovalStatus != KernelOnlineResponseType.UnableToGoOnline)
            {
                TLV _91 = response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag);
                EMVExternalAuthenticateRequest request = new EMVExternalAuthenticateRequest(_91.Value);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_EXTERNAL_AUTHENTICATE);
            }
            else
            {
                //if scripts need to be run before gen ac, do now
                return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));
            }
        }
        public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse)
        {
            #region S3R1.1
            TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList();
            if (nextTLV != null)
            {
                database.ActiveTag = nextTLV.Tag.TagLable;
            }
            else
            {
                database.ActiveTag = null;
            }

            if (database.ActiveTag != null)
            {
                #region S3R1.2
                EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag));
                #endregion
                #region S3R1.3
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                #endregion
                #region S3R1.3
                database.NextCommandEnum = NextCommandEnum.GET_DATA;
                #endregion
            }
            #endregion
            else
            {
                #region S3R1.5
                if (database.ActiveAFL == null)
                #endregion
                {
                    #region S3R1.6
                    return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    #region S3R1.7
                    EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
                    #endregion
                    #region S3R1.8
                    cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                    #endregion
                    #region S3R1.9
                    database.NextCommandEnum = NextCommandEnum.READ_RECORD;
                    #endregion
                }
            }

            #region S3R1.10
            TLVList dataToSend         = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children;
            IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
            if (ids.Value.IsRead)
            #endregion
            {
                #region S3R1.11
                if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2));
                }
                if (database.IsNotEmpty(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag))
                {
                    dataToSend.AddToList(database.Get(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2));
                }
                dataToSend.AddToList(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN));
                #endregion
                #region S3R1.12
                if (!((database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag) &&
                       database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) &&
                       database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag) &&
                       database.IsNotPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag))
                      ||
                      (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) &&
                       database.IsPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag))
                      ))
                {
                    #region S3R1.13
                    ids = new IDS_STATUS_DF8128_KRN2(database);
                    ids.Value.IsRead = false;
                    ids.UpdateDB();
                    #endregion
                }
                #endregion
            }

            #region S3R1.14
            TLVList tagsToRemove = new TLVList();
            foreach (TLV ttry in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(ttry.Tag.TagLable))
                {
                    dataToSend.AddToList(ttry);
                    tagsToRemove.AddToList(ttry);
                }
            }
            foreach (TLV ttr in tagsToRemove)
            {
                database.TagsToReadYet.RemoveFromList(ttr);
            }

            #endregion

            #region S3R1.15
            if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) ||
                (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0))
            {
                #region S3R1.16
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion
            }
            #endregion

            #region S3R1.17
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            TERMINAL_CAPABILITIES_9F33_KRN         tc  = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            if (!(aip.Value.CDASupported && tc.Value.CDACapable))
            {
                #region S3R1.18
                ids = new IDS_STATUS_DF8128_KRN2(database);
                if (!ids.Value.IsRead)
                {
                    #region S3R1.20
                    TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                    tvr.Value.OfflineDataAuthenticationWasNotPerformed = true;
                    tvr.UpdateDB();
                    #endregion
                }
                else
                {
                    #region S3R1.19
                    database.ODAStatus = 0x80;
                    #endregion
                }
                #endregion
            }
            else
            {
                #region S3R1.19
                database.ODAStatus = 0x80;
                #endregion
            }
            #endregion

            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            {
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }
            else
            {
                return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE);
            }
        }
        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));
            }

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

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

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

            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, true);
                }
                else
                {
                    tvr.Value.CDAFailed = true;
                    tvr.UpdateDB();
                }
            }
            else
            {
                if (aip.Value.DDAsupported && tc.Value.DDACapable)
                {
                    //oda was done already in waiting for internal authenticate
                }
                else
                {
                    if (aip.Value.SDASupported && tc.Value.SDACapable)
                    {
                        //sda was done already in card action analysis
                    }
                }
            }

            //check for offline approved or declined, if so end transaction
            if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40 ||
                (database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00)
            {
                return(State_7_10_CommonProcessing.EndOnTCorAAC(database, qManager, cardQManager));
            }
            else
            {
                CommonRoutines.CreateEMVDataRecord(database);
                CommonRoutines.CreateEMVDiscretionaryData(database);
                qManager.EnqueueToOutput(new KernelOnlineResponse(database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2), database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2)));
                return(SignalsEnum.WAITING_FOR_ONLINE_RESPONSE);
            }
        }
        /*
         * S3.1
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            #region S3.8
            if (!cardResponse.ApduResponse.Succeeded)
            #endregion
            {
                #region 3.9.1 and 3.9.2
                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));

                #endregion
            }

            #region S3.10
            bool parsingResult = false;
            if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77)
            {
                EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse;
                parsingResult = database.ParseAndStoreCardResponse(response.ResponseData);
            }
            else
            {
                if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80)
                {
                    EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse;
                    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
                    {
                        //database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN).Value = new byte[] { cardResponse.ApduResponse.ResponseData[0], cardResponse.ApduResponse.ResponseData[1]};
                        //byte[] afl = new byte[cardResponse.ApduResponse.ResponseData.Length - 2];
                        //Array.Copy(cardResponse.ApduResponse.ResponseData, 2, afl, 0, afl.Length);
                        //database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN).Value = afl;

                        //EMVGetProcessingOptionsResponse does the unpacking of the tags
                        foreach (TLV tlv in response.GetResponseTags())
                        {
                            parsingResult = database.ParseAndStoreCardResponse(tlv);
                            if (!parsingResult)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            #endregion

            #region S3.11
            if (!parsingResult)
            {
                #region S3.12
                return(State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));

                #endregion
            }
            else
            {
                #region S3.13
                if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) &&
                    database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag))
                {
                    #region S3.14
                    return(State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));

                    #endregion
                }
                else
                {
                    #region S3.15
                    KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database);
                    if (!kc.Value.EMVModeContactlessTransactionsNotSupported)
                    {
                        #region S3.16
                        APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
                        if (aip.Value.EMVModeIsSupported)
                        {
                            //goto 3.30
                            return(DoEMVMode(database, qManager, cardQManager, cardResponse, sw));
                        }
                        #endregion
                    }

                    #region S3.17
                    if (kc.Value.MagStripeModeContactlessTransactionsNotSupported)
                    {
                        #region S3.18
                        return(State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.MAGSTRIPE_NOT_SUPPORTED, L3Enum.NOT_SET));

                        #endregion
                    }
                    else
                    {
                        //goto 3.70
                        return(DoMagMode(database, qManager, cardQManager));
                    }
                    #endregion

                    #endregion
                }
                #endregion
            }
            #endregion
        }
        private static SignalsEnum DoMagMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager)
        {
            KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database);

            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);
            #region 3.70
            if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100")
            #endregion
            {
                #region 3.72
                byte[] activeAFLBytes = new byte[4];
                Array.Copy(aflRaw.Value, 0, 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);
                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(activeAFLBytes));
                #endregion
            }
            else
            {
                #region 3.71
                List <byte[]> bytes = new List <byte[]>
                {
                    new byte[] { (byte)aflRaw.Value.Length },
                    aflRaw.Value
                };
                database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0);
                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value));
                #endregion
            }

            #region 3.73
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported)
            {
                #region 3.75
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value);
                #endregion
            }
            else
            {
                #region 3.74
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value);
                #endregion
            }
            #endregion

            #region 3.76
            TLVList dataToSend   = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children;
            TLVList tagsToRemove = new TLVList();
            foreach (TLV ttry in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(ttry.Tag.TagLable))
                {
                    dataToSend.AddToList(ttry);
                    tagsToRemove.AddToList(ttry);
                }
            }
            foreach (TLV ttr in tagsToRemove)
            {
                database.TagsToReadYet.RemoveFromList(ttr);
            }
            #endregion

            #region 3.77
            if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) ||
                (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0))
            {
                #region 3.78
                CommonRoutines.PostDEK(database, qManager);
                database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                #endregion
            }

            #region 3.80
            EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber);
            #endregion
            #region 3.81
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            #endregion
            return(SignalsEnum.WAITING_FOR_MAG_STRIPE_READ_RECORD_RESPONSE);

            #endregion
        }
        private static SignalsEnum DoEMVMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse, Stopwatch sw)
        {
            #region 3.30
            KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database);

            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" && !kc.Value.MagStripeModeContactlessTransactionsNotSupported)
            {
                #region 3.32
                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);

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

                //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value));
                #endregion
            }
            #endregion

            #region 3.33
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
            if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported)
            {
                #region 3.35
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value);
                #endregion
            }
            else
            {
                #region 3.34
                database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value);
                #endregion
            }
            #endregion

            #region 3.60
            if (kc.Value.RelayResistanceProtocolSupported && aip.Value.RelayResistanceProtocolIsSupported)
            #endregion
            {
                #region 3.61
                database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber();
                database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value;
                #endregion
                #region 3.62
                EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value);
                #endregion
                #region 3.63
                sw.Start();
                #endregion
                #region 3.64
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                #endregion
                return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE);
            }
            else
            {
                #region 3.65
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_NOT_PERFORMED;
                tvr.UpdateDB();
                #endregion
                return(State_3_R1_CommonProcessing.DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, cardResponse));
            }
        }
        public static SignalsEnum DoCommonProcessing(string source, KernelDatabase database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            {
                DoDEKIfNeeded(database, qManager);
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }

            DoDEKIfNeeded(database, qManager);

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

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

            #region Book 3 Section 10.3
            APPLICATION_INTERCHANGE_PROFILE_82_KRN aipCheck = 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);
            if ((aipCheck.Value.CDASupported && tc.Value.CDACapable) ||
                aipCheck.Value.DDAsupported && tc.Value.DDACapable ||
                aipCheck.Value.SDASupported && tc.Value.SDACapable)
            {
                if (aipCheck.Value.CDASupported && tc.Value.CDACapable)
                {
                    //some checking in preperation for ODA is done here, ODA is done after 1st gen ac
                    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;
                    }
                }

                string  aid     = emvSelectApplicationResponse.GetDFName();
                string  rid     = aid.Substring(0, 10);
                RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid);
                if (database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null)
                {
                    if (aipCheck.Value.CDASupported && tc.Value.CDACapable)
                    {
                        tvr.Value.CDAFailed = true;
                    }
                    if (aipCheck.Value.DDAsupported && tc.Value.DDACapable)
                    {
                        tvr.Value.DDAFailed = true;
                    }
                    if (aipCheck.Value.SDASupported && tc.Value.SDACapable)
                    {
                        tvr.Value.SDAFailed = true;
                    }
                }

                //bool aipFound = 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)
                //    {
                //        aipFound = true;
                //    }
                //    //}
                //}
                //else
                //{
                //    if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag))
                //    {
                //        aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                //        aipFound = true;
                //    }
                //}
                //if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag))
                //{
                //    aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                //    aipFound = true;
                //}

                TLV aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN);
                if (database.IsEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag))
                {
                    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));
                }

                int length = database.StaticDataToBeAuthenticated.Serialize().Length;
                if (2048 - length >= aip.Value.Length)
                {
                    //will be removed later when the SDA is done
                    database.StaticDataToBeAuthenticated.AddToList(aip);
                }
                //else
                //{
                //    if (aipCheck.Value.CDASupported && tc.Value.CDACapable)
                //    {
                //        tvr.Value.CDAFailed = true;
                //    }
                //    if (aipCheck.Value.DDAsupported && tc.Value.DDACapable)
                //    {
                //        tvr.Value.DDAFailed = true;
                //    }
                //    if (aipCheck.Value.SDASupported && tc.Value.SDACapable)
                //    {
                //        tvr.Value.SDAFailed = true;
                //    }
                //}
                tvr.UpdateDB();
            }
            #endregion

            #region Book 3 Section 10.4
            //using kernel 2 processing restrictions
            ProcessingRestrictions_7_7.ProcessingRestrictions(database);
            #endregion

            return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
        }
Exemplo n.º 13
0
        public static SignalsEnum InitiateCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            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);

            //time to get signature data for dda cards, in order to do oda after 1st gen ac
            EMVGenerateACRequest request = null;

            if (aip.Value.CDASupported && tc.Value.CDACapable)
            {
                //cda done after gen ac 1, call gen ac1 now with signature requested
                request = CreateGenAC(database, true);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GEN_AC_1);
            }
            if (aip.Value.DDAsupported && tc.Value.DDACapable)
            {
                #region Book 3 Section 10.3
                //do dda signature request, internal authenticate will do oda once it has the signature
                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 requestDDA = new EMVInternalAuthenticateRequest(ddolRelatedData);
                cardQManager.EnqueueToInput(new CardRequest(requestDDA, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE);

                #endregion
            }
            if (aip.Value.SDASupported && tc.Value.SDACapable)
            {
                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]);

                TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN);
                if (capk == null || ssadTLV == null)
                {
                    tvr.Value.SDAFailed = true;
                    tvr.UpdateDB();
                }
                else
                {
                    TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                    tsi.Value.OfflineDataAuthenticationWasPerformed = true;
                    tsi.UpdateDB();

                    byte[] sdadRaw  = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN).Value;
                    byte[] authCode = VerifySAD.VerifySSAD(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw);
                    if (authCode == null)
                    {
                        tvr.Value.SDAFailed = true;
                        tvr.UpdateDB();
                    }
                    else
                    {
                        TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN);
                        if (dataAuthenticationCode == null)
                        {
                            dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode);
                        }
                        else
                        {
                            dataAuthenticationCode.Value = authCode;
                        }
                    }
                }

                //sda done after gen ac 1, call gen ac 1 now with no signature requested
                request = CreateGenAC(database, false);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_GEN_AC_1);
            }

            tvr.Value.OfflineDataAuthenticationWasNotPerformed = true;
            tvr.UpdateDB();
            //to do: ceck this, is this correct for a card where no oda is supported
            request = CreateGenAC(database, false);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            return(SignalsEnum.WAITING_FOR_GEN_AC_1);
        }
        private static bool CheckMandatoryFields(Kernel3Database database, PublicKeyCertificateManager pkcm)
        {
            TLV ttqCheck = database.Get(EMVTagsEnum.TERMINAL_TRANSACTION_QUALIFIERS_TTQ_9F66_KRN);

            if (ttqCheck == null)
            {
                return(false);
            }

            TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database);

            //Reader
            if (database.IsNotPresent(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN.Tag))
            {
                return(false);
            }
            //if (database.IsNotPresent(EMVTagsEnum.APPLICATION_IDENTIFIER_AID_TERMINAL_9F06_KRN.Tag)) return false;
            //if (database.IsNotPresent(EMVTagsEnum.MERCHANT_NAME_AND_LOCATION_9F4E_KRN.Tag)) return false;
            if (database.IsNotPresent(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.TRANSACTION_DATE_9A_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN.Tag))
            {
                return(false);
            }

            //Card
            //if (database.IsNotPresent(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag)) return false;
            //CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database);

            //if (database.IsNotPresent(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag)) return false;
            //if (database.IsNotPresent(EMVTagsEnum.APPLICATION_DEDICATED_FILE_ADF_NAME_4F_KRN.Tag)) return false;
            if (database.IsNotPresent(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag))
            {
                return(false);
            }

            if (database.IsNotPresent(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag))
            {
                return(false);
            }
            //if (database.IsNotPresent(EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_PROPRIETARY_TEMPLATE_A5_KRN.Tag)) return false;
            //if (database.IsNotPresent(EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)) return false;
            //if (database.IsNotPresent(EMVTagsEnum.FORM_FACTOR_INDICATOR_FFI_9F6E_KRN3.Tag)) return false;
            if (database.IsNotPresent(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN.Tag))
            {
                return(false);
            }
            if (database.IsNotPresent(EMVTagsEnum.TRACK_2_EQUIVALENT_DATA_57_KRN.Tag))
            {
                return(false);
            }

            bool odaCardSupported = true;

            if (database.IsPresent(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag))
            {
                APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database);
                APPLICATION_INTERCHANGE_PROFILE_82_KRN.APPLICATION_INTERCHANGE_PROFILE_82_KRN_VALUE aipST = aip.Value;
                if (!aipST.DDAsupported)
                {
                    odaCardSupported = false;
                }
                else
                {
                    odaCardSupported = true;
                }

                if (database.IsPresent(EMVTagsEnum.CARD_ADDITIONAL_PROCESSES_9F68_KRN.Tag))
                {
                    if (Formatting.IsBitSet(database.Get(EMVTagsEnum.CARD_ADDITIONAL_PROCESSES_9F68_KRN).Value[1], 5))
                    {
                        odaCardSupported = true;
                    }
                    else
                    {
                        odaCardSupported = false;
                    }
                }
            }

            //Card fdda
            if (odaCardSupported && ttq.Value.OfflineDataAuthenticationForOnlineAuthorizationsSupported && database.Kernel3Configuration.FDDAForOnlineSupported)
            {
                if (database.IsNotPresent(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag) &&
                    database.IsNotPresent(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN.Tag) &&
                    database.IsNotPresent(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag))
                {
                    return(false);
                }

                if (database.IsPresent(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag))
                {
                    if (database.IsNotPresent(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag))
                    {
                        return(false);
                    }
                    if (pkcm.GetCAPK(RIDEnum.A000000003, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null)
                    {
                        return(false);
                    }

                    if (database.IsNotPresent(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag))
                    {
                        return(false);
                    }
                    if (database.IsNotPresent(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag))
                    {
                        return(false);
                    }
                    if (database.IsNotPresent(EMVTagsEnum.ISSUER_PUBLIC_KEY_REMAINDER_92_KRN.Tag))
                    {
                        return(false);
                    }

                    if (database.IsNotPresent(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN.Tag))
                    {
                        return(false);
                    }
                    if (database.IsNotPresent(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN.Tag))
                    {
                        return(false);
                    }
                    //if (database.IsNotPresent(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_REMAINDER_9F48_KRN.Tag)) return false;

                    if (database.IsNotPresent(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3.Tag))
                    {
                        return(false);
                    }

                    //if (database.IsNotPresent(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag)) return false;
                    if (database.IsNotPresent(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag))
                    {
                        return(false);
                    }
                }

                if (database.IsPresent(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN.Tag))
                {
                    if (database.IsNotPresent(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag))
                    {
                        return(false);
                    }
                    if (pkcm.GetCAPK(RIDEnum.A000000003, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null)
                    {
                        return(false);
                    }

                    if (database.IsNotPresent(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag))
                    {
                        return(false);
                    }
                    if (database.IsNotPresent(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag))
                    {
                        return(false);
                    }
                    if (database.IsNotPresent(EMVTagsEnum.ISSUER_PUBLIC_KEY_REMAINDER_92_KRN.Tag))
                    {
                        return(false);
                    }

                    //if (database.IsNotPresent(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag)) return false;
                    if (database.IsNotPresent(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag))
                    {
                        return(false);
                    }
                }
            }

            //Application Usage Control
            //if (database.IsNotPresent(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN.Tag)) return false;

            return(true);
        }