private static SignalsEnum DoProcessingRestrictions(Kernel1Database database, KernelQ qManager) { #region 3.7.1.1 DateTime transactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN).Value); DateTime appExpiryDate = DateTime.Now; TLV appExiryDateTLV = database.Get(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN); if (appExiryDateTLV != null) { appExpiryDate = EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.FormatAsDateTime(appExiryDateTLV.Value); } if (appExiryDateTLV == null || (transactionDate > appExpiryDate)) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } #endregion return(SignalsEnum.NONE); }
public static void DoCVMProcessing(Kernel1Database database, ACTypeEnum acType) { CVMSelection_7_5.CVMSelection(database, new Func <bool>(() => { return(new KERNEL_CONFIGURATION_DF811B_KRN2(database).Value.OnDeviceCardholderVerificationSupported); })); }
public static SignalsEnum DoCommonProcessing(string source, KernelDatabaseBase databaseIn, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager pkcm, CardExceptionManager cardExceptionManager) { Kernel1Database database = (Kernel1Database)databaseIn; if (database.NextCommandEnum == NextCommandEnum.READ_RECORD) { DoDEKIfNeeded(database, qManager); return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); } DoDEKIfNeeded(database, qManager); //ReaderContactlessTransactionLimit exceeded if (database.ProcessingIndicatorsForSelected.ContactlessApplicationNotAllowed) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET)); } bool goOnline = false; #region 3.2.1.1 if (database.IsPresent(EMVTagsEnum.VLP_ISSUER_AUTHORISATION_CODE_9F74_KRN1.Tag)) { if (database.ProcessingIndicatorsForSelected.ReaderContactlessFloorLimitExceeded) { goOnline = true; } if (database.ProcessingIndicatorsForSelected.ReaderCVMRequiredLimitExceeded) { goOnline = true; } } else { goOnline = true; } #endregion if (goOnline) { return(DoOnlineProcess(database, cardQManager)); } else { return(DoOfflineProcess(database, cardQManager)); } }
private static SignalsEnum EntryPointL1RSP(Kernel1Database database, CardResponse cardResponse, KernelQ qManager) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.TRY_AGAIN, KernelStatusEnum.READY_TO_READ, new byte[] { 0x00, 0x00, 0x00 }, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.B, false, KernelMessageidentifierEnum.TRY_AGAIN, cardResponse.L1Enum, null, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); }
public static SignalsEnum Execute( Kernel1Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager) { if (qManager.GetOutputQCount() > 0) //there is a pending request to the terminal { KernelRequest kernel1Request = qManager.DequeueFromInput(false); switch (kernel1Request.KernelTerminalReaderServiceRequestEnum) { case KernelTerminalReaderServiceRequestEnum.STOP: return(EntryPointSTOP(database, qManager)); case KernelTerminalReaderServiceRequestEnum.DET: return(EntryPointDET(database, kernel1Request)); default: throw new EMVProtocolException("Invalid Kernel1TerminalReaderServiceRequestEnum in State_3_WaitingForGPOResponse:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), kernel1Request.KernelTerminalReaderServiceRequestEnum)); } } else { CardResponse cardResponse = cardQManager.DequeueFromOutput(false); switch (cardResponse.CardInterfaceServiceResponseEnum) { case CardInterfaceServiceResponseEnum.RA: return(EntryPointRA(database, cardResponse, qManager, cardQManager, sw, publicKeyCertificateManager, cardExceptionManager)); case CardInterfaceServiceResponseEnum.L1RSP: return(EntryPointL1RSP(database, cardResponse, qManager)); default: throw new EMVProtocolException("Invalid Kernel1CardinterfaceServiceResponseEnum in State_3_WaitingForGPOResponse:" + Enum.GetName(typeof(CardInterfaceServiceResponseEnum), cardResponse.CardInterfaceServiceResponseEnum)); } } }
private static SignalsEnum EntryPointRA(Kernel1Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager) { if (!cardResponse.ApduResponse.Succeeded) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } bool parsingResult = false; EMVInternalAuthenticateResponse response = cardResponse.ApduResponse as EMVInternalAuthenticateResponse; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { database.AddToList(response.GetTLVSignedApplicationData()); } if (!parsingResult) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag))) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } TLV cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN); byte cid = cidTLV.Value[0]; cid = (byte)(cid >> 6); if (cid == (byte)ACTypeEnum.ARQC) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } #region 3.6.1.1 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true); #endregion #region 3.8.1.1 bool ddaPassed = K3.State_3_4_CommonProcessing.DoOfflineAuth(database, qManager, publicKeyCertificateManager); #endregion if (!ddaPassed) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } if (cid == (byte)ACTypeEnum.TC) { #region 3.9.2 CommonRoutines.CreateEMVDataRecord(database); CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.APPROVED, KernelStatusEnum.READY_TO_READ, null, Kernel2OutcomeStatusEnum.APPROVED, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, ValueQualifierEnum.NONE, null, null, false, KernelCVMEnum.N_A)); #endregion } //declined CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.DECLINED, KernelStatusEnum.READY_TO_READ, null, Kernel2OutcomeStatusEnum.DECLINED, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, ValueQualifierEnum.NONE, null, null, false, KernelCVMEnum.N_A)); }
private static SignalsEnum EntryPointSTOP(Kernel1Database database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE); }
private static SignalsEnum EntryPointDET(Kernel1Database database, KernelRequest kernel1Request) { return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE); }
private static SignalsEnum EntryPointRA(Kernel1Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, CardExceptionManager cardExceptionManager) { if (!cardResponse.ApduResponse.Succeeded) { 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)); } 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 { 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 { TLV aflRaw = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN); if (aflRaw != null) { List <byte[]> bytes = new List <byte[]>(); bytes.Add(new byte[] { (byte)aflRaw.Value.Length }); bytes.Add(aflRaw.Value); database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); return(K1K3.State_3_R1_CommonProcessing.DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, cardResponse)); } else { //GPO and ReadRecords Complete database.NextCommandEnum = NextCommandEnum.NONE; return(State_3_4_CommonProcessing.DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, sw, publicKeyCertificateManager, cardExceptionManager)); } } } }
private static SignalsEnum EntryPointSTOP(Kernel1Database database, KernelQ qManager) { return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.STOP)); }
private static SignalsEnum EntryPointL1RSP(Kernel1Database database, CardResponse cardResponse, KernelQ qManager) { return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.TRY_AGAIN, Kernel2StartEnum.B, cardResponse.L1Enum, L2Enum.NOT_SET, L3Enum.NOT_SET)); }
private static SignalsEnum EntryPointDET(Kernel1Database database, KernelRequest kernel1Request) { database.UpdateWithDETData(kernel1Request.InputData); return(SignalsEnum.WAITING_FOR_GPO_REPONSE); }
public Kernel1(TransactionTypeEnum tt, CardQProcessor cardQProcessor, PublicKeyCertificateManager publicKeyCertificateManager, EntryPointPreProcessingIndicators processingIndicatorsForSelected, CardExceptionManager cardExceptionManager, IConfigurationProvider configProvider) : base(cardQProcessor, publicKeyCertificateManager, processingIndicatorsForSelected, cardExceptionManager, configProvider) { database = new Kernel1Database(processingIndicatorsForSelected, publicKeyCertificateManager); database.InitializeDefaultDataObjects(tt, configProvider); }
private static SignalsEnum EntryPointRA(Kernel1Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager) { if (!cardResponse.ApduResponse.Succeeded) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); } bool parsingResult = false; EMVGenerateACResponse response = cardResponse.ApduResponse as EMVGenerateACResponse; if (cardResponse.ApduResponse.ResponseData.Length > 0 && cardResponse.ApduResponse.ResponseData[0] == 0x77) { parsingResult = database.ParseAndStoreCardResponse(response.ResponseData); } else { 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 { database.AddToList(TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag, response.CryptogramInformationData.Value)); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag, response.ApplicationTransactionCounter.Value)); database.AddToList(TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag, response.ApplicationCryptogram.Value)); database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag, response.IssuerApplicationData.Value)); parsingResult = true; } } if (!parsingResult) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); } if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag))) { return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } #region 3.5.2.2 TLV cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN); byte cid = cidTLV.Value[0]; cid = (byte)(cid >> 6); if (cid != (byte)ACTypeEnum.ARQC) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } #endregion #region 3.6.1.1 CommonRoutines.PostUIOnly(database, qManager, KernelMessageidentifierEnum.CLEAR_DISPLAY, KernelStatusEnum.CARD_READ_SUCCESSFULLY, true); #endregion SignalsEnum result = DoProcessingRestrictions(database, qManager); if (result != SignalsEnum.NONE) { return(result); } #region 3.9 KernelCVMEnum cvm = KernelCVMEnum.N_A; if (database.ProcessingIndicatorsForSelected.ReaderCVMRequiredLimitExceeded) { DoCVMProcessing(database, (ACTypeEnum)GetEnum(typeof(ACTypeEnum), cid)); OUTCOME_PARAMETER_SET_DF8129_KRN2 ops = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database); if (ops.Value.CVM == KernelCVMEnum.NO_CVM) { #region 3.10.3.1 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.PROCESSING_ERROR, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } cvm = ops.Value.CVM; } #endregion #region 3.9.2 CommonRoutines.CreateEMVDataRecord(database); CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.AUTHORISING_PLEASE_WAIT, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.ONLINE_REQUEST, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, ValueQualifierEnum.NONE, null, null, false, cvm)); #endregion }
private static SignalsEnum EntryPointSTOP(Kernel1Database database, KernelQ qManager) { return(SignalsEnum.WAITING_FOR_GEN_AC_1); }
private static SignalsEnum EntryPointDET(Kernel1Database database, KernelRequest kernel1Request) { return(SignalsEnum.WAITING_FOR_GEN_AC_1); }