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); } }
public static SignalsEnum Initiate2ndCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse, bool entryFromScriptProcessingCompleted = false) { if (!entryFromScriptProcessingCompleted) { //check if scripts need to be run TLV _71 = database.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN); if (_71 != null) { ((KernelDatabase)database).ScriptsToRunBeforeGenAC = BuildScriptList(_71); if (((KernelDatabase)database).ScriptsToRunBeforeGenAC.Count > 0) { ((KernelDatabase)database).IsScriptProcessingBeforeGenACInProgress = true; //post first script TLV firstScript = ((KernelDatabase)database).ScriptsToRunBeforeGenAC.GetFirstAndRemoveFromList(); EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest(); scriptRequest.Deserialize(firstScript.Value); cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING); } } } APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); //section 6.5.5 in Book 3 TLV cdol2 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_2_CDOL2_8D_KRN); byte[] cdol2Data = CommonRoutines.PackRelatedDataTag(database, cdol2); REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database); rcpST.Value.ACTypeEnum = GetDSACType(database); if (aip.Value.CDASupported && tc.Value.CDACapable) { rcpST.Value.CDASignatureRequested = true; } else { rcpST.Value.CDASignatureRequested = false; } rcpST.UpdateDB(); EMVGenerateACRequest request = new EMVGenerateACRequest(cdol2Data, null, rcpST); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_2); }
private static 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); }
private static SignalsEnum EntryPointPIN(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); //store the pin database.AddToList(kernel1Request.InputData.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag)); string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); //online pin if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline) { PinProcessing.VerifyOnlinePin(pin, tvr, cvr); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //offline pin if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper) { EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN.Tag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GET_PIN_TRY_COUNTER); } throw new EMVProtocolException("Invalid cvr in State_5a_WaitingForGetPinReponse"); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, 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); }
/* * S6.5 - S6.7 */ private static SignalsEnum EntryPointDET(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw) { #region 6.6 database.UpdateWithDETData(kernel1Request.InputData); #endregion #region 6.7 sw.Stop(); #endregion #region 6.8 TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList(); if (nextTLV != null) database.ActiveTag = nextTLV.Tag.TagLable; else database.ActiveTag = null; if (database.ActiveTag != null) #endregion { #region 6.9 - 6.12 EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); database.NextCommandEnum = NextCommandEnum.GET_DATA; #endregion } else { #region 6.12 database.NextCommandEnum = NextCommandEnum.NONE; #endregion } return State_4_5_6_CommonProcessing.DoCommonProcessing("State_6_WaitingForEMVModeFirstWriteFlag", database, qManager, cardQManager, sw, tornTransactionLogManager); }
/* * 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)); }
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 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, PublicKeyCertificateManager pkcm, EMVSelectApplicationResponse emvSelectApplicationResponse, Stopwatch sw) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); EMVGetChallengeResponse response = (EMVGetChallengeResponse)cardResponse.ApduResponse; if (!response.Succeeded) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //store the challenge byte[] pinChallenge = response.ResponseData; if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper) { string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = pkcm.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); byte[] pinBlock = PinProcessing.BuildPlainTextPinBlock(pin); //encrypt the pin byte[] encipheredPin = PinProcessing.BuildPinVerifyData(database, capk, pinBlock, pinChallenge); if (encipheredPin == null) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //fire off verify for enciphered pin EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Enciphered_PIN, encipheredPin); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); } //verify message for plain text pin fired in waiting for pin response return(SignalsEnum.WAITING_FOR_VERIFY); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { if (!cardResponse.ApduResponse.Succeeded) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } EMVInternalAuthenticateResponse response = cardResponse.ApduResponse as EMVInternalAuthenticateResponse; string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); #region 3.8.1.1 bool ddaPassed = DoDDA(database, qManager, capk, response.GetTLVSignedApplicationData()); #endregion if (!ddaPassed) { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.DDAFailed = true; tvr.UpdateDB(); } TLV cdol1 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN); CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2, cdol1); REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database); rcpST.Value.ACTypeEnum = database.ACType.Value.DSACTypeEnum; rcpST.Value.CDASignatureRequested = false; rcpST.UpdateDB(); EMVGenerateACRequest request = new EMVGenerateACRequest(database.Get(EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2), null, rcpST); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); }
public static SignalsEnum DoOnlineProcess(KernelDatabaseBase database, CardQ cardQManager) { #region 3.5.1.1 TLV tvr = database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN); if (tvr == null) { tvr = TLV.Create(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00 }); database.AddToList(tvr); } TLV cdol1 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN); byte[] cdol1RelatedData = CommonRoutines.PackRelatedDataTag(database, cdol1); EMVGenerateACRequest request = new EMVGenerateACRequest(cdol1RelatedData); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); #endregion }
public static SignalsEnum DoOfflineProcess(KernelDatabaseBase database, CardQ cardQManager) { #region 3.4.1.1 and 3.4.1.2 TLV ddol = database.Get(EMVTagsEnum.DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST_DDOL_9F49_KRN); byte[] ddolRelatedData; if (ddol == null) { TLV unpred = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN); unpred.Val.PackValue(unpred.Val.GetLength()); ddolRelatedData = unpred.Value; } else { ddolRelatedData = CommonRoutines.PackRelatedDataTag(database, ddol); } EMVInternalAuthenticateRequest request = new EMVInternalAuthenticateRequest(ddolRelatedData); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE); #endregion }
public static SignalsEnum DoCommonProcessing(string source, KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse) { 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; } if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) || (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)) { CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); } return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); }
/* * SR1.9 - SR1.32 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { #region SR1.10 sw.Stop(); #endregion #region SR1.11 if (!cardResponse.ApduResponse.Succeeded) #endregion { #region SR1.12 - SR1.13 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); #endregion } #region SR1.14 bool parsingResult = false; EMVExchangeRelayResistanceDataResponse emverrdr = (EMVExchangeRelayResistanceDataResponse)cardResponse.ApduResponse; if ((cardResponse.ApduResponse.ResponseData.Length > 11 && cardResponse.ApduResponse.ResponseData[0] == 0x80))// && cardResponse.ApduResponse.ResponseData.Length == 10) { database.AddListToList(emverrdr.GetResponseTags()); parsingResult = true; } #region SR1.15 if (!parsingResult) #endregion { #region SR1.16, SR1.17 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); #endregion } #region SR1.18 int a = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.TERMINAL_EXPECTED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_CAPDU_DF8134_KRN2).Value); int b = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.TERMINAL_EXPECTED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8135_KRN2).Value); int c = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.DEVICE_ESTIMATED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8305_KRN2).Value); int measuredRelayResistanceProcessingTime = ((int)sw.ElapsedMilliseconds / 100) - a - Math.Min(c, b); #endregion int d = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MINIMUM_RELAY_RESISTANCE_GRACE_PERIOD_DF8132_KRN2).Value); int e = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MIN_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8303_KRN2).Value); #region SR1.19 if (measuredRelayResistanceProcessingTime < (e - d)) #endregion { #region SR1.20, SR1.21 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } int g = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MAX_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8304_KRN2).Value); int f = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2).Value); #region SR1.22 if ((f < 2) && (measuredRelayResistanceProcessingTime > (g + d))) #endregion { #region SR1.23 - SR1.27 database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber(); database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value; f++; database.Get(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2).Value = BitConverter.GetBytes(f); EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value); sw.Start(); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE); #endregion } TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); #region SR1.28 if (measuredRelayResistanceProcessingTime > (g + d)) #endregion { #region SR1.29 tvr.Value.RelayResistanceTimeLimitsExceeded = true; #endregion } int h = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RELAY_RESISTANCE_TRANSMISSION_TIME_MISMATCH_THRESHOLD_DF8137_KRN2).Value); int i = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RELAY_RESISTANCE_ACCURACY_THRESHOLD_DF8136_KRN2).Value); #region SR1.30 if (((c / b) * 100 < h) || ((b / c) * 100 < h) || ((measuredRelayResistanceProcessingTime - e) > i)) { tvr.Value.RelayResistanceThresholdExceeded = true; } else { tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_PERFORMED; } tvr.UpdateDB(); #endregion #endregion return(State_3_R1_CommonProcessing.DoCommonProcessing("State_R1_ExchangeRelayResistanceData", database, qManager, cardQManager, cardResponse)); }
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 } } }
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); }
/* * S12.2 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw) { #region 12.8 if (cardResponse.ApduResponse.Succeeded) #endregion { #region 12.9 if (database.TagsToWriteBeforeGenACYet.Count != 0) #endregion { #region 12.10 TLV tagToPut = database.TagsToWriteBeforeGenACYet.GetFirstAndRemoveFromList(); EMVPutDataRequest requestPutData = new EMVPutDataRequest(tagToPut); #endregion #region 12.11 cardQManager.EnqueueToInput(new CardRequest(requestPutData, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_BEFORE_GEN_AC); #endregion } else { #region 12.12 byte pgacps = database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value[0]; pgacps = (byte)(pgacps | 0x80); database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value[0] = pgacps; #endregion } } #region 12.13 int mnttl = (int)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 12.14 foreach (TORN_RECORD_FF8101_KRN2 ttr in tornTransactionLogManager.TornTransactionLogs) { string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value); string panR = Formatting.ByteArrayToHexString(ttr.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value); if (ttr.Children.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)) { string sn = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value); string snR = Formatting.ByteArrayToHexString(ttr.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag).Value); if (pan == panR && sn == snR) { database.Get(EMVTagsEnum.TORN_RECORD_FF8101_KRN2).Value = ttr.Value; #region 12.17 database.TornTempRecord.Value = database.Get(EMVTagsEnum.TORN_RECORD_FF8101_KRN2).Value; #endregion #region 12.18 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)); #endregion #region 12.19 cardQManager.EnqueueToInput(new CardRequest(requestRecover, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_RECOVER_AC); #endregion } } else { if (pan == panR) { database.Get(EMVTagsEnum.TORN_RECORD_FF8101_KRN2).Value = ttr.Value; #region 12.17 database.TornTempRecord.Value = database.Get(EMVTagsEnum.TORN_RECORD_FF8101_KRN2).Value; #endregion #region 12.18 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)); #endregion #region 12.19 cardQManager.EnqueueToInput(new CardRequest(requestRecover, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_RECOVER_AC); #endregion } } } #endregion } #region 12.15 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 DoEMVMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse, Stopwatch sw) { #region 3.30 KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database); TLV aflRaw = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN); byte[] kcValCheck = new byte[4]; Array.Copy(aflRaw.Value, 0, kcValCheck, 0, kcValCheck.Length); if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100" && !kc.Value.MagStripeModeContactlessTransactionsNotSupported) { #region 3.32 byte[] activeAFLBytes = new byte[aflRaw.Value.Length - 4]; Array.Copy(aflRaw.Value, 4, activeAFLBytes, 0, activeAFLBytes.Length); List <byte[]> bytes = new List <byte[]> { new byte[] { (byte)activeAFLBytes.Length }, activeAFLBytes }; database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(activeAFLBytes)); #endregion } else { #region 3.31 List <byte[]> bytes = new List <byte[]> { new byte[] { (byte)aflRaw.Value.Length }, aflRaw.Value }; database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value)); #endregion } #endregion #region 3.33 APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported) { #region 3.35 database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value); #endregion } else { #region 3.34 database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value); #endregion } #endregion #region 3.60 if (kc.Value.RelayResistanceProtocolSupported && aip.Value.RelayResistanceProtocolIsSupported) #endregion { #region 3.61 database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber(); database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value; #endregion #region 3.62 EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value); #endregion #region 3.63 sw.Start(); #endregion #region 3.64 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE); } else { #region 3.65 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_NOT_PERFORMED; tvr.UpdateDB(); #endregion return(State_3_R1_CommonProcessing.DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, cardResponse)); } }
public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse) { #region S3R1.1 TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList(); if (nextTLV != null) { database.ActiveTag = nextTLV.Tag.TagLable; } else { database.ActiveTag = null; } if (database.ActiveTag != null) { #region S3R1.2 EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag)); #endregion #region S3R1.3 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion #region S3R1.3 database.NextCommandEnum = NextCommandEnum.GET_DATA; #endregion } #endregion else { #region S3R1.5 if (database.ActiveAFL == null) #endregion { #region S3R1.6 return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } else { #region S3R1.7 EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); #endregion #region S3R1.8 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion #region S3R1.9 database.NextCommandEnum = NextCommandEnum.READ_RECORD; #endregion } } #region S3R1.10 TLVList dataToSend = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children; IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region S3R1.11 if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2)); } dataToSend.AddToList(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN)); #endregion #region S3R1.12 if (!((database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag) && database.IsNotPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag)) || (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag)) )) { #region S3R1.13 ids = new IDS_STATUS_DF8128_KRN2(database); ids.Value.IsRead = false; ids.UpdateDB(); #endregion } #endregion } #region S3R1.14 TLVList tagsToRemove = new TLVList(); foreach (TLV ttry in database.TagsToReadYet) { if (database.IsNotEmpty(ttry.Tag.TagLable)) { dataToSend.AddToList(ttry); tagsToRemove.AddToList(ttry); } } foreach (TLV ttr in tagsToRemove) { database.TagsToReadYet.RemoveFromList(ttr); } #endregion #region S3R1.15 if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) || (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)) { #region S3R1.16 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } #endregion #region S3R1.17 APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); if (!(aip.Value.CDASupported && tc.Value.CDACapable)) { #region S3R1.18 ids = new IDS_STATUS_DF8128_KRN2(database); if (!ids.Value.IsRead) { #region S3R1.20 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.OfflineDataAuthenticationWasNotPerformed = true; tvr.UpdateDB(); #endregion } else { #region S3R1.19 database.ODAStatus = 0x80; #endregion } #endregion } else { #region S3R1.19 database.ODAStatus = 0x80; #endregion } #endregion if (database.NextCommandEnum == NextCommandEnum.READ_RECORD) { return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); } else { return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE); } }
private static SignalsEnum DoMagMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager) { KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database); TLV aflRaw = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN); byte[] kcValCheck = new byte[4]; Array.Copy(aflRaw.Value, 0, kcValCheck, 0, kcValCheck.Length); #region 3.70 if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100") #endregion { #region 3.72 byte[] activeAFLBytes = new byte[4]; Array.Copy(aflRaw.Value, 0, activeAFLBytes, 0, activeAFLBytes.Length); List <byte[]> bytes = new List <byte[]> { new byte[] { (byte)activeAFLBytes.Length }, activeAFLBytes }; database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(activeAFLBytes)); #endregion } else { #region 3.71 List <byte[]> bytes = new List <byte[]> { new byte[] { (byte)aflRaw.Value.Length }, aflRaw.Value }; database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value)); #endregion } #region 3.73 APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported) { #region 3.75 database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value); #endregion } else { #region 3.74 database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value); #endregion } #endregion #region 3.76 TLVList dataToSend = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children; TLVList tagsToRemove = new TLVList(); foreach (TLV ttry in database.TagsToReadYet) { if (database.IsNotEmpty(ttry.Tag.TagLable)) { dataToSend.AddToList(ttry); tagsToRemove.AddToList(ttry); } } foreach (TLV ttr in tagsToRemove) { database.TagsToReadYet.RemoveFromList(ttr); } #endregion #region 3.77 if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) || (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)) { #region 3.78 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } #region 3.80 EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); #endregion #region 3.81 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion return(SignalsEnum.WAITING_FOR_MAG_STRIPE_READ_RECORD_RESPONSE); #endregion }
/* * 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)); }
/* * 7.3 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, TornTransactionLogManager tornTransactionLogManager, Stopwatch sw) { #region 7.9 if (!cardResponse.ApduResponse.Succeeded) #endregion { #region 7.10.1 - 7.10.2 CommonRoutines.CreateMSDiscretionaryDataRecord(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 7.11 bool parsingResult = false; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x70) { parsingResult = database.ParseAndStoreCardResponse(cardResponse.ApduResponse.ResponseData); } else { parsingResult = false; } #endregion if (!parsingResult) { #region 7.13.1 CommonRoutines.CreateMSDiscretionaryDataRecord(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); #endregion } #region 7.14 if ((cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags().IsPresent(EMVTagsEnum.UDOL_9F69_KRN2.Tag)) #endregion { #region 7.15 TLV udol = (cardResponse.ApduResponse as EMVReadRecordResponse).GetResponseTags().Get(EMVTagsEnum.UDOL_9F69_KRN2.Tag); foreach (TLV tlv in udol.Children) { if (database.IsEmpty(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Children.AddToList(tlv); } } #endregion } #region 7.16 database.ActiveAFL.Value.Entries.RemoveAt(0); #endregion #region 7.17 if (database.ActiveAFL.Value.Entries.Count != 0) #endregion { #region 7.18 - 7.19 EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_MAG_STRIPE_READ_RECORD_RESPONSE); #endregion } #region 7.20 if (database.IsEmpty(EMVTagsEnum.TRACK_2_DATA_9F6B_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.PCVC3_TRACK2_9F65_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.NATC_TRACK2_9F67_KRN2.Tag)) #endregion { #region 7.21.1 CommonRoutines.CreateMSDiscretionaryDataRecord(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_MISSING, L3Enum.NOT_SET)); #endregion } #region 7.22 TLV punatc2 = database.Get(EMVTagsEnum.PUNATC_TRACK2_9F66_KRN2); int natc2 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK2_9F67_KRN2).Value); int nonZeroBits = 0; for (int i = 0; i < 8; i++) { if (((punatc2.Value[0] >> i) & 0x01) == 0x01) { nonZeroBits++; } if (((punatc2.Value[1] >> i) & 0x01) == 0x01) { nonZeroBits++; } } int check2 = nonZeroBits - natc2; database.NUN = check2; if (check2 < 0 && check2 > 8) { #region 7.24.1 return(DoInvalidResponse(database, qManager)); #endregion } if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag)) { int check1 = 0; if (database.IsNotEmpty(EMVTagsEnum.NATC_TRACK1_9F64_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2.Tag)) { TLV punatc1 = database.Get(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2); int natc1 = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.NATC_TRACK1_9F64_KRN2).Value); int nonZeroBits1 = 0; for (int i = 0; i < 8; i++) { if (((punatc1.Value[0] >> i) & 0x01) == 0x01) { nonZeroBits1++; } if (((punatc1.Value[1] >> i) & 0x01) == 0x01) { nonZeroBits1++; } if (((punatc1.Value[2] >> i) & 0x01) == 0x01) { nonZeroBits1++; } if (((punatc1.Value[3] >> i) & 0x01) == 0x01) { nonZeroBits1++; } if (((punatc1.Value[4] >> i) & 0x01) == 0x01) { nonZeroBits1++; } if (((punatc1.Value[5] >> i) & 0x01) == 0x01) { nonZeroBits1++; } } check1 = nonZeroBits1 - natc1; } else { #region 7.24.1 return(DoInvalidResponse(database, qManager)); #endregion } if ((database.IsNotPresent(EMVTagsEnum.NATC_TRACK1_9F64_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.NATC_TRACK1_9F64_KRN2.Tag)) || (database.IsNotPresent(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.PCVC3_TRACK1_9F62_KRN2.Tag)) || (database.IsNotPresent(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2.Tag) || database.IsEmpty(EMVTagsEnum.PUNATC_TRACK1_9F63_KRN2.Tag)) || check1 != check2 ) { #region 7.24.1 return(DoInvalidResponse(database, qManager)); #endregion } } #region 7.23 TRACK_2_DATA_9F6B_KRN2 t2d = new TRACK_2_DATA_9F6B_KRN2(database); TLV ddCardT2 = database.Get(EMVTagsEnum.DD_CARD_TRACK2_DF812B_KRN2); if (ddCardT2 == null) { ddCardT2 = TLV.Create(EMVTagsEnum.DD_CARD_TRACK2_DF812B_KRN2.Tag); } ddCardT2.Value = t2d.Value.DiscretionaryData; if (database.IsNotEmpty(EMVTagsEnum.TRACK_1_DATA_56_KRN2.Tag)) { TRACK_1_DATA_56_KRN2 t1d = new TRACK_1_DATA_56_KRN2(database); TLV ddCardT1 = database.Get(EMVTagsEnum.DD_CARD_TRACK1_DF812A_KRN2); if (ddCardT1 == null) { ddCardT1 = TLV.Create(EMVTagsEnum.DD_CARD_TRACK1_DF812A_KRN2.Tag); } ddCardT1.Value = t1d.Value.DiscretionaryData; } return(State_7_8_CommonProcessing.DoCommonProcessing("State_7_WaitingForMagStripeReadRecordResponse", database, qManager, cardQManager, sw)); #endregion #endregion }
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 EntryPointOnline(KernelDatabase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { KernelOnlineRequest response = (KernelOnlineRequest)kernel1Request; //check if approved or not or unable to go online if (response.OnlineApprovalStatus == KernelOnlineResponseType.UnableToGoOnline) { //if unable to go online, check what action to take using TAC/IAC default, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); ulong tvrAsNumber = Formatting.ConvertToInt64(tvr.Value.Value); ulong tacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_DEFAULT_DF8120_KRN2).Value); if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN.Tag)) { ulong iacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN).Value); if (!( ((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0) ) { database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; } else { database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; } } else { if (!((tacAsNumber & tvrAsNumber) == 0)) { database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; } else { database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; } } //what should these be set to in this case? database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag)); database.AddToList(TLV.Create(EMVTagsEnum.AUTHORISATION_RESPONSE_CODE_8A_KRN.Tag)); } else { if (response.OnlineApprovalStatus == KernelOnlineResponseType.Approve) { database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; } else { database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; } database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag)); database.AddToList(response.InputData.Get(EMVTagsEnum.AUTHORISATION_RESPONSE_CODE_8A_KRN.Tag)); if (response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN.Tag) != null) { database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN.Tag)); } if (response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN.Tag) != null) { database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN.Tag)); } } APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); if (aip.Value.IssuerAuthenticationIsSupported && response.OnlineApprovalStatus != KernelOnlineResponseType.UnableToGoOnline) { TLV _91 = response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag); EMVExternalAuthenticateRequest request = new EMVExternalAuthenticateRequest(_91.Value); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_EXTERNAL_AUTHENTICATE); } else { //if scripts need to be run before gen ac, do now return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse)); } }
public static SignalsEnum InitiateCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); //time to get signature data for dda cards, in order to do oda after 1st gen ac EMVGenerateACRequest request = null; if (aip.Value.CDASupported && tc.Value.CDACapable) { //cda done after gen ac 1, call gen ac1 now with signature requested request = CreateGenAC(database, true); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); } if (aip.Value.DDAsupported && tc.Value.DDACapable) { #region Book 3 Section 10.3 //do dda signature request, internal authenticate will do oda once it has the signature TLV ddol = database.Get(EMVTagsEnum.DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST_DDOL_9F49_KRN); byte[] ddolRelatedData; if (ddol == null) { TLV unpred = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN); unpred.Val.PackValue(unpred.Val.GetLength()); ddolRelatedData = unpred.Value; } else { ddolRelatedData = CommonRoutines.PackRelatedDataTag(database, ddol); } EMVInternalAuthenticateRequest requestDDA = new EMVInternalAuthenticateRequest(ddolRelatedData); cardQManager.EnqueueToInput(new CardRequest(requestDDA, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE); #endregion } if (aip.Value.SDASupported && tc.Value.SDACapable) { string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN); if (capk == null || ssadTLV == null) { tvr.Value.SDAFailed = true; tvr.UpdateDB(); } else { TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.Value.OfflineDataAuthenticationWasPerformed = true; tsi.UpdateDB(); byte[] sdadRaw = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN).Value; byte[] authCode = VerifySAD.VerifySSAD(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw); if (authCode == null) { tvr.Value.SDAFailed = true; tvr.UpdateDB(); } else { TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN); if (dataAuthenticationCode == null) { dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode); } else { dataAuthenticationCode.Value = authCode; } } } //sda done after gen ac 1, call gen ac 1 now with no signature requested request = CreateGenAC(database, false); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); } tvr.Value.OfflineDataAuthenticationWasNotPerformed = true; tvr.UpdateDB(); //to do: ceck this, is this correct for a card where no oda is supported request = CreateGenAC(database, false); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); }
private static 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); }
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)); }