private static bool VerifySDAD_Summaries_42(Kernel2Database database, CAPublicKeyCertificate capk, CardResponse cardResponse) { ICCDynamicData iccdd = VerifySAD.VerifySDAD(ICCDynamicDataType.IDS, true, database, database.StaticDataToBeAuthenticated, capk, cardResponse); if (iccdd == null) { return(false); } AddSDADDataToDatabase(database, iccdd); TLV ds2 = database.Get(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2); TLV ds3 = database.Get(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2); if (ds2 == null && iccdd.DSSummary2 != null) { ds2 = TLV.Create(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2.Tag); } if (ds3 == null && iccdd.DSSummary3 != null) { ds3 = TLV.Create(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2.Tag); } if (iccdd.DSSummary2 != null) { ds2.Value = iccdd.DSSummary2; } if (iccdd.DSSummary3 != null) { ds3.Value = iccdd.DSSummary3; } return(true); }
private static bool VerifySDAD_9_10__4(Kernel2Database database, CAPublicKeyCertificate capk, CardResponse cardResponse) { ICCDynamicData iccdd = VerifySAD.VerifySDAD(ICCDynamicDataType.NO_IDS_OR_RRP, true, database, database.StaticDataToBeAuthenticated, capk, cardResponse); if (iccdd == null) { return(false); } VerifySAD.AddSDADDataToDatabase(database, iccdd); return(true); }
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 SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, PublicKeyCertificateManager pkcm, EMVSelectApplicationResponse emvSelectApplicationResponse, Stopwatch sw) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); EMVGetChallengeResponse response = (EMVGetChallengeResponse)cardResponse.ApduResponse; if (!response.Succeeded) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //store the challenge byte[] pinChallenge = response.ResponseData; if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper) { string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); CAPublicKeyCertificate capk = pkcm.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); byte[] pinBlock = PinProcessing.BuildPlainTextPinBlock(pin); //encrypt the pin byte[] encipheredPin = PinProcessing.BuildPinVerifyData(database, capk, pinBlock, pinChallenge); if (encipheredPin == null) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //fire off verify for enciphered pin EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Enciphered_PIN, encipheredPin); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); } //verify message for plain text pin fired in waiting for pin response return(SignalsEnum.WAITING_FOR_VERIFY); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { 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)); } EMVInternalAuthenticateResponse response = cardResponse.ApduResponse as EMVInternalAuthenticateResponse; 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]); #region 3.8.1.1 bool ddaPassed = DoDDA(database, qManager, capk, response.GetTLVSignedApplicationData()); #endregion if (!ddaPassed) { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.DDAFailed = true; tvr.UpdateDB(); } TLV cdol1 = database.Get(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN); CommonRoutines.PackRelatedDataTag(database, EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2, cdol1); REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpST = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(database); rcpST.Value.ACTypeEnum = database.ACType.Value.DSACTypeEnum; rcpST.Value.CDASignatureRequested = false; rcpST.UpdateDB(); EMVGenerateACRequest request = new EMVGenerateACRequest(database.Get(EMVTagsEnum.CDOL1_RELATED_DATA_DF8107_KRN2), null, rcpST); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); }
private static bool VerifySDAD_CheckRelayData_43_1(Kernel2Database database, CAPublicKeyCertificate capk, CardResponse cardResponse) { ICCDynamicData iccdd = VerifySAD.VerifySDAD(ICCDynamicDataType.RRP, true, database, database.StaticDataToBeAuthenticated, capk, cardResponse); if (iccdd == null) { return(false); } AddSDADDataToDatabase(database, iccdd); string s1 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value); string s2 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DEVICE_RELAY_RESISTANCE_ENTROPY_DF8302_KRN2).Value); string s3 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.MIN_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8303_KRN2).Value); string s4 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.MAX_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8304_KRN2).Value); string s5 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DEVICE_ESTIMATED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8305_KRN2).Value); if (s1 != Formatting.ByteArrayToHexString(iccdd.Terminal_Relay_Resistance_Entropy)) { return(false); } if (s2 != Formatting.ByteArrayToHexString(iccdd.Device_Relay_Resistance_Entropy)) { return(false); } if (s3 != Formatting.ByteArrayToHexString(iccdd.Min_Time_For_Processing_Relay_Resistance_APDU)) { return(false); } if (s4 != Formatting.ByteArrayToHexString(iccdd.Max_Time_For_Processing_Relay_Resistance_APDU)) { return(false); } if (s5 != Formatting.ByteArrayToHexString(iccdd.Device_Estimated_Transmission_Time_For_Relay_Resistance_R_APDU)) { return(false); } return(true); }
public static bool DoCDA(KernelDatabase database, KernelQ qManager, CAPublicKeyCertificate capk, CardQ cardQManager, CardResponse cardResponse, EMVSelectApplicationResponse emvSelectApplicationResponse, bool isFirstGenAC) { //#region 9_10.2 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.Value.OfflineDataAuthenticationWasPerformed = true; tsi.UpdateDB(); bool cdaSucceeded = VerifySDAD_CDA(database, capk, cardResponse, isFirstGenAC); if (!cdaSucceeded) { tvr.Value.CDAFailed = true; tvr.UpdateDB(); return(false); } else { return(true); } }
public static byte[] BuildPinVerifyData(KernelDatabaseBase database, CAPublicKeyCertificate caPublicKey, byte[] pinBlock, byte[] challenge) { IssuerPublicKeyCertificate ipk = IssuerPublicKeyCertificate.BuildAndValidatePublicKey(database, caPublicKey.Modulus, caPublicKey.Exponent); if (ipk == null) { return(null); } int keyLength = 0; PublicKeyCertificate iccKey = IccPinKeyCertificate.BuildAndValidatePublicKey(database, ipk.Modulus, ipk.Exponent); if (iccKey == null) { iccKey = IccPublicKeyCertificate.BuildAndValidatePublicKey(database, database.StaticDataToBeAuthenticated, ipk.Modulus, ipk.Exponent); if (iccKey == null) { return(null); } keyLength = ((IccPublicKeyCertificate)iccKey).ICCPublicKeyLength; } else { keyLength = ((IccPinKeyCertificate)iccKey).ICCPinKeyLength; } int paddingLength = keyLength - 17; byte[] padding = new byte[paddingLength]; byte[] pinData = Formatting.ConcatArrays(new byte[] { 0x7F }, pinBlock, challenge, padding); //apply recovery function byte[] encryptedPin = PublicKeyCertificate.DecryptRSA(pinData, iccKey.Modulus, iccKey.Exponent); return(encryptedPin); }
private static SignalsEnum ProcessGenACCommand(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { //remove values stored during 1st gen ac database.RemoveFromList(database.Get(EMVTagsEnum.CRYPTOGRAM_INFORMATION_DATA_9F27_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag)); database.RemoveFromList(database.Get(EMVTagsEnum.ISSUER_APPLICATION_DATA_9F10_KRN.Tag)); //will only exist if CDA was perfomred after 1st gen ac database.RemoveFromList(database.Get(EMVTagsEnum.SIGNED_DYNAMIC_APPLICATION_DATA_9F4B_KRN.Tag)); 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)); } 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); 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)); } 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, false); } else { tvr.Value.CDAFailed = true; tvr.UpdateDB(); } } return(State_7_10_CommonProcessing.EndOnTCorAAC(database, qManager, cardQManager)); }
private static bool VerifySDAD_Summaries_CheckRelayData_9_10__3_1(Kernel2Database database, CAPublicKeyCertificate capk, CardResponse cardResponse) { ICCDynamicData iccdd = VerifySAD.VerifySDAD(ICCDynamicDataType.IDS_AND_RRP, true, database, database.StaticDataToBeAuthenticated, capk, cardResponse); if (iccdd == null) { return(false); } VerifySAD.AddSDADDataToDatabase(database, iccdd); TLV ds2 = database.Get(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2); TLV ds3 = database.Get(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2); if (ds2 == null && iccdd.DSSummary2 != null) { ds2 = TLV.Create(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2.Tag, iccdd.DSSummary2); database.AddToList(ds2); } if (ds3 == null && iccdd.DSSummary3 != null) { ds3 = TLV.Create(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2.Tag, iccdd.DSSummary3); database.AddToList(ds3); } if (iccdd.DSSummary2 != null) { ds2.Value = iccdd.DSSummary2; } if (iccdd.DSSummary3 != null) { ds3.Value = iccdd.DSSummary3; } string s1 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value); string s2 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DEVICE_RELAY_RESISTANCE_ENTROPY_DF8302_KRN2).Value); string s3 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.MIN_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8303_KRN2).Value); string s4 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.MAX_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8304_KRN2).Value); string s5 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DEVICE_ESTIMATED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8305_KRN2).Value); if (s1 != Formatting.ByteArrayToHexString(iccdd.Terminal_Relay_Resistance_Entropy)) { return(false); } if (s2 != Formatting.ByteArrayToHexString(iccdd.Device_Relay_Resistance_Entropy)) { return(false); } if (s3 != Formatting.ByteArrayToHexString(iccdd.Min_Time_For_Processing_Relay_Resistance_APDU)) { return(false); } if (s4 != Formatting.ByteArrayToHexString(iccdd.Max_Time_For_Processing_Relay_Resistance_APDU)) { return(false); } if (s5 != Formatting.ByteArrayToHexString(iccdd.Device_Estimated_Transmission_Time_For_Relay_Resistance_R_APDU)) { return(false); } return(true); }
public static SignalsEnum DoCDA9_10_1(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse) { CAPublicKeyCertificate capk = publicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); if (capk == null) { #region 9_10.1 return(DoPart_F(database, qManager, cardResponse)); #endregion } else { #region 9_10.2 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (ids.Value.IsRead) #endregion { bool successIDSRead = false; #region 9_10.2.2 if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED) #endregion { #region 9_10.3.1 successIDSRead = VerifySDAD_Summaries_CheckRelayData_9_10__3_1(database, capk, cardResponse); #endregion } else { #region 9_10.3 successIDSRead = VerifySDAD_Summaries_9_10__3(database, capk, cardResponse); #endregion } #region 9_10.3.5 if (!successIDSRead) #endregion { return(DoPart_F(database, qManager, cardResponse)); } else { #region 9_10.8 string dbds1 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2).Value); if (!database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2.Tag)) #endregion { #region 9_10.9 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } #region 9_10.10 string dbds2 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2).Value); if (dbds1 != dbds2) #endregion { #region 9_10.11 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.IDS_READ_ERROR, L3Enum.NOT_SET)); #endregion } #region 9_10.12 byte dsss = database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0]; dsss = (byte)(dsss | 0x80); //set succesful read database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss; #endregion #region 9_10.13 if (!ids.Value.IsWrite) #endregion { #region 9_10.70 return(DoPart_E(database, qManager, cardQManager)); #endregion } else { #region 9_10.14 if (!database.IsPresent(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2.Tag)) #endregion { #region 9_10.15 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } else { #region 9_10.16 string dbds3 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2).Value); if (dbds2 == dbds3) #endregion { #region 9_10.18 byte dsodsifr = database.Get(EMVTagsEnum.DS_ODS_INFO_FOR_READER_DF810A_KRN2).Value[0]; if ((dsodsifr & 0x02) == 0x02) //stop if write set #endregion { #region 9_10.19 return(DoInvalidResponsePart_D(database, qManager, L1Enum.NOT_SET, L2Enum.IDS_WRITE_ERROR, L3Enum.NOT_SET)); #endregion } else { return(DoPart_E(database, qManager, cardQManager)); } } else { #region 9_10.17 dsss = (byte)(dsss | 0x40); //set succesful write database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss; return(DoPart_E(database, qManager, cardQManager)); #endregion } } } } } else { bool successIDSNotRead = false; #region 9_10.2.1 if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED) #endregion { #region 9_10.4.1 successIDSNotRead = VerifySDAD_CheckRelayData_9_10__4_1(database, capk, cardResponse); #endregion } else { #region 9_10.4 successIDSNotRead = VerifySDAD_9_10__4(database, capk, cardResponse); #endregion } #region 9_10.6 if (!successIDSNotRead) #endregion { return(DoPart_F(database, qManager, cardResponse)); } else { return(DoPart_E(database, qManager, cardQManager)); } } } }
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); } }
private static SignalsEnum DoCDAPart_A(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse) { #region 11.40 CAPublicKeyCertificate capk = publicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]); #endregion if (capk == null) { #region 11.46 return(DoPart_F(database, qManager, cardResponse)); #endregion } else { #region 11.41 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (ids.Value.IsRead) #endregion { bool successIDSRead = false; #region 11.41.2 if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED) #endregion { #region 11.42.1 successIDSRead = VerifySDAD_Summaries_CheckRelayData_42_1(database, capk, cardResponse); #endregion } else { #region 11.42 successIDSRead = VerifySDAD_Summaries_42(database, capk, cardResponse); #endregion } if (!successIDSRead) { #region 11.46 return(DoPart_F(database, qManager, cardResponse)); #endregion } else { #region return(DoPart_E(database, qManager, cardQManager)); #endregion } } else { bool successIDSNotRead = false; #region 11.41.1 if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED) #endregion { #region 11.43.1 successIDSNotRead = VerifySDAD_CheckRelayData_43_1(database, capk, cardResponse); #endregion } else { #region 11.43 successIDSNotRead = VerifySDAD_43(database, capk, cardResponse); #endregion } if (!successIDSNotRead) { #region 11.46 return(DoPart_F(database, qManager, cardResponse)); #endregion } else { #region 11.47 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); string dbds1 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2).Value); if (idsV.IsWrite) #endregion { #region 11.48 string ttrds1 = Formatting.ByteArrayToHexString(database.TornTempRecord.Children.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag).Value); if (dbds1 != ttrds1) #endregion { #region 11.49 return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.IDS_READ_ERROR, L3Enum.NOT_SET)); #endregion } } #region 11.50 if (!database.IsPresent(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2.Tag)) #endregion { #region 11.51 return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } #region 11.52 string dbds2 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_2_DF8101_KRN2).Value); if (dbds1 != dbds2) #endregion { #region 11.53 return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.IDS_READ_ERROR, L3Enum.NOT_SET)); #endregion } #region 11.54 byte dsss = database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0]; dsss = (byte)(dsss | 0x80); //set succesful read database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss; #endregion #region 11.55 if (!ids.Value.IsWrite) #endregion { #region 11.110 return(DoPart_E(database, qManager, cardQManager)); #endregion } else { #region 11.56 if (!database.IsPresent(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2.Tag)) #endregion { #region 11.57 return(DoInvalidResponsePart_C(database, qManager, cardResponse, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } else { #region 11.58 string dbds3 = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_SUMMARY_3_DF8102_KRN2).Value); if (dbds2 == dbds3) #endregion { #region 11.60 byte dsodsifr = database.Get(EMVTagsEnum.DS_ODS_INFO_FOR_READER_DF810A_KRN2).Value[0]; if ((dsodsifr & 0x02) == 0x02) //stop if write set #endregion { #region 11.61 CommonRoutines.UpdateErrorIndication(database, cardResponse, L1Enum.NOT_SET, L2Enum.IDS_WRITE_ERROR, L3Enum.NOT_SET); #endregion return(DoInvalidResponsePart_D(database, qManager)); } else { return(DoPart_E(database, qManager, cardQManager)); } } else { #region 11.59 dsss = (byte)(dsss | 0x40); //set succesful write database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value[0] = dsss; return(DoPart_E(database, qManager, cardQManager)); #endregion } } } } } } }
public static SignalsEnum InitiateCardActionAnalysis(KernelDatabaseBase database, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { 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); //time to get signature data for dda cards, in order to do oda after 1st gen ac EMVGenerateACRequest request = null; if (aip.Value.CDASupported && tc.Value.CDACapable) { //cda done after gen ac 1, call gen ac1 now with signature requested request = CreateGenAC(database, true); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); } if (aip.Value.DDAsupported && tc.Value.DDACapable) { #region Book 3 Section 10.3 //do dda signature request, internal authenticate will do oda once it has the signature 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); } EMVInternalAuthenticateRequest requestDDA = new EMVInternalAuthenticateRequest(ddolRelatedData); cardQManager.EnqueueToInput(new CardRequest(requestDDA, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_INTERNAL_AUTHENTICATE); #endregion } if (aip.Value.SDASupported && tc.Value.SDACapable) { 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]); TLV ssadTLV = database.Get(EMVTagsEnum.SIGNED_STATIC_APPLICATION_DATA_93_KRN); if (capk == null || ssadTLV == null) { tvr.Value.SDAFailed = true; tvr.UpdateDB(); } else { TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.Value.OfflineDataAuthenticationWasPerformed = true; tsi.UpdateDB(); 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) { tvr.Value.SDAFailed = true; tvr.UpdateDB(); } else { TLV dataAuthenticationCode = database.Get(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN); if (dataAuthenticationCode == null) { dataAuthenticationCode = TLV.Create(EMVTagsEnum.DATA_AUTHENTICATION_CODE_9F45_KRN.Tag, authCode); } else { dataAuthenticationCode.Value = authCode; } } } //sda done after gen ac 1, call gen ac 1 now with no signature requested request = CreateGenAC(database, false); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); } tvr.Value.OfflineDataAuthenticationWasNotPerformed = true; tvr.UpdateDB(); //to do: ceck this, is this correct for a card where no oda is supported request = CreateGenAC(database, false); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); }
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); } }