private static SignalsEnum EntryPointRA(Kernel3Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager) { #region 5.2.2.2 if (!cardResponse.ApduResponse.Succeeded) { TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database); if (cardResponse.ApduResponse.SW1 == 0x69 && cardResponse.ApduResponse.SW2 == 0x84 && ttq.Value.EMVModeSupported) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.INSERT_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.TRY_ANOTHER_INTERFACE, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.INSERT_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } if (cardResponse.ApduResponse.SW1 == 0x69 && cardResponse.ApduResponse.SW2 == 0x85) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, null, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); } if (cardResponse.ApduResponse.SW1 == 0x69 && cardResponse.ApduResponse.SW2 == 0x86 && ttq.Value.EMVModeSupported) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.SEE_PHONE, KernelStatusEnum.READY_TO_READ, new byte[] { 0x00, 0x00, 0x0D }, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.B, true, KernelMessageidentifierEnum.SEE_PHONE, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } #endregion bool parsingResult = false; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse; parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x80) { EMVGetProcessingOptionsResponse response = cardResponse.ApduResponse as EMVGetProcessingOptionsResponse; if (cardResponse.ApduResponse.ResponseData.Length < 6 || ((cardResponse.ApduResponse.ResponseData.Length - 2) % 4 != 0) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag) || database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag)) { parsingResult = false; } else { database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag, response.GetResponseTags().Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag).Value)); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag, response.GetResponseTags().Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag).Value)); parsingResult = true; } } } if (!parsingResult) { return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } else { #region 5.4.1.1 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true); #endregion if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN.Tag)) { return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } else { TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database); if (ttq.Value.MagStripeModeSupported && !ttq.Value.EMVModeSupported) { return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.MAGSTRIPE_NOT_SUPPORTED, L3Enum.NOT_SET)); } else { if (!ttq.Value.MagStripeModeSupported && ttq.Value.EMVModeSupported) { return(DoEMVMode(database, qManager, cardQManager, cardResponse, sw, publicKeyCertificateManager, cardExceptionManager)); } else { return(K1K3.State_3_R1_CommonProcessing.DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.MAGSTRIPE_NOT_SUPPORTED, L3Enum.NOT_SET)); } } } } }
public static KernelCVMEnum DoCVMProcessing(Kernel3Database database, ACTypeEnum acType) { KernelCVMEnum cvm = KernelCVMEnum.N_A; TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database); if (!database.DeclineRequiredByReaderIndicator) { #region 5.7.1.1 if (database.IsEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag) && ttq.Value.CVMRequired) #endregion { if (ttq.Value.SignatureSupported) { cvm = KernelCVMEnum.OBTAIN_SIGNATURE; } else if (ttq.Value.ConsumerDeviceCVMSupported && ttq.Value.OnlinePINSupported) { cvm = KernelCVMEnum.ONLINE_PIN; } else// only ttq.Value.ConsumerDeviceCVMSupported { database.DeclineRequiredByReaderIndicator = true; } } if (database.IsNotEmpty(EMVTagsEnum.CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3.Tag)) { #region 5.7.1.2 CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database); if (ctq.Value.OnlinePINRequired && ttq.Value.OnlinePINSupported) { cvm = KernelCVMEnum.ONLINE_PIN; database.OnlineRequiredByReaderIndicator = true; } else { if (ctq.Value.ConsumerDeviceCVMPerformed) { TLV card = database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3); if (card != null) { byte[] card67 = new byte[2]; byte[] ctq12 = new byte[2]; Array.Copy(card.Value, 6, card67, 0, 2); Array.Copy(ctq.Value.Value, 0, ctq12, 0, 2); if (Formatting.ByteArrayToHexString(card67) == Formatting.ByteArrayToHexString(ctq12)) { cvm = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED; } else { database.DeclineRequiredByReaderIndicator = true; } } else { if (acType == ACTypeEnum.ARQC) { cvm = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED; } else { database.DeclineRequiredByReaderIndicator = true; } } } } if (!ctq.Value.OnlinePINRequired && !ctq.Value.ConsumerDeviceCVMPerformed) { if (ttq.Value.SignatureSupported && ctq.Value.SignatureRequired) { cvm = KernelCVMEnum.OBTAIN_SIGNATURE; } } #endregion } } if (cvm == KernelCVMEnum.N_A && ttq.Value.CVMRequired) { cvm = KernelCVMEnum.NO_CVM; database.DeclineRequiredByReaderIndicator = true; } if (cvm == KernelCVMEnum.N_A) { cvm = KernelCVMEnum.NO_CVM; } return(cvm); }