private static SignalsEnum EntryPointDET(KernelDatabaseBase database, KernelRequest kernel1Request, CardQ cardQManager, Stopwatch sw) { database.UpdateWithDETData(kernel1Request.InputData); bool missingPDOLData = false; TLV _9f38 = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN); TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0); DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); foreach (TLV tlv in pdolList) { if (database.IsEmpty(tlv.Tag.TagLable)) { missingPDOLData = true; dataNeeded.Value.Tags.Add(tlv.Tag.TagLable); } } dataNeeded.UpdateDB(); if (missingPDOLData) { return(SignalsEnum.WAITING_FOR_PDOL_DATA); } database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag); CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList); EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2)); sw.Stop(); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GPO_REPONSE); }
internal static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag)) { DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); #region 78.2 dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag); #endregion dataNeeded.UpdateDB(); return(Do78_3(source, database, qManager, sw)); } else { #region 78.7 if (database.IsPresent(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag) && database.Get(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2).Value[0] == 0x00) #endregion { #region 78.3 return(Do78_3(source, database, qManager, sw)); #endregion } else { #region 78.8 if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag)) #endregion { #region 78.9 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT)); #endregion } #region 78.10 long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long rctl = database.ReaderContactlessTransactionLismit; if (aa > rctl) #endregion { #region 78.11 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET)); #endregion } #region 78.12 foreach (TLV tlv in database.TagsToReadYet) { if (database.IsPresent(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv); } else if (database.IsKnown(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(tlv.Tag.TagLable)); } database.TagsToReadYet.RemoveFromList(tlv); } #endregion #region 78.13 if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag)) #endregion { #region 78.14 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } #region 78.15 //The 8-nUN most significant digits must be set to zero TLV rNN = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2); if (rNN == null) { database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2.Tag)); rNN = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2); } rNN.Value = Formatting.GetRandomNumberNumeric(8 - database.NUN); #endregion #region 78.16 APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); if (aip.Value.OnDeviceCardholderVerificationIsSupported) #endregion { #region 78.19 if (aa > rctl) #endregion { #region 78.20 byte msi = database.Get(EMVTagsEnum.MOBILE_SUPPORT_INDICATOR_9F7E_KRN2).Value[0]; msi = (byte)(msi | 0x02); database.Get(EMVTagsEnum.MOBILE_SUPPORT_INDICATOR_9F7E_KRN2).Value[0] = msi; #endregion } #region 78.21 EMVComputeCryptographicChecksumRequest request = new EMVComputeCryptographicChecksumRequest(CommonRoutines.PackUdolRelatedDataTag(database)); #endregion #region 78.22 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_2); } else { #region 78.17 EMVComputeCryptographicChecksumRequest request = new EMVComputeCryptographicChecksumRequest(CommonRoutines.PackUdolRelatedDataTag(database)); #endregion #region 78.17 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_1); } } } }
/* * S1.1, S1.7 - S1.23 */ private static SignalsEnum EntryPointACT(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { #region S1.7 foreach (TLV tlv in kernel1Request.InputData) { if (tlv.Tag.TagLable == EMVTagsEnum.FILE_CONTROL_INFORMATION_FCI_TEMPLATE_6F_KRN.Tag) { if (!database.ParseAndStoreCardResponse(tlv)) { return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } } else { if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT)) { database.AddToList(tlv); } } } if (database.IsNotEmpty(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN.Tag)) { byte[] languagePrefFromCard = database.Get(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN).Value; byte[] languagePrefFromCardPadded = new byte[8]; //will be padded with trailing 0's Array.Copy(languagePrefFromCard, languagePrefFromCardPadded, languagePrefFromCard.Length); CommonRoutines.UpdateUserInterfaceRequestData(database, languagePrefFromCardPadded); } #region S1.8 if (database.IsNotPresent(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag) || database.IsEmpty(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag)) { return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } #endregion if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag)) { APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aciVal = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database); if (aciVal.Value.SupportForFieldOffDetection) { byte[] holdTimeValue = database.GetDefault(EMVTagsEnum.HOLD_TIME_VALUE_DF8130_KRN2).Value; CommonRoutines.UpdateOutcomeParameterSet(database, holdTimeValue[0]); } } #endregion #region S1.9 CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); cvmr.UpdateDB(); database.ACType = new DS_AC_TYPE_DF8108_KRN2(database); database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.UpdateDB(); database.ODAStatus = 0x00; database.AddToList(TLV.Create(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2.Tag, new byte[] { 0x00 })); //CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2 df8117 = new CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2(database); //SECURITY_CAPABILITY_DF811F_KRN2 df811f = new SECURITY_CAPABILITY_DF811F_KRN2(database); TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database); //_9f33.Value.SetCardDataInputCapabilityValue(df8117); //_9f33.Value.SetSecurityCapabilityValue(df811f); _9f33.UpdateDB(); database.StaticDataToBeAuthenticated.Initialize(); database.AddToList(TLV.Create(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00 })); database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber(); //REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpv = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(); //rcpv.Value.ACTypeEnum = ACTypeEnum.TC; //rcpv.UpdateDB(); #endregion #region S1.10 database.Initialize(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag); database.Initialize(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag); DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); DATA_TO_SEND_FF8104_KRN2 dataToSend = new DATA_TO_SEND_FF8104_KRN2(database); database.TagsToReadYet.Initialize(); if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2.Tag)) { database.TagsToReadYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2).Children); } else { dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_READ_DF8112_KRN2); dataNeeded.UpdateDB(); } #endregion #region S1.11 bool MissingPDOLDataFlag = false; #endregion #region S1.12 TLV _9f38 = database.Get(EMVTagsEnum.PROCESSING_OPTIONS_DATA_OBJECT_LIST_PDOL_9F38_KRN); TLVList pdolList = TLV.DeserializeChildrenWithNoV(_9f38.Value, 0); foreach (TLV tlv in pdolList) { if (database.IsEmpty(tlv.Tag.TagLable)) { MissingPDOLDataFlag = true; dataNeeded.Value.AddTag(tlv.Tag.TagLable); } } dataNeeded.UpdateDB(); #region S1.13 and S1.14 if (!MissingPDOLDataFlag) { database.Initialize(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2.Tag); CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2, pdolList); EMVGetProcessingOptionsRequest request = new EMVGetProcessingOptionsRequest(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); } #endregion #endregion #region S1.15 TLVList toRemove = new TLVList(); foreach (TLV tlv in database.TagsToReadYet) { if (database.IsNotEmpty(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv); toRemove.AddToList(tlv); } } foreach (TLV tlv in toRemove) { database.TagsToReadYet.RemoveFromList(tlv); } #endregion #region S1.16 database.Initialize(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag); database.Initialize(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2.Tag); database.Initialize(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2.Tag); database.Initialize(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2.Tag); database.Initialize(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag); database.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2).Value = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; database.TagsToWriteAfterGenACYet.Initialize(); database.TagsToWriteBeforeGenACYet.Initialize(); if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag)) { database.TagsToWriteBeforeGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2).Children); } if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag)) { database.TagsToWriteAfterGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2).Children); } if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag)) { dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2); } if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag)) { dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2); } dataNeeded.UpdateDB(); #endregion #region S1.17 if (database.IsNotEmpty(EMVTagsEnum.DSVN_TERM_DF810D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2.Tag)) { #region S1.18 if (database.IsPresent(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2)); } else { TLV dsid = TLV.Create(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag); dsid.Val.PackValue(EMVTagsEnum.DS_ID_9F5E_KRN2.DataFormatter.GetMaxLength()); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(dsid); } if (database.IsPresent(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2)); } else { TLV aci = TLV.Create(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag); aci.Val.PackValue(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.DataFormatter.GetMaxLength()); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(aci); } #endregion #region S1.19 if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag)) { APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database); if ((aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_1 || aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_2) && database.IsNotEmpty(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag)) { #region S1.20 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); ids.Value.IsRead = true; ids.UpdateDB(); #endregion } } #endregion } #endregion #region S1.21 if (MissingPDOLDataFlag) { #region S1.22 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion #region S1.23 sw.Restart(); #endregion return(SignalsEnum.WAITING_FOR_PDOL_DATA); } #endregion return(SignalsEnum.WAITING_FOR_GPO_REPONSE); }
/* * S4.3 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw) { bool signedFlag; byte sfi; #region 4.9 if (!cardResponse.ApduResponse.Succeeded) #endregion { #region 4.10 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); #endregion } #region 4.11 if (database.ActiveAFL.Value.Entries[0].OfflineDataAuthenticationRecordLength > 0) #endregion { #region 4.12 signedFlag = true; #endregion } else { #region 4.13 signedFlag = false; #endregion } #region 4.14 sfi = database.ActiveAFL.Value.Entries[0].SFI; database.ActiveAFL.Value.Entries.RemoveAt(0); #endregion #region 4.15 TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList(); if (nextTLV != null) { database.ActiveTag = nextTLV.Tag.TagLable; } else { database.ActiveTag = null; } #endregion if (database.ActiveTag != null) { #region 4.16 - 4.19 EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); database.NextCommandEnum = NextCommandEnum.GET_DATA; #endregion } else { #region 4.19 if (database.ActiveAFL.Value.Entries.Count == 0) #endregion { #region 4.20 database.NextCommandEnum = NextCommandEnum.NONE; #endregion } else { #region 4.21 - 4.23 EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); database.NextCommandEnum = NextCommandEnum.READ_RECORD; #endregion } } bool parsingResult; #region 4.24 if (sfi <= 10) #endregion { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70) { parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData); } else { parsingResult = false; } } else //Processing of records in proprietary files is beyond the scope of thisspecification { parsingResult = false; } #region 4.25 if (!parsingResult) #endregion { #region 4.26 if (database.NextCommandEnum == NextCommandEnum.NONE) #endregion { #region 4.27.1 - 4.27.2 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); #endregion } else { return(SignalsEnum.TEMINATE_ON_NEXT_RA); } } TLVList responseTags; if (cardResponse.ApduResponse is EMVReadRecordResponse) { responseTags = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags(); } else if (cardResponse.ApduResponse is EMVGetDataResponse) { responseTags = (cardResponse.ApduResponse as EMVGetDataResponse).GetResponseTags(); } else { throw new EMVProtocolException("Invalid card response in State4"); } #region 4.28 TLVList cdols = responseTags.FindAll(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag); if (cdols.Count > 0) #endregion { TLVList cdolList = TLV.DeserializeChildrenWithNoV(cdols.GetFirst().Value, 0); DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); #region 4.29 foreach (TLV tlv in cdolList) { if (database.IsEmpty(tlv.Tag.TagLable)) { dataNeeded.Value.Tags.Add(tlv.Tag.TagLable); } } dataNeeded.UpdateDB(); #endregion } #region 4.30 TLVList dsdols = responseTags.FindAll(EMVTagsEnum.DSDOL_9F5B_KRN2.Tag); if (dsdols.Count > 0) #endregion { #region 4.31 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region 4.32 if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) && new DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2(database).Value.LockedSlot) #endregion { DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); #region 4.33 foreach (TLV tlv in dsdols.GetFirst().Children) { if (database.IsEmpty(tlv.Tag.TagLable)) { dataNeeded.Value.Tags.Add(tlv.Tag.TagLable); } } dataNeeded.UpdateDB(); #endregion } else { #region 4.34 Do434(database, signedFlag, sfi, cardResponse, responseTags); #endregion } } else { #region 4.34 Do434(database, signedFlag, sfi, cardResponse, responseTags); #endregion } } else { #region 4.34 Do434(database, signedFlag, sfi, cardResponse, responseTags); #endregion } return(State_4_5_6_CommonProcessing.DoCommonProcessing("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, tornTransactionLogManager)); }
private static SignalsEnum EntryPointRA(KernelDatabaseBase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager, Func <string, KernelDatabaseBase, KernelQ, CardQ, Stopwatch, PublicKeyCertificateManager, CardExceptionManager, SignalsEnum> ReadRecordCompleteCallback) { byte sfi; bool signedFlag; if (!cardResponse.ApduResponse.Succeeded) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } if (database.ActiveAFL.Value.Entries[0].OfflineDataAuthenticationRecordLength > 0) { signedFlag = true; } else { signedFlag = false; } sfi = database.ActiveAFL.Value.Entries[0].SFI; database.ActiveAFL.Value.Entries.RemoveAt(0); if (database.ActiveAFL.Value.Entries.Count == 0) { database.NextCommandEnum = NextCommandEnum.NONE; } else { EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); database.NextCommandEnum = NextCommandEnum.READ_RECORD; } bool parsingResult; if (sfi <= 10) { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70) { parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData); } else { parsingResult = false; } } else //Processing of records in proprietary files is beyond the scope of thisspecification { parsingResult = false; } if (!parsingResult) { if (database.NextCommandEnum == NextCommandEnum.NONE) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } else { return(SignalsEnum.TEMINATE_ON_NEXT_RA); } } TLVList responseTags; if (cardResponse.ApduResponse is EMVReadRecordResponse) { responseTags = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags(); } else if (cardResponse.ApduResponse is EMVGetDataResponse) { responseTags = (cardResponse.ApduResponse as EMVGetDataResponse).GetResponseTags(); } else { throw new EMVProtocolException("Invalid card response in State4"); } TLVList cdols = responseTags.FindAll(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag); if (cdols.Count > 0) { TLVList cdolList = TLV.DeserializeChildrenWithNoV(cdols.GetFirst().Value, 0); DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); foreach (TLV tlv in cdolList) { if (database.IsEmpty(tlv.Tag.TagLable)) { dataNeeded.Value.Tags.Add(tlv.Tag.TagLable); } } dataNeeded.UpdateDB(); } Do434(database, signedFlag, sfi, cardResponse, responseTags); return(ReadRecordCompleteCallback("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, publicKeyCertificateManager, cardExceptionManager)); //return State_4_5_6_CommonProcessing.DoCommonProcessing("State_4_WaitingForEMVReadRecord", database, qManager, cardQManager, sw, publicKeyCertificateManager); }
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, Stopwatch sw, TornTransactionLogManager tornTransactionLogManager) { #region 456.1 if (database.NextCommandEnum == NextCommandEnum.READ_RECORD) #endregion { #region 456.2 TLVList toRemove = new TLVList(); foreach (TLV tlv in database.TagsToReadYet) { if (database.IsNotEmpty(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv); toRemove.AddToList(tlv); } } foreach (TLV tlv in toRemove) { database.TagsToReadYet.RemoveFromList(tlv); } #endregion #region 456.3 if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0) #endregion { #region 456.4 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); } else { if (database.NextCommandEnum == NextCommandEnum.GET_DATA) { return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE); } else { #region 456.5 if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag)) #endregion { DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); #region 456.6 dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag); #endregion dataNeeded.UpdateDB(); return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw)); } else { #region 456.11 if (database.IsPresent(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag) && database.Get(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2).Value[0] == 0x00) #endregion { #region 456.7 return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw)); #endregion } } } } #region 456.12 if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag)) #endregion { #region 456.13 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT)); #endregion } #region 456.14 long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long rctl = database.ReaderContactlessTransactionLismit; if (aa > rctl) #endregion { #region 456.15 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET)); #endregion } #region 456.16 if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag))) #endregion { #region 456.17 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } #region 456.18 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region 456.19 string dsid = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value); string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value); string seqNumber = "00"; if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)) { seqNumber = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value); } string concat = pan + seqNumber; if (concat.Length % 2 != 0) { concat = "0" + concat; } if (concat.Length < 16) { concat.PadLeft(16, '0'); } if (dsid != concat) #endregion { #region 456.20.1,456.20.2 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } } #region 456.21 TLVList toRemove2 = new TLVList(); foreach (TLV tlv in database.TagsToReadYet) { if (database.IsPresent(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv); } else { if (database.IsKnown(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(tlv.Tag.TagLable)); } } toRemove2.AddToList(tlv); } foreach (TLV tlv in toRemove2) { database.TagsToReadYet.RemoveFromList(tlv); } #endregion #region 456.22 if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag)) #endregion { #region 456.23 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } #region 456.24 if (database.ODAStatus == 0x80) #endregion { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); #region 456.25 if (!( database.IsNotEmpty(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag) )) { tvr.Value.ICCDataMissing = true; tvr.Value.CDAFailed = true; } if (database.PublicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null) { tvr.Value.CDAFailed = true; } #endregion #region 456.26 bool test = false; TLV aip = null; if (database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag)) { TLV sdal = database.Get(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN); TLVList list = TLV.DeserializeChildrenWithNoLV(sdal.Value, 0); if (list.Count == 1) { aip = list.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); if (aip != null) { test = true; } } } if (test == false) { #region 456.27.1 - 456.27.2 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } #endregion #region 456.28 int length = database.StaticDataToBeAuthenticated.Serialize().Length; if (2048 - length >= aip.Value.Length) { database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN)); } else { tvr.Value.CDAFailed = true; } #endregion tvr.UpdateDB(); } #region 456.30 long cvmrl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value); if (aa > cvmrl) #endregion { #region 456.31 CommonRoutines.UpdateOutcomeParameterSet(database, true); #endregion #region 456.32 database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_CVM_REQUIRED_DF8118_KRN2).Value[0]; #endregion } else { #region 456.33 database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_NO_CVM_REQUIRED_DF8119_KRN2).Value[0]; #endregion } #region 456.34 SignalsEnum se = PreGenACBalanceReading_7_1.PreGenACBalanceReading(database, qManager, cardQManager); if (se != SignalsEnum.NONE) { return(se); } #endregion #region 456.35 ProcessingRestrictions_7_7.ProcessingRestrictions(database); #endregion #region 456.35 CVMSelection_7_5.CVMSelection(database, new Func <bool>(() => { return(new KERNEL_CONFIGURATION_DF811B_KRN2(database).Value.OnDeviceCardholderVerificationSupported); })); #endregion #region 456.36 long rcfl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_FLOOR_LIMIT_DF8123_KRN2).Value); if (aa > rcfl) #endregion { #region 456.38 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.TransactionExceedsFloorLimit = true; tvr.UpdateDB(); #endregion } #region 456.39 database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database); #endregion //#region support for Refunds pg 177 //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]; //if (transactionType == (byte)TransactionTypeEnum.Refund) //{ // database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; // database.ODAStatus = 0x00; //dont request CDA in first gen ac //} //#endregion #region 456.42 if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag)) #endregion { #region 456.50 TLV tlvRemoved = database.TagsToWriteBeforeGenACYet.GetFirstAndRemoveFromList(); EMVPutDataRequest request = new EMVPutDataRequest(tlvRemoved); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_BEFORE_GEN_AC); #endregion } else { TORN_RECORD_FF8101_KRN2 foundTTL = null; #region 456.43 uint mnttl = Formatting.ConvertToInt32(database.GetDefault(EMVTagsEnum.MAX_NUMBER_OF_TORN_TRANSACTION_LOG_RECORDS_DF811D_KRN2).Value); if (database.IsNotEmpty(EMVTagsEnum.DRDOL_9F51_KRN2.Tag) && mnttl != 0) #endregion { #region 456.44 foreach (TORN_RECORD_FF8101_KRN2 tlv in tornTransactionLogManager.TornTransactionLogs) { if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)) { if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) && (Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value))) { foundTTL = tlv; } } else { if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) && (tlv.Children.IsNotPresent(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))) { foundTTL = tlv; } } } #endregion if (foundTTL == null) { #region 456.45 EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); #endregion } else { #region 456.47 database.TornTempRecord = foundTTL; #endregion #region 456.48 database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2).Value = database.TornTempRecord.Children.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2.Tag).Value; EMVRecoverACRequest requestRecover = new EMVRecoverACRequest(database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2)); cardQManager.EnqueueToInput(new CardRequest(requestRecover, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_RECOVER_AC); #endregion } } else { #region 456.45 EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); #endregion } } }
private static SignalsEnum ProcessNextCVM(KernelDatabase database, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN cvl = new CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN(database); CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); bool goToNextCVM = false; if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline) { if (cvr.Value.GetCVMResult() == CVMResult.Failed) { goToNextCVM = true; } } else { //if a previously run CVM failed then state returns here and we try the next CVM if (cvr.Value.GetCVMResult() != CVMResult.Success) { goToNextCVM = true; } } if (goToNextCVM && database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count) { //if previous cvm was offline pin, check pin try counter if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper) { TLV pinTryCounterTLV = database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN); if (pinTryCounterTLV != null) { ushort pinTryCounter = Formatting.ConvertToInt16(pinTryCounterTLV.Value); if (pinTryCounter > 1) //at this point the pin try counter on the card is 0, we are always 1 behind { qManager.EnqueueToOutput(new KernelPinResponse()); return(SignalsEnum.WAITING_FOR_PIN_RESPONSE); } } } #region Book 3 Section 10.5 CVMSelection_7_5.CVMSelection(database, new Func <bool>(() => { return(true); })); cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database);//update after calling cvm selection #endregion if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline) { qManager.EnqueueToOutput(new KernelPinResponse()); return(SignalsEnum.WAITING_FOR_PIN_RESPONSE); } if (cvr.Value.GetCVMResult() == CVMResult.Failed) { return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } } if (cvr.Value.GetCVMPerformed() != CVMCode.NoCVMDone) { TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.Value.CardholderVerificationWasPerformed = true; tsi.UpdateDB(); } #region Book 3 Section 10.6 //Terminal Risk Management TLV lcol = database.Get(EMVTagsEnum.LOWER_CONSECUTIVE_OFFLINE_LIMIT_9F14_KRN); TLV ucol = database.Get(EMVTagsEnum.UPPER_CONSECUTIVE_OFFLINE_LIMIT_9F23_KRN); if (lcol != null && ucol != null) { EMVGetDataRequest requestATC = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag)); EMVGetDataRequest requestLastOnlineATC = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag)); cardQManager.EnqueueToInput(new CardRequest(requestATC, CardinterfaceServiceRequestEnum.ADPU)); cardQManager.EnqueueToInput(new CardRequest(requestLastOnlineATC, CardinterfaceServiceRequestEnum.ADPU)); } //Get Floor Limit Data if (database.IsEmpty(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag)) { DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); dataNeeded.Value.Tags.Add(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag); dataNeeded.UpdateDB(); CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); } qManager.EnqueueToOutput(new KernelTRMResponse()); return(SignalsEnum.WAITING_FOR_TERMINAL_RISK_MANAGEMENT); #endregion }