public static SignalsEnum DoInvalidResponsePart_C(Kernel2Database database, KernelQ qManager, L1Enum l1Enum, L2Enum l2Enum, L3Enum l3Enum) { #region 9_10.50 CommonRoutines.UpdateUserInterfaceRequestData(database, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY); #endregion #region 9_10.51 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); CommonRoutines.CreateEMVDiscretionaryData(database); if (ids.Value.IsWrite) #endregion { #region 9_10.52 CommonRoutines.CreateEMVDataRecord(database); #endregion } #region 9_10.53 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, l1Enum, null, l2Enum, l3Enum)); #endregion }
private static SignalsEnum EntryPointL1RSP(KernelDatabase database, CardResponse cardResponse, KernelQ qManager) { CommonRoutines.CreateEMVDiscretionaryData(database); CommonRoutines.CreateEMVDataRecord(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, cardResponse.L1Enum, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); }
private static SignalsEnum DoInvalidResponsePart_C(Kernel2Database database, KernelQ qManager, CardResponse cardResponse, KernelMessageidentifierEnum message, L1Enum l1Enum, L2Enum l2Enum, L3Enum l3Enum) { #region 11.90 //done in 11.95 #endregion #region 11.91 IDS_STATUS_DF8128_KRN2.IDS_STATUS_DF8128_KRN2_VALUE idsV = new IDS_STATUS_DF8128_KRN2.IDS_STATUS_DF8128_KRN2_VALUE(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.DataFormatter); idsV.Deserialize(database.TornTempRecord.Children.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag).Value, 0); if (!idsV.IsWrite) #endregion { #region 11.92 database.Get(EMVTagsEnum.TORN_RECORD_FF8101_KRN2).Value = database.TornTempRecord.Value; #endregion } #region 11.93 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); CommonRoutines.CreateEMVDiscretionaryData(database); if (ids.Value.IsWrite) #endregion { #region 11.94 CommonRoutines.CreateEMVDataRecord(database); #endregion } #region 11.95 return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, message, l1Enum, cardResponse.ApduResponse.SW12, l2Enum, l3Enum)); #endregion }
public static SignalsEnum DoInvalidResponsePart_C(KernelDatabase database, KernelQ qManager, L1Enum l1Enum, L2Enum l2Enum, L3Enum l3Enum) { CommonRoutines.UpdateUserInterfaceRequestData(database, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY); CommonRoutines.CreateEMVDiscretionaryData(database); CommonRoutines.CreateEMVDataRecord(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.N_A, KernelStatusEnum.N_A, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, l1Enum, null, l2Enum, l3Enum)); }
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 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)); }
public static SignalsEnum EndOnTCorAAC(KernelDatabase database, KernelQ qManager, CardQ cardQManager) { 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; string tt = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value); if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x40) { k2OutcomeStatus = Kernel2OutcomeStatusEnum.APPROVED; } else { if ((database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN).Value[0] & 0xC0) == 0x80) { throw new EMVProtocolException("Invalid state in EndOnTCorAAC"); } else { k2OutcomeStatus = Kernel2OutcomeStatusEnum.DECLINED; } } 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 (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) { throw new EMVProtocolException("Invalid state in EndOnTCorAAC"); } else { k2MessageIdentifier = KernelMessageidentifierEnum.DECLINED; } } CommonRoutines.CreateEMVDiscretionaryData(database); uiRequestOnOutcomePresent = true; return(CommonRoutines.PostOutcome(database, qManager, k2MessageIdentifier, k2Status, holdTime, k2OutcomeStatus, k2StartStatus, uiRequestOnOutcomePresent, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.NOT_SET, L3Enum.NOT_SET, valueQualifierEnum, valueQualifier, currencyCode, false, cvmEnum)); }
private static SignalsEnum 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); } }
/* * S9.1 */ private static SignalsEnum EntryPointL1RSP(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, TornTransactionLogManager tornTransactionLogManager) { int mnttl = (int)Formatting.ConvertToInt32(database.GetDefault(EMVTagsEnum.MAX_NUMBER_OF_TORN_TRANSACTION_LOG_RECORDS_DF811D_KRN2).Value); #region 9.5 if (!(mnttl > 0 && database.IsNotEmpty(EMVTagsEnum.DRDOL_9F51_KRN2.Tag))) #endregion { #region 9.6 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsWrite) #endregion { #region 9.7 - 9.8 CommonRoutines.CreateEMVDiscretionaryData(database); CommonRoutines.CreateEMVDataRecord(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, cardResponse.L1Enum, null, L2Enum.NOT_SET, L3Enum.NOT_SET)); #endregion } else { #region 9.9 - 9.10 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.NOT_SET, L3Enum.NOT_SET)); #endregion } } #region 9.11 database.TornTempRecord = new TORN_RECORD_FF8101_KRN2(database); database.TornTempRecord.Initialize(); database.TornTempRecord.AddTornTransactionLog(database); #endregion #region 9.13 tornTransactionLogManager.AddTornTransactionLog(database); #endregion { #region 9.14 - 9.15 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)); #endregion } }
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 }
public static SignalsEnum DoCommonProcessing(string source, KernelDatabaseBase databaseIn, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager pkcm, CardExceptionManager cardExceptionManager) { Kernel3Database database = (Kernel3Database)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)); } #region 5.4.3.1 TLV cidTLV = database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN); if (cidTLV == null) { cidTLV = TLV.Create(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag); cidTLV.Val.PackValue(cidTLV.Val.DataFormatter.GetMaxLength()); byte iad = database.Get(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN).Value[4]; Formatting.SetBitPosition(ref cidTLV.Value[0], Formatting.GetBitPosition(iad, 6), 8); Formatting.SetBitPosition(ref cidTLV.Value[0], Formatting.GetBitPosition(iad, 5), 7); database.AddToList(cidTLV); } #endregion #region 5.4.3.2 byte cid = cidTLV.Value[0]; cid = (byte)(cid >> 6); TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN ttq = new TERMINAL_TRANSACTION_QUALIFIERS_9F66_KRN(database); if (cid == (byte)ACTypeEnum.AAC) { database.DeclineRequiredByReaderIndicator = true; } if (cid == (byte)ACTypeEnum.ARQC || ttq.Value.OnlineCryptogramRequired) { database.OnlineRequiredByReaderIndicator = true; } if (cid != (byte)ACTypeEnum.AAC && cid != (byte)ACTypeEnum.ARQC && cid != (byte)ACTypeEnum.TC) { database.DeclineRequiredByReaderIndicator = true; } #endregion #region 5.4.2.1 if (!database.DeclineRequiredByReaderIndicator) { if (!CheckMandatoryFields(database, pkcm)) { 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 (!database.DeclineRequiredByReaderIndicator && !database.OnlineRequiredByReaderIndicator) { #region 5.5.1.1 to 5.5.1.5 SignalsEnum result = DoProcessingRestrictions(database, qManager, cardExceptionManager); if (result != SignalsEnum.NONE) { return(result); } #endregion #region 5.6.1.1, 5.6.1.2 and 5.6.2.1, 5.6.2.1 if (!DoOfflineAuth(database, qManager, pkcm)) #endregion { CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3 ctq = new CARD_TRANSACTION_QUALIFIERS_CTQ_9F6C_KRN3(database); if (ctq.Value.GoOnlineIfOfflineDataAuthenticationFailsAndReaderIsOnlineCapable && !database.ProcessingIndicatorsForSelected.TTQ.Value.OfflineOnlyReader) { database.OnlineRequiredByReaderIndicator = true; } else if (ctq.Value.SwitchInterfaceIfOfflineDataAuthenticationFailsAndReaderSupportsVIS && database.ProcessingIndicatorsForSelected.TTQ.Value.EMVContactChipSupported) { 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, null, L2Enum.TERMINAL_DATA_ERROR, L3Enum.NOT_SET)); } else { database.DeclineRequiredByReaderIndicator = true; } } } #region 5.7.1.1, 5.7.1.2, 5.7.1.3 KernelCVMEnum cvm = KernelCVMEnum.N_A; if (!database.DeclineRequiredByReaderIndicator) { cvm = DoCVMProcessing(database, (ACTypeEnum)Formatting.GetEnum(typeof(ACTypeEnum), cid)); if (cvm == KernelCVMEnum.NO_CVM && ttq.Value.CVMRequired) { database.DeclineRequiredByReaderIndicator = true; } } #endregion #region 4.3.1.1 byte[] currencyCode = null; byte[] balance = null; ValueQualifierEnum vq = ValueQualifierEnum.NONE; if (database.Kernel3Configuration.DisplayAvailableSpendingAmount) { TLV balanceTLV = database.Get(EMVTagsEnum.AVAILABLE_OFFLINE_SPENDING_AMOUNT_AOSA_9F5D_KRN3); if (balanceTLV != null) { vq = ValueQualifierEnum.BALANCE; balance = balanceTLV.Value; currencyCode = database.Get(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN).Value; } } #endregion //#region support for Refunds //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]; //if (transactionType == (byte)TransactionTypeEnum.Refund) // database.DeclineRequiredByReaderIndicator = true; //#endregion #region 5.8.1.1 if (database.OnlineRequiredByReaderIndicator && !database.DeclineRequiredByReaderIndicator) { 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, vq, balance, currencyCode, false, cvm)); } #endregion #region 5.9.1.1 if (!database.OnlineRequiredByReaderIndicator && !database.DeclineRequiredByReaderIndicator) { CommonRoutines.CreateEMVDataRecord(database); CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, cvm == KernelCVMEnum.OBTAIN_SIGNATURE ? KernelMessageidentifierEnum.APPROVED_SIGN : 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, vq, balance, currencyCode, false, cvm)); } #endregion CommonRoutines.CreateEMVDiscretionaryData(database); //#region support for Refunds //if (transactionType == (byte)TransactionTypeEnum.Refund) //#endregion //{ // //CommonRoutines.PostUIOnly(database, qManager, Kernel1MessageidentifierEnum.CLEAR_DISPLAY, Kernel1StatusEnum.N_A, true, new byte[] { 0x00, 0x00, 0x00 }); // CommonRoutines.CreateEMVDataRecord(database); // return CommonRoutines.PostOutcome(database, qManager, // KernelMessageidentifierEnum.N_A, // KernelStatusEnum.N_A, // null, // Kernel2OutcomeStatusEnum.END_APPLICATION, // Kernel2StartEnum.N_A, // true, // KernelMessageidentifierEnum.N_A, // L1Enum.NOT_SET, // null, // L2Enum.NOT_SET, // L3Enum.NOT_SET, // ValueQualifierEnum.NONE, // null, // null, // false, // cvm); //} //else //{ #region 5.9.1.2 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, vq, balance, currencyCode, false, cvm)); #endregion //} }