public static void PackRelatedDataTag(KernelDatabaseBase database, EMVTagMeta tagToPack, TLVList tagListForPack) { TLV tlvRelatedData = database.Get(tagToPack); List <byte[]> tlvRelatedDataBytes = new List <byte[]>(); Logger.Log("Packing tag: " + tagListForPack.ToString()); foreach (TLV tlv in tagListForPack) { TLV valForPackDb = database.Get(tlv.Tag.TagLable); TLV valForPack; if (valForPackDb == null) { valForPack = TLV.Create(tlv.Tag.TagLable); } else { byte[] copyVal = new byte[valForPackDb.Value.Length]; Array.Copy(valForPackDb.Value, copyVal, valForPackDb.Value.Length); valForPack = TLV.Create(tlv.Tag.TagLable, copyVal); } valForPack.Val.PackValue(tlv.Val.GetLength()); Logger.Log("Adding tag: " + valForPack.ToString()); tlvRelatedDataBytes.Add(valForPack.Value); } tlvRelatedData.Value = tlvRelatedDataBytes.SelectMany(a => a).ToArray(); }
public static byte[] PackUdolRelatedDataTag(KernelDatabaseBase database) { TLV udol = database.Get(EMVTagsEnum.UDOL_9F69_KRN2); byte[] udolRelatedData; if (udol == null) { udol = database.Get(EMVTagsEnum.DEFAULT_UDOL_DF811A_KRN2); } udolRelatedData = PackRelatedDataTag(database, udol); return(udolRelatedData); }
public static byte[] PackRelatedDataTag(KernelDatabaseBase database, TLV tagListForPack) { List <byte[]> tlvRelatedDataBytes = new List <byte[]>(); TLVList tags = TLV.DeserializeChildrenWithNoV(tagListForPack.Value, 0); Logger.Log("Packing tag: " + tagListForPack.ToString()); foreach (TLV tlv in tags) { TLV valForPackDb = database.Get(tlv.Tag.TagLable); TLV valForPack; if (valForPackDb == null) { valForPack = TLV.Create(tlv.Tag.TagLable); } else { byte[] copyVal = new byte[valForPackDb.Value.Length]; Array.Copy(valForPackDb.Value, copyVal, valForPackDb.Value.Length); valForPack = TLV.Create(tlv.Tag.TagLable, copyVal); } valForPack.Val.PackValue(tlv.Val.GetLength()); Logger.Log("Adding tag: " + valForPack.ToString()); tlvRelatedDataBytes.Add(valForPack.Value); } return(tlvRelatedDataBytes.SelectMany(a => a).ToArray()); }
private static void AddDDEntry(EMVTagMeta tag, KernelDatabaseBase database) { if (database.IsPresent(tag.Tag)) { database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2).Children.AddToList(TLV.Create(tag.Tag, database.Get(tag).Value)); } }
public static TLV InitializeDiscretionaryData(KernelDatabaseBase database) { TLV disc = database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2); if (disc == null) { disc = TLV.Create(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2.Tag); database.AddToList(disc); } return(disc); }
public static void AddSDADDataToDatabase(KernelDatabaseBase database, ICCDynamicData iccdd) { if (iccdd.ApplicationCryptogram != null) { TLV ac = database.Get(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN); if (ac == null) { ac = TLV.Create(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag); } ac.Value = iccdd.ApplicationCryptogram; database.AddToList(ac); } TLV iccdn = database.Get(EMVTagsEnum.ICC_DYNAMIC_NUMBER_9F4C_KRN); if (iccdn == null) { iccdn = TLV.Create(EMVTagsEnum.ICC_DYNAMIC_NUMBER_9F4C_KRN.Tag); } iccdn.Value = iccdd.ICCDynamicNumber; database.AddToList(iccdn); }
public static void CreateMSDiscretionaryDataRecord(KernelDatabaseBase database) { //Table 4.8 if (database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2) == null) { database.AddToList(TLV.Create(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2.Tag)); } AddDDEntry(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2, database); AddDDEntry(EMVTagsEnum.DD_CARD_TRACK1_DF812A_KRN2, database); AddDDEntry(EMVTagsEnum.DD_CARD_TRACK2_DF812B_KRN2, database); AddDDEntry(EMVTagsEnum.ERROR_INDICATION_DF8115_KRN2, database); AddDDEntry(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2, database); }
public static void PackDSDOLRelatedDataTag(KernelDatabaseBase database) { TLV tlvRelatedData = database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2); if (tlvRelatedData == null) { database.AddToList(TLV.Create(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2.Tag)); tlvRelatedData = database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2); } List <byte[]> tlvRelatedDataBytes = new List <byte[]>(); TLVList tags = TLV.DeserializeChildrenWithNoV(database.Get(EMVTagsEnum.DSDOL_9F5B_KRN2).Value, 0); int count = 1; foreach (TLV tlv in tags) { TLV valForPack = database.Get(tlv.Tag.TagLable); if (valForPack == null) { valForPack = TLV.Create(tlv.Tag.TagLable); } if (count == tags.Count && tlv.Val.GetLength() > valForPack.Value.Length) { tlvRelatedDataBytes.Add(valForPack.Value); } else { valForPack.Val.PackValue(tlv.Val.GetLength()); tlvRelatedDataBytes.Add(valForPack.Value); count++; } Logger.Log("Packing DSDOL, Adding tag: " + valForPack.ToString()); } tlvRelatedData.Value = tlvRelatedDataBytes.SelectMany(a => a).ToArray(); }
public SmartTag(KernelDatabaseBase database, EMVTagMeta emvTagMeta, V value) : base() { this.database = database; EMVTagMeta = emvTagMeta; Tag = new T(EMVTagMeta.Tag); Val = value; TLV tlv = database.Get(EMVTagMeta); if (tlv != null && tlv.Val.Value.Length > 0) { Val.Deserialize(tlv.Val.Serialize(), 0); } }
public virtual void UpdateDB() { if (database == null) { throw new EMVProtocolException("cannot call UpdateDB with database = null"); } TLV tlv = database.Get(EMVTagMeta); if (tlv != null) { tlv.Val.Deserialize(Val.Serialize(), 0); } else { Val.Serialize(); database.AddToList(TLV.Create(this.Tag.TagLable, Val.Value)); } }
public static void CreateMSDataRecord(KernelDatabaseBase database) { //Table 4.10 if (database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) == null) { database.AddToList(TLV.Create(EMVTagsEnum.DATA_RECORD_FF8105_KRN2.Tag)); } AddDREntry(EMVTagsEnum.POINTOFSERVICE_POS_ENTRY_MODE_9F39_KRN, database); AddDREntry(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_LABEL_50_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_PREFERRED_NAME_9F12_KRN, database); AddDREntry(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN, database); AddDREntry(EMVTagsEnum.ISSUER_CODE_TABLE_INDEX_9F11_KRN, database); AddDREntry(EMVTagsEnum.MAGSTRIPE_APPLICATION_VERSION_NUMBER_READER_9F6D_KRN2, database); AddDREntry(EMVTagsEnum.TRACK_1_DATA_56_KRN2, database); AddDREntry(EMVTagsEnum.TRACK_2_DATA_9F6B_KRN2, database); }
public static void CreateEMVDiscretionaryData(KernelDatabaseBase database) { //Table 4.9 if (database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2) == null) { database.AddToList(TLV.Create(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2.Tag)); } AddDDEntry(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2, database); AddDDEntry(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN, database); AddDDEntry(EMVTagsEnum.BALANCE_READ_AFTER_GEN_AC_DF8105_KRN2, database); AddDDEntry(EMVTagsEnum.BALANCE_READ_BEFORE_GEN_AC_DF8104_KRN2, database); AddDDEntry(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2, database); AddDDEntry(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2, database); AddDDEntry(EMVTagsEnum.ERROR_INDICATION_DF8115_KRN2, database); AddDDEntry(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2, database); AddDDEntry(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2, database); AddDDEntry(EMVTagsEnum.THIRD_PARTY_DATA_9F6E_KRN2, database); AddDDEntry(EMVTagsEnum.TORN_RECORD_FF8101_KRN2, database); }
public byte[] BuildStaticDataToBeAuthenticated() { TLV aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); if (aip != null) { TLVList newList = new TLVList(); foreach (TLV tlv in listToManage) { if (tlv.Tag.TagLable != aip.Tag.TagLable) { newList.AddToList(tlv, true); } } if (database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag)) { StringBuilder sb = new StringBuilder(); int depth = 0; sb.Append("Final StaticDataToBeAuthenticatedList (AIP and STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN in DB): \n"); sb.AppendLine(newList.ToPrintString(ref depth)); depth = 1; sb.AppendLine(aip.ToPrintString(ref depth)); Logger.Log(sb.ToString()); return(Formatting.ConcatArrays(newList.Serialize(), aip.Value)); } else { int depth = 0; Logger.Log("Final StaticDataToBeAuthenticatedList: (AIP in DB but No STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN in DB)\n" + ToPrintString(ref depth)); return(newList.Serialize()); } } else { int depth = 0; Logger.Log("Final StaticDataToBeAuthenticatedList (No AIP in DB): \n" + ToPrintString(ref depth)); return(Serialize()); } }
internal bool ConditionsSatisfied(KernelDatabaseBase database, long amountX, long amountY) { byte tt = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]; TERMINAL_TYPE_9F35_KRN.TerminalType terminalType = new TERMINAL_TYPE_9F35_KRN(database).Value.TerminalType; bool isManual = false; byte posEntryMode = database.Get(EMVTagsEnum.POINTOFSERVICE_POS_ENTRY_MODE_9F39_KRN).Value[0]; if (posEntryMode == 0x01) { isManual = true; } long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); bool tccEqualsacc = false; if (database.IsNotEmpty(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN.Tag)) { string tcc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN).Value); string acc = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_CURRENCY_CODE_9F42_KRN).Value); if (tcc == acc) { tccEqualsacc = true; } } switch (CVMConditionCode) { case CVMConditionCode.Always: return(true); case CVMConditionCode.IfUnattendedCash: if (terminalType.AttendedUnattended == TERMINAL_TYPE_9F35_KRN.AttendedUnattended.Unattended && tt == (byte)TransactionTypeEnum.CashWithdrawal) { return(true); } else { return(false); } case CVMConditionCode.IfManualCash: if (isManual && tt == (byte)TransactionTypeEnum.CashWithdrawal) { return(true); } else { return(false); } case CVMConditionCode.IfNotUnattendedCashAndNotManualCashAndNotPurchaseWithCashBack: if (!(terminalType.AttendedUnattended == TERMINAL_TYPE_9F35_KRN.AttendedUnattended.Unattended && tt == (byte)TransactionTypeEnum.CashWithdrawal) && (!(isManual && tt == (byte)TransactionTypeEnum.CashWithdrawal)) && (!(tt == (byte)TransactionTypeEnum.PurchaseWithCashback)) ) { return(true); } else { return(false); } case CVMConditionCode.IfTerminalSupportstheCVM: return(IsSupported(database)); case CVMConditionCode.IfPurchaseWithCashBack: if ((tt == (byte)TransactionTypeEnum.PurchaseWithCashback)) { return(true); } else { return(false); } case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsUnderX: if (tccEqualsacc && aa <= amountX) { return(true); } else { return(false); } case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsOverX: if (tccEqualsacc && aa > amountX) { return(true); } else { return(false); } case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsUnderY: if (tccEqualsacc && aa <= amountY) { return(true); } else { return(false); } case CVMConditionCode.IfTransactionIsInTheApplicationCurrencyAndIsOverY: if (tccEqualsacc && aa > amountY) { return(true); } else { return(false); } default: throw new EMVProtocolException("invalid CVM ConditionCode in Rule"); } }
internal static IssuerPublicKeyCertificate BuildAndValidatePublicKey(KernelDatabaseBase database, byte[] caPublicKeyModulus, byte[] caPublicKeyExponent) { //section 6.3 EMV 4.3 Book 2 TLV issuerPublicKeyCertificate = database.Get(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN); TLV issuerPublicKeyExponent = database.Get(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN); TLV issuerPublicKeyRemainder = database.Get(EMVTagsEnum.ISSUER_PUBLIC_KEY_REMAINDER_92_KRN); if (issuerPublicKeyCertificate.Value.Length != caPublicKeyModulus.Length) { return(null); } byte[] decrypt = DecryptRSA(issuerPublicKeyCertificate.Value, caPublicKeyModulus, caPublicKeyExponent); IssuerPublicKeyCertificate issuerCertData = new IssuerPublicKeyCertificate(decrypt, caPublicKeyModulus.Length, issuerPublicKeyRemainder == null ? new byte[0] : issuerPublicKeyRemainder.Value, issuerPublicKeyExponent.Value); if (issuerCertData.RecoveredDataTrailer != 0xBC) { return(null); } if (issuerCertData.RecoveredDataHeader != 0x6A) { return(null); } if (issuerCertData.CertificateFormat != 0x02) { return(null); } if (!issuerCertData.ValidateHash()) { return(null); } string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value); string issuerIdentifier = Formatting.ByteArrayToHexString(issuerCertData.IssuerIdentifier).Replace("FF", ""); if (!pan.StartsWith(issuerIdentifier)) { return(null); } DateTime expiry = DateTime.ParseExact(Formatting.BcdToString(issuerCertData.ExpiryDate), "MMyy", System.Globalization.CultureInfo.InvariantCulture); //TODO: if you have a test tool trying to use an expired cert then comment this test out or update your test tool //if (expiry <= DateTime.Now) //{ // Logger.Log("Error: Trying to use an expired issuer public key"); // return null; //} //step 10 optional if (issuerCertData.PublicKeyAlgorithmIndicator != 0x01) { return(null); } if (issuerPublicKeyRemainder != null) { issuerCertData.Modulus = Formatting.ConcatArrays(issuerCertData.UnpaddedIssuerPublicKeyorLeftmostDigitsofIssuerPublicKey, issuerPublicKeyRemainder.Value); } else { issuerCertData.Modulus = issuerCertData.UnpaddedIssuerPublicKeyorLeftmostDigitsofIssuerPublicKey; } return(issuerCertData); }
internal static IccPublicKeyCertificate BuildAndValidatePublicKey(KernelDatabaseBase database, StaticDataToBeAuthenticatedList staticDataToBeAuthenticated, byte[] issuerPublicKeyModulus, byte[] issuerPublicKeyExponent) { //section 6.4 EMV 4.3 Book 2 TLV iccPublicKeyCertificate = database.Get(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN); TLV iccPublicKeyExponent = database.Get(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN); TLV iccPublicKeyRemainder = database.Get(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_REMAINDER_9F48_KRN); if (iccPublicKeyCertificate.Value.Length != issuerPublicKeyModulus.Length) { return(null); } byte[] decrypt = DecryptRSA(iccPublicKeyCertificate.Value, issuerPublicKeyModulus, issuerPublicKeyExponent); IccPublicKeyCertificate iccCertData = new IccPublicKeyCertificate(decrypt, issuerPublicKeyModulus.Length, iccPublicKeyRemainder == null ? new byte[0] : iccPublicKeyRemainder.Value, iccPublicKeyExponent.Value, database.StaticDataToBeAuthenticated.BuildStaticDataToBeAuthenticated()); if (iccCertData.RecoveredDataTrailer != 0xBC) { return(null); } if (iccCertData.RecoveredDataHeader != 0x6A) { return(null); } if (iccCertData.CertificateFormat != 0x04) { return(null); } if (!iccCertData.ValidateHash()) { return(null); } string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value); string panToCompare = Formatting.ByteArrayToHexString(iccCertData.ApplicationPAN).Replace("FF", ""); if (!pan.StartsWith(panToCompare)) { return(null); } DateTime expiry = DateTime.ParseExact(Formatting.BcdToString(iccCertData.ExpiryDate), "MMyy", System.Globalization.CultureInfo.InvariantCulture); //TODO: if you have a test tool trying to use an expired cert then comment this test out or update your test tool //if (expiry <= DateTime.Now) //{ // Logger.Log("Error: Trying to use an expired issuer public key"); // return null; //} if (iccCertData.PublicKeyAlgorithmIndicator != 0x01) { return(null); } if (iccPublicKeyRemainder != null) { iccCertData.Modulus = Formatting.ConcatArrays(iccCertData.UnpaddedICCPublicKeyorLeftmostDigitsofIssuerPublicKey, iccPublicKeyRemainder.Value); } else { iccCertData.Modulus = iccCertData.UnpaddedICCPublicKeyorLeftmostDigitsofIssuerPublicKey; } return(iccCertData); }
internal static IccPinKeyCertificate BuildAndValidatePublicKey(KernelDatabaseBase database, byte[] issuerPublicKeyModulus, byte[] issuerPublicKeyExponent) { TLV iccPinKeyCertificate = database.Get(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PIN_ENCIPHERMENT_PUBLIC_KEY_CERTIFICATE_9F2D_KRN); if (iccPinKeyCertificate == null) { return(null); } TLV iccPinKeyExponent = database.Get(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PIN_ENCIPHERMENT_PUBLIC_KEY_EXPONENT_9F2E_KRN); if (iccPinKeyExponent == null) { return(null); } TLV iccPinKeyRemainder = database.Get(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PIN_ENCIPHERMENT_PUBLIC_KEY_REMAINDER_9F2F_KRN); if (iccPinKeyRemainder == null) { return(null); } if (iccPinKeyCertificate.Value.Length != issuerPublicKeyModulus.Length) { return(null); } byte[] decrypt = DecryptRSA(iccPinKeyCertificate.Value, issuerPublicKeyModulus, issuerPublicKeyExponent); IccPinKeyCertificate iccCertData = new IccPinKeyCertificate(decrypt, issuerPublicKeyModulus.Length, iccPinKeyRemainder == null ? new byte[0] : iccPinKeyRemainder.Value, iccPinKeyExponent.Value); if (iccCertData.RecoveredDataTrailer != 0xBC) { return(null); } if (iccCertData.RecoveredDataHeader != 0x6A) { return(null); } if (iccCertData.CertificateFormat != 0x04) { return(null); } if (!iccCertData.ValidateHash()) { return(null); } string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value); string panToCompare = Formatting.ByteArrayToHexString(iccCertData.ApplicationPAN).Replace("FF", ""); if (!pan.StartsWith(panToCompare)) { return(null); } DateTime expiry = DateTime.ParseExact(Formatting.BcdToString(iccCertData.ExpiryDate), "MMyy", System.Globalization.CultureInfo.InvariantCulture); if (expiry <= DateTime.Now) { return(null); } if (iccCertData.PublicKeyAlgorithmIndicator != 0x01) { return(null); } if (iccPinKeyRemainder != null) { iccCertData.Modulus = Formatting.ConcatArrays(iccCertData.UnpaddedICCPinKeyorLeftmostDigitsofIssuerPublicKey, iccPinKeyRemainder.Value); } else { iccCertData.Modulus = iccCertData.UnpaddedICCPinKeyorLeftmostDigitsofIssuerPublicKey; } return(iccCertData); }
public static void CreateEMVDataRecord(KernelDatabaseBase database) { //Table 4.7 if (database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) == null) { database.AddToList(TLV.Create(EMVTagsEnum.DATA_RECORD_FF8105_KRN2.Tag)); } CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline && cvr.Value.GetCVMResult() != CVMResult.Failed) { AddDREntry(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN, database); } AddDREntry(EMVTagsEnum.POINTOFSERVICE_POS_ENTRY_MODE_9F39_KRN, database); AddDREntry(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN, database); AddDREntry(EMVTagsEnum.AMOUNT_OTHER_NUMERIC_9F03_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_LABEL_50_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_PREFERRED_NAME_9F12_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_USAGE_CONTROL_9F07_KRN, database); AddDREntry(EMVTagsEnum.APPLICATION_VERSION_NUMBER_TERMINAL_9F09_KRN, database); AddDREntry(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN, database); AddDREntry(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN, database); AddDREntry(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN, database); AddDREntry(EMVTagsEnum.INTERFACE_DEVICE_IFD_SERIAL_NUMBER_9F1E_KRN, database); AddDREntry(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN, database); AddDREntry(EMVTagsEnum.ISSUER_CODE_TABLE_INDEX_9F11_KRN, database); AddDREntry(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN, database); AddDREntry(EMVTagsEnum.TERMINAL_COUNTRY_CODE_9F1A_KRN, database); AddDREntry(EMVTagsEnum.TERMINAL_TYPE_9F35_KRN, database); AddDREntry(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN, database); AddDREntry(EMVTagsEnum.TRACK_2_EQUIVALENT_DATA_57_KRN, database); AddDREntry(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN, database); AddDREntry(EMVTagsEnum.TRANSACTION_DATE_9A_KRN, database); AddDREntry(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN, database); AddDREntry(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN, database); AddDREntry(EMVTagsEnum.TRANSACTION_STATUS_INFORMATION_9B_KRN, database); #region c-3 kernel 3 req 3.2.1.3 AddDREntry(EMVTagsEnum.PAYMENT_ACCOUNT_REFERENCE_9F24_KRN, database); #endregion //Kernel 2 AddDREntry(EMVTagsEnum.TRANSACTION_CATEGORY_CODE_9F53_KRN2, database); //Kernel 3 #region c-3 kernel 3 req 3.2.1.2 AddDREntry(EMVTagsEnum.FORM_FACTOR_INDICATOR_FFI_9F6E_KRN3, database); AddDREntry(EMVTagsEnum.CUSTOMER_EXCLUSIVE_DATA_CED_9F7C_KRN3, database); #endregion #region c-3 kernel 3 req 4.1.1.1 TLV ffi = database.Get(EMVTagsEnum.FORM_FACTOR_INDICATOR_FFI_9F6E_KRN3); if (ffi != null) { ffi.Value[3] = (byte)(ffi.Value[3] & 0xF0);//indicating that the transaction was conducted using [ISO 14443] } #endregion }
public static ICCDynamicData VerifySDAD_K3(ICCDynamicDataType iccDDType, KernelDatabaseBase database, CAPublicKeyCertificate caPublicKey, byte[] sdadRaw) { //section 6.5.2 of EMV book 2 - DDA //1.If the Signed Dynamic Application Data has a length different from the //length of the ICC Public Key Modulus, CDA has failed IssuerPublicKeyCertificate ipk = IssuerPublicKeyCertificate.BuildAndValidatePublicKey(database, caPublicKey.Modulus, caPublicKey.Exponent); if (ipk == null) { return(null); } IccPublicKeyCertificate iccpk = IccPublicKeyCertificate.BuildAndValidatePublicKey(database, database.StaticDataToBeAuthenticated, ipk.Modulus, ipk.Exponent); if (iccpk == null) { return(null); } if (sdadRaw.Length != iccpk.Modulus.Length) { return(null); } //2.To obtain the recovered data specified in Table 22, apply the recovery //function as specified in Annex A2.1 on the Signed Dynamic Application //Data using the ICC Public Key in conjunction with the corresponding //algorithm.If the Recovered Data Trailer is not equal to 'BC', CDA has //failed byte[] decrypted = PublicKeyCertificate.DecryptRSA(sdadRaw, iccpk.Modulus, iccpk.Exponent); SDAD sdad = new SDAD(decrypted); //3.Check the Recovered Data Header. If it is not '6A', CDA has failed. if (sdad.DataHeader != 0x6A) { return(null); } //4.Check the Signed Data Format. If it is not '05', CDA has failed. //For Visa specialpurpose readers it may return 0x95 iff offline data authentication is supported for online transactions (in the TTQ) if (sdad.SignedDataFormat != 0x05 && sdad.SignedDataFormat != 0x95) { return(null); } ICCDynamicData iccDD = new ICCDynamicData(database, sdad.ICCDynamicData, iccDDType); //5.Concatenate from left to right the second to the sixth data elements in //Table 17(that is, Signed Data Format through Pad Pattern), followed by //the data elements specified by the DDOL. //C.1 K3 Kernel wants it done this way rather than they way sepecified in step 5 //The Terminal Dynamic Data elements input to the hash algorithm shall be as //specified in Table C-1 instead of being specified in the DDOL(as the DDOL is //not a recognized data element for Kernel 3).The kernel may treat the tags //specified in Table C-1 as default DDOLs for fDDA version '01' List <byte[]> hashList = new List <byte[]> { database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value, database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value, database.Get(EMVTagsEnum.TRANSACTION_CURRENCY_CODE_5F2A_KRN).Value, database.Get(EMVTagsEnum.CARD_AUTHENTICATION_RELATED_DATA_9F69_KRN3).Value }; //6.Apply the indicated hash algorithm(derived from the Hash Algorithm //Indicator) to the result of the concatenation of the previous step to //produce the hash result. byte[] dataForHash = sdad.Concat(hashList.SelectMany(x => x).ToArray()); byte[] hash = SHA1.Create().ComputeHash(dataForHash); //7.Compare the calculated hash result from the previous step with the //recovered Hash Result.If they are not the same, DDA has failed. if (Formatting.ByteArrayToHexString(sdad.HashResult) != Formatting.ByteArrayToHexString(hash)) { return(null); } return(iccDD); }
public static ICCDynamicData VerifySDAD(ICCDynamicDataType iccDDType, bool isFirstGenAC, KernelDatabaseBase database, StaticDataToBeAuthenticatedList staticDataToBeAuthenticated, CAPublicKeyCertificate caPublicKey, CardResponse genACCardResponse) { EMVGenerateACResponse genAcResponse = (genACCardResponse.ApduResponse as EMVGenerateACResponse); //section 6.6.2 of EMV book 2 - CDA //1.If the Signed Dynamic Application Data has a length different from the //length of the ICC Public Key Modulus, CDA has failed byte[] sdadRaw = genAcResponse.SignedDynamicApplicationData.Value; IssuerPublicKeyCertificate ipk = IssuerPublicKeyCertificate.BuildAndValidatePublicKey(database, caPublicKey.Modulus, caPublicKey.Exponent); if (ipk == null) { return(null); } IccPublicKeyCertificate iccpk = IccPublicKeyCertificate.BuildAndValidatePublicKey(database, staticDataToBeAuthenticated, ipk.Modulus, ipk.Exponent); if (iccpk == null) { return(null); } if (sdadRaw.Length != iccpk.Modulus.Length) { return(null); } //2.To obtain the recovered data specified in Table 22, apply the recovery //function as specified in Annex A2.1 on the Signed Dynamic Application //Data using the ICC Public Key in conjunction with the corresponding //algorithm.If the Recovered Data Trailer is not equal to 'BC', CDA has //failed byte[] decrypted = PublicKeyCertificate.DecryptRSA(sdadRaw, iccpk.Modulus, iccpk.Exponent); SDAD sdad = new SDAD(decrypted); //3.Check the Recovered Data Header. If it is not '6A', CDA has failed. if (sdad.DataHeader != 0x6A) { return(null); } //4.Check the Signed Data Format. If it is not '05', CDA has failed. if (sdad.SignedDataFormat != 0x05) { return(null); } //5. Retrieve from the ICC Dynamic Data the data specified in Table 19 ICCDynamicData iccDD = new ICCDynamicData(database, sdad.ICCDynamicData, iccDDType); //6.Check that the Cryptogram Information Data retrieved from the ICC //Dynamic Data is equal to the Cryptogram Information Data obtained from //the response to the GENERATE AC command. If this is not the case, CDA //has failed. if (genAcResponse.CryptogramInformationData.Value[0] != iccDD.CryptogramInformationData) { return(null); } //7.Concatenate from left to right the second to the sixth data elements in //Table 22(that is, Signed Data Format through Pad Pattern), followed by //the Unpredictable Number. byte[] unpredicatbleNumber = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value; byte[] dataForHash = sdad.Concat(unpredicatbleNumber); //8.Apply the indicated hash algorithm (derived from the Hash Algorithm //Indicator) to the result of the concatenation of the previous step to //produce the hash result. byte[] hash = SHA1.Create().ComputeHash(dataForHash); //9.Compare the calculated hash result from the previous step with the //recovered Hash Result.If they are not the same, CDA has failed. if (Formatting.ByteArrayToHexString(sdad.HashResult) != Formatting.ByteArrayToHexString(hash)) { return(null); } //10. Concatenate from left to right the values of the following data elements: List <byte[]> result = new List <byte[]>(); if (isFirstGenAC) { //-The values of the data elements specified by, and in the order they //appear in the PDOL, and sent by the terminal in the GET //PROCESSING OPTIONS command. result.Add(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2).Value); //-The values of the data elements specified by, and in the order they //appear in the CDOL1, and sent by the terminal in the first //GENERATE AC command. result.Add(database.Get(EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2).Value); //-The tags, lengths, and values of the data elements returned by the ICC //in the response to the GENERATE AC command in the order they are //returned, with the exception of the Signed Dynamic Application Data. foreach (TLV tlv in genAcResponse.GetResponseTags()) { if (tlv.Tag.TagLable != EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag) { result.Add(tlv.Serialize()); } } } else { //-The values of the data elements specified by, and in the order they //appear in the PDOL, and sent by the terminal in the GET //PROCESSING OPTIONS command. result.Add(database.Get(EMVTagsEnum.PDOL_RELATED_DATA_DF8111_KRN2).Value); //-The values of the data elements specified by, and in the order they //appear in the CDOL1, and sent by the terminal in the first //GENERATE AC command. result.Add(database.Get(EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2).Value); //-The values of the data elements specified by, and in the order they //appear in the CDOL2, and sent by the terminal in the second //GENERATE AC command. TLV cdol2 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_2_CDOL2_8D_KRN); if (cdol2 != null) { result.Add(CommonRoutines.PackRelatedDataTag(database, cdol2)); } //-The tags, lengths, and values of the data elements returned by the ICC //in the response to the GENERATE AC command in the order they are //returned, with the exception of the Signed Dynamic Application Data. foreach (TLV tlv in genAcResponse.GetResponseTags()) { if (tlv.Tag.TagLable != EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag) { result.Add(tlv.Serialize()); } } } byte[] transactionHashData = result.SelectMany(a => a).ToArray(); //11.Apply the indicated hash algorithm (derived from the Hash Algorithm //Indicator) to the result of the concatenation of the previous step to //produce the Transaction Data Hash Code. byte[] transactionHash = SHA1.Create().ComputeHash(transactionHashData); //12.Compare the calculated Transaction Data Hash Code from the previous //step with the Transaction Data Hash Code retrieved from the ICC //Dynamic Data in Step 5.If they are not the same, CDA has failed. if (Formatting.ByteArrayToHexString(iccDD.TransactionDataHashCode) != Formatting.ByteArrayToHexString(transactionHash)) { return(null); } return(iccDD); }
public static void CVMSelection(KernelDatabaseBase database, Func <bool> kernelSupportedCallback) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmResults = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); //#region support for Refunds pg 177 //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]; //if (transactionType == (byte)TransactionTypeEnum.Refund) //{ // Do_CVM_14(database, cvmResults); // return; //} //#endregion APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); KernelCVMEnum cvmEnum = KernelCVMEnum.N_A; CardHolderVerificationRule cvrCurrentlySelected; if (aip.Value.OnDeviceCardholderVerificationIsSupported && kernelSupportedCallback.Invoke()) { #region cvm.2 long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long rcvml = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value); if (aa > rcvml) #endregion { #region cvm.4 cvmEnum = KernelCVMEnum.CONFIRMATION_CODE_VERIFIED; cvmResults.Value.CVMPerformed = 0x01; //on-device cardholder verification performed cvmResults.Value.CVMCondition = 0x00; cvmResults.Value.CVMResult = 0x02; //successful CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum); cvmResults.UpdateDB(); return; #endregion } else { #region cvm.3 cvmEnum = KernelCVMEnum.NO_CVM; cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed cvmResults.Value.CVMCondition = 0x00; cvmResults.Value.CVMResult = 0x02; //successful CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum); cvmResults.UpdateDB(); return; #endregion } } #region cvm.5 if (!aip.Value.CardholderVerificationIsSupported) #endregion { #region cvm.6 cvmEnum = KernelCVMEnum.NO_CVM; cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed cvmResults.Value.CVMCondition = 0x00; cvmResults.Value.CVMResult = 0x00; //unknown CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum); cvmResults.UpdateDB(); return; #endregion } #region cvm.7 if (database.IsNotPresent(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN.Tag) || database.IsEmpty(EMVTagsEnum.CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN.Tag)) #endregion { #region cvm.8 cvmEnum = KernelCVMEnum.NO_CVM; cvmResults.Value.CVMPerformed = 0x3F; //No CVM performed cvmResults.Value.CVMCondition = 0x00; cvmResults.Value.CVMResult = 0x00; //unknown CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum); cvmResults.UpdateDB(); tvr.Value.ICCDataMissing = true; tvr.UpdateDB(); return; #endregion } #region cvm.9 CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN cvl = new CARDHOLDER_VERIFICATION_METHOD_CVM_LIST_8E_KRN(database); #endregion BackToIterate: CVMListIterationReturn result; do { cvrCurrentlySelected = cvl.Value.CardHolderVerificationRules[database.CVMCurrentlySelectedCounter]; #region cvm.10 cvm.11 result = IterateCVM(database, cvrCurrentlySelected, cvl.Value.AmountX, cvl.Value.AmountY); #endregion database.CVMCurrentlySelectedCounter++; #region cvm.12 cvm.13 } while (database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count && result != CVMListIterationReturn.ConditionsMet); #endregion if (result != CVMListIterationReturn.ConditionsMet) { Do_CVM_14(database, cvmResults); return; } #region cvm.15 if (!cvrCurrentlySelected.IsCVMRecognised()) #endregion { #region cvm.16 tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.UnrecognisedCVM = true; tvr.UpdateDB(); #endregion } else { #region cvm.17 if (cvrCurrentlySelected.IsSupported(database) && cvrCurrentlySelected.GetCVMCode() != (byte)CVMCode.FailCVMProcessing) #endregion { #region cvm.18 and from EMV Book 3 Section 10.5 switch ((byte)(cvrCurrentlySelected.CVMRule & 0x3F)) { //Pin processing (U,X,Z) continues in PinProcessing Procedure after CVM Selection case (byte)CVMCode.EncipheredPINVerifiedOnline: cvmEnum = KernelCVMEnum.ONLINE_PIN; cvmResults.Value.CVMResult = 0x00; //unknown tvr.Value.OnlinePINEntered = true; break; case (byte)CVMCode.EncipheredPINVerificationPerformedByICC: case (byte)CVMCode.PlaintextPINVerificationPerformedByICC: cvmEnum = KernelCVMEnum.OFFLINE_PIN; cvmResults.Value.CVMResult = 0x00; //unknown break; case (byte)CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper: case (byte)CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper: cvmEnum = KernelCVMEnum.COMBO; cvmResults.Value.CVMResult = 0x00; //unknown break; //V in diagram case (byte)CVMCode.Signature_Paper: cvmEnum = KernelCVMEnum.OBTAIN_SIGNATURE; cvmResults.Value.CVMResult = 0x00; //unknown CommonRoutines.UpdateOutcomeParameterSet(database, true); break; //W in diagram case (byte)CVMCode.NoCVMRequired: cvmEnum = KernelCVMEnum.NO_CVM; cvmResults.Value.CVMResult = 0x02; //successful break; case (byte)CVMCode.RFU: cvmEnum = KernelCVMEnum.N_A; tvr.Value.UnrecognisedCVM = true; cvmResults.Value.CVMResult = 0x01; //failed break; default: goto BackToIterate; } #endregion cvmResults.Value.CVMPerformed = cvrCurrentlySelected.CVMRule; cvmResults.Value.CVMCondition = (byte)cvrCurrentlySelected.CVMConditionCode; cvmResults.UpdateDB(); int depth = 0; Logger.Log(cvmResults.ToPrintString(ref depth)); CommonRoutines.UpdateOutcomeParameterSet(database, cvmEnum); tvr.UpdateDB(); return; } } #region cvm.19 if (((byte)cvrCurrentlySelected.CVMConditionCode & 0x40) == (byte)CVMFailureCondition.ApplySucceedingCVRuleIfThisCVMIsUnsuccessful) #endregion { #region cvm.20 if (database.CVMCurrentlySelectedCounter < cvl.Value.CardHolderVerificationRules.Count) #endregion { #region cvm.10 goto BackToIterate; #endregion } else { Do22_25(database, cvrCurrentlySelected); return; } } else { Do22_25(database, cvrCurrentlySelected); return; } }
public static ICCDynamicData VerifySDAD(ICCDynamicDataType iccDDType, KernelDatabaseBase database, CAPublicKeyCertificate caPublicKey, byte[] sdadRaw) { //section 6.5.2 of EMV book 2 - DDA //1.If the Signed Dynamic Application Data has a length different from the //length of the ICC Public Key Modulus, CDA has failed IssuerPublicKeyCertificate ipk = IssuerPublicKeyCertificate.BuildAndValidatePublicKey(database, caPublicKey.Modulus, caPublicKey.Exponent); if (ipk == null) { return(null); } IccPublicKeyCertificate iccpk = IccPublicKeyCertificate.BuildAndValidatePublicKey(database, database.StaticDataToBeAuthenticated, ipk.Modulus, ipk.Exponent); if (iccpk == null) { return(null); } if (sdadRaw.Length != iccpk.Modulus.Length) { return(null); } //2.To obtain the recovered data specified in Table 22, apply the recovery //function as specified in Annex A2.1 on the Signed Dynamic Application //Data using the ICC Public Key in conjunction with the corresponding //algorithm.If the Recovered Data Trailer is not equal to 'BC', CDA has //failed byte[] decrypted = PublicKeyCertificate.DecryptRSA(sdadRaw, iccpk.Modulus, iccpk.Exponent); SDAD sdad = new SDAD(decrypted); //3.Check the Recovered Data Header. If it is not '6A', CDA has failed. if (sdad.DataHeader != 0x6A) { return(null); } //4.Check the Signed Data Format. If it is not '05', CDA has failed. //For Visa specialpurpose readers it may return 0x95 iff offline data authentication is supported for online transactions (in the TTQ) if (sdad.SignedDataFormat != 0x05 && sdad.SignedDataFormat != 0x95) { return(null); } ICCDynamicData iccDD = new ICCDynamicData(database, sdad.ICCDynamicData, iccDDType); //5.Concatenate from left to right the second to the sixth data elements in //Table 17(that is, Signed Data Format through Pad Pattern), followed by //the data elements specified by the DDOL. TLV ddol = database.Get(EMVTagsEnum.DYNAMIC_DATA_AUTHENTICATION_DATA_OBJECT_LIST_DDOL_9F49_KRN); byte[] ddolRelatedData; if (ddol == null) { TLV unpred = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN); unpred.Val.PackValue(unpred.Val.GetLength()); ddolRelatedData = unpred.Value; } else { ddolRelatedData = CommonRoutines.PackRelatedDataTag(database, ddol); } byte[] dataForHash = sdad.Concat(ddolRelatedData); //6.Apply the indicated hash algorithm(derived from the Hash Algorithm //Indicator) to the result of the concatenation of the previous step to //produce the hash result. byte[] hash = SHA1.Create().ComputeHash(dataForHash); //7.Compare the calculated hash result from the previous step with the //recovered Hash Result.If they are not the same, DDA has failed. if (Formatting.ByteArrayToHexString(sdad.HashResult) != Formatting.ByteArrayToHexString(hash)) { return(null); } return(iccDD); }
internal static SignalsEnum PostOutcome(KernelDatabaseBase database, KernelQ qManager, KernelMessageidentifierEnum uiMessage, KernelStatusEnum uiStatus, byte[] holdTime, Kernel2OutcomeStatusEnum status, Kernel2StartEnum start, bool?isUIRequestOnOutcomePresent, KernelMessageidentifierEnum messageOnError, L1Enum l1Enum, byte[] SW12, L2Enum l2Enum, L3Enum l3Enum, ValueQualifierEnum valueQualifierEnum, byte[] valueQualifier, byte[] currencyCode, bool receipt, KernelCVMEnum cvmStatus) { if (messageOnError != KernelMessageidentifierEnum.N_A || l1Enum != L1Enum.NOT_SET || l2Enum != L2Enum.NOT_SET || l3Enum != L3Enum.NOT_SET) { TLV disc = InitializeDiscretionaryData(database); ERROR_INDICATION_DF8115_KRN2 kei = new ERROR_INDICATION_DF8115_KRN2(database); kei.Value.MsgOnError = messageOnError; kei.Value.L1Enum = l1Enum; kei.Value.L2Enum = l2Enum; kei.Value.L3Enum = l3Enum; if (SW12 != null) { kei.Value.SW12 = SW12; } kei.UpdateDB(); disc.Children.AddToList(kei); disc.Serialize(); } if (uiMessage != KernelMessageidentifierEnum.N_A || uiStatus != KernelStatusEnum.N_A) { USER_INTERFACE_REQUEST_DATA_DF8116_KRN2 uird = new USER_INTERFACE_REQUEST_DATA_DF8116_KRN2(database); uird.Value.KernelMessageidentifierEnum = uiMessage; uird.Value.KernelStatusEnum = uiStatus; if (holdTime == null) { TLV holdTimeTLV = database.GetDefault(EMVTagsEnum.MESSAGE_HOLD_TIME_DF812D_KRN2); if (holdTimeTLV != null) { holdTime = holdTimeTLV.Value; } else { holdTime = new byte[] { 0x00, 0x00, 0x00 } }; } uird.Value.HoldTime = holdTime; if (valueQualifier != null) { uird.Value.ValueQualifier = valueQualifier; } uird.Value.ValueQualifierEnum = valueQualifierEnum; if (currencyCode != null) { uird.Value.CurrencyCode = currencyCode; } uird.UpdateDB(); } OUTCOME_PARAMETER_SET_DF8129_KRN2 kops = new OUTCOME_PARAMETER_SET_DF8129_KRN2(database); kops.Value.Status = status; kops.Value.Start = start; if (isUIRequestOnOutcomePresent == null) { kops.Value.UIRequestOnOutcomePresent = isUIRequestOnOutcomePresent == false; kops.Value.UIRequestOnRestartPresent = isUIRequestOnOutcomePresent == false; } else { kops.Value.UIRequestOnOutcomePresent = isUIRequestOnOutcomePresent == true ? true : false; kops.Value.UIRequestOnRestartPresent = isUIRequestOnOutcomePresent == true ? false : true; } kops.Value.DataRecordPresent = database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) != null ? true : false; kops.Value.DiscretionaryDataPresent = database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2) != null ? true : false; //kops.Value.Receipt = receipt; kops.Value.CVM = cvmStatus; kops.UpdateDB(); qManager.EnqueueToOutput(new KernelOUTResponse( database.Get(EMVTagsEnum.OUTCOME_PARAMETER_SET_DF8129_KRN2), database.Get(EMVTagsEnum.ERROR_INDICATION_DF8115_KRN2), database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2), database.Get(EMVTagsEnum.DISCRETIONARY_DATA_FF8106_KRN2), database.Get(EMVTagsEnum.USER_INTERFACE_REQUEST_DATA_DF8116_KRN2))); return(SignalsEnum.STOP); }