public void ObserveEmv(EmvApplication emv) { emv.BeforeSelectEvent += BeforeApplicationSelection; emv.AfterSelectEvent += AfterApplicationSelection; emv.BeforeGetProcessingOptionsEvent += BeforeGetProcessingOptions; emv.AfterGetProcessingOptionsEvent += AfterGetProcessingOptions; emv.BeforeReadApplicationDataEvent += BeforeReadApplicationData; emv.AfterReadApplicationDataEvent += AfterReadApplicationData; emv.BeforeGetDataEvent += BeforeGetData; emv.AfterGetDataEvent += AfterGetData; emv.BeforeReadLogFileEvent += BeforeReadLogFile; emv.AfterReadLogFileEvent += AfterReadLogFile; emv.BeforeVerifyPinEvent += BeforeVerifyPin; emv.AfterVerifyPinEvent += AfterVerifyPin; emv.BeforeInternalAuthenticateEvent += BeforeInternalAuthenticate; emv.AfterInternalAuthenticateEvent += AfterInternalAuthenticate; emv.BeforeGetChallengeEvent += BeforeGetChallenge; emv.AfterGetChallengeEvent += AfterGetChallenge; emv.BeforeGenerateAC1Event += BeforeGenerateAc1; emv.AfterGenerateAC1Event += AfterGenerateAc1; }
private void UpdateAuthenticationTabSdaDone(EmvApplication emv) { if (emv.Sda != null) { guiSDARecoveredData.Text = emv.Sda.Recovered.ToHexa('\0'); guiSDAHashResult.Text = emv.Sda.HashResult.ToHexa(); guiSDADataAuthenticationCode.Text = emv.Sda.DataAuthenticationCode.ToHexa(); } }
private void UpdateAuthenticationTabDdaDone(EmvApplication emv) { if (emv.Dda != null) { guiDDARecoveredData.Text = emv.Dda.Recovered.ToHexa('\0'); guiDDAHashResult.Text = emv.Dda.HashResult.ToHexa(); guiDDAICCDynamicData.Text = emv.Dda.IccDynamicData.ToHexa(); } }
private void UpdateLogRecords(EmvApplication emv) { if (emv.LogRecords == null) { return; } // Initialize the output guiLogRecords.Columns.Clear(); guiLogRecords.Items.Clear(); // Set column names. If tag is known by tlvManager, its name is used instead of the tag number. guiLogRecords.Columns.Add("Record"); foreach (var dol in emv.LogFormat.GetDataObjectDefinitions()) { var tagStr = String.Format("{0:T}", dol); if (_tlvDictionary.Get(tagStr) != null) { guiLogRecords.Columns.Add(_tlvDictionary.Get(tagStr).Name); } else { guiLogRecords.Columns.Add(tagStr); } } // Fill the list view: 1 line (list view item) by record byte recordNumber = 0; foreach (var tlvDataList in emv.LogRecords) { recordNumber++; var item = new ListViewItem(String.Format("{0}", recordNumber)); foreach (var tlvData in tlvDataList) { // if tag is known by tlvManager, use the corresponding AbstractTLVObject else use BinaryTlvObject. var tagStr = String.Format("{0:T}", tlvData); if (_tlvDictionary.Get(tagStr) != null) { var tlvObject = _tlvDictionary.CreateInstance(tagStr); tlvObject.Tlv = tlvData; item.SubItems.Add(String.Format("{0}", tlvObject)); } else { AbstractTlvObject tlvObject = new BinaryTlvObject(); tlvObject.Tlv = tlvData; item.SubItems.Add(String.Format("{0}", tlvObject)); } } guiLogRecords.Items.Add(item); } guiLogRecords.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); guiDoCardLogSave.Enabled = true; }
private void ObserveEmv(EmvApplication emv) { emv.AfterSelectEvent += afterEMVSelectEventHandler; emv.AfterGetProcessingOptionsEvent += afterGetProcessingOptionsEventHandler; emv.AfterReadApplicationDataEvent += afterReadApplicationDataEventHandler; emv.AfterGetDataEvent += afterGetDataEventHandler; emv.AfterReadLogFileEvent += afterReadLogFileEventHandler; emv.AfterInternalAuthenticateEvent += afterInternalAuthenticateEventHandler; emv.AfterVerifyPinEvent += afterVerifyPinEventHandler; emv.AfterGenerateAC1Event += afterGenerateAC1EventHandler; }
private void UpdateAuthenticationTabSignedData(EmvApplication emv) { if (emv.TlvOfflineRecords != null) { var index = 0; foreach (var tlv in emv.TlvOfflineRecords) { index++; var item = new ListViewItem(String.Format("{0}", index)); // tag item.SubItems.Add(String.Format("{0:T}", tlv)); // name if (_tlvDictionary != null && _tlvDictionary.Get(String.Format("{0:T}", tlv)) != null) { var tlvObject = _tlvDictionary.CreateInstance(tlv); tlvObject.Tlv = tlv; item.SubItems.Add(String.Format("{0:N}", tlvObject)); } else { item.SubItems.Add(String.Format("")); } // value item.SubItems.Add(String.Format("{0:V}", tlv)); // insert item in SDA, DDA and/or CDA list if (emv.Aip.Sda) { guiSDASignedData.Items.Add((ListViewItem)item.Clone()); } if (emv.Aip.Dda) { guiDDASignedData.Items.Add((ListViewItem)item.Clone()); } if (emv.Aip.Cda) { guiCDASignedData.Items.Add((ListViewItem)item.Clone()); } } //if (emv.tlvDataRecords.hasTag(0x9F4A)) //{ // DataObjectList sdaTagList = new DataObjectList(); // sdaTagList.tlv = emv.tlvDataRecords.getTag(0x9F4A); //} } }
private void guiDoExplicitDiscoveryOfAID_Click(object sender, EventArgs e) { try { // Try to select AID known by the terminal and undiscovered in PSE foreach (var app in _pluginConfiguration.terminalConfiguration.TerminalCapabilities.SupportedApplications) { var notFound = true; foreach (var emvFound in _emvApplications) { if (emvFound.Aid == app.Aid) { notFound = false; } } // If AID not discovered, try to select it if (notFound) { var emv = new EmvApplication(SharedData.CardChannel, new TlvData()); emv.Aid = app.Aid; _detailedLogs.ObserveEmv(emv); ObserveEmv(emv); // If success, add the EMV ApplicationID instance to the candidate list if (emv.Select() == 0x9000) { _emvApplications.Add(emv); } } } // Enable next step ActivateEMVSelectAid(); // Update GUI UpdateApplicationsList(); } catch (Exception exception) { MessageBox.Show(exception.Message, "PSE Selection Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
private void UpdateTvr(EmvApplication emv) { // byte 1 guiTVR_1_1.Checked = emv.Tvr.OfflineDataAuthenticationNotPerformed; guiTVR_1_2.Checked = emv.Tvr.SdaFailed; guiTVR1_3.Checked = emv.Tvr.IccDataMissing; guiTVR1_4.Checked = emv.Tvr.TerminalExceptionFile; guiTVR1_5.Checked = emv.Tvr.DdaFailed; guiTVR1_6.Checked = emv.Tvr.CdaFailed; // byte 2 guiTVR2_1.Checked = emv.Tvr.IccAndTerminalVersionsDifferent; guiTVR2_2.Checked = emv.Tvr.ExpiredApplication; guiTVR2_3.Checked = emv.Tvr.NotYetEffectiveApplication; guiTVR2_4.Checked = emv.Tvr.ServiceNotAllowed; guiTVR2_5.Checked = emv.Tvr.NewCard; // byte 3 guiTVR3_1.Checked = emv.Tvr.CardholderVerificationFailed; guiTVR3_2.Checked = emv.Tvr.UnrecognisedCvm; guiTVR3_3.Checked = emv.Tvr.PINTryLimitExceeded; guiTVR3_4.Checked = emv.Tvr.PinpadError; guiTVR3_5.Checked = emv.Tvr.PINNotEntered; guiTVR3_6.Checked = emv.Tvr.OnlinePinEntered; // byte 4 guiTVR4_1.Checked = emv.Tvr.TransactionExceedFloorLimit; guiTVR4_2.Checked = emv.Tvr.LowerConsecutiveOfflineLimitExceeded; guiTVR4_3.Checked = emv.Tvr.UpperConsecutiveOfflineLimitExceeded; guiTVR4_4.Checked = emv.Tvr.TransactionRandomlySelectedOnline; guiTVR4_5.Checked = emv.Tvr.MerchantForcedTransactionOnline; // byte 5 guiTVR5_1.Checked = emv.Tvr.DefaultTdolUsed; guiTVR5_2.Checked = emv.Tvr.IssuerAuthenticationFailed; guiTVR5_3.Checked = emv.Tvr.ScriptProcessingFailedBeforeGenerateAC; guiTVR5_4.Checked = emv.Tvr.ScriptProcessingFailedAfterGenerateAC; }
private void UpdatePublicKeysTab(EmvApplication emv) { // Certification Authority Public Key var aidObject = new ApplicationIdentifier(emv.Aid); guiPublicKeysAID.Text = emv.Aid; guiPublicKeysRID.Text = aidObject.Rid; if (emv.TlvDataRecords.HasTag(0x8F)) { guiPublicKeysCAIndex.Text = emv.TlvDataRecords.GetTag(0x8F).Value.ToHexa(); } if (emv.CertificationAuthorityPublicKey != null) { guiPublicKeysCertificationAuthorityPKModulus.Text = emv.CertificationAuthorityPublicKey.Modulus; guiPublicKeysCertificationAuthorityPKExponent.Text = emv.CertificationAuthorityPublicKey.Exponent; } // Issuer Public Key if (emv.IssuerPublicKeyCertificate != null) { guiPublicKeysIssuerPKRecoveredData.Text = emv.IssuerPublicKeyCertificate.Recovered.ToHexa('\0'); guiPublicKeysIssuerPKHashResult.Text = emv.IssuerPublicKeyCertificate.HashResult.ToHexa(); guiPublicKeysIssuerPKModulus.Text = emv.IssuerPublicKey.Modulus; guiPublicKeysIssuerPKExponent.Text = emv.IssuerPublicKey.Exponent; } // ICC Public Key if (emv.IccPublicKeyCertificate != null) { guiPublicKeysICCPKRecoveredData.Text = emv.IccPublicKeyCertificate.Recovered.ToHexa('\0'); guiPublicKeysICCPKHashResult.Text = emv.IccPublicKeyCertificate.HashResult.ToHexa(); guiPublicKeysICCPKModulus.Text = emv.IccPublicKey.Modulus; guiPublicKeysICCPKExponent.Text = emv.IccPublicKey.Exponent; } }
private void guiDoSelectAID_Click(object sender, EventArgs e) { // Get the EMV ApplicationID instance _emv = (EmvApplication)guiApplicationAID.SelectedItem; // Check if it is a valid instance if (_emv == null) { MessageBox.Show("An EMV application must be first selected.", "EMV application missing", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } // Set the Certification Authorities _emv.CertificationAuthorityRepository = _certificationAuthorityRepository; // Add default terminal data _emv.TlvTerminalData.AddRange(_pluginConfiguration.transactionContext.TlvDatas); // Select the PSE _emv.Select(); // Enable next step ActivateEMVGetProcessingOptions(); }
private void updateAfterAIDSelect_Content(EmvApplication emv) { var emvAppNode = new TreeNode(emv.Aid); var fciNode = new TreeNode("File Control Information"); emvAppNode.Nodes.Add(fciNode); if (emv.TlvFci != null) { fciNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvFci, _tlvDictionary)); } else { var errorNode = new TreeNode(String.Format("EMV application [{0}] not found.", emv.Aid)); fciNode.Nodes.Add(errorNode); } var optionsNode = new TreeNode("Processing Options"); emvAppNode.Nodes.Add(optionsNode); if (emv.TlvProcessingOptions != null) { optionsNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvProcessingOptions, _tlvDictionary)); } else { var errorNode = new TreeNode(String.Format("Processing Options not found.")); optionsNode.Nodes.Add(errorNode); } var aipNode = new TreeNode("Application Interchange Profile"); optionsNode.Nodes.Add(aipNode); if (emv.Aip != null) { aipNode.Nodes.Add(String.Format("{0}", emv.Aip)); } else { var errorNode = new TreeNode(String.Format("AIP not found.")); aipNode.Nodes.Add(errorNode); } var aflNode = new TreeNode("Application File Locator"); optionsNode.Nodes.Add(aflNode); if (emv.Afl != null) { foreach (var file in emv.Afl.Files) { aflNode.Nodes.Add(new TreeNode(String.Format("{0}", file))); } } else { var errorNode = new TreeNode(String.Format("AFL not found.")); aflNode.Nodes.Add(errorNode); } var recordsNode = new TreeNode("Records"); emvAppNode.Nodes.Add(recordsNode); if (emv.TlvRecords.Count != 0) { byte recordNumber = 0; foreach (var tlv70 in emv.TlvRecords) { recordNumber++; var recordNode = new TreeNode(String.Format("Record {0}", recordNumber)); recordNode.Nodes.Add(ConvertTlvDataToTreeNode(tlv70, _tlvDictionary)); recordsNode.Nodes.Add(recordNode); } } else { var errorNode = new TreeNode(String.Format("No records found.")); recordsNode.Nodes.Add(errorNode); } var dataNode = new TreeNode("Get data"); emvAppNode.Nodes.Add(dataNode); if (emv.TlvATC != null) { dataNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvATC, _tlvDictionary)); } if (emv.TlvLastOnlineATCRegister != null) { dataNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvLastOnlineATCRegister, _tlvDictionary)); } if (emv.TlvLogFormat != null) { dataNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvLogFormat, _tlvDictionary)); } if (emv.TlvPINTryCounter != null) { dataNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvPINTryCounter, _tlvDictionary)); } var internalAuthenticateNode = new TreeNode("Internal Authenticate"); emvAppNode.Nodes.Add(internalAuthenticateNode); if (emv.TlvSignedDynamicApplicationResponse != null) { internalAuthenticateNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvInternalAuthenticateUnpredictableNumber, _tlvDictionary)); internalAuthenticateNode.Nodes.Add(ConvertTlvDataToTreeNode(emv.TlvSignedDynamicApplicationResponse, _tlvDictionary)); } else { var errorNode = new TreeNode("Internal authenticate APDU not done or failed."); internalAuthenticateNode.Nodes.Add(errorNode); } var sdaNode = new TreeNode("Static Data Authentication"); emvAppNode.Nodes.Add(sdaNode); if (emv.Sda != null) { sdaNode.Nodes.Add(new TreeNode(String.Format("Hash Algorithm Indicator: {0:X2}", emv.Sda.HashAlgorithmIndicator))); sdaNode.Nodes.Add(new TreeNode(String.Format("Hash Result: {0}", emv.Sda.HashResult.ToHexa()))); sdaNode.Nodes.Add(new TreeNode(String.Format("Data Authentication Code: {0}", emv.Sda.DataAuthenticationCode.ToHexa()))); } else { sdaNode.Nodes.Add("SDA not done, supported or cryptographic error"); } var ddaNode = new TreeNode("Dynamic Data Authentication"); emvAppNode.Nodes.Add(ddaNode); if (emv.Dda != null) { ddaNode.Nodes.Add(new TreeNode(String.Format("Hash Algorithm Indicator: {0:X2}", emv.Dda.HashAlgorithmIndicator))); ddaNode.Nodes.Add(new TreeNode(String.Format("Hash Result: {0}", emv.Dda.HashResult.ToHexa()))); ddaNode.Nodes.Add(new TreeNode(String.Format("ICC Dynamic Data Length:{0:X2}", emv.Dda.IccDynamicDataLength))); ddaNode.Nodes.Add(new TreeNode(String.Format("ICC Dynamic Data: {0}", emv.Dda.IccDynamicData.ToHexa()))); } else { ddaNode.Nodes.Add("DDA not done, supported or cryptographic error"); } var pinNode = new TreeNode("Cardholder Verification"); emvAppNode.Nodes.Add(pinNode); pinNode.Nodes.Add(new TreeNode(String.Format("TVR :: Cardholder Verification: {0}", (emv.Tvr.CardholderVerificationFailed ? "failed" : "success")))); if (emv.VerifyPinStatusWord != 0x0000) { pinNode.Nodes.Add(new TreeNode(String.Format("VERIFY PIN status: 0x{0:X4}", emv.VerifyPinStatusWord))); } var AC1Node = new TreeNode("Application Cryptogram 1"); emvAppNode.Nodes.Add(AC1Node); if (emv.TlvGenerateAC1Response != null) { AC1Node.Nodes.Add(new TreeNode(String.Format("Requested AC: {0}", emv.RequestedAC1Type))); AC1Node.Nodes.Add(new TreeNode(String.Format("Unpredictable Number: {0}", emv.TlvGenerateAC1UnpredictableNumber.Value.ToHexa()))); var responseNode = new TreeNode(String.Format("Response: {0}", emv.TlvGenerateAC1Response)); AC1Node.Nodes.Add(responseNode); responseNode.Nodes.Add(new TreeNode(String.Format("Cryptogram Information Data: {0}", emv.Cid1))); responseNode.Nodes.Add(new TreeNode(String.Format("Application Transaction Counter: {0}", emv.AtcFromAC1))); } guiEMVApplicationsContent.Nodes.Clear(); guiEMVApplicationsContent.Nodes.Add(emvAppNode); guiEMVApplicationsContent.ExpandAll(); }