示例#1
0
        private static SignalsEnum EntryPointPIN(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

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

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

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

            throw new EMVProtocolException("Invalid cvr in State_5a_WaitingForGetPinReponse");
        }
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            EMVGetDataResponse response = (EMVGetDataResponse)cardResponse.ApduResponse;

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

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

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

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

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

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

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

                return(SignalsEnum.WAITING_FOR_VERIFY);
            }

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

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

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

                TLV firstScript = database.ScriptsToRunAfterGenAC.GetFirstAndRemoveFromList();
                EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest();
                scriptRequest.Deserialize(firstScript.Value);
                cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING);
            }
        }
        private static SignalsEnum DoPart_F(Kernel2Database database, KernelQ qManager, CardResponse cardResponse)
        {
            #region 9_10.46
            //see below
            #endregion

            #region 9_10.46.1
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            tvr.Value.CDAFailed = true;
            tvr.UpdateDB();
            #endregion

            return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CAM_FAILED, L3Enum.NOT_SET));
        }
示例#5
0
        //U in diagram
        public static bool VerifyOnlinePin(string pin, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr)
        {
            if (string.IsNullOrEmpty(pin))
            {
                tvr.Value.PINEntryRequiredPINPadPresentButPINWasNotEntered = true;
                cvr.Value.CVMResult = 0x01;//failed

                cvr.UpdateDB();
                tvr.UpdateDB();
                return(false);
            }
            //cvm and tvr already set correctly in CVM selection
            return(true);
        }
        private static EMVGenerateACRequest DoNoIDS(KernelDatabaseBase database)
        {
            #region GAC.20
            if (GetODAStatus(database) == 0x80)
            {
                #region GAC.21
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                if (tvr.Value.CDAFailed)
                #endregion
                {
                    return(DoGAC22_26(database));
                }
                else
                {
                    #region GAC.24
                    if (GetDSACType(database) == ACTypeEnum.AAC)
                    #endregion
                    {
                        APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database);
                        #region GAC.25
                        if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag) &&
                            aci.Value.CDAIndicatorEnum == CDAIndicatorEnum.CDA_SUPPORTED_OVER_TC_ARQC_AAC)
                        {
                            #region GAC.27
                            return(DoIDSReadOnly(database));

                            #endregion
                        }
                        else
                        {
                            return(DoGAC26(database));
                        }
                        #endregion
                    }
                    else
                    {
                        #region GAC.27
                        return(DoIDSReadOnly(database));

                        #endregion
                    }
                }
            }
            else
            {
                return(DoGAC22_26(database));
            }
            #endregion
        }
示例#7
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.N_A,
                                                  KernelStatusEnum.N_A,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  cardResponse.ApduResponse.SW12,
                                                  L2Enum.STATUS_BYTES,
                                                  L3Enum.NOT_SET));
            }

            EMVInternalAuthenticateResponse response = cardResponse.ApduResponse as EMVInternalAuthenticateResponse;

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

            #region 3.8.1.1
            bool ddaPassed = DoDDA(database, qManager, capk, response.GetTLVSignedApplicationData());
            #endregion
            if (!ddaPassed)
            {
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.DDAFailed = true;
                tvr.UpdateDB();
            }

            TLV cdol1 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN);
            CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2, cdol1);

            REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database);
            rcpST.Value.ACTypeEnum            = database.ACType.Value.DSACTypeEnum;
            rcpST.Value.CDASignatureRequested = false;
            rcpST.UpdateDB();

            EMVGenerateACRequest request = new EMVGenerateACRequest(database.Get(EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2), null, rcpST);
            cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));

            return(SignalsEnum.WAITING_FOR_GEN_AC_1);
        }
示例#8
0
        private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            if (!cardResponse.ApduResponse.Succeeded)
            {
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                tvr.Value.IssuerAuthenticationFailed = true;
                tvr.UpdateDB();
            }
            else
            {
                TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);
                tsi.Value.IssuerAuthenticationWasPerformed = true;
                tsi.UpdateDB();
            }

            //EMVExternalAuthenticateResponse response = cardResponse.ApduResponse as EMVExternalAuthenticateResponse;

            //if scripts need to be run before gen ac, do now
            return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse));
        }
 private static void Do434(Kernel2Database database, bool signedFlag, int sfi, CardResponse cardResponse, TLVList responseTags)
 {
     #region 4.34
     if (signedFlag && database.ODAStatus == 0x80)
     {
         #region 4.35
         if (sfi <= 10)
         {
             int length = cardResponse.ApduResponse.ResponseData.Length - 2; //without tag '70' and length
             if (2048 - database.StaticDataToBeAuthenticated.Serialize().Length >= length)
             {
                 database.StaticDataToBeAuthenticated.AddListToList(responseTags);
             }
             else
             {
                 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                 tvr.Value.CDAFailed = true;
                 tvr.UpdateDB();
             }
         }
         else
         {
             int length = cardResponse.ApduResponse.ResponseData.Length;
             if (cardResponse.ApduResponse.ResponseData[0] == 0x70 && 2048 - database.StaticDataToBeAuthenticated.Serialize().Length >= length)
             {
                 TLV template = TLV.Create(EMVTagsEnum.READ_RECORD_RESPONSE_MESSAGE_TEMPLATE_70_KRN.Tag);
                 template.Children.AddListToList(responseTags);
                 template.Serialize();
                 database.StaticDataToBeAuthenticated.AddToList(template);
             }
             else
             {
                 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                 tvr.Value.CDAFailed = true;
                 tvr.UpdateDB();
             }
         }
         #endregion
     }
     #endregion
 }
示例#10
0
        public static bool DoCDA(KernelDatabase database, KernelQ qManager, CAPublicKeyCertificate capk, CardQ cardQManager, CardResponse cardResponse, EMVSelectApplicationResponse emvSelectApplicationResponse, bool isFirstGenAC)
        {
            //#region 9_10.2
            TERMINAL_VERIFICATION_RESULTS_95_KRN  tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);

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

            bool cdaSucceeded = VerifySDAD_CDA(database, capk, cardResponse, isFirstGenAC);

            if (!cdaSucceeded)
            {
                tvr.Value.CDAFailed = true;
                tvr.UpdateDB();
                return(false);
            }
            else
            {
                return(true);
            }
        }
示例#11
0
        //X in diagram
        public static bool VerifyOfflinePin(string pin, int pinTryCounter, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr)
        {
            if (pinTryCounter == 0)
            {
                tvr.Value.PINTryLimitExceeded = true;
                cvr.Value.CVMResult           = 0x01;//failed

                cvr.UpdateDB();
                tvr.UpdateDB();
                return(false);
            }
            if (string.IsNullOrEmpty(pin))
            {
                tvr.Value.PINEntryRequiredPINPadPresentButPINWasNotEntered = true;
                cvr.Value.CVMResult = 0x01;//failed

                cvr.UpdateDB();
                tvr.UpdateDB();
                return(false);
            }

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

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

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

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

                        #endregion
                    }
                    else
                    {
                        #region 9_10.38
                        TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                        if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED)
                        #endregion
                        {
                            #region 9_10.39
                            Do9_10__39(database);
                            #endregion
                        }
                        return(DoPart_E(database, qManager, cardQManager));
                    }
                }
            }
        }
        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);
        }
        public static ACTypeEnum TerminalActionAnalysis(KernelDatabaseBase database)
        {
            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_DENIAL_DF8121_KRN2).Value);

            #region taa.1
            if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DENIAL_9F0E_KRN.Tag))
            #endregion
            {
                #region taa.4
                ulong iacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DENIAL_9F0E_KRN).Value);
                if (!(
                        ((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0)
                    )
                #endregion
                {
                    #region taa.5
                    Logger.Log("Declining: !(((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0)):" + ((tacAsNumber | iacAsNumber) & tvrAsNumber));
                    Logger.Log("tacAsNumber: " + tacAsNumber);
                    Logger.Log("iacAsNumber: " + iacAsNumber);
                    int depth = 0;
                    Logger.Log(tvr.ToPrintString(ref depth));
                    return(ACTypeEnum.AAC);

                    #endregion
                }
            }
            else
            {
                #region taa.2
                if (!((tacAsNumber & tvrAsNumber) == 0))
                #endregion
                {
                    #region taa.3
                    Logger.Log("Declining: !((tacAsNumber & tvrAsNumber) == 0)");
                    Logger.Log("tacAsNumber: " + tacAsNumber);
                    int depth = 0;
                    Logger.Log(tvr.ToPrintString(ref depth));
                    return(ACTypeEnum.AAC);

                    #endregion
                }
            }

            #region taa.4.1
            TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database);
            if (tt.Value.TerminalType.Code == 0x11 || tt.Value.TerminalType.Code == 0x21 ||
                tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x24 ||
                tt.Value.TerminalType.Code == 0x34)
            #endregion
            {
                #region taa.4.2
                return(ACTypeEnum.ARQC);

                #endregion
            }

            #region taa.6
            if (tt.Value.TerminalType.Code == 0x23 || tt.Value.TerminalType.Code == 0x26 ||
                tt.Value.TerminalType.Code == 0x36 || tt.Value.TerminalType.Code == 0x13 ||
                tt.Value.TerminalType.Code == 0x16)
            #endregion
            {
                #region taa.13
                if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN.Tag))
                #endregion
                {
                    ulong iacDefaultNumber  = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN).Value);
                    ulong taDefaultAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_DEFAULT_DF8120_KRN2).Value);
                    #region taa.16
                    if (((iacDefaultNumber | taDefaultAsNumber) & tvrAsNumber) == 0)
                    #endregion
                    {
                        #region taa.18
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.17
                        Logger.Log("Declining: ((iacDefaultNumber | taDefaultAsNumber) & tvrAsNumber) == 0");
                        Logger.Log("iacDefaultNumber: " + iacDefaultNumber);
                        Logger.Log("taDefaultAsNumber: " + taDefaultAsNumber);
                        int depth = 0;
                        Logger.Log(tvr.ToPrintString(ref depth));
                        return(ACTypeEnum.AAC);

                        #endregion
                    }
                }
                else
                {
                    #region taa.14
                    if (tvrAsNumber == 0)
                    #endregion
                    {
                        #region taa.15
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.17
                        Logger.Log("Declining: tvrAsNumber == 0");
                        int depth = 0;
                        Logger.Log(tvr.ToPrintString(ref depth));
                        return(ACTypeEnum.AAC);

                        #endregion
                    }
                }
            }
            else
            {
                #region taa.7
                if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_ONLINE_9F0F_KRN.Tag))
                #endregion
                {
                    ulong iacOnlineNumber   = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_ONLINE_9F0F_KRN).Value);
                    ulong tacOnlineAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_ONLINE_DF8122_KRN2).Value);
                    #region taa.10
                    if (((tacOnlineAsNumber | iacOnlineNumber) & tvrAsNumber) == 0)
                    #endregion
                    {
                        #region taa.12
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.11
                        return(ACTypeEnum.ARQC);

                        #endregion
                    }
                }
                else
                {
                    #region taa.8
                    if (tvrAsNumber == 0)
                    #endregion
                    {
                        #region taa.9
                        return(ACTypeEnum.TC);

                        #endregion
                    }
                    else
                    {
                        #region taa.11
                        return(ACTypeEnum.ARQC);

                        #endregion
                    }
                }
            }
        }
示例#15
0
        public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, TornTransactionLogManager tornTransactionLogManager)
        {
            #region 456.1
            if (database.NextCommandEnum == NextCommandEnum.READ_RECORD)
            #endregion
            {
                #region 456.2
                TLVList toRemove = new TLVList();
                foreach (TLV tlv in database.TagsToReadYet)
                {
                    if (database.IsNotEmpty(tlv.Tag.TagLable))
                    {
                        database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                        toRemove.AddToList(tlv);
                    }
                }
                foreach (TLV tlv in toRemove)
                {
                    database.TagsToReadYet.RemoveFromList(tlv);
                }
                #endregion

                #region 456.3
                if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)
                #endregion
                {
                    #region 456.4
                    CommonRoutines.PostDEK(database, qManager);
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize();
                    database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize();
                    #endregion
                }
                return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE);
            }
            else
            {
                if (database.NextCommandEnum == NextCommandEnum.GET_DATA)
                {
                    return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE);
                }
                else
                {
                    #region 456.5
                    if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag))
                    #endregion
                    {
                        DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database);
                        #region 456.6
                        dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag);
                        #endregion
                        dataNeeded.UpdateDB();

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

                            #endregion
                        }
                    }
                }
            }

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

                #endregion
            }

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

                #endregion
            }

            #region 456.16
            if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag) &&
                  database.IsNotEmpty(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag)))
            #endregion
            {
                #region 456.17
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.N_A,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_MISSING,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region 456.18
            IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
            if (ids.Value.IsRead)
            #endregion
            {
                #region 456.19
                string dsid      = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value);
                string pan       = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value);
                string seqNumber = "00";
                if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))
                {
                    seqNumber = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value);
                }
                string concat = pan + seqNumber;
                if (concat.Length % 2 != 0)
                {
                    concat = "0" + concat;
                }
                if (concat.Length < 16)
                {
                    concat.PadLeft(16, '0');
                }
                if (dsid != concat)
                #endregion
                {
                    #region 456.20.1,456.20.2
                    CommonRoutines.CreateEMVDiscretionaryData(database);
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.NOT_READY,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
            }

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

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

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

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

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


                #endregion

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

                if (test == false)
                {
                    #region 456.27.1 - 456.27.2
                    CommonRoutines.CreateEMVDiscretionaryData(database);
                    return(CommonRoutines.PostOutcome(database, qManager,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      KernelStatusEnum.NOT_READY,
                                                      null,
                                                      Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                      Kernel2StartEnum.N_A,
                                                      true,
                                                      KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                      L1Enum.NOT_SET,
                                                      null,
                                                      L2Enum.CARD_DATA_ERROR,
                                                      L3Enum.NOT_SET));

                    #endregion
                }
                #endregion

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

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

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

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

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

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

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

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

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


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

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

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

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

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

                    #endregion
                }
            }
        }
示例#16
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));
        }
示例#17
0
        private static SignalsEnum EntryPointACT(KernelDatabaseBase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            foreach (TLV tlv in kernel1Request.InputData)
            {
                if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)
                {
                    if (!database.ParseAndStoreCardResponse(tlv))
                    {
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
                    }
                }
                else
                {
                    if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT))
                    {
                        database.AddToList(tlv);
                    }
                }
            }

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

            CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);

            cvmr.UpdateDB();

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            tvr.UpdateDB();

            TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database);

            _9f33.UpdateDB();

            database.Initialize(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag);
            database.Initialize(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag);

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

            database.TagsToReadYet.Initialize();

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

            bool MissingPDOLDataFlag = false;

            TLV     _9f38    = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN);
            TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0);

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

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

            TLVList toRemove = new TLVList();

            foreach (TLV tlv in database.TagsToReadYet)
            {
                if (database.IsNotEmpty(tlv.Tag.TagLable))
                {
                    database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv);
                    toRemove.AddToList(tlv);
                }
            }

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

            dataNeeded.UpdateDB();

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

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

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
        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 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 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));
                    }
                }
            }
        }
        /*
         * SR1.9 - SR1.32
         */
        private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            #region SR1.10
            sw.Stop();
            #endregion

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

                #endregion
            }

            #region SR1.14
            bool parsingResult = false;
            EMVExchangeRelayResistanceDataResponse emverrdr = (EMVExchangeRelayResistanceDataResponse)cardResponse.ApduResponse;
            if ((cardResponse.ApduResponse.ResponseData.Length > 11 && cardResponse.ApduResponse.ResponseData[0] == 0x80))// && cardResponse.ApduResponse.ResponseData.Length == 10)
            {
                database.AddListToList(emverrdr.GetResponseTags());
                parsingResult = true;
            }
            #region SR1.15
            if (!parsingResult)
            #endregion
            {
                #region SR1.16, SR1.17
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.PARSING_ERROR,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            #region SR1.18
            int a = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.TERMINAL_EXPECTED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_CAPDU_DF8134_KRN2).Value);
            int b = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.TERMINAL_EXPECTED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8135_KRN2).Value);
            int c = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.DEVICE_ESTIMATED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8305_KRN2).Value);

            int measuredRelayResistanceProcessingTime = ((int)sw.ElapsedMilliseconds / 100) - a - Math.Min(c, b);
            #endregion

            int d = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MINIMUM_RELAY_RESISTANCE_GRACE_PERIOD_DF8132_KRN2).Value);
            int e = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MIN_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8303_KRN2).Value);

            #region SR1.19
            if (measuredRelayResistanceProcessingTime < (e - d))
            #endregion
            {
                #region SR1.20, SR1.21
                CommonRoutines.CreateEMVDiscretionaryData(database);
                return(CommonRoutines.PostOutcome(database, qManager,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  KernelStatusEnum.NOT_READY,
                                                  null,
                                                  Kernel2OutcomeStatusEnum.END_APPLICATION,
                                                  Kernel2StartEnum.N_A,
                                                  true,
                                                  KernelMessageidentifierEnum.ERROR_OTHER_CARD,
                                                  L1Enum.NOT_SET,
                                                  null,
                                                  L2Enum.CARD_DATA_ERROR,
                                                  L3Enum.NOT_SET));

                #endregion
            }

            int g = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MAX_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8304_KRN2).Value);
            int f = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2).Value);
            #region SR1.22
            if ((f < 2) && (measuredRelayResistanceProcessingTime > (g + d)))
            #endregion
            {
                #region SR1.23 - SR1.27
                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;
                f++;
                database.Get(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2).Value = BitConverter.GetBytes(f);
                EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value);
                sw.Start();
                cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU));
                return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE);

                #endregion
            }

            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            #region SR1.28
            if (measuredRelayResistanceProcessingTime > (g + d))
            #endregion
            {
                #region SR1.29
                tvr.Value.RelayResistanceTimeLimitsExceeded = true;
                #endregion
            }

            int h = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RELAY_RESISTANCE_TRANSMISSION_TIME_MISMATCH_THRESHOLD_DF8137_KRN2).Value);
            int i = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RELAY_RESISTANCE_ACCURACY_THRESHOLD_DF8136_KRN2).Value);
            #region SR1.30
            if (((c / b) * 100 < h) || ((b / c) * 100 < h) || ((measuredRelayResistanceProcessingTime - e) > i))
            {
                tvr.Value.RelayResistanceThresholdExceeded = true;
            }
            else
            {
                tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_PERFORMED;
            }
            tvr.UpdateDB();
            #endregion
            #endregion

            return(State_3_R1_CommonProcessing.DoCommonProcessing("State_R1_ExchangeRelayResistanceData", database, qManager, cardQManager, cardResponse));
        }
        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 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));
            }
        }
示例#24
0
        public static void ProcessingRestrictions(KernelDatabaseBase database)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);

            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN.Tag))
            {
                #region pre.2
                string pvnCard = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN).Value);
                string pvnTerm = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_TERMINAL_9F09_KRN).Value);
                if (pvnCard != pvnTerm)
                #endregion
                {
                    #region pre.3
                    tvr.Value.ICCAndTerminalHaveDifferentApplicationVersions = true;
                    tvr.UpdateDB();
                    #endregion
                }
            }

            DateTime transactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN).Value);
            DateTime appExpiryDate   = EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN).Value);

            #region pre.4
            if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.Tag))
            #endregion
            {
                DateTime appEffectiveDate = EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN).Value);
                #region pre.5
                if (transactionDate < appEffectiveDate)
                #endregion
                {
                    #region pre.6
                    tvr.Value.ApplicationNotYetEffective = true;
                    tvr.UpdateDB();
                    #endregion
                }
            }

            #region pre.7
            if (transactionDate > appExpiryDate)
            #endregion
            {
                #region pre.8

                tvr.Value.ExpiredApplication = true;
                tvr.UpdateDB();
                #endregion
            }

            #region pre.9
            if (database.IsEmpty(EMVTagsEnum.APPLICATION_USAGE_CONTROL_9F07_KRN.Tag))
            {
                return;
            }
            #endregion

            #region pre.10
            TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database);
            ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN atc = new ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN(database);
            APPLICATION_USAGE_CONTROL_9F07_KRN        auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database);

            if ((tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x15 || tt.Value.TerminalType.Code == 0x16) &&
                atc.Value.IsCash)
            #endregion
            {
                #region pre.12
                if (!auc.Value.IsValidAtATMs)
                #endregion
                {
                    #region pre.13
                    tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                    tvr.UpdateDB();
                    return;

                    #endregion
                }
            }
            else
            {
                #region pre.11
                if (!auc.Value.IsValidAtTerminalsOtherThanATMs)
                #endregion
                {
                    #region pre.13
                    tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                    tvr.UpdateDB();
                    return;

                    #endregion
                }
            }

            #region pre.14
            if (database.IsEmpty(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN.Tag))
            {
                tvr.UpdateDB();
                return;
            }
            #endregion

            string tcc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN).Value);
            string icc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN).Value);

            byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0];


            #region pre.15
            if (transactionType == (byte)TransactionTypeEnum.CashWithdrawal ||
                transactionType == (byte)TransactionTypeEnum.CashDisbursement)
            #endregion
            {
                #region pre.16
                if (tcc == icc)
                #endregion
                {
                    #region pre.17
                    if (!auc.Value.IsValidForDomesticCashTransactions)
                    #endregion
                    {
                        #region pre.19
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
                else
                {
                    #region pre.18
                    if (!auc.Value.IsValidForInternationalCashTransactions)
                    #endregion
                    {
                        #region pre.19
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
            }

            #region pre.20
            if (transactionType == (byte)TransactionTypeEnum.PurchaseGoodsAndServices ||
                transactionType == (byte)TransactionTypeEnum.PurchaseWithCashback)
            #endregion
            {
                #region pre.21
                if (tcc == icc)
                #endregion
                {
                    #region pre.22
                    if (!(auc.Value.IsValidForDomesticGoods || auc.Value.IsValidForDomesticServices))
                    #endregion
                    {
                        #region pre.24
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
                else
                {
                    #region pre.23
                    if (!(auc.Value.IsValidForInternationalGoods || auc.Value.IsValidForInternationalServices))
                    #endregion
                    {
                        #region pre.24
                        tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
                        #endregion
                    }
                }
            }

            #region pre.25
            if (database.IsNotPresent(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN.Tag))
            {
                tvr.UpdateDB();
                return;
            }

            if (Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN).Value) == 0)
            {
                tvr.UpdateDB();
                return;
            }
            #endregion

            #region pre.26
            if (tcc == icc)
            #endregion
            {
                #region pre.27
                if (auc.Value.IsDomesticCashbackAllowed)
                {
                    tvr.UpdateDB();
                    return;
                }
                #endregion
            }
            else
            {
                #region pre.28
                if (auc.Value.IsInternationalCashbackAllowed)
                {
                    tvr.UpdateDB();
                    return;
                }
                #endregion
            }

            #region pre.29
            tvr.Value.RequestedServiceNotAllowedForCardProduct = true;
            tvr.UpdateDB();
            #endregion
        }
        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);
            }
        }
示例#26
0
        /*
         * S1.1, S1.7 - S1.23
         */
        private static SignalsEnum EntryPointACT(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw)
        {
            #region S1.7
            foreach (TLV tlv in kernel1Request.InputData)
            {
                if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag)
                {
                    if (!database.ParseAndStoreCardResponse(tlv))
                    {
                        return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET));
                    }
                }
                else
                {
                    if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT))
                    {
                        database.AddToList(tlv);
                    }
                }
            }

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

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

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

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

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

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

            database.ODAStatus = 0x00;

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

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

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

            database.StaticDataToBeAuthenticated.Initialize();

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

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

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

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

            database.TagsToReadYet.Initialize();

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

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

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

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

            #endregion

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

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

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

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

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

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

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

            dataNeeded.UpdateDB();
            #endregion

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

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

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

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

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

                return(SignalsEnum.WAITING_FOR_PDOL_DATA);
            }
            #endregion

            return(SignalsEnum.WAITING_FOR_GPO_REPONSE);
        }
        internal static EMVGenerateACRequest PrepareGenACCommand(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager)
        {
            #region GAC.1
            IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database);
            if (ids.Value.IsRead)
            #endregion
            {
                #region GAC.2
                TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
                if (tvr.Value.CDAFailed)
                #endregion
                {
                    return(DoGAC22_26(database));
                }
                else
                {
                    #region GAC.3
                    if (database.IsNotEmpty(EMVTagsEnum.DS_ODS_INFO_DF62_KRN2.Tag))
                    #endregion
                    {
                        #region GAC.4
                        if (database.IsNotEmpty(EMVTagsEnum.DSDOL_9F5B_KRN2.Tag))
                        {
                            #region GAC.5
                            if (database.IsNotEmpty(EMVTagsEnum.DS_AC_TYPE_DF8108_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.DS_ODS_INFO_FOR_READER_DF810A_KRN2.Tag))
                            #endregion
                            {
                                #region GAC.7
                                DS_AC_TYPE_DF8108_KRN2 dsactype = new DS_AC_TYPE_DF8108_KRN2(database);
                                if (dsactype.Value.DSACTypeEnum == ACTypeEnum.AAC ||
                                    GetDSACType(database) == dsactype.Value.DSACTypeEnum ||
                                    (dsactype.Value.DSACTypeEnum == ACTypeEnum.ARQC && GetDSACType(database) == ACTypeEnum.TC))
                                {
                                    #region GAC.8
                                    SetDSACType(database, dsactype.Value.DSACTypeEnum);
                                    #endregion
                                    #region GAC.40
                                    return(DoIDSWrite(database));

                                    #endregion
                                }
                                else
                                {
                                    #region GAC.9
                                    DS_ODS_INFO_FOR_READER_DF810A_KRN2 dsodsifr = new DS_ODS_INFO_FOR_READER_DF810A_KRN2(database);
                                    if ((GetDSACType(database) == ACTypeEnum.AAC && dsodsifr.Value.UsableForAAC) ||
                                        (GetDSACType(database) == ACTypeEnum.ARQC && dsodsifr.Value.UsableForARQC))
                                    #endregion
                                    {
                                        #region GAC.40
                                        return(DoIDSWrite(database));

                                        #endregion
                                    }
                                    else
                                    {
                                        #region GAC.10
                                        if (dsodsifr.Value.StopIfNoDSODSTerm)
                                        #endregion
                                        {
                                            #region GAC.11
                                            return(GenerateErrorOutput(database, L2Enum.IDS_NO_MATCHING_AC, qManager));

                                            #endregion
                                        }
                                        else
                                        {
                                            #region GAC.27
                                            return(DoIDSReadOnly(database));

                                            #endregion
                                        }
                                    }
                                }

                                #endregion
                            }
                            else
                            {
                                #region GAC.6
                                return(GenerateErrorOutput(database, L2Enum.IDS_DATA_ERROR, qManager));

                                #endregion
                            }
                        }
                        else
                        {
                            #region GAC.27
                            return(DoIDSReadOnly(database));

                            #endregion
                        }
                        #endregion
                    }
                    else
                    {
                        #region GAC.27
                        return(DoIDSReadOnly(database));

                        #endregion
                    }
                }
            }
            else
            {
                #region GAC.20
                return(DoNoIDS(database));

                #endregion
            }
        }
        private static SignalsEnum EntryPointTRM(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager, KernelQ qManager, EMVSelectApplicationResponse emvSelectApplicationResponse)
        {
            TERMINAL_VERIFICATION_RESULTS_95_KRN  tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database);
            TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database);

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

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

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

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

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

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

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

            bool doVelocity = false;

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

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

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

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

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

            #endregion
        }
示例#29
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);
        }