Exemplo n.º 1
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, PublicKeyCertificateManager pkcm, EMVSelectApplicationResponse emvSelectApplicationResponse, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            EMVGetChallengeResponse response = (EMVGetChallengeResponse)cardResponse.ApduResponse;

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

            //store the challenge
            byte[] pinChallenge = response.ResponseData;

            if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC ||
                cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper)
            {
                string  aid                 = emvSelectApplicationResponse.GetDFName();
                string  rid                 = aid.Substring(0, 10);
                RIDEnum ridEnum             = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid);
                CAPublicKeyCertificate capk = pkcm.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);
                if (capk == null)
                {
                    cvr.Value.CVMResult = 0x01;//failed
                    cvr.UpdateDB();
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }

                string pin      = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value);
                byte[] pinBlock = PinProcessing.BuildPlainTextPinBlock(pin);

                //encrypt the pin
                byte[] encipheredPin = PinProcessing.BuildPinVerifyData(database, capk, pinBlock, pinChallenge);
                if (encipheredPin == null)
                {
                    cvr.Value.CVMResult = 0x01;//failed
                    cvr.UpdateDB();
                    return(SignalsEnum.WAITING_FOR_CVM_PROCESSING);
                }

                //fire off verify for enciphered pin
                EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Enciphered_PIN, encipheredPin);
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
            }


            //verify message for plain text pin fired in waiting for pin response
            return(SignalsEnum.WAITING_FOR_VERIFY);
        }
        public static SignalsEnum DoCDA9_10_1(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse)
        {
            CAPublicKeyCertificate capk = publicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);

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

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

                            #endregion
                        }

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

                            #endregion
                        }

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

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

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

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

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

                                    #endregion
                                }
                            }
                        }
                    }
                }
                else
                {
                    bool successIDSNotRead = false;
                    #region 9_10.2.1
                    if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                    #endregion
                    {
                        #region 9_10.4.1
                        successIDSNotRead = VerifySDAD_CheckRelayData_9_10__4_1(database, capk, cardResponse);
                        #endregion
                    }
                    else
                    {
                        #region 9_10.4
                        successIDSNotRead = VerifySDAD_9_10__4(database, capk, cardResponse);
                        #endregion
                    }
                    #region 9_10.6
                    if (!successIDSNotRead)
                    #endregion
                    {
                        return(DoPart_F(database, qManager, cardResponse));
                    }
                    else
                    {
                        return(DoPart_E(database, qManager, cardQManager));
                    }
                }
            }
        }
        private static SignalsEnum DoCDAPart_A(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse)
        {
            #region 11.40
            CAPublicKeyCertificate capk = publicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]);
            #endregion

            if (capk == null)
            {
                #region 11.46
                return(DoPart_F(database, qManager, cardResponse));

                #endregion
            }
            else
            {
                #region 11.41
                IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                if (ids.Value.IsRead)
                #endregion
                {
                    bool successIDSRead = false;
                    #region 11.41.2
                    if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                    #endregion
                    {
                        #region 11.42.1
                        successIDSRead = VerifySDAD_Summaries_CheckRelayData_42_1(database, capk, cardResponse);
                        #endregion
                    }
                    else
                    {
                        #region 11.42
                        successIDSRead = VerifySDAD_Summaries_42(database, capk, cardResponse);
                        #endregion
                    }
                    if (!successIDSRead)
                    {
                        #region 11.46
                        return(DoPart_F(database, qManager, cardResponse));

                        #endregion
                    }
                    else
                    {
                        #region
                        return(DoPart_E(database, qManager, cardQManager));

                        #endregion
                    }
                }
                else
                {
                    bool successIDSNotRead = false;
                    #region 11.41.1
                    if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                    #endregion
                    {
                        #region 11.43.1
                        successIDSNotRead = VerifySDAD_CheckRelayData_43_1(database, capk, cardResponse);
                        #endregion
                    }
                    else
                    {
                        #region 11.43
                        successIDSNotRead = VerifySDAD_43(database, capk, cardResponse);
                        #endregion
                    }

                    if (!successIDSNotRead)
                    {
                        #region 11.46
                        return(DoPart_F(database, qManager, cardResponse));

                        #endregion
                    }
                    else
                    {
                        #region 11.47
                        IDS_STATUS_DF8128_KRN2.IDS_STATUS_DF8128_KRN2_VALUE idsV = new IDS_STATUS_DF8128_KRN2.IDS_STATUS_DF8128_KRN2_VALUE(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.DataFormatter);
                        idsV.Deserialize(database.TornTempRecord.Children.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag).Value, 0);
                        string dbds1 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2).Value);
                        if (idsV.IsWrite)
                        #endregion
                        {
                            #region 11.48
                            string ttrds1 = Formatting.ByteArrayToHexString(database.TornTempRecord.Children.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag).Value);
                            if (dbds1 != ttrds1)
                            #endregion
                            {
                                #region 11.49
                                return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.IDS_READ_ERROR, L3Enum.NOT_SET));

                                #endregion
                            }
                        }
                        #region 11.50
                        if (!database.IsPresent(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2.Tag))
                        #endregion
                        {
                            #region 11.51
                            return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));

                            #endregion
                        }

                        #region 11.52
                        string dbds2 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2).Value);
                        if (dbds1 != dbds2)
                        #endregion
                        {
                            #region 11.53
                            return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.IDS_READ_ERROR, L3Enum.NOT_SET));

                            #endregion
                        }

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

                        #region 11.55
                        if (!ids.Value.IsWrite)
                        #endregion
                        {
                            #region 11.110
                            return(DoPart_E(database, qManager, cardQManager));

                            #endregion
                        }
                        else
                        {
                            #region 11.56
                            if (!database.IsPresent(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2.Tag))
                            #endregion
                            {
                                #region 11.57
                                return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET));

                                #endregion
                            }
                            else
                            {
                                #region 11.58
                                string dbds3 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2).Value);
                                if (dbds2 == dbds3)
                                #endregion
                                {
                                    #region 11.60
                                    byte dsodsifr = database.Get(EMVTagsEnum.DS_ODS_INFO_FOR_READER_DF810A_KRN2).Value[0];
                                    if ((dsodsifr & 0x02) == 0x02) //stop if write set
                                    #endregion
                                    {
                                        #region 11.61
                                        CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.IDS_WRITE_ERROR, L3Enum.NOT_SET);
                                        #endregion
                                        return(DoInvalidResponsePart_D(database, qManager));
                                    }
                                    else
                                    {
                                        return(DoPart_E(database, qManager, cardQManager));
                                    }
                                }
                                else
                                {
                                    #region 11.59
                                    dsss = (byte)(dsss | 0x40); //set succesful write
                                    database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss;
                                    return(DoPart_E(database, qManager, cardQManager));

                                    #endregion
                                }
                            }
                        }
                    }
                }
            }
        }
        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);
        }
        public static bool DoOfflineAuth(KernelDatabaseBase database, KernelQ qManager, PublicKeyCertificateManager pkcm)
        {
            try
            {
                TLV sdadTLV = database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN);
                TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN);
                if (sdadTLV == null && ssadTLV == null)
                {
                    return(false);
                }

                if (database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN) == null)
                {
                    return(false);
                }

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

                TLV aip    = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag);
                int length = database.StaticDataToBeAuthenticated.Serialize().Length;
                if (aip != null && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_SDA_TAG_LIST_9F4A_KRN3.Tag))
                {
                    if (2048 - length >= aip.Value.Length)
                    {
                        database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN));
                    }
                    else
                    {
                        return(false);
                    }
                }

                if (sdadTLV != null)
                {
                    TLV card = database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3);
                    if (card == null || card.Value[0] != 0x01) //check version number of fdda
                    {
                        return(false);
                    }

                    byte[]         sdadRaw = database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN).Value;
                    ICCDynamicData iccdd   = VerifySAD.VerifySDAD_K3(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw);
                    if (iccdd == null)
                    {
                        return(false);
                    }

                    VerifySAD.AddSDADDataToDatabase(database, iccdd);
                    return(true);
                }

                if (ssadTLV != null)
                {
                    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)
                    {
                        return(false);
                    }
                    TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN);
                    if (dataAuthenticationCode == null)
                    {
                        dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode);
                    }
                    database.AddToList(dataAuthenticationCode);
                    return(true);
                }

                return(false);
            }
            catch
            {
                return(false);
            }
        }