public static SignalsEnum Execute( Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { KernelRequest kernel2Request = qManager.DequeueFromInput(false); switch (kernel2Request.KernelTerminalReaderServiceRequestEnum) { case KernelTerminalReaderServiceRequestEnum.STOP: return(EntryPointSTOP(database, qManager)); case KernelTerminalReaderServiceRequestEnum.TIMEOUT: return(EntryPointTIMEOUT(database, qManager)); case KernelTerminalReaderServiceRequestEnum.DET: return(EntryPointDET(database, kernel2Request, qManager, cardQManager, sw)); default: throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_8_WaitingForMagStripeFirstWriteFlag:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel2Request.KernelTerminalReaderServiceRequestEnum)); } }
public static SignalsEnum Execute( KernelDatabase database, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { if (qManager.GetOutputQCount() > 0) //there is a pending request to the terminal { KernelRequest kernel1Request = qManager.DequeueFromInput(false); switch (kernel1Request.KernelTerminalReaderServiceRequestEnum) { case KernelTerminalReaderServiceRequestEnum.STOP: return(EntryPointSTOP(database, qManager)); case KernelTerminalReaderServiceRequestEnum.DET: return(EntryPointDET(database, kernel1Request)); default: throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_5b_WaitingForGetPinTryCounter:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum)); } } else { CardResponse cardResponse = cardQManager.DequeueFromOutput(false); switch (cardResponse.CardInterfaceServiceResponseEnum) { case CardInterfaceServiceResponseEnum.RA: return(EntryPointRA(database, cardResponse, qManager, cardQManager, sw)); case CardInterfaceServiceResponseEnum.L1RSP: return(EntryPointL1RSP(database, cardResponse, qManager)); default: throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_5b_WaitingForGetPinTryCounter:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), cardResponse.CardInterfaceServiceResponseEnum)); } } }
private static SignalsEnum DoInvalidResponse(Kernel2Database database, KernelQ qManager) { #region 14.40 int waitTime = ((2 ^ database.FailedMSCntr) * 300); Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait(); #endregion #region 14.41 database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5); #endregion CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.N_A, database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); }
private static SignalsEnum EntryPointL1RSP(KernelDatabase database, CardResponse cardResponse, KernelQ qManager) { CommonRoutines.CreateEMVDiscretionaryData(database); CommonRoutines.CreateEMVDataRecord(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, cardResponse.L1Enum, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); }
/* * 15.2 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw) { #region 15.5 if (cardResponse.ApduResponse.Succeeded) #endregion { #region 15.6 if (database.TagsToWriteAfterGenACYet.Count != 0) #endregion { #region 15.7 TLV tagToPut = database.TagsToWriteAfterGenACYet.GetFirstAndRemoveFromList(); EMVPutDataRequest requestPutData = new EMVPutDataRequest(tagToPut); #endregion #region 15.8 cardQManager.EnqueueToInput(new CardRequest(requestPutData, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_AFTER_GEN_AC); #endregion } else { #region 15.9 byte pgacps = database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value[0]; pgacps = (byte)(pgacps | 0x80); database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value[0] = pgacps; #endregion } } return(DoCommon(database, cardResponse, qManager)); }
private static SignalsEnum EntryPointL1RSP(KernelDatabase database, CardResponse cardResponse, KernelQ qManager) { CommonRoutines.InitializeDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.TRY_AGAIN, KernelStatusEnum.READY_TO_READ, new byte[] { 0x00, 0x00, 0x00 }, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.B, false, KernelMessageidentifierEnum.TRY_AGAIN, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); }
private static SignalsEnum EntryPointSTOP(KernelDatabase database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING); }
private static SignalsEnum DoCommonProcessing(string source, KernelDatabase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse) { TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList(); if (nextTLV != null) { database.ActiveTag = nextTLV.Tag.TagLable; } else { database.ActiveTag = null; } if (database.ActiveTag != null) { EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); database.NextCommandEnum = NextCommandEnum.GET_DATA; } else { if (database.ActiveAFL == null) { return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); } else { EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); database.NextCommandEnum = NextCommandEnum.READ_RECORD; } } TLVList dataToSend = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children; APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); }
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)); }
/* * S1.4, S1.5 and S1.6 */ private static SignalsEnum EntryPointCLEAN(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, TornTransactionLogManager tornTransactionLogManager) { foreach (TLV tlv in kernel1Request.InputData) { bool updateConditionsOfTIncludeACTSignal = EMVTagsEnum.DoesTagIncludesPermission(tlv.Tag.TagLable, UpdatePermissionEnum.ACT); if ((database.IsKnown(tlv.Tag.TagLable) || database.IsPresent(tlv.Tag.TagLable)) && updateConditionsOfTIncludeACTSignal) { database.AddToList(tlv); } } TLV discretionaryData = CommonRoutines.InitializeDiscretionaryData(database); foreach (TORN_RECORD_FF8101_KRN2 ttl in tornTransactionLogManager.TornTransactionLogs) { DateTime ttlTransactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(ttl.Children.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN.Tag).Value); DateTime ttlTransactionTime = EMVTagsEnum.TRANSACTION_TIME_9F21_KRN.FormatAsDateTime(ttl.Children.Get(EMVTagsEnum.TRANSACTION_TIME_9F21_KRN.Tag).Value); DateTime configTransactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN.Tag).Value); DateTime configTransactionTime = EMVTagsEnum.TRANSACTION_TIME_9F21_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_TIME_9F21_KRN.Tag).Value); TimeSpan tsDate = ttlTransactionDate - configTransactionDate; TimeSpan tsTime = ttlTransactionTime - configTransactionTime; int totalSeconds = tsDate.Seconds + tsTime.Seconds; int defaultToCheck = (int)Formatting.ConvertToInt32(database.GetDefault(EMVTagsEnum.MAX_LIFETIME_OF_TORN_TRANSACTION_LOG_RECORD_DF811C_KRN2).Value); if (totalSeconds > defaultToCheck) { discretionaryData.Children.AddToList(ttl); tornTransactionLogManager.TornTransactionLogs.RemoveFromList(ttl); } } return(CommonRoutines.PostOutcomeOnly(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A)); }
private static SignalsEnum DoCommon(Kernel2Database database, CardResponse cardResponse, KernelQ qManager) { #region 15.9.1 if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) && ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x00030F) != 0x000000) #endregion { #region 15.10 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true); #endregion //TODO: this changes ui in db which means when response is dequeued, it will have been //changed by code below, should we not create a copy in Kernel2Response constructor #region 15.11 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.READY_TO_READ, new byte[] { 0x00, 0x00, 0x00 }, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, false, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); #endregion } else { #region 15.12 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, false); //TODO: we created a temp ui and never saved it to db, so what ui is used below CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, new byte[] { 0x00, 0x00, 0x00 }, Kernel2OutcomeStatusEnum.N_A, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); #endregion } }
private static SignalsEnum EntryPointSTOP(Kernel1Database database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE); }
private static SignalsEnum EntryPointRA(Kernel1Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager) { 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)); } bool parsingResult = false; EMVInternalAuthenticateResponse response = cardResponse.ApduResponse as EMVInternalAuthenticateResponse; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { database.AddToList(response.GetTLVSignedApplicationData()); } if (!parsingResult) { 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, null, 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(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, null, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } TLV cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN); byte cid = cidTLV.Value[0]; cid = (byte)(cid >> 6); if (cid == (byte)ACTypeEnum.ARQC) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, 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 3.6.1.1 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true); #endregion #region 3.8.1.1 bool ddaPassed = K3.State_3_4_CommonProcessing.DoOfflineAuth(database, qManager, publicKeyCertificateManager); #endregion if (!ddaPassed) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } if (cid == (byte)ACTypeEnum.TC) { #region 3.9.2 CommonRoutines.CreateEMVDataRecord(database); CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.APPROVED, KernelStatusEnum.READY_TO_READ, null, Kernel2OutcomeStatusEnum.APPROVED, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, ValueQualifierEnum.NONE, null, null, false, KernelCVMEnum.N_A)); #endregion } //declined CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.DECLINED, KernelStatusEnum.READY_TO_READ, null, Kernel2OutcomeStatusEnum.DECLINED, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, ValueQualifierEnum.NONE, null, null, false, KernelCVMEnum.N_A)); }
private static SignalsEnum ProcessGenACCommand(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { //remove values stored during 1st gen ac database.RemoveFromList(database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag)); //will only exist if CDA was perfomred after 1st gen ac database.RemoveFromList(database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag)); bool parsingResult = false; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { EMVGenerateACResponse response = cardResponse.ApduResponse as EMVGenerateACResponse; parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80) { if (cardResponse.ApduResponse.ResponseData.Length < 11 || cardResponse.ApduResponse.ResponseData.Length > 43 || database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag) || (cardResponse.ApduResponse.ResponseData.Length > 11 && database.IsNotEmpty(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag)) ) { parsingResult = false; } else { byte[] responseBuffer = new byte[cardResponse.ApduResponse.ResponseData.Length - 2]; Array.Copy(cardResponse.ApduResponse.ResponseData, 2, responseBuffer, 0, responseBuffer.Length); database.AddToList(TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag, new byte[] { responseBuffer[0] })); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag, new byte[] { responseBuffer[1], responseBuffer[2] })); byte[] ac = new byte[8]; Array.Copy(responseBuffer, 3, ac, 0, 8); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag, ac)); if (responseBuffer.Length > 11) { byte[] iad = new byte[responseBuffer.Length - 11]; Array.Copy(responseBuffer, 11, iad, 0, iad.Length); database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag, iad)); } parsingResult = true; } } } if (!parsingResult) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag))) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcp = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database); if (! (((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40 && rcp.Value.ACTypeEnum == ACTypeEnum.TC) || ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80 && (rcp.Value.ACTypeEnum == ACTypeEnum.TC || rcp.Value.ACTypeEnum == ACTypeEnum.ARQC)) || ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00)) ) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } if (aip.Value.CDASupported && tc.Value.CDACapable) { string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } if (database.IsNotEmpty(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag)) { State_7_10_CommonProcessing.DoCDA(database, qManager, capk, cardQManager, cardResponse, emvSelectApplicationResponse, false); } else { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } } return(State_7_10_CommonProcessing.EndOnTCorAAC(database, qManager, cardQManager)); }
private static SignalsEnum 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)); } SignalsEnum result = ProcessGenACCommand(database, cardResponse, qManager, cardQManager, sw, publicKeyCertificateManager, emvSelectApplicationResponse); TLV _72 = database.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN); if (_72 != null) { database.ScriptsToRunAfterGenAC = CardActionAnalysis.BuildScriptList(_72); if (database.ScriptsToRunAfterGenAC.Count > 0) { //post first script 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); } } return(result); }
private static SignalsEnum EntryPointSTOP(KernelDatabase database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_GEN_AC_2); }
/* * 15.1 */ private static SignalsEnum EntryPointL1RSP(Kernel2Database database, CardResponse cardResponse, KernelQ qManager) { return(DoCommon(database, cardResponse, qManager)); }
/* * 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); }
/* * 15.3 */ private static SignalsEnum EntryPointSTOP(Kernel2Database database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_AFTER_GEN_AC); }
/* * 14.6 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager) { #region 14.9 if (!cardResponse.ApduResponse.Succeeded) #endregion { #region 14.10 CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.STATUS_BYTES, L3Enum.NOT_SET); return(DoInvalidResponse(database, qManager)); #endregion } #region 14.11 bool parsingResult = false; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { EMVComputeCryptographicChecksumResponse response = cardResponse.ApduResponse as EMVComputeCryptographicChecksumResponse; parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { parsingResult = false; } #endregion #region 14.12 if (!parsingResult) #endregion { #region 14.13 CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET); return(DoInvalidResponse(database, qManager)); #endregion } #region 14.12.1 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true); #endregion #region 14.14 if (database.IsEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) || database.IsEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag)) #endregion { #region 14.17 CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET); return(DoInvalidResponse(database, qManager)); #endregion } long nUN = 0; #region 14.15 if (database.IsNotEmpty(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2.Tag)) #endregion { #region 14.16 if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag) && (database.IsNotPresent(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2.Tag))) #endregion { #region 14.17 CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET); return(DoInvalidResponse(database, qManager)); #endregion } #region 14.20 byte pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1]; #endregion if ((pcii & 0x10) == 0x10) //OD-CVM verification successful { #region 14.24 nUN = (nUN + 5) % 10; #endregion } else { #region 14.21 long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long rctl = database.ReaderContactlessTransactionLismit; if (aa > rctl) #endregion { #region 14.21.1 CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET); return(DoInvalidResponse(database, qManager)); #endregion } else { #region 14.25 nUN = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value); #endregion } } #region 14.25.1 database.FailedMSCntr = 0; #endregion #region 14.26 TRACK_2_DATA_9F6B_KRN2 t2d = new TRACK_2_DATA_9F6B_KRN2(database); ushort t2 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK2_9F67_KRN2).Value); TLV PCVC3_TRACK2_9F65_KRN2 = database.Get(EMVTagsEnum.PCVC3_TRACK2_9F65_KRN2); MagBitmap bitmapPCVC3_TRACK2_9F65_KRN2 = new MagBitmap(PCVC3_TRACK2_9F65_KRN2.Value); TLV CVC3_TRACK2_9F61_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK2_9F61_KRN2); ushort cvc3T2AsShort = Formatting.ConvertToInt16(CVC3_TRACK2_9F61_KRN2.Value.Reverse().ToArray()); string q2LeastSigDigits = Convert.ToString(cvc3T2AsShort); q2LeastSigDigits = q2LeastSigDigits.Substring(q2LeastSigDigits.Length - bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount); t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPCVC3_TRACK2_9F65_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), q2LeastSigDigits, bitmapPCVC3_TRACK2_9F65_KRN2.NonZeroCount, true), false); TLV PUNATC_TRACK2_9F66_KRN2 = database.Get(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2); MagBitmap bitmapPUNATC_TRACK2_9F66_KRN2 = new MagBitmap(PUNATC_TRACK2_9F66_KRN2.Value); uint unpredInt = Formatting.ConvertToInt32(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_NUMERIC_9F6A_KRN2).Value.Reverse().ToArray()); string unpredString = Convert.ToString(unpredInt); unpredString = unpredString.Substring(unpredString.Length - database.NUN); t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), unpredString, database.NUN, true), false); if (t2 != 0) { TLV APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN); uint atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray()); string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort); atcAsShortLeastSigDigits = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t2); t2d.Value.DiscretionaryData = Formatting.StringToBcd(bitmapPUNATC_TRACK2_9F66_KRN2.ReplaceValues(Formatting.BcdToString(t2d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t2, false), false); } #endregion #region 14.27 StringBuilder dd = new StringBuilder(Formatting.BcdToString(t2d.Value.DiscretionaryData)); dd[dd.Length - 1] = Convert.ToString(nUN)[0]; t2d.Value.DiscretionaryData = Formatting.StringToBcd(dd.ToString(), false); #endregion t2d.Serialize(); //reserialize in case the length of discretionary data changed t2d.UpdateDB(); #region 14.28 if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag)) #endregion { #region 14.29 TRACK_1_DATA_56_KRN2 t1d = new TRACK_1_DATA_56_KRN2(database); ushort t1 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK1_9F64_KRN2).Value); TLV PCVC3_TRACK1_9F62_KRN2 = database.Get(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2); MagBitmap bitmapPCVC3_TRACK1_9F62_KRN2 = new MagBitmap(PCVC3_TRACK1_9F62_KRN2.Value); TLV CVC3_TRACK1_9F60_KRN2 = database.Get(EMVTagsEnum.CVC3_TRACK1_9F60_KRN2); ushort cvc3T1AsShort = Formatting.ConvertToInt16(CVC3_TRACK1_9F60_KRN2.Value.Reverse().ToArray()); string q1LeastSigDigits = Convert.ToString(cvc3T1AsShort); q1LeastSigDigits = q1LeastSigDigits.Substring(q1LeastSigDigits.Length - bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount); t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPCVC3_TRACK1_9F62_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), q1LeastSigDigits, bitmapPCVC3_TRACK1_9F62_KRN2.NonZeroCount, true)); TLV PUNATC_TRACK1_9F63_KRN2 = database.Get(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2); MagBitmap bitmapPUNATC_TRACK1_9F63_KRN2 = new MagBitmap(PUNATC_TRACK1_9F63_KRN2.Value); t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), unpredString, database.NUN, true)); if (t2 != 0) { TLV APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN); uint atcAsShort = Formatting.ConvertToInt32(APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Value.Reverse().ToArray()); string atcAsShortLeastSigDigits = Convert.ToString(atcAsShort); atcAsShortLeastSigDigits = atcAsShortLeastSigDigits.PadLeft(t2, '0').Substring(atcAsShortLeastSigDigits.Length - t1); t2d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(bitmapPUNATC_TRACK1_9F63_KRN2.ReplaceValues(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData), atcAsShortLeastSigDigits, t1, false)); } #endregion #region 14.30 StringBuilder dd1 = new StringBuilder(Formatting.ByteArrayToASCIIString(t1d.Value.DiscretionaryData)); dd1[dd1.Length - 1] = Convert.ToString(nUN)[0]; t1d.Value.DiscretionaryData = Formatting.ASCIIStringToByteArray(dd1.ToString()); #endregion t1d.Serialize(); //reserialize in case the length of discretionary data changed t1d.UpdateDB(); } #region 14.32 Kernel2OutcomeStatusEnum k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST; KernelCVMEnum cvmEnum = KernelCVMEnum.N_A; bool receipt = false; pcii = database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value[1]; if ((pcii & 0x10) == 0x10) //OD-CVM verification successful #endregion { #region 14.34 cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED; long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long rctl = database.ReaderContactlessTransactionLismit; if (aa > rctl) { receipt = true; } #endregion } else { #region 14.33 cvmEnum = KernelCVMEnum.NO_CVM; #endregion } CommonRoutines.CreateMSDiscretionaryDataRecord(database); CommonRoutines.CreateMSDataRecord(database); return(CommonRoutines.PostOutcomeOnly(database, qManager, k2OutcomeStatus, cvmEnum, receipt)); } else { #region 14.19.1 if (((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x00030F) != 0x000000) #endregion { KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED; KernelStatusEnum k2Status = KernelStatusEnum.READY_TO_READ; byte[] holdTime = new byte[] { 0x00, 0x00, 0x00 }; #region 14.22 PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = (PHONE_MESSAGE_TABLE_DF8131_KRN2)database.GetDefault(EMVTagsEnum.PHONE_MESSAGE_TABLE_DF8131_KRN2); foreach (PhoneMessageTableEntry_DF8131 entry in pmt.Value.Entries) { int pcii = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value); int pciMask = (int)Formatting.ConvertToInt32(entry.PCIIMask); int pciValue = (int)Formatting.ConvertToInt32(entry.PCIIValue); if ((pciMask & pcii) == pciValue) { k2MessageIdentifier = entry.MessageIdentifier; k2Status = entry.Status; holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value; break; } } #endregion #region 14.21.1 int waitTime = ((2 ^ database.FailedMSCntr) * 300); Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait(); #endregion #region 14.21.2 database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5); #endregion #region 14.23 CommonRoutines.CreateMSDiscretionaryDataRecord(database); CommonRoutines.CreateMSDataRecord(database); return(CommonRoutines.PostOutcome(database, qManager, k2MessageIdentifier, k2Status, holdTime, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.B, false, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); #endregion } else { #region 14.19.2.1 int waitTime = ((2 ^ database.FailedMSCntr) * 300); Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait(); #endregion #region 14.19.2.2 database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5); #endregion #region 14.19.3 CommonRoutines.CreateMSDiscretionaryDataRecord(database); CommonRoutines.CreateMSDataRecord(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.DECLINED, KernelStatusEnum.NOT_READY, database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); #endregion } } }
private static SignalsEnum EntryPointL1RSP(KernelDatabase database, CardResponse cardResponse, KernelQ qManager) { return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.TRY_AGAIN, Kernel2StartEnum.B, cardResponse.L1Enum, L2Enum.NOT_SET, L3Enum.NOT_SET)); }
/* * 14.1 */ private static SignalsEnum EntryPointL1RSP(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, TornTransactionLogManager tornTransactionLogManager) { #region 14.2 int waitTime = ((2 ^ database.FailedMSCntr) * 300); Task.Delay(TimeSpan.FromMilliseconds(waitTime)).Wait(); #endregion #region 14.3 database.FailedMSCntr = Math.Min(database.FailedMSCntr + 1, 5); #endregion #region 14.4 - 14.5 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.TRY_AGAIN, KernelStatusEnum.READY_TO_READ, new byte[] { 0x00, 0x00, 0x00 }, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.B, false, KernelMessageidentifierEnum.TRY_AGAIN, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); #endregion }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { if (!cardResponse.ApduResponse.Succeeded) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, null, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } bool parsingResult = false; EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80) { //if (cardResponse.ApduResponse.ResponseData.Length < 6 || // ((cardResponse.ApduResponse.ResponseData.Length - 2) % 4 != 0) || // database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag) || // database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag)) //{ // parsingResult = false; //} //else //{ foreach (TLV tlv in response.GetResponseTags()) { parsingResult = database.ParseAndStoreCardResponse(tlv); if (!parsingResult) { break; } } //} } } if (!parsingResult) { return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } else { if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag)) { return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } else { return(DoEMVMode(database, qManager, cardQManager, cardResponse, sw)); } } }
/* * 14.7 */ private static SignalsEnum EntryPointSTOP(Kernel2Database database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_CCC_RESPONSE_2); }
internal static SignalsEnum PostGenACBalanceReading(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager) { APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database); if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag) && aci.Value.SupportForBalanceReading)) { return(SignalsEnum.NONE); } if (!database.IsPresent(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2.Tag)) { return(SignalsEnum.NONE); } EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.OFFLINE_ACCUMULATOR_BALANCE_9F50_KRN2.Tag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); SignalsEnum result = SignalsEnum.WAITING_FOR_POST_GEN_AC_BALANCE; while (result == SignalsEnum.WAITING_FOR_POST_GEN_AC_BALANCE) { CardResponse cardResponse = cardQManager.DequeueFromOutput(false); result = State_17_WaitingForPostGenACBalance_7_4.Execute_State_17_WaitingForPostGenACBalance(database, qManager, cardQManager); } return(result); }
private static SignalsEnum DoPart_E(Kernel2Database database, KernelQ qManager, CardQ cardQManager) { #region 9_10.70 CommonRoutines.CreateEMVDataRecord(database); Kernel2OutcomeStatusEnum k2OutcomeStatus = Kernel2OutcomeStatusEnum.N_A; Kernel2StartEnum k2StartStatus = Kernel2StartEnum.N_A; KernelStatusEnum k2Status = KernelStatusEnum.N_A; KernelMessageidentifierEnum k2MessageIdentifier = KernelMessageidentifierEnum.N_A; byte[] holdTime = new byte[] { 0x00, 0x00, 0x00 }; ValueQualifierEnum valueQualifierEnum = ValueQualifierEnum.NONE; KernelCVMEnum cvmEnum = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database).Value.CVM; byte[] currencyCode = new byte[2]; byte[] valueQualifier = new byte[6]; bool uiRequestOnOutcomePresent; #endregion #region 9_10.71 if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) && ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x0000030F) != 0x00000000) #endregion { #region 9_10.72 k2OutcomeStatus = Kernel2OutcomeStatusEnum.END_APPLICATION; k2StartStatus = Kernel2StartEnum.B; #endregion #region 9_10.73 PHONE_MESSAGE_TABLE_DF8131_KRN2 pmt = new PHONE_MESSAGE_TABLE_DF8131_KRN2(database.GetDefault(EMVTagsEnum.PHONE_MESSAGE_TABLE_DF8131_KRN2)); foreach (PhoneMessageTableEntry_DF8131 entry in pmt.Value.Entries) { int pcii = (int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value); int pciMask = (int)Formatting.ConvertToInt32(entry.PCIIMask); int pciValue = (int)Formatting.ConvertToInt32(entry.PCIIValue); if ((pciMask & pcii) == pciValue) { k2MessageIdentifier = entry.MessageIdentifier; k2Status = entry.Status; holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value; break; } } #endregion } else { string tt = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value); #region 9_10.74 if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40) #endregion { k2OutcomeStatus = Kernel2OutcomeStatusEnum.APPROVED; } else { if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80) { k2OutcomeStatus = Kernel2OutcomeStatusEnum.ONLINE_REQUEST; } else { /* * Check if Transaction Type indicates a cash transaction (cash * withdrawal or cash disbursement) or a purchase transaction (purchase * or purchase with cashback). */ if (tt == "01" || tt == "17" || tt == "00" || tt == "09") { if (database.IsNotEmpty(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2.Tag)) { THIRD_PARTY_DATA_9F6E_KRN tpd = new THIRD_PARTY_DATA_9F6E_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); ushort uid = Formatting.ConvertToInt16(tpd.Value.UniqueIdentifier); ushort dt = Formatting.ConvertToInt16(tpd.Value.DeviceType); if ((uid & 0x8000) == 0x0000 && dt != 0x3030 || tc.Value.ICWithContactsCapable) { k2OutcomeStatus = Kernel2OutcomeStatusEnum.DECLINED; } else { k2OutcomeStatus = Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE; } } else { k2OutcomeStatus = Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE; } } else { k2OutcomeStatus = Kernel2OutcomeStatusEnum.END_APPLICATION; } } } #region 9_10.75 k2Status = KernelStatusEnum.NOT_READY; if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40) { holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value; if (database.IsNotEmpty(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2.Tag)) { valueQualifierEnum = ValueQualifierEnum.BALANCE; valueQualifier = database.Get(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2).Value; if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN.Tag)) { currencyCode = database.Get(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN).Value; } } if (cvmEnum == KernelCVMEnum.OBTAIN_SIGNATURE) { k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED_SIGN; } else { k2MessageIdentifier = KernelMessageidentifierEnum.APPROVED; } } else { if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80) { holdTime = new byte[] { 0x00, 0x00, 0x00 }; k2MessageIdentifier = KernelMessageidentifierEnum.AUTHORISING_PLEASE_WAIT; } else { if (tt == "01" || tt == "17" || tt == "00" || tt == "09") { holdTime = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2).Value; if (database.IsNotEmpty(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2.Tag)) { THIRD_PARTY_DATA_9F6E_KRN tpd = new THIRD_PARTY_DATA_9F6E_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); ushort uid = Formatting.ConvertToInt16(tpd.Value.UniqueIdentifier); ushort dt = Formatting.ConvertToInt16(tpd.Value.DeviceType); if ((uid & 0x8000) == 0x0000 && dt != 0x3030 || tc.Value.ICWithContactsCapable) { k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED; } else { k2MessageIdentifier = KernelMessageidentifierEnum.INSERT_CARD; } } else { k2MessageIdentifier = KernelMessageidentifierEnum.INSERT_CARD; } } else { holdTime = new byte[] { 0x00, 0x00, 0x00 }; k2MessageIdentifier = KernelMessageidentifierEnum.CLEAR_DISPLAY; } } } #endregion } #region 9_10.76 if (database.IsNotEmpty(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag)) #endregion { #region 9_10.77 TLV tagToPut = database.TagsToWriteAfterGenACYet.GetFirstAndRemoveFromList(); EMVPutDataRequest request = new EMVPutDataRequest(tagToPut); #endregion #region 9_10.78 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_AFTER_GEN_AC); #endregion } CommonRoutines.CreateEMVDiscretionaryData(database); #region 9_10.78.1 if (database.IsNotEmpty(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2.Tag) && ((int)Formatting.ConvertToInt32(database.Get(EMVTagsEnum.POS_CARDHOLDER_INTERACTION_INFORMATION_DF4B_KRN2).Value) & 0x0000030F) != 0x00000000) #endregion { #region 9_10.79 CommonRoutines.PostUIOnly(database, qManager, k2MessageIdentifier, k2Status, true, holdTime); #endregion #region 9_10.80 uiRequestOnOutcomePresent = false; k2Status = KernelStatusEnum.READY_TO_READ; holdTime = new byte[] { 0x00, 0x00, 0x00 }; #endregion } else { #region 9_10.81 uiRequestOnOutcomePresent = true; #endregion } return(CommonRoutines.PostOutcome(database, qManager, k2MessageIdentifier, k2Status, holdTime, k2OutcomeStatus, k2StartStatus, uiRequestOnOutcomePresent, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, valueQualifierEnum, valueQualifier, currencyCode, false, cvmEnum)); }
private static SignalsEnum EntryPointSTOP(KernelDatabase database, KernelQ qManager) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.STOP)); }
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); } } } }
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); } }