private static SignalsEnum EntryPointPIN(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); //store the pin database.AddToList(kernel1Request.InputData.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag)); string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); //online pin if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline) { PinProcessing.VerifyOnlinePin(pin, tvr, cvr); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //offline pin if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper) { EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN.Tag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GET_PIN_TRY_COUNTER); } throw new EMVProtocolException("Invalid cvr in State_5a_WaitingForGetPinReponse"); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); EMVGetDataResponse response = (EMVGetDataResponse)cardResponse.ApduResponse; if (!response.Succeeded) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //store the pin try counter value database.AddToList(response.GetResponseTag()); int pinTryCounter = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN).Value); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper) { string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr)) { return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //fire off get challenge command EMVGetChallengeRequest request = new EMVGetChallengeRequest(); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GET_CHALLENGE); } if (cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper) { string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr)) { return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } byte[] pinData = PinProcessing.BuildPlainTextPinBlock(pin); //fire off verify for plain text pin EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Plaintext_PIN, pinData); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_VERIFY); } throw new EMVProtocolException("Invalid cvr in State_5b_WaitingForGetPinTryCounter"); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { EMVGetDataResponse response = (EMVGetDataResponse)cardResponse.ApduResponse; if (!response.Succeeded) { if (response.SW1 == 0x6A && response.SW2 == 0x88) //data not found { //do nothing return(SignalsEnum.WAITING_FOR_TERMINAL_RISK_MANAGEMENT); } else { 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 (response.GetResponseTag().Tag.TagLable == EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) { database.AddToList(response.GetResponseTag()); } if (response.GetResponseTag().Tag.TagLable == EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag) { database.AddToList(response.GetResponseTag()); } return(SignalsEnum.WAITING_FOR_TERMINAL_RISK_MANAGEMENT); }
private static SignalsEnum ProcessGenACCommand(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { //remove values stored during 1st gen ac database.RemoveFromList(database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag)); //will only exist if CDA was perfomred after 1st gen ac database.RemoveFromList(database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag)); bool parsingResult = false; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { EMVGenerateACResponse response = cardResponse.ApduResponse as EMVGenerateACResponse; parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80) { if (cardResponse.ApduResponse.ResponseData.Length < 11 || cardResponse.ApduResponse.ResponseData.Length > 43 || database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag) || (cardResponse.ApduResponse.ResponseData.Length > 11 && database.IsNotEmpty(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag)) ) { parsingResult = false; } else { byte[] responseBuffer = new byte[cardResponse.ApduResponse.ResponseData.Length - 2]; Array.Copy(cardResponse.ApduResponse.ResponseData, 2, responseBuffer, 0, responseBuffer.Length); database.AddToList(TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag, new byte[] { responseBuffer[0] })); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag, new byte[] { responseBuffer[1], responseBuffer[2] })); byte[] ac = new byte[8]; Array.Copy(responseBuffer, 3, ac, 0, 8); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag, ac)); if (responseBuffer.Length > 11) { byte[] iad = new byte[responseBuffer.Length - 11]; Array.Copy(responseBuffer, 11, iad, 0, iad.Length); database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag, iad)); } parsingResult = true; } } } if (!parsingResult) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag))) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcp = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database); if (! (((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40 && rcp.Value.ACTypeEnum == ACTypeEnum.TC) || ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80 && (rcp.Value.ACTypeEnum == ACTypeEnum.TC || rcp.Value.ACTypeEnum == ACTypeEnum.ARQC)) || ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00)) ) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } if (aip.Value.CDASupported && tc.Value.CDACapable) { string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } if (database.IsNotEmpty(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag)) { State_7_10_CommonProcessing.DoCDA(database, qManager, capk, cardQManager, cardResponse, emvSelectApplicationResponse, false); } else { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } } return(State_7_10_CommonProcessing.EndOnTCorAAC(database, qManager, cardQManager)); }
private static SignalsEnum 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)); } }
private static SignalsEnum EntryPointACT(KernelDatabase database, KernelRequest kernelRequest, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { foreach (TLV tlv in kernelRequest.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(); 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(); TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.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 EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { if (!cardResponse.ApduResponse.Succeeded) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } bool parsingResult = false; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { EMVGenerateACResponse response = cardResponse.ApduResponse as EMVGenerateACResponse; parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80) { if (cardResponse.ApduResponse.ResponseData.Length < 11 || cardResponse.ApduResponse.ResponseData.Length > 43 || database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag) || (cardResponse.ApduResponse.ResponseData.Length > 11 && database.IsNotEmpty(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag)) ) { parsingResult = false; } else { byte[] responseBuffer = new byte[cardResponse.ApduResponse.ResponseData.Length - 2]; Array.Copy(cardResponse.ApduResponse.ResponseData, 2, responseBuffer, 0, responseBuffer.Length); database.AddToList(TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag, new byte[] { responseBuffer[0] })); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag, new byte[] { responseBuffer[1], responseBuffer[2] })); byte[] ac = new byte[8]; Array.Copy(responseBuffer, 3, ac, 0, 8); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag, ac)); if (responseBuffer.Length > 11) { byte[] iad = new byte[responseBuffer.Length - 11]; Array.Copy(responseBuffer, 11, iad, 0, iad.Length); database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag, iad)); } parsingResult = true; } } } if (!parsingResult) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag))) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcp = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database); if (! (((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40 && rcp.Value.ACTypeEnum == ACTypeEnum.TC) || ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80 && (rcp.Value.ACTypeEnum == ACTypeEnum.TC || rcp.Value.ACTypeEnum == ACTypeEnum.ARQC)) || ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00)) ) { return(State_7_10_CommonProcessing.DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (aip.Value.CDASupported && tc.Value.CDACapable) { string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } if (database.IsNotEmpty(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag)) { State_7_10_CommonProcessing.DoCDA(database, qManager, capk, cardQManager, cardResponse, emvSelectApplicationResponse, true); } else { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } } else { if (aip.Value.DDAsupported && tc.Value.DDACapable) { //oda was done already in waiting for internal authenticate } else { if (aip.Value.SDASupported && tc.Value.SDACapable) { //sda was done already in card action analysis } } } //check for offline approved or declined, if so end transaction if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40 || (database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x00) { return(State_7_10_CommonProcessing.EndOnTCorAAC(database, qManager, cardQManager)); } else { CommonRoutines.CreateEMVDataRecord(database); CommonRoutines.CreateEMVDiscretionaryData(database); qManager.EnqueueToOutput(new KernelOnlineResponse(database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2), database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2))); return(SignalsEnum.WAITING_FOR_ONLINE_RESPONSE); } }