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 bool DoDEKIfNeeded(KernelDatabaseBase database, KernelQ qManager) { 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); } if (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(true); } return(false); }
private void AddTTL(EMVTagMeta tag, KernelDatabaseBase database) { if (database.IsNotEmpty(tag.Tag)) { Children.AddToList(TLV.Create(tag.Tag, database.Get(tag).Value)); } }
public static byte[] OWHF2AES_8_3(KernelDatabaseBase database, byte[] c) { byte[] oid = new byte[8]; if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) && (database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2).Value[0] & 0x80) == 0x80 && // Permanent slot type (database.Get(EMVTagsEnum.DS_ODS_INFO_DF62_KRN2).Value[0] & 0x40) == 0x40 //Volatile slot type ) { oid = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; } else { oid = database.Get(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2).Value; } List <byte[]> keyComps = new List <byte[]>(); keyComps.Add(c); keyComps.Add(oid); byte[] m = keyComps.SelectMany(x => x).ToArray(); byte[] dsid = database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value; byte[] y = new byte[11]; Array.Copy(dsid, 0, y, 0, y.Length);//this will be padded keyComps = new List <byte[]>(); keyComps.Add(y); keyComps.Add(new byte[] { oid[5], oid[6], oid[7], oid[8] }); keyComps.Add(new byte[] { 0x3F }); byte[] k = keyComps.SelectMany(x => x).ToArray(); Aes aes = Aes.Create(); aes.Key = k; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.None; MemoryStream ms = new MemoryStream(); using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(m, 0, m.Length); } byte[] t = ms.ToArray(); ms.Dispose(); t = XOR(t, m); byte[] r = new byte[8]; Array.Copy(t, 0, r, 0, 8); return(r); }
public static bool DoDDA(KernelDatabaseBase database, KernelQ qManager, CAPublicKeyCertificate capk, TLV sdadTLV) { try { TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.Value.OfflineDataAuthenticationWasPerformed = true; tsi.UpdateDB(); if (database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN) == null) { return(false); } if (capk == null) { return(false); } TLV aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); int length = database.StaticDataToBeAuthenticated.Serialize().Length; if (aip != null && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_SDA_TAG_LIST_9F4A_KRN3.Tag)) { if (2048 - length >= aip.Value.Length) { database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN)); } else { return(false); } } if (sdadTLV != null) { ICCDynamicData iccdd = VerifySAD.VerifySDAD(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadTLV.Value); if (iccdd == null) { return(false); } VerifySAD.AddSDADDataToDatabase(database, iccdd); return(true); } return(false); } catch { return(false); } }
private static EMVGenerateACRequest DoNoIDS(KernelDatabaseBase database) { #region GAC.20 if (GetODAStatus(database) == 0x80) { #region GAC.21 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (tvr.Value.CDAFailed) #endregion { return(DoGAC22_26(database)); } else { #region GAC.24 if (GetDSACType(database) == ACTypeEnum.AAC) #endregion { APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database); #region GAC.25 if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag) && aci.Value.CDAIndicatorEnum == CDAIndicatorEnum.CDA_SUPPORTED_OVER_TC_ARQC_AAC) { #region GAC.27 return(DoIDSReadOnly(database)); #endregion } else { return(DoGAC26(database)); } #endregion } else { #region GAC.27 return(DoIDSReadOnly(database)); #endregion } } } else { return(DoGAC22_26(database)); } #endregion }
public static void ProcessingRestrictions(KernelDatabaseBase database) { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN.Tag)) { #region pre.2 string pvnCard = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_CARD_9F08_KRN).Value); string pvnTerm = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_VERSION_NUMBER_TERMINAL_9F09_KRN).Value); if (pvnCard != pvnTerm) #endregion { #region pre.3 tvr.Value.ICCAndTerminalHaveDifferentApplicationVersions = true; tvr.UpdateDB(); #endregion } } DateTime transactionDate = EMVTagsEnum.TRANSACTION_DATE_9A_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.TRANSACTION_DATE_9A_KRN).Value); DateTime appExpiryDate = EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN).Value); #region pre.4 if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.Tag)) #endregion { DateTime appEffectiveDate = EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN.FormatAsDateTime(database.Get(EMVTagsEnum.APPLICATION_EFFECTIVE_DATE_5F25_KRN).Value); #region pre.5 if (transactionDate < appEffectiveDate) #endregion { #region pre.6 tvr.Value.ApplicationNotYetEffective = true; tvr.UpdateDB(); #endregion } } #region pre.7 if (transactionDate > appExpiryDate) #endregion { #region pre.8 tvr.Value.ExpiredApplication = true; tvr.UpdateDB(); #endregion } #region pre.9 if (database.IsEmpty(EMVTagsEnum.APPLICATION_USAGE_CONTROL_9F07_KRN.Tag)) { return; } #endregion #region pre.10 TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database); ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN atc = new ADDITIONAL_TERMINAL_CAPABILITIES_9F40_KRN(database); APPLICATION_USAGE_CONTROL_9F07_KRN auc = new APPLICATION_USAGE_CONTROL_9F07_KRN(database); if ((tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x15 || tt.Value.TerminalType.Code == 0x16) && atc.Value.IsCash) #endregion { #region pre.12 if (!auc.Value.IsValidAtATMs) #endregion { #region pre.13 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; tvr.UpdateDB(); return; #endregion } } else { #region pre.11 if (!auc.Value.IsValidAtTerminalsOtherThanATMs) #endregion { #region pre.13 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; tvr.UpdateDB(); return; #endregion } } #region pre.14 if (database.IsEmpty(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN.Tag)) { tvr.UpdateDB(); return; } #endregion string tcc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN).Value); string icc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.ISSUER_COUNTRY_CODE_5F28_KRN).Value); byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]; #region pre.15 if (transactionType == (byte)TransactionTypeEnum.CashWithdrawal || transactionType == (byte)TransactionTypeEnum.CashDisbursement) #endregion { #region pre.16 if (tcc == icc) #endregion { #region pre.17 if (!auc.Value.IsValidForDomesticCashTransactions) #endregion { #region pre.19 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; #endregion } } else { #region pre.18 if (!auc.Value.IsValidForInternationalCashTransactions) #endregion { #region pre.19 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; #endregion } } } #region pre.20 if (transactionType == (byte)TransactionTypeEnum.PurchaseGoodsAndServices || transactionType == (byte)TransactionTypeEnum.PurchaseWithCashback) #endregion { #region pre.21 if (tcc == icc) #endregion { #region pre.22 if (!(auc.Value.IsValidForDomesticGoods || auc.Value.IsValidForDomesticServices)) #endregion { #region pre.24 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; #endregion } } else { #region pre.23 if (!(auc.Value.IsValidForInternationalGoods || auc.Value.IsValidForInternationalServices)) #endregion { #region pre.24 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; #endregion } } } #region pre.25 if (database.IsNotPresent(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN.Tag)) { tvr.UpdateDB(); return; } if (Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN).Value) == 0) { tvr.UpdateDB(); return; } #endregion #region pre.26 if (tcc == icc) #endregion { #region pre.27 if (auc.Value.IsDomesticCashbackAllowed) { tvr.UpdateDB(); return; } #endregion } else { #region pre.28 if (auc.Value.IsInternationalCashbackAllowed) { tvr.UpdateDB(); return; } #endregion } #region pre.29 tvr.Value.RequestedServiceNotAllowedForCardProduct = true; tvr.UpdateDB(); #endregion }
public static ACTypeEnum TerminalActionAnalysis(KernelDatabaseBase database) { 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_DENIAL_DF8121_KRN2).Value); #region taa.1 if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DENIAL_9F0E_KRN.Tag)) #endregion { #region taa.4 ulong iacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DENIAL_9F0E_KRN).Value); if (!( ((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0) ) #endregion { #region taa.5 Logger.Log("Declining: !(((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0)):" + ((tacAsNumber | iacAsNumber) & tvrAsNumber)); Logger.Log("tacAsNumber: " + tacAsNumber); Logger.Log("iacAsNumber: " + iacAsNumber); int depth = 0; Logger.Log(tvr.ToPrintString(ref depth)); return(ACTypeEnum.AAC); #endregion } } else { #region taa.2 if (!((tacAsNumber & tvrAsNumber) == 0)) #endregion { #region taa.3 Logger.Log("Declining: !((tacAsNumber & tvrAsNumber) == 0)"); Logger.Log("tacAsNumber: " + tacAsNumber); int depth = 0; Logger.Log(tvr.ToPrintString(ref depth)); return(ACTypeEnum.AAC); #endregion } } #region taa.4.1 TERMINAL_TYPE_9F35_KRN tt = new TERMINAL_TYPE_9F35_KRN(database); if (tt.Value.TerminalType.Code == 0x11 || tt.Value.TerminalType.Code == 0x21 || tt.Value.TerminalType.Code == 0x14 || tt.Value.TerminalType.Code == 0x24 || tt.Value.TerminalType.Code == 0x34) #endregion { #region taa.4.2 return(ACTypeEnum.ARQC); #endregion } #region taa.6 if (tt.Value.TerminalType.Code == 0x23 || tt.Value.TerminalType.Code == 0x26 || tt.Value.TerminalType.Code == 0x36 || tt.Value.TerminalType.Code == 0x13 || tt.Value.TerminalType.Code == 0x16) #endregion { #region taa.13 if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN.Tag)) #endregion { ulong iacDefaultNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN).Value); ulong taDefaultAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_DEFAULT_DF8120_KRN2).Value); #region taa.16 if (((iacDefaultNumber | taDefaultAsNumber) & tvrAsNumber) == 0) #endregion { #region taa.18 return(ACTypeEnum.TC); #endregion } else { #region taa.17 Logger.Log("Declining: ((iacDefaultNumber | taDefaultAsNumber) & tvrAsNumber) == 0"); Logger.Log("iacDefaultNumber: " + iacDefaultNumber); Logger.Log("taDefaultAsNumber: " + taDefaultAsNumber); int depth = 0; Logger.Log(tvr.ToPrintString(ref depth)); return(ACTypeEnum.AAC); #endregion } } else { #region taa.14 if (tvrAsNumber == 0) #endregion { #region taa.15 return(ACTypeEnum.TC); #endregion } else { #region taa.17 Logger.Log("Declining: tvrAsNumber == 0"); int depth = 0; Logger.Log(tvr.ToPrintString(ref depth)); return(ACTypeEnum.AAC); #endregion } } } else { #region taa.7 if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_ONLINE_9F0F_KRN.Tag)) #endregion { ulong iacOnlineNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_ONLINE_9F0F_KRN).Value); ulong tacOnlineAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.TERMINAL_ACTION_CODE_ONLINE_DF8122_KRN2).Value); #region taa.10 if (((tacOnlineAsNumber | iacOnlineNumber) & tvrAsNumber) == 0) #endregion { #region taa.12 return(ACTypeEnum.TC); #endregion } else { #region taa.11 return(ACTypeEnum.ARQC); #endregion } } else { #region taa.8 if (tvrAsNumber == 0) #endregion { #region taa.9 return(ACTypeEnum.TC); #endregion } else { #region taa.11 return(ACTypeEnum.ARQC); #endregion } } } }
internal static EMVGenerateACRequest PrepareGenACCommand(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager) { #region GAC.1 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region GAC.2 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (tvr.Value.CDAFailed) #endregion { return(DoGAC22_26(database)); } else { #region GAC.3 if (database.IsNotEmpty(EMVTagsEnum.DS_ODS_INFO_DF62_KRN2.Tag)) #endregion { #region GAC.4 if (database.IsNotEmpty(EMVTagsEnum.DSDOL_9F5B_KRN2.Tag)) { #region GAC.5 if (database.IsNotEmpty(EMVTagsEnum.DS_AC_TYPE_DF8108_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.DS_ODS_INFO_FOR_READER_DF810A_KRN2.Tag)) #endregion { #region GAC.7 DS_AC_TYPE_DF8108_KRN2 dsactype = new DS_AC_TYPE_DF8108_KRN2(database); if (dsactype.Value.DSACTypeEnum == ACTypeEnum.AAC || GetDSACType(database) == dsactype.Value.DSACTypeEnum || (dsactype.Value.DSACTypeEnum == ACTypeEnum.ARQC && GetDSACType(database) == ACTypeEnum.TC)) { #region GAC.8 SetDSACType(database, dsactype.Value.DSACTypeEnum); #endregion #region GAC.40 return(DoIDSWrite(database)); #endregion } else { #region GAC.9 DS_ODS_INFO_FOR_READER_DF810A_KRN2 dsodsifr = new DS_ODS_INFO_FOR_READER_DF810A_KRN2(database); if ((GetDSACType(database) == ACTypeEnum.AAC && dsodsifr.Value.UsableForAAC) || (GetDSACType(database) == ACTypeEnum.ARQC && dsodsifr.Value.UsableForARQC)) #endregion { #region GAC.40 return(DoIDSWrite(database)); #endregion } else { #region GAC.10 if (dsodsifr.Value.StopIfNoDSODSTerm) #endregion { #region GAC.11 return(GenerateErrorOutput(database, L2Enum.IDS_NO_MATCHING_AC, qManager)); #endregion } else { #region GAC.27 return(DoIDSReadOnly(database)); #endregion } } } #endregion } else { #region GAC.6 return(GenerateErrorOutput(database, L2Enum.IDS_DATA_ERROR, qManager)); #endregion } } else { #region GAC.27 return(DoIDSReadOnly(database)); #endregion } #endregion } else { #region GAC.27 return(DoIDSReadOnly(database)); #endregion } } } else { #region GAC.20 return(DoNoIDS(database)); #endregion } }
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); }
public static bool DoOfflineAuth(KernelDatabaseBase database, KernelQ qManager, PublicKeyCertificateManager pkcm) { try { TLV sdadTLV = database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN); TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN); if (sdadTLV == null && ssadTLV == null) { return(false); } if (database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN) == null) { return(false); } CAPublicKeyCertificate capk = pkcm.GetCAPK(RIDEnum.A000000003, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { return(false); } TLV aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); int length = database.StaticDataToBeAuthenticated.Serialize().Length; if (aip != null && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_SDA_TAG_LIST_9F4A_KRN3.Tag)) { if (2048 - length >= aip.Value.Length) { database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN)); } else { return(false); } } if (sdadTLV != null) { TLV card = database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3); if (card == null || card.Value[0] != 0x01) //check version number of fdda { return(false); } byte[] sdadRaw = database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN).Value; ICCDynamicData iccdd = VerifySAD.VerifySDAD_K3(ICCDynamicDataType.DYNAMIC_NUMBER_ONLY, database, capk, sdadRaw); if (iccdd == null) { return(false); } VerifySAD.AddSDADDataToDatabase(database, iccdd); return(true); } if (ssadTLV != null) { 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) { return(false); } TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN); if (dataAuthenticationCode == null) { dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode); } database.AddToList(dataAuthenticationCode); return(true); } return(false); } catch { return(false); } }
public static byte[] OWHF2_8_2(KernelDatabaseBase database, byte[] pd) { int pl = database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value.Length; byte[] dsid = database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value; byte[] dspkl = new byte[6]; byte[] dspkr = new byte[6]; for (int i = 0; i < 6; i++) { dspkl[i] = (byte)(((dsid[i] / 16) * 10 + (dsid[i] % 16)) * 2); dspkr[i] = (byte)(((dsid[pl - 6 + i] / 16) * 10 + (dsid[pl - 6 + i] % 16)) * 2); } byte[] oid = new byte[8]; if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag) && (database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2).Value[0] & 0x80) == 0x80 && // Permanent slot type (database.Get(EMVTagsEnum.DS_ODS_INFO_DF62_KRN2).Value[0] & 0x40) == 0x40 //Volatile slot type ) { oid = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; } else { oid = database.Get(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2).Value; } byte[] kl = new byte[8]; byte[] kr = new byte[8]; for (int i = 0; i < 6; i++) { kl[i] = dspkl[i]; kr[i] = dspkr[i]; } for (int i = 6; i < 8; i++) { kl[i] = oid[i - 2]; kr[i] = oid[i]; } TripleDES des = TripleDES.Create(); List <byte[]> keyComps = new List <byte[]>(); keyComps.Add(kl); keyComps.Add(kr); keyComps.Add(kl); byte[] key = keyComps.SelectMany(x => x).ToArray(); des.Key = key; des.Mode = CipherMode.CBC; des.Padding = PaddingMode.None; byte[] exOrData = XOR(oid, pd); MemoryStream ms = new MemoryStream(); using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(exOrData, 0, exOrData.Length); } byte[] r = ms.ToArray(); ms.Dispose(); return(XOR(r, pd)); }