/* * SecureBlackbox 2024 .NET Edition - Sample Project * * This sample project demonstrates the usage of SecureBlackbox in a * simple, straightforward way. It is not intended to be a complete * application. Error handling and other checks are simplified for clarity. * * www.nsoftware.com/secureblackbox * * This code is subject to the terms and conditions specified in the * corresponding product license agreement which outlines the authorized * usage and restrictions. * */ using System; using System.Windows.Forms; using nsoftware.SecureBlackbox; namespace PKCS11CertificateStorage { /// /// Summary description for Form1. /// public class frmMain : System.Windows.Forms.Form { private System.Windows.Forms.MainMenu MainMenu; private System.Windows.Forms.OpenFileDialog OpenDialog; private System.Windows.Forms.OpenFileDialog OpenDialogCert; private System.Windows.Forms.ImageList ImageList; private System.Windows.Forms.MenuItem menuItem1; private System.Windows.Forms.MenuItem menuItem6; private System.Windows.Forms.MenuItem mnuOpenStorage; private System.Windows.Forms.MenuItem mnuCloseStorage; private System.Windows.Forms.MenuItem mnuExit; private FolderBrowserDialog folderBrowserDialog; private MenuItem mnuSaveStorage; private Panel panelMain; private Label label1; private Panel panel1; private Panel panel3; private ListView lvCerts; private ColumnHeader chSubject; private ColumnHeader chIssuer; private ColumnHeader chValidFrom; private ColumnHeader chValidTo; private ColumnHeader chAlgorithm; private Panel panel2; private Button btnProcessFiles; private Button btnRemoveCert; private Button btnOpen; private ComboBox cbSlots; private Label lbAvailableSlots; private Button btnAddCert; private System.ComponentModel.IContainer components; public frmMain() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // certstorage = new CertificateStorage(); certstorage.OnPasswordNeeded += new CertificateStorage.OnPasswordNeededHandler(DoPasswordNeeded); SetupButtons(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { if (certstorage.Opened) certstorage.Close(false); certstorage.Dispose(); components.Dispose(); frmPIN.Dispose(); frmProcessor.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmMain)); this.MainMenu = new System.Windows.Forms.MainMenu(this.components); this.menuItem1 = new System.Windows.Forms.MenuItem(); this.mnuOpenStorage = new System.Windows.Forms.MenuItem(); this.mnuSaveStorage = new System.Windows.Forms.MenuItem(); this.mnuCloseStorage = new System.Windows.Forms.MenuItem(); this.menuItem6 = new System.Windows.Forms.MenuItem(); this.mnuExit = new System.Windows.Forms.MenuItem(); this.OpenDialog = new System.Windows.Forms.OpenFileDialog(); this.OpenDialogCert = new System.Windows.Forms.OpenFileDialog(); this.ImageList = new System.Windows.Forms.ImageList(this.components); this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); this.panelMain = new System.Windows.Forms.Panel(); this.label1 = new System.Windows.Forms.Label(); this.panel1 = new System.Windows.Forms.Panel(); this.panel3 = new System.Windows.Forms.Panel(); this.lvCerts = new System.Windows.Forms.ListView(); this.chSubject = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chIssuer = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chValidFrom = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chValidTo = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.chAlgorithm = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); this.panel2 = new System.Windows.Forms.Panel(); this.btnProcessFiles = new System.Windows.Forms.Button(); this.btnRemoveCert = new System.Windows.Forms.Button(); this.btnOpen = new System.Windows.Forms.Button(); this.cbSlots = new System.Windows.Forms.ComboBox(); this.lbAvailableSlots = new System.Windows.Forms.Label(); this.btnAddCert = new System.Windows.Forms.Button(); this.panelMain.SuspendLayout(); this.panel1.SuspendLayout(); this.panel3.SuspendLayout(); this.panel2.SuspendLayout(); this.SuspendLayout(); // // MainMenu // this.MainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.menuItem1}); // // menuItem1 // this.menuItem1.Index = 0; this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.mnuOpenStorage, this.mnuSaveStorage, this.mnuCloseStorage, this.menuItem6, this.mnuExit}); this.menuItem1.Text = "File"; // // mnuOpenStorage // this.mnuOpenStorage.Index = 0; this.mnuOpenStorage.Text = "Open storage..."; this.mnuOpenStorage.Click += new System.EventHandler(this.mnuOpenStorage_Click); // // mnuSaveStorage // this.mnuSaveStorage.Index = 1; this.mnuSaveStorage.Text = "Save and close storage"; this.mnuSaveStorage.Click += new System.EventHandler(this.mnuSaveStorage_Click); // // mnuCloseStorage // this.mnuCloseStorage.Index = 2; this.mnuCloseStorage.Text = "Close storage"; this.mnuCloseStorage.Click += new System.EventHandler(this.mnuCloseStorage_Click); // // menuItem6 // this.menuItem6.Index = 3; this.menuItem6.Text = "-"; // // mnuExit // this.mnuExit.Index = 4; this.mnuExit.Text = "Exit"; this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click); // // OpenDialog // this.OpenDialog.Filter = "PKCS #11 Library (*.dll)|*.dll"; this.OpenDialog.InitialDirectory = "."; this.OpenDialog.Title = "Please select PKCS #11 Library file"; // // OpenDialogCert // this.OpenDialogCert.Filter = "PKCS#12 Certificate (*.pfx)|*.pfx"; this.OpenDialogCert.InitialDirectory = "."; // // ImageList // this.ImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImageList.ImageStream"))); this.ImageList.TransparentColor = System.Drawing.Color.Magenta; this.ImageList.Images.SetKeyName(0, ""); this.ImageList.Images.SetKeyName(1, ""); this.ImageList.Images.SetKeyName(2, ""); this.ImageList.Images.SetKeyName(3, ""); // // panelMain // this.panelMain.Controls.Add(this.label1); this.panelMain.Dock = System.Windows.Forms.DockStyle.Top; this.panelMain.Location = new System.Drawing.Point(0, 0); this.panelMain.Name = "panelMain"; this.panelMain.Size = new System.Drawing.Size(604, 30); this.panelMain.TabIndex = 4; // // label1 // this.label1.AutoSize = true; this.label1.ForeColor = System.Drawing.SystemColors.Highlight; this.label1.Location = new System.Drawing.Point(10, 10); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(449, 13); this.label1.TabIndex = 0; this.label1.Text = "This sample illustrates the use of CertificateStorage component for work with PKC" + "S11 storage."; // // panel1 // this.panel1.Controls.Add(this.panel3); this.panel1.Controls.Add(this.panel2); this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; this.panel1.Location = new System.Drawing.Point(0, 30); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(604, 300); this.panel1.TabIndex = 5; // // panel3 // this.panel3.Controls.Add(this.lvCerts); this.panel3.Dock = System.Windows.Forms.DockStyle.Fill; this.panel3.Location = new System.Drawing.Point(0, 65); this.panel3.Name = "panel3"; this.panel3.Size = new System.Drawing.Size(604, 235); this.panel3.TabIndex = 5; // // lvCerts // this.lvCerts.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.chSubject, this.chIssuer, this.chValidFrom, this.chValidTo, this.chAlgorithm}); this.lvCerts.Dock = System.Windows.Forms.DockStyle.Fill; this.lvCerts.FullRowSelect = true; this.lvCerts.Location = new System.Drawing.Point(0, 0); this.lvCerts.MultiSelect = false; this.lvCerts.Name = "lvCerts"; this.lvCerts.Size = new System.Drawing.Size(604, 235); this.lvCerts.SmallImageList = this.ImageList; this.lvCerts.TabIndex = 4; this.lvCerts.UseCompatibleStateImageBehavior = false; this.lvCerts.View = System.Windows.Forms.View.Details; this.lvCerts.SelectedIndexChanged += new System.EventHandler(this.lvCerts_SelectedIndexChanged); // // chSubject // this.chSubject.Text = "Subject"; this.chSubject.Width = 150; // // chIssuer // this.chIssuer.Text = "Issuer"; this.chIssuer.Width = 150; // // chValidFrom // this.chValidFrom.Text = "Valid from"; this.chValidFrom.Width = 80; // // chValidTo // this.chValidTo.Text = "Valid to"; this.chValidTo.Width = 80; // // chAlgorithm // this.chAlgorithm.Text = "Algorithm"; this.chAlgorithm.Width = 100; // // panel2 // this.panel2.Controls.Add(this.btnProcessFiles); this.panel2.Controls.Add(this.btnRemoveCert); this.panel2.Controls.Add(this.btnOpen); this.panel2.Controls.Add(this.cbSlots); this.panel2.Controls.Add(this.lbAvailableSlots); this.panel2.Controls.Add(this.btnAddCert); this.panel2.Dock = System.Windows.Forms.DockStyle.Top; this.panel2.Location = new System.Drawing.Point(0, 0); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(604, 65); this.panel2.TabIndex = 4; // // btnProcessFiles // this.btnProcessFiles.Enabled = false; this.btnProcessFiles.Location = new System.Drawing.Point(496, 30); this.btnProcessFiles.Name = "btnProcessFiles"; this.btnProcessFiles.Size = new System.Drawing.Size(88, 25); this.btnProcessFiles.TabIndex = 5; this.btnProcessFiles.Text = "Process Files"; this.btnProcessFiles.Click += new System.EventHandler(this.btnProcessFiles_Click); // // btnRemoveCert // this.btnRemoveCert.Location = new System.Drawing.Point(376, 30); this.btnRemoveCert.Name = "btnRemoveCert"; this.btnRemoveCert.Size = new System.Drawing.Size(112, 25); this.btnRemoveCert.TabIndex = 4; this.btnRemoveCert.Text = "Remove Certificate"; this.btnRemoveCert.Click += new System.EventHandler(this.btnRemoveCert_Click); // // btnOpen // this.btnOpen.Location = new System.Drawing.Point(184, 30); this.btnOpen.Name = "btnOpen"; this.btnOpen.Size = new System.Drawing.Size(75, 25); this.btnOpen.TabIndex = 2; this.btnOpen.Text = "Open"; this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click); // // cbSlots // this.cbSlots.Location = new System.Drawing.Point(16, 32); this.cbSlots.Name = "cbSlots"; this.cbSlots.Size = new System.Drawing.Size(160, 21); this.cbSlots.TabIndex = 1; // // lbAvailableSlots // this.lbAvailableSlots.Location = new System.Drawing.Point(16, 8); this.lbAvailableSlots.Name = "lbAvailableSlots"; this.lbAvailableSlots.Size = new System.Drawing.Size(100, 13); this.lbAvailableSlots.TabIndex = 0; this.lbAvailableSlots.Text = "Available slots:"; // // btnAddCert // this.btnAddCert.Location = new System.Drawing.Point(272, 30); this.btnAddCert.Name = "btnAddCert"; this.btnAddCert.Size = new System.Drawing.Size(96, 25); this.btnAddCert.TabIndex = 3; this.btnAddCert.Text = "Add Certificate"; this.btnAddCert.Click += new System.EventHandler(this.btnAddCert_Click); // // frmMain // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(604, 330); this.Controls.Add(this.panel1); this.Controls.Add(this.panelMain); this.Menu = this.MainMenu; this.Name = "frmMain"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "PKCS11 Certificate storage demo"; this.panelMain.ResumeLayout(false); this.panelMain.PerformLayout(); this.panel1.ResumeLayout(false); this.panel3.ResumeLayout(false); this.panel2.ResumeLayout(false); this.ResumeLayout(false); } #endregion /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new frmMain()); } frmPIN frmPIN = new frmPIN(); frmProcessor frmProcessor = new frmProcessor(); CertificateStorage certstorage; string storageFilename = ""; string certPassword = ""; private void DoPasswordNeeded(object sender, CertificateStoragePasswordNeededEventArgs e) { e.Password = certPassword; } private void mnuOpenStorage_Click(object sender, System.EventArgs e) { if (OpenDialog.ShowDialog() == DialogResult.OK) { storageFilename = OpenDialog.FileName; OpenStorage(); } } private void mnuSaveStorage_Click(object sender, EventArgs e) { CloseStorage(true); } private void mnuCloseStorage_Click(object sender, System.EventArgs e) { CloseStorage(false); } private void mnuExit_Click(object sender, System.EventArgs e) { CloseStorage(false); Application.Exit(); } public int StrToIntDef(string s, int @default) { int number; if (int.TryParse(s, out number)) return number; return @default; } private void OpenStorage() { CloseStorage(false); cbSlots.Items.Add(""); try { certstorage.Open("pkcs11:///" + storageFilename + "?slot=-1"); int slotCount = StrToIntDef(certstorage.Config("PKCS11SlotCount"), 0); for (int i = 0; i < slotCount; i++) { cbSlots.Items.Add(certstorage.Config("PKCS11SlotDescription[" + i.ToString() + "]")); } cbSlots.SelectedIndex = 0; } catch (Exception E) { CloseStorage(false); MessageBox.Show("Error opening storage: " + storageFilename + "\r\n" + E.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } SetupButtons(); } private void CloseStorage(bool save) { if (certstorage.Opened) certstorage.Close(save); cbSlots.Items.Clear(); lvCerts.Items.Clear(); SetupButtons(); } private void SetupButtons() { btnAddCert.Enabled = certstorage.Opened && (StrToIntDef(certstorage.Config("PKCS11ActiveSlot"), -1) >= 0); btnRemoveCert.Enabled = certstorage.Opened && (StrToIntDef(certstorage.Config("PKCS11ActiveSlot"), -1) >= 0); mnuSaveStorage.Enabled = certstorage.Opened; mnuCloseStorage.Enabled = certstorage.Opened; btnOpen.Enabled = certstorage.Opened; } private void AddCertificate() { if (OpenDialogCert.ShowDialog() == DialogResult.OK) { if (RequestPassword("Password request", "Please enter password for certificate:", out certPassword)) { try { certstorage.ImportFromFile(OpenDialogCert.FileName, certPassword, false); } catch (Exception E) { MessageBox.Show("Failed to load certificate, error " +E.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } RefreshCertificates(); } } } private void RemoveCertificate() { string S; if ((lvCerts.SelectedIndices.Count > 0) && (lvCerts.SelectedIndices[0] < certstorage.Certificates.Count)) { Certificate Cert = certstorage.Certificates[lvCerts.SelectedIndices[0]]; S = "Subject: " + Cert.Subject + "\r\nIssuer: " + Cert.Issuer; if (MessageBox.Show("The following certificate will be deleted:\r\n" + S, "", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) { certstorage.Remove(lvCerts.SelectedIndices[0]); RefreshCertificates(); } } } private void OpenSlot() { string Pin; string RO; // Checking whether we can establish a new session if (cbSlots.SelectedIndex <= 0) return; if (certstorage.Config("PKCS11SlotTokenPresent[" + (cbSlots.SelectedIndex - 1).ToString() + "]").ToUpper() != "TRUE") { MessageBox.Show("Token not found in specified slot", "", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (certstorage.Config("PKCS11SlotReadOnly[" + (cbSlots.SelectedIndex - 1).ToString() + "]").ToUpper() == "TRUE") { RO = "&readonly=1"; } else { RO = "&readonly=0"; } if (RequestPassword("PIN request", "Please enter your PIN:", out Pin)) { if (certstorage.Opened) certstorage.Close(false); try { certstorage.Open("pkcs11://user:" + Pin + "@/" + storageFilename + "?slot=" + (cbSlots.SelectedIndex - 1).ToString() + RO); RefreshCertificates(); SetupButtons(); } catch (Exception E) { MessageBox.Show("Error opening slot:" + E.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error); OpenStorage(); return; } } } private void RefreshCertificates() { Certificate Cert; ListViewItem Item; lvCerts.Items.Clear(); for (int i = 0; i < certstorage.Certificates.Count; i++) { Cert = certstorage.Certificates[i]; Item = lvCerts.Items.Add(""); Item.ImageIndex = 3; // Subject Item.Text = Cert.Subject; // Issuer Item.SubItems.Add(Cert.Issuer); // Validity period Item.SubItems.Add(Cert.ValidFrom); Item.SubItems.Add(Cert.ValidTo); // Algorithm Item.SubItems.Add(Cert.KeyAlgorithm + " (" + Cert.PublicKeyBytes.ToString() + " bits)"); } } private Boolean RequestPassword(string Caption, string Prompt, out string Pass) { frmPIN.lbPrompt.Text = Prompt; frmPIN.Text = Caption; frmPIN.edPIN.Text = ""; frmPIN.edPIN.Focus(); Pass = ""; if (frmPIN.ShowDialog() == DialogResult.OK) { Pass = frmPIN.edPIN.Text; return true; } else return false; } private void ProcessFiles() { if ((lvCerts.SelectedIndices.Count > 0) && (lvCerts.SelectedIndices[0] < certstorage.Certificates.Count)) { frmProcessor.Cert = certstorage.Certificates[lvCerts.SelectedIndices[0]]; frmProcessor.ShowDialog(); } } private void btnOpen_Click(object sender, System.EventArgs e) { OpenSlot(); } private void btnAddCert_Click(object sender, System.EventArgs e) { AddCertificate(); } private void btnRemoveCert_Click(object sender, System.EventArgs e) { if (lvCerts.SelectedIndices.Count > 0) RemoveCertificate(); } private void btnProcessFiles_Click(object sender, System.EventArgs e) { if (lvCerts.SelectedIndices.Count > 0) ProcessFiles(); } private void lvCerts_SelectedIndexChanged(object sender, System.EventArgs e) { btnRemoveCert.Enabled = (lvCerts.SelectedIndices.Count > 0); btnProcessFiles.Enabled = (lvCerts.SelectedIndices.Count > 0); } } }