private static SignalsEnum EntryPointPIN(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); //store the pin database.AddToList(kernel1Request.InputData.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag)); string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); //online pin if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerifiedOnline) { PinProcessing.VerifyOnlinePin(pin, tvr, cvr); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //offline pin if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper) { EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN.Tag)); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GET_PIN_TRY_COUNTER); } throw new EMVProtocolException("Invalid cvr in State_5a_WaitingForGetPinReponse"); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); EMVGetDataResponse response = (EMVGetDataResponse)cardResponse.ApduResponse; if (!response.Succeeded) { cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //store the pin try counter value database.AddToList(response.GetResponseTag()); int pinTryCounter = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.PERSONAL_IDENTIFICATION_NUMBER_PIN_TRY_COUNTER_9F17_KRN).Value); TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.EncipheredPINVerificationPerformedByICCAndSignature_Paper) { string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr)) { return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } //fire off get challenge command EMVGetChallengeRequest request = new EMVGetChallengeRequest(); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GET_CHALLENGE); } if (cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICC || cvr.Value.GetCVMPerformed() == CVMCode.PlaintextPINVerificationPerformedByICCAndSignature_Paper) { string pin = Formatting.ByteArrayToASCIIString(database.Get(EMVTagsEnum.TRANSACTION_PERSONAL_IDENTIFICATION_NUMBER_PIN_DATA_99_KRN.Tag).Value); if (!PinProcessing.VerifyOfflinePin(pin, pinTryCounter, tvr, cvr)) { return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); } byte[] pinData = PinProcessing.BuildPlainTextPinBlock(pin); //fire off verify for plain text pin EMVVerifyRequest request = new EMVVerifyRequest(VerifyCommandDataQualifier.Plaintext_PIN, pinData); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_VERIFY); } throw new EMVProtocolException("Invalid cvr in State_5b_WaitingForGetPinTryCounter"); }
private static SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { if (database.IsScriptProcessingBeforeGenACInProgress) { if (cardResponse.ApduResponse.SW1 != 0x90 && cardResponse.ApduResponse.SW1 != 0x62 && cardResponse.ApduResponse.SW1 != 0x63) { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.ScriptProcessingFailedBeforeFinalGENERATEAC = true; tvr.UpdateDB(); database.IsScriptProcessingBeforeGenACInProgress = false; return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse)); } if (database.ScriptsToRunBeforeGenAC.Count == 0) { database.IsScriptProcessingBeforeGenACInProgress = false; return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse, true)); } TLV firstScript = database.ScriptsToRunBeforeGenAC.GetFirstAndRemoveFromList(); EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest(); scriptRequest.Deserialize(firstScript.Value); cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING); } else { if (cardResponse.ApduResponse.SW1 != 0x90 && cardResponse.ApduResponse.SW1 != 0x62 && cardResponse.ApduResponse.SW1 != 0x63) { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.ScriptProcessingFailedAfterFinalGENERATEAC = true; tvr.UpdateDB(); //update emv data to return with this updated value if (database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2) != null) { database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2).Children.RemoveFromList(database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag)); database.Get(EMVTagsEnum.DATA_RECORD_FF8105_KRN2).Children.AddToList(TLV.Create(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN.Tag, database.Get(EMVTagsEnum.TERMINAL_VERIFICATION_RESULTS_95_KRN).Value)); } return(SignalsEnum.STOP); } if (database.ScriptsToRunAfterGenAC.Count == 0) { return(SignalsEnum.STOP); } TLV firstScript = database.ScriptsToRunAfterGenAC.GetFirstAndRemoveFromList(); EMVScriptCommandRequest scriptRequest = new EMVScriptCommandRequest(); scriptRequest.Deserialize(firstScript.Value); cardQManager.EnqueueToInput(new CardRequest(scriptRequest, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_SCRIPT_PROCESSING); } }
private static SignalsEnum DoPart_F(Kernel2Database database, KernelQ qManager, CardResponse cardResponse) { #region 9_10.46 //see below #endregion #region 9_10.46.1 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.CDAFailed = true; tvr.UpdateDB(); #endregion return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CAM_FAILED, L3Enum.NOT_SET)); }
//U in diagram public static bool VerifyOnlinePin(string pin, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr) { if (string.IsNullOrEmpty(pin)) { tvr.Value.PINEntryRequiredPINPadPresentButPINWasNotEntered = true; cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); tvr.UpdateDB(); return(false); } //cvm and tvr already set correctly in CVM selection return(true); }
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 }
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 SignalsEnum EntryPointRA(KernelDatabase database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw, PublicKeyCertificateManager publicKeyCertificateManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { if (!cardResponse.ApduResponse.Succeeded) { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.IssuerAuthenticationFailed = true; tvr.UpdateDB(); } else { TRANSACTION_STATUS_INFORMATION_9B_KRN tsi = new TRANSACTION_STATUS_INFORMATION_9B_KRN(database); tsi.Value.IssuerAuthenticationWasPerformed = true; tsi.UpdateDB(); } //EMVExternalAuthenticateResponse response = cardResponse.ApduResponse as EMVExternalAuthenticateResponse; //if scripts need to be run before gen ac, do now return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse)); }
private static void Do434(Kernel2Database database, bool signedFlag, int sfi, CardResponse cardResponse, TLVList responseTags) { #region 4.34 if (signedFlag && database.ODAStatus == 0x80) { #region 4.35 if (sfi <= 10) { int length = cardResponse.ApduResponse.ResponseData.Length - 2; //without tag '70' and length if (2048 - database.StaticDataToBeAuthenticated.Serialize().Length >= length) { database.StaticDataToBeAuthenticated.AddListToList(responseTags); } else { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.CDAFailed = true; tvr.UpdateDB(); } } else { int length = cardResponse.ApduResponse.ResponseData.Length; if (cardResponse.ApduResponse.ResponseData[0] == 0x70 && 2048 - database.StaticDataToBeAuthenticated.Serialize().Length >= length) { TLV template = TLV.Create(EMVTagsEnum.READ_RECORD_RESPONSE_MESSAGE_TEMPLATE_70_KRN.Tag); template.Children.AddListToList(responseTags); template.Serialize(); database.StaticDataToBeAuthenticated.AddToList(template); } else { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.CDAFailed = true; tvr.UpdateDB(); } } #endregion } #endregion }
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); } }
//X in diagram public static bool VerifyOfflinePin(string pin, int pinTryCounter, TERMINAL_VERIFICATION_RESULTS_95_KRN tvr, CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvr) { if (pinTryCounter == 0) { tvr.Value.PINTryLimitExceeded = true; cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); tvr.UpdateDB(); return(false); } if (string.IsNullOrEmpty(pin)) { tvr.Value.PINEntryRequiredPINPadPresentButPINWasNotEntered = true; cvr.Value.CVMResult = 0x01;//failed cvr.UpdateDB(); tvr.UpdateDB(); return(false); } return(true); }
public static SignalsEnum DoNOCDA9_10_30(Kernel2Database database, KernelQ qManager, PublicKeyCertificateManager publicKeyCertificateManager, CardQ cardQManager, CardResponse cardResponse) { #region 9_10.30 if (!database.IsPresent(EMVTagsEnum.APPLICATION_CRYPTOGRAM_9F26_KRN.Tag)) #endregion { #region 9_10.31 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } else { #region 9_10.32 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) == 0x00) #endregion { #region 9_10.33 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region 9_10.37 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } else { #region 9_10.35 if (rcp.Value.ACTypeEnum == ACTypeEnum.AAC) #endregion { #region 9_10.36 if (rcp.Value.CDASignatureRequested) #endregion { #region 9_10.37 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } else { return(DoPart_E(database, qManager, cardQManager)); } } else { return(DoPart_E(database, qManager, cardQManager)); } } } else { #region 9_10.34 if (rcp.Value.CDASignatureRequested) #endregion { #region 9_10.37 return(DoInvalidResponsePart_C(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } else { #region 9_10.38 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); if (tvr.Value.RelayResistancePerformedEnum == RelayResistancePerformedEnum.RRP_PERFORMED) #endregion { #region 9_10.39 Do9_10__39(database); #endregion } return(DoPart_E(database, qManager, cardQManager)); } } } }
public static SignalsEnum DoCommonProcessing(string source, KernelDatabase database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, EMVSelectApplicationResponse emvSelectApplicationResponse) { if (database.NextCommandEnum == NextCommandEnum.READ_RECORD) { DoDEKIfNeeded(database, qManager); return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); } DoDEKIfNeeded(database, qManager); if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag)) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT)); } if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag))) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } #region Book 3 Section 10.3 APPLICATION_INTERCHANGE_PROFILE_82_KRN aipCheck = 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 ((aipCheck.Value.CDASupported && tc.Value.CDACapable) || aipCheck.Value.DDAsupported && tc.Value.DDACapable || aipCheck.Value.SDASupported && tc.Value.SDACapable) { if (aipCheck.Value.CDASupported && tc.Value.CDACapable) { //some checking in preperation for ODA is done here, ODA is done after 1st gen ac if (!( database.IsNotEmpty(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN.Tag) //&& //database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag) )) { tvr.Value.ICCDataMissing = true; tvr.Value.CDAFailed = true; } } string aid = emvSelectApplicationResponse.GetDFName(); string rid = aid.Substring(0, 10); RIDEnum ridEnum = (RIDEnum)Enum.Parse(typeof(RIDEnum), rid); if (database.PublicKeyCertificateManager.GetCAPK(ridEnum, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null) { if (aipCheck.Value.CDASupported && tc.Value.CDACapable) { tvr.Value.CDAFailed = true; } if (aipCheck.Value.DDAsupported && tc.Value.DDACapable) { tvr.Value.DDAFailed = true; } if (aipCheck.Value.SDASupported && tc.Value.SDACapable) { tvr.Value.SDAFailed = true; } } //bool aipFound = false; //TLV aip = null; //if (database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag)) //{ // TLV sdal = database.Get(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN); // TLVList list = TLV.DeserializeChildrenWithNoLV(sdal.Value, 0); // //if (list.Count == 1) // //{ // aip = list.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); // if (aip != null) // { // aipFound = true; // } // //} //} //else //{ // if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) // { // aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); // aipFound = true; // } //} //if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) //{ // aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); // aipFound = true; //} TLV aip = database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN); if (database.IsEmpty(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag)) { CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); } int length = database.StaticDataToBeAuthenticated.Serialize().Length; if (2048 - length >= aip.Value.Length) { //will be removed later when the SDA is done database.StaticDataToBeAuthenticated.AddToList(aip); } //else //{ // if (aipCheck.Value.CDASupported && tc.Value.CDACapable) // { // tvr.Value.CDAFailed = true; // } // if (aipCheck.Value.DDAsupported && tc.Value.DDACapable) // { // tvr.Value.DDAFailed = true; // } // if (aipCheck.Value.SDASupported && tc.Value.SDACapable) // { // tvr.Value.SDAFailed = true; // } //} tvr.UpdateDB(); } #endregion #region Book 3 Section 10.4 //using kernel 2 processing restrictions ProcessingRestrictions_7_7.ProcessingRestrictions(database); #endregion return(SignalsEnum.WAITING_FOR_CVM_PROCESSING); }
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 } } } }
public static SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, Stopwatch sw, TornTransactionLogManager tornTransactionLogManager) { #region 456.1 if (database.NextCommandEnum == NextCommandEnum.READ_RECORD) #endregion { #region 456.2 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); } #endregion #region 456.3 if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0) #endregion { #region 456.4 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); } else { if (database.NextCommandEnum == NextCommandEnum.GET_DATA) { return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE); } else { #region 456.5 if (database.IsEmpty(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag)) #endregion { DATA_NEEDED_DF8106_KRN2 dataNeeded = new DATA_NEEDED_DF8106_KRN2(database); #region 456.6 dataNeeded.Value.Tags.Add(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag); #endregion dataNeeded.UpdateDB(); return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw)); } else { #region 456.11 if (database.IsPresent(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2.Tag) && database.Get(EMVTagsEnum.PROCEED_TO_FIRST_WRITE_FLAG_DF8110_KRN2).Value[0] == 0x00) #endregion { #region 456.7 return(Do456_7_To_456_10(source, database, qManager, cardQManager, sw)); #endregion } } } } #region 456.12 if (database.IsEmpty(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag)) #endregion { #region 456.13 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, L1Enum.NOT_SET, L2Enum.NOT_SET, L3Enum.AMOUNT_NOT_PRESENT)); #endregion } #region 456.14 long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long rctl = database.ReaderContactlessTransactionLismit; if (aa > rctl) #endregion { #region 456.15 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.MAX_LIMIT_EXCEEDED, L3Enum.NOT_SET)); #endregion } #region 456.16 if (!(database.IsNotEmpty(EMVTagsEnum.APPLICATION_EXPIRATION_DATE_5F24_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.CARD_RISK_MANAGEMENT_DATA_OBJECT_LIST_1_CDOL1_8C_KRN.Tag))) #endregion { #region 456.17 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.N_A, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); #endregion } #region 456.18 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region 456.19 string dsid = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2).Value); string pan = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value); string seqNumber = "00"; if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)) { seqNumber = Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value); } string concat = pan + seqNumber; if (concat.Length % 2 != 0) { concat = "0" + concat; } if (concat.Length < 16) { concat.PadLeft(16, '0'); } if (dsid != concat) #endregion { #region 456.20.1,456.20.2 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } } #region 456.21 TLVList toRemove2 = new TLVList(); foreach (TLV tlv in database.TagsToReadYet) { if (database.IsPresent(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(tlv); } else { if (database.IsKnown(tlv.Tag.TagLable)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(TLV.Create(tlv.Tag.TagLable)); } } toRemove2.AddToList(tlv); } foreach (TLV tlv in toRemove2) { database.TagsToReadYet.RemoveFromList(tlv); } #endregion #region 456.22 if (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag)) #endregion { #region 456.23 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } #region 456.24 if (database.ODAStatus == 0x80) #endregion { TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); #region 456.25 if (!( database.IsNotEmpty(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_CERTIFICATE_90_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.ISSUER_PUBLIC_KEY_EXPONENT_9F32_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_CERTIFICATE_9F46_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.INTEGRATED_CIRCUIT_CARD_ICC_PUBLIC_KEY_EXPONENT_9F47_KRN.Tag) && database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag) )) { tvr.Value.ICCDataMissing = true; tvr.Value.CDAFailed = true; } if (database.PublicKeyCertificateManager.GetCAPK(RIDEnum.A000000004, database.Get(EMVTagsEnum.CERTIFICATION_AUTHORITY_PUBLIC_KEY_INDEX_8F_KRN).Value[0]) == null) { tvr.Value.CDAFailed = true; } #endregion #region 456.26 bool test = false; TLV aip = null; if (database.IsNotEmpty(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN.Tag)) { TLV sdal = database.Get(EMVTagsEnum.STATIC_DATA_AUTHENTICATION_TAG_LIST_9F4A_KRN); TLVList list = TLV.DeserializeChildrenWithNoLV(sdal.Value, 0); if (list.Count == 1) { aip = list.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN.Tag); if (aip != null) { test = true; } } } if (test == false) { #region 456.27.1 - 456.27.2 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } #endregion #region 456.28 int length = database.StaticDataToBeAuthenticated.Serialize().Length; if (2048 - length >= aip.Value.Length) { database.StaticDataToBeAuthenticated.AddToList(database.Get(EMVTagsEnum.APPLICATION_INTERCHANGE_PROFILE_82_KRN)); } else { tvr.Value.CDAFailed = true; } #endregion tvr.UpdateDB(); } #region 456.30 long cvmrl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CVM_REQUIRED_LIMIT_DF8126_KRN2).Value); if (aa > cvmrl) #endregion { #region 456.31 CommonRoutines.UpdateOutcomeParameterSet(database, true); #endregion #region 456.32 database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_CVM_REQUIRED_DF8118_KRN2).Value[0]; #endregion } else { #region 456.33 database.Get(EMVTagsEnum.TERMINAL_CAPABILITIES_9F33_KRN).Value[1] = database.Get(EMVTagsEnum.CVM_CAPABILITY_NO_CVM_REQUIRED_DF8119_KRN2).Value[0]; #endregion } #region 456.34 SignalsEnum se = PreGenACBalanceReading_7_1.PreGenACBalanceReading(database, qManager, cardQManager); if (se != SignalsEnum.NONE) { return(se); } #endregion #region 456.35 ProcessingRestrictions_7_7.ProcessingRestrictions(database); #endregion #region 456.35 CVMSelection_7_5.CVMSelection(database, new Func <bool>(() => { return(new KERNEL_CONFIGURATION_DF811B_KRN2(database).Value.OnDeviceCardholderVerificationSupported); })); #endregion #region 456.36 long rcfl = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_FLOOR_LIMIT_DF8123_KRN2).Value); if (aa > rcfl) #endregion { #region 456.38 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.TransactionExceedsFloorLimit = true; tvr.UpdateDB(); #endregion } #region 456.39 database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database); #endregion //#region support for Refunds pg 177 //byte transactionType = database.Get(EMVTagsEnum.TRANSACTION_TYPE_9C_KRN).Value[0]; //if (transactionType == (byte)TransactionTypeEnum.Refund) //{ // database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; // database.ODAStatus = 0x00; //dont request CDA in first gen ac //} //#endregion #region 456.42 if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag)) #endregion { #region 456.50 TLV tlvRemoved = database.TagsToWriteBeforeGenACYet.GetFirstAndRemoveFromList(); EMVPutDataRequest request = new EMVPutDataRequest(tlvRemoved); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_PUT_DATA_RESPONSE_BEFORE_GEN_AC); #endregion } else { TORN_RECORD_FF8101_KRN2 foundTTL = null; #region 456.43 uint mnttl = Formatting.ConvertToInt32(database.GetDefault(EMVTagsEnum.MAX_NUMBER_OF_TORN_TRANSACTION_LOG_RECORDS_DF811D_KRN2).Value); if (database.IsNotEmpty(EMVTagsEnum.DRDOL_9F51_KRN2.Tag) && mnttl != 0) #endregion { #region 456.44 foreach (TORN_RECORD_FF8101_KRN2 tlv in tornTransactionLogManager.TornTransactionLogs) { if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag)) { if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) && (Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN).Value))) { foundTTL = tlv; } } else { if ((Formatting.ByteArrayToHexString(tlv.Children.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN.Tag).Value) == Formatting.ByteArrayToHexString(database.Get(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_5A_KRN).Value)) && (tlv.Children.IsNotPresent(EMVTagsEnum.APPLICATION_PRIMARY_ACCOUNT_NUMBER_PAN_SEQUENCE_NUMBER_5F34_KRN.Tag))) { foundTTL = tlv; } } } #endregion if (foundTTL == null) { #region 456.45 EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); #endregion } else { #region 456.47 database.TornTempRecord = foundTTL; #endregion #region 456.48 database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2).Value = database.TornTempRecord.Children.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2.Tag).Value; EMVRecoverACRequest requestRecover = new EMVRecoverACRequest(database.Get(EMVTagsEnum.DRDOL_RELATED_DATA_DF8113_KRN2)); cardQManager.EnqueueToInput(new CardRequest(requestRecover, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_RECOVER_AC); #endregion } } else { #region 456.45 EMVGenerateACRequest request = PrepareGenACCommandProcedure_7_6.PrepareGenACCommand(database, qManager, cardQManager); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_GEN_AC_1); #endregion } } }
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 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 SignalsEnum DoCommonProcessing(string source, Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse) { #region S3R1.1 TLV nextTLV = database.TagsToReadYet.GetNextGetDataTagFromList(); if (nextTLV != null) { database.ActiveTag = nextTLV.Tag.TagLable; } else { database.ActiveTag = null; } if (database.ActiveTag != null) { #region S3R1.2 EMVGetDataRequest request = new EMVGetDataRequest(Formatting.HexStringToByteArray(database.ActiveTag)); #endregion #region S3R1.3 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion #region S3R1.3 database.NextCommandEnum = NextCommandEnum.GET_DATA; #endregion } #endregion else { #region S3R1.5 if (database.ActiveAFL == null) #endregion { #region S3R1.6 return(DoInvalidReponse(database, qManager, L1Enum.NOT_SET, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } else { #region S3R1.7 EMVReadRecordRequest request = new EMVReadRecordRequest(database.ActiveAFL.Value.Entries[0].SFI, database.ActiveAFL.Value.Entries[0].FirstRecordNumber); #endregion #region S3R1.8 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion #region S3R1.9 database.NextCommandEnum = NextCommandEnum.READ_RECORD; #endregion } } #region S3R1.10 TLVList dataToSend = database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children; IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); if (ids.Value.IsRead) #endregion { #region S3R1.11 if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_SLOT_MANAGEMENT_CONTROL_9F6F_KRN2)); } if (database.IsNotEmpty(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag)) { dataToSend.AddToList(database.Get(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2)); } dataToSend.AddToList(database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN)); #endregion #region S3R1.12 if (!((database.IsNotEmpty(EMVTagsEnum.DS_SLOT_AVAILABILITY_9F5F_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) && database.IsNotEmpty(EMVTagsEnum.DS_UNPREDICTABLE_NUMBER_9F7F_KRN2.Tag) && database.IsNotPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag)) || (database.IsNotEmpty(EMVTagsEnum.DS_SUMMARY_1_9F7D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_ODS_CARD_9F54_KRN2.Tag)) )) { #region S3R1.13 ids = new IDS_STATUS_DF8128_KRN2(database); ids.Value.IsRead = false; ids.UpdateDB(); #endregion } #endregion } #region S3R1.14 TLVList tagsToRemove = new TLVList(); foreach (TLV ttry in database.TagsToReadYet) { if (database.IsNotEmpty(ttry.Tag.TagLable)) { dataToSend.AddToList(ttry); tagsToRemove.AddToList(ttry); } } foreach (TLV ttr in tagsToRemove) { database.TagsToReadYet.RemoveFromList(ttr); } #endregion #region S3R1.15 if (database.IsNotEmptyList(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2.Tag) || (database.IsNotEmptyList(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2.Tag) && database.TagsToReadYet.Count == 0)) { #region S3R1.16 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion } #endregion #region S3R1.17 APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); TERMINAL_CAPABILITIES_9F33_KRN tc = new TERMINAL_CAPABILITIES_9F33_KRN(database); if (!(aip.Value.CDASupported && tc.Value.CDACapable)) { #region S3R1.18 ids = new IDS_STATUS_DF8128_KRN2(database); if (!ids.Value.IsRead) { #region S3R1.20 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.OfflineDataAuthenticationWasNotPerformed = true; tvr.UpdateDB(); #endregion } else { #region S3R1.19 database.ODAStatus = 0x80; #endregion } #endregion } else { #region S3R1.19 database.ODAStatus = 0x80; #endregion } #endregion if (database.NextCommandEnum == NextCommandEnum.READ_RECORD) { return(SignalsEnum.WAITING_FOR_EMV_READ_RECORD_RESPONSE); } else { return(SignalsEnum.WAITING_FOR_GET_DATA_RESPONSE); } }
private static SignalsEnum DoEMVMode(Kernel2Database database, KernelQ qManager, CardQ cardQManager, CardResponse cardResponse, Stopwatch sw) { #region 3.30 KERNEL_CONFIGURATION_DF811B_KRN2 kc = new KERNEL_CONFIGURATION_DF811B_KRN2(database); TLV aflRaw = database.Get(EMVTagsEnum.APPLICATION_FILE_LOCATOR_AFL_94_KRN); byte[] kcValCheck = new byte[4]; Array.Copy(aflRaw.Value, 0, kcValCheck, 0, kcValCheck.Length); if (aflRaw.Value.Length >= 4 && Formatting.ByteArrayToHexString(kcValCheck) == "08010100" && !kc.Value.MagStripeModeContactlessTransactionsNotSupported) { #region 3.32 byte[] activeAFLBytes = new byte[aflRaw.Value.Length - 4]; Array.Copy(aflRaw.Value, 4, activeAFLBytes, 0, activeAFLBytes.Length); List <byte[]> bytes = new List <byte[]> { new byte[] { (byte)activeAFLBytes.Length }, activeAFLBytes }; database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(activeAFLBytes)); #endregion } else { #region 3.31 List <byte[]> bytes = new List <byte[]> { new byte[] { (byte)aflRaw.Value.Length }, aflRaw.Value }; database.ActiveAFL.Value.Deserialize(bytes.SelectMany(a => a).ToArray(), 0); //database.ActiveAFL.Value.Entries.Add(new FILE_LOCATOR_ENTRY(aflRaw.Value)); #endregion } #endregion #region 3.33 APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); if (aip.Value.OnDeviceCardholderVerificationIsSupported && kc.Value.OnDeviceCardholderVerificationSupported) { #region 3.35 database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_ONDEVICE_CVM_DF8125_KRN2).Value); #endregion } else { #region 3.34 database.ReaderContactlessTransactionLismit = Formatting.BcdToLong(database.Get(EMVTagsEnum.READER_CONTACTLESS_TRANSACTION_LIMIT_NO_ONDEVICE_CVM_DF8124_KRN2).Value); #endregion } #endregion #region 3.60 if (kc.Value.RelayResistanceProtocolSupported && aip.Value.RelayResistanceProtocolIsSupported) #endregion { #region 3.61 database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber(); database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value; #endregion #region 3.62 EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value); #endregion #region 3.63 sw.Start(); #endregion #region 3.64 cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); #endregion return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE); } else { #region 3.65 TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_NOT_PERFORMED; tvr.UpdateDB(); #endregion return(State_3_R1_CommonProcessing.DoCommonProcessing("State_3_WaitingForGPOResponse", database, qManager, cardQManager, cardResponse)); } }
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)); } } } }
/* * SR1.9 - SR1.32 */ private static SignalsEnum EntryPointRA(Kernel2Database database, CardResponse cardResponse, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { #region SR1.10 sw.Stop(); #endregion #region SR1.11 if (!cardResponse.ApduResponse.Succeeded) #endregion { #region SR1.12 - SR1.13 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, cardResponse.ApduResponse.SW12, L2Enum.STATUS_BYTES, L3Enum.NOT_SET)); #endregion } #region SR1.14 bool parsingResult = false; EMVExchangeRelayResistanceDataResponse emverrdr = (EMVExchangeRelayResistanceDataResponse)cardResponse.ApduResponse; if ((cardResponse.ApduResponse.ResponseData.Length > 11 && cardResponse.ApduResponse.ResponseData[0] == 0x80))// && cardResponse.ApduResponse.ResponseData.Length == 10) { database.AddListToList(emverrdr.GetResponseTags()); parsingResult = true; } #region SR1.15 if (!parsingResult) #endregion { #region SR1.16, SR1.17 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.PARSING_ERROR, L3Enum.NOT_SET)); #endregion } #region SR1.18 int a = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.TERMINAL_EXPECTED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_CAPDU_DF8134_KRN2).Value); int b = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.TERMINAL_EXPECTED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8135_KRN2).Value); int c = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.DEVICE_ESTIMATED_TRANSMISSION_TIME_FOR_RELAY_RESISTANCE_RAPDU_DF8305_KRN2).Value); int measuredRelayResistanceProcessingTime = ((int)sw.ElapsedMilliseconds / 100) - a - Math.Min(c, b); #endregion int d = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MINIMUM_RELAY_RESISTANCE_GRACE_PERIOD_DF8132_KRN2).Value); int e = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MIN_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8303_KRN2).Value); #region SR1.19 if (measuredRelayResistanceProcessingTime < (e - d)) #endregion { #region SR1.20, SR1.21 CommonRoutines.CreateEMVDiscretionaryData(database); return(CommonRoutines.PostOutcome(database, qManager, KernelMessageidentifierEnum.ERROR_OTHER_CARD, KernelStatusEnum.NOT_READY, null, Kernel2OutcomeStatusEnum.END_APPLICATION, Kernel2StartEnum.N_A, true, KernelMessageidentifierEnum.ERROR_OTHER_CARD, L1Enum.NOT_SET, null, L2Enum.CARD_DATA_ERROR, L3Enum.NOT_SET)); #endregion } int g = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.MAX_TIME_FOR_PROCESSING_RELAY_RESISTANCE_APDU_DF8304_KRN2).Value); int f = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2).Value); #region SR1.22 if ((f < 2) && (measuredRelayResistanceProcessingTime > (g + d))) #endregion { #region SR1.23 - SR1.27 database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value = Formatting.GetRandomNumber(); database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value = database.Get(EMVTagsEnum.UNPREDICTABLE_NUMBER_9F37_KRN).Value; f++; database.Get(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2).Value = BitConverter.GetBytes(f); EMVExchangeRelayResistanceDataRequest request = new EMVExchangeRelayResistanceDataRequest(database.Get(EMVTagsEnum.TERMINAL_RELAY_RESISTANCE_ENTROPY_DF8301_KRN2).Value); sw.Start(); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_EXCHANGE_RELAY_RESISTANCE_DATA_RESPONSE); #endregion } TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); #region SR1.28 if (measuredRelayResistanceProcessingTime > (g + d)) #endregion { #region SR1.29 tvr.Value.RelayResistanceTimeLimitsExceeded = true; #endregion } int h = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RELAY_RESISTANCE_TRANSMISSION_TIME_MISMATCH_THRESHOLD_DF8137_KRN2).Value); int i = Formatting.ConvertToInt16(database.Get(EMVTagsEnum.RELAY_RESISTANCE_ACCURACY_THRESHOLD_DF8136_KRN2).Value); #region SR1.30 if (((c / b) * 100 < h) || ((b / c) * 100 < h) || ((measuredRelayResistanceProcessingTime - e) > i)) { tvr.Value.RelayResistanceThresholdExceeded = true; } else { tvr.Value.RelayResistancePerformedEnum = RelayResistancePerformedEnum.RRP_PERFORMED; } tvr.UpdateDB(); #endregion #endregion return(State_3_R1_CommonProcessing.DoCommonProcessing("State_R1_ExchangeRelayResistanceData", database, qManager, cardQManager, cardResponse)); }
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 } } } } } } }
private static SignalsEnum EntryPointOnline(KernelDatabase database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { KernelOnlineRequest response = (KernelOnlineRequest)kernel1Request; //check if approved or not or unable to go online if (response.OnlineApprovalStatus == KernelOnlineResponseType.UnableToGoOnline) { //if unable to go online, check what action to take using TAC/IAC default, 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_DEFAULT_DF8120_KRN2).Value); if (database.IsNotEmpty(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN.Tag)) { ulong iacAsNumber = Formatting.ConvertToInt64(database.Get(EMVTagsEnum.ISSUER_ACTION_CODE_DEFAULT_9F0D_KRN).Value); if (!( ((tacAsNumber | iacAsNumber) & tvrAsNumber) == 0) ) { database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; } else { database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; } } else { if (!((tacAsNumber & tvrAsNumber) == 0)) { database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; } else { database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; } } //what should these be set to in this case? database.AddToList(TLV.Create(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag)); database.AddToList(TLV.Create(EMVTagsEnum.AUTHORISATION_RESPONSE_CODE_8A_KRN.Tag)); } else { if (response.OnlineApprovalStatus == KernelOnlineResponseType.Approve) { database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; } else { database.ACType.Value.DSACTypeEnum = ACTypeEnum.AAC; } database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag)); database.AddToList(response.InputData.Get(EMVTagsEnum.AUTHORISATION_RESPONSE_CODE_8A_KRN.Tag)); if (response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN.Tag) != null) { database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_1_71_KRN.Tag)); } if (response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN.Tag) != null) { database.AddToList(response.InputData.Get(EMVTagsEnum.ISSUER_SCRIPT_TEMPLATE_2_72_KRN.Tag)); } } APPLICATION_INTERCHANGE_PROFILE_82_KRN aip = new APPLICATION_INTERCHANGE_PROFILE_82_KRN(database); if (aip.Value.IssuerAuthenticationIsSupported && response.OnlineApprovalStatus != KernelOnlineResponseType.UnableToGoOnline) { TLV _91 = response.InputData.Get(EMVTagsEnum.ISSUER_AUTHENTICATION_DATA_91_KRN.Tag); EMVExternalAuthenticateRequest request = new EMVExternalAuthenticateRequest(_91.Value); cardQManager.EnqueueToInput(new CardRequest(request, CardinterfaceServiceRequestEnum.ADPU)); return(SignalsEnum.WAITING_FOR_EXTERNAL_AUTHENTICATE); } else { //if scripts need to be run before gen ac, do now return(CardActionAnalysis.Initiate2ndCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse)); } }
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 }
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); } }
/* * S1.1, S1.7 - S1.23 */ private static SignalsEnum EntryPointACT(Kernel2Database database, KernelRequest kernel1Request, KernelQ qManager, CardQ cardQManager, Stopwatch sw) { #region S1.7 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); } } } if (database.IsNotEmpty(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN.Tag)) { byte[] languagePrefFromCard = database.Get(EMVTagsEnum.LANGUAGE_PREFERENCE_5F2D_KRN).Value; byte[] languagePrefFromCardPadded = new byte[8]; //will be padded with trailing 0's Array.Copy(languagePrefFromCard, languagePrefFromCardPadded, languagePrefFromCard.Length); CommonRoutines.UpdateUserInterfaceRequestData(database, languagePrefFromCardPadded); } #region S1.8 if (database.IsNotPresent(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag) || database.IsEmpty(EMVTagsEnum.DEDICATED_FILE_DF_NAME_84_KRN.Tag)) { return(CommonRoutines.PostOutcomeWithError(database, qManager, Kernel2OutcomeStatusEnum.SELECT_NEXT, Kernel2StartEnum.C, L1Enum.NOT_SET, L2Enum.CARD_DATA_MISSING, L3Enum.NOT_SET)); } #endregion if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag)) { APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aciVal = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database); if (aciVal.Value.SupportForFieldOffDetection) { byte[] holdTimeValue = database.GetDefault(EMVTagsEnum.HOLD_TIME_VALUE_DF8130_KRN2).Value; CommonRoutines.UpdateOutcomeParameterSet(database, holdTimeValue[0]); } } #endregion #region S1.9 CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN cvmr = new CARDHOLDER_VERIFICATION_METHOD_CVM_RESULTS_9F34_KRN(database); cvmr.UpdateDB(); database.ACType = new DS_AC_TYPE_DF8108_KRN2(database); database.ACType.Value.DSACTypeEnum = ACTypeEnum.TC; TERMINAL_VERIFICATION_RESULTS_95_KRN tvr = new TERMINAL_VERIFICATION_RESULTS_95_KRN(database); tvr.UpdateDB(); database.ODAStatus = 0x00; database.AddToList(TLV.Create(EMVTagsEnum.RRP_COUNTER_DF8307_KRN2.Tag, new byte[] { 0x00 })); //CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2 df8117 = new CARD_DATA_INPUT_CAPABILITY_DF8117_KRN2(database); //SECURITY_CAPABILITY_DF811F_KRN2 df811f = new SECURITY_CAPABILITY_DF811F_KRN2(database); TERMINAL_CAPABILITIES_9F33_KRN _9f33 = new TERMINAL_CAPABILITIES_9F33_KRN(database); //_9f33.Value.SetCardDataInputCapabilityValue(df8117); //_9f33.Value.SetSecurityCapabilityValue(df811f); _9f33.UpdateDB(); database.StaticDataToBeAuthenticated.Initialize(); 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(); //REFERENCE_CONTROL_PARAMETER_DF8114_KRN2 rcpv = new REFERENCE_CONTROL_PARAMETER_DF8114_KRN2(); //rcpv.Value.ACTypeEnum = ACTypeEnum.TC; //rcpv.UpdateDB(); #endregion #region S1.10 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(); } #endregion #region S1.11 bool MissingPDOLDataFlag = false; #endregion #region S1.12 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(); #region S1.13 and S1.14 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)); } #endregion #endregion #region S1.15 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); } #endregion #region S1.16 database.Initialize(EMVTagsEnum.IDS_STATUS_DF8128_KRN2.Tag); database.Initialize(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2.Tag); database.Initialize(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2.Tag); database.Initialize(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2.Tag); database.Initialize(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2.Tag); database.Get(EMVTagsEnum.IDS_STATUS_DF8128_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.DS_SUMMARY_STATUS_DF810B_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.POSTGEN_AC_PUT_DATA_STATUS_DF810E_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.PREGEN_AC_PUT_DATA_STATUS_DF810F_KRN2).Value = new byte[] { 0x00 }; database.Get(EMVTagsEnum.DS_DIGEST_H_DF61_KRN2).Value = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; database.TagsToWriteAfterGenACYet.Initialize(); database.TagsToWriteBeforeGenACYet.Initialize(); if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag)) { database.TagsToWriteBeforeGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2).Children); } if (database.IsNotEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag)) { database.TagsToWriteAfterGenACYet.AddListToList(database.Get(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2).Children); } if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2.Tag)) { dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_BEFORE_GEN_AC_FF8102_KRN2); } if (database.IsEmptyList(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2.Tag)) { dataNeeded.Value.AddTag(EMVTagsEnum.TAGS_TO_WRITE_AFTER_GEN_AC_FF8103_KRN2); } dataNeeded.UpdateDB(); #endregion #region S1.17 if (database.IsNotEmpty(EMVTagsEnum.DSVN_TERM_DF810D_KRN2.Tag) && database.IsPresent(EMVTagsEnum.DS_REQUESTED_OPERATOR_ID_9F5C_KRN2.Tag)) { #region S1.18 if (database.IsPresent(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.DS_ID_9F5E_KRN2)); } else { TLV dsid = TLV.Create(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag); dsid.Val.PackValue(EMVTagsEnum.DS_ID_9F5E_KRN2.DataFormatter.GetMaxLength()); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(dsid); } if (database.IsPresent(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag)) { database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(database.Get(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2)); } else { TLV aci = TLV.Create(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag); aci.Val.PackValue(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.DataFormatter.GetMaxLength()); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Children.AddToList(aci); } #endregion #region S1.19 if (database.IsNotEmpty(EMVTagsEnum.APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2.Tag)) { APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2 aci = new APPLICATION_CAPABILITIES_INFORMATION_9F5D_KRN2(database); if ((aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_1 || aci.Value.DataStorageVersionNumberEnum == DataStorageVersionNumberEnum.VERSION_2) && database.IsNotEmpty(EMVTagsEnum.DS_ID_9F5E_KRN2.Tag)) { #region S1.20 IDS_STATUS_DF8128_KRN2 ids = new IDS_STATUS_DF8128_KRN2(database); ids.Value.IsRead = true; ids.UpdateDB(); #endregion } } #endregion } #endregion #region S1.21 if (MissingPDOLDataFlag) { #region S1.22 CommonRoutines.PostDEK(database, qManager); database.Get(EMVTagsEnum.DATA_TO_SEND_FF8104_KRN2).Initialize(); database.Get(EMVTagsEnum.DATA_NEEDED_DF8106_KRN2).Initialize(); #endregion #region S1.23 sw.Restart(); #endregion return(SignalsEnum.WAITING_FOR_PDOL_DATA); } #endregion return(SignalsEnum.WAITING_FOR_GPO_REPONSE); }
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 EntryPointTRM(KernelDatabase database, KernelRequest kernel1Request, CardQ cardQManager, KernelQ qManager, EMVSelectApplicationResponse emvSelectApplicationResponse) { 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.TerminalRiskmanagementWasPerformed = true; tsi.UpdateDB(); //The state works as follows: //State_5_WaitingForCVMProcessing ends by possibly adding 2 messages to the card q //and 1 or 2 messages in the terminal q (get floor limit (optional) and do trm) //the card messages are processed by this state first, then the get floor limit by DEK if it //was in the q and then this method //Random Transaction Selection determined by terminal, not kernel //Terminal can also force transaction online //EMVTagsEnum.MAXIMUM_TARGET_PERCENTAGE_TO_BE_USED_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN //EMVTagsEnum.THRESHOLD_VALUE_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN //EMVTagsEnum.MAXIMUM_TARGET_PERCENTAGE_TO_BE_USED_FOR_BIASED_RANDOM_SELECTION_INTERNAL_KRN switch (((KernelTRMRequest)kernel1Request).KernelTRMRequestType) { case KernelTRMRequestType.GoOnlineForRandomSelection: tvr.Value.TransactionSelectedRandomlyForOnlineProcessing = true; tvr.UpdateDB(); break; case KernelTRMRequestType.GoOnline: tvr.Value.MerchantForcedTransactionOnline = true; tvr.UpdateDB(); break; } //Floor limit check done by kernel, no need for it to be done by terminal if (database.IsNotEmpty(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN.Tag)) { long aa = Formatting.BcdToLong(database.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN).Value); long fl = Formatting.BcdToLong(database.Get(EMVTagsEnum.TERMINAL_FLOOR_LIMIT_9F1B_KRN).Value); if (aa > fl) { tvr.Value.TransactionExceedsFloorLimit = true; tvr.UpdateDB(); } } //Velocity Check TLV lcol = database.Get(EMVTagsEnum.LOWER_CONSECUTIVE_OFFLINE_LIMIT_9F14_KRN); TLV ucol = database.Get(EMVTagsEnum.UPPER_CONSECUTIVE_OFFLINE_LIMIT_9F23_KRN); TLV atcTLV = database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag); TLV lastOnlineATCRegisterTLV = database.Get(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag); bool doVelocity = false; if (lcol != null && ucol != null) { if (database.Get(EMVTagsEnum.APPLICATION_TRANSACTION_COUNTER_ATC_9F36_KRN.Tag) != null && database.Get(EMVTagsEnum.LAST_ONLINE_APPLICATION_TRANSACTION_COUNTER_ATC_REGISTER_9F13_KRN.Tag) != null) { if (Formatting.ConvertToInt32(atcTLV.Value) > Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value)) { doVelocity = true; } else { // Set both the ‘Lower consecutive offline limit exceeded’ and the ‘Upper consecutive offline limit exceeded’ bits in the TVR to 1. // Not set the ‘New card’ indicator in the TVR unless the Last Online ATC Register is returned and equals zero. // End velocity checking for this transaction tvr.Value.LowerConsecutiveOfflineLimitExceeded = true; tvr.Value.UpperConsecutiveOfflineLimitExceeded = true; if (lastOnlineATCRegisterTLV != null) { if (Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value) == 0) { tvr.Value.NewCard = true; } } tvr.UpdateDB(); } } } if (doVelocity == true) { uint atc = Formatting.ConvertToInt32(atcTLV.Value); uint lastATC = Formatting.ConvertToInt32(lastOnlineATCRegisterTLV.Value); uint atcDiff = atc - lastATC; uint lcolInt = Formatting.ConvertToInt32(lcol.Value); uint ucolInt = Formatting.ConvertToInt32(ucol.Value); if (atcDiff > lcolInt) { //set ‘Lower consecutive offline limit exceeded’ bit in the TVR to 1 tvr.Value.LowerConsecutiveOfflineLimitExceeded = true; if (atcDiff > ucolInt) { //set the ‘Upper consecutive offline limit exceeded’ bit in the TVR to 1. tvr.Value.UpperConsecutiveOfflineLimitExceeded = true; } } if (lastATC == 0) { //set ‘New card’ bit in the TVR to 1. tvr.Value.NewCard = true; } tvr.UpdateDB(); } #region Book 3 Section 10.7 //Terminal Action Analysis of kernel 2 being used database.ACType.Value.DSACTypeEnum = TerminalActionAnalysis_7_8.TerminalActionAnalysis(database); #endregion #region Book 3 Section 10.8 //Card Action Analysis return(CardActionAnalysis.InitiateCardActionAnalysis(database, qManager, cardQManager, emvSelectApplicationResponse)); #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); }