502 lines
20 KiB
C#
502 lines
20 KiB
C#
|
/*
|
||
|
* 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 PDFSignerDemo
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Summary description for frmMain.
|
||
|
/// </summary>
|
||
|
public class MainForm : System.Windows.Forms.Form
|
||
|
{
|
||
|
private System.Windows.Forms.Label lbInputFile;
|
||
|
private System.Windows.Forms.TextBox edInputFile;
|
||
|
private System.Windows.Forms.Button sbBrowseInputFile;
|
||
|
private System.Windows.Forms.OpenFileDialog dlgOpen;
|
||
|
/// <summary>
|
||
|
/// Required designer variable.
|
||
|
/// </summary>
|
||
|
private System.ComponentModel.Container components = null;
|
||
|
private System.Windows.Forms.Button btnSign;
|
||
|
private TextBox edOutputFile;
|
||
|
private Button sbBrowseOutputFile;
|
||
|
private Label label2;
|
||
|
|
||
|
private SaveFileDialog dlgSave;
|
||
|
public CheckBox cbVisible;
|
||
|
private Label label1;
|
||
|
private ComboBox cbLevel;
|
||
|
private Button btnLoadCert;
|
||
|
private TextBox edStoragePIN;
|
||
|
private Label label6;
|
||
|
private Label label7;
|
||
|
private GroupBox groupBox5;
|
||
|
private ListView lvCerts;
|
||
|
private ColumnHeader chSubject;
|
||
|
private ColumnHeader chIssuer;
|
||
|
private ColumnHeader chValidFrom;
|
||
|
private ColumnHeader chValidTo;
|
||
|
private ColumnHeader chAlgorithm;
|
||
|
private PDFSigner signer;
|
||
|
private OpenFileDialog dlgOpenDLL;
|
||
|
private CertificateStorage certstorage;
|
||
|
|
||
|
public MainForm()
|
||
|
{
|
||
|
//
|
||
|
// Required for Windows Form Designer support
|
||
|
//
|
||
|
InitializeComponent();
|
||
|
|
||
|
//
|
||
|
// TODO: Add any constructor code after InitializeComponent call
|
||
|
//
|
||
|
signer = new PDFSigner();
|
||
|
certstorage = new CertificateStorage();
|
||
|
|
||
|
cbLevel.SelectedIndex = 1;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Clean up any resources being used.
|
||
|
/// </summary>
|
||
|
protected override void Dispose(bool disposing)
|
||
|
{
|
||
|
if (disposing)
|
||
|
{
|
||
|
if (components != null)
|
||
|
{
|
||
|
components.Dispose();
|
||
|
signer.Dispose();
|
||
|
certstorage.Dispose();
|
||
|
}
|
||
|
}
|
||
|
base.Dispose(disposing);
|
||
|
}
|
||
|
|
||
|
#region Windows Form Designer generated code
|
||
|
/// <summary>
|
||
|
/// Required method for Designer support - do not modify
|
||
|
/// the contents of this method with the code editor.
|
||
|
/// </summary>
|
||
|
private void InitializeComponent()
|
||
|
{
|
||
|
this.lbInputFile = new System.Windows.Forms.Label();
|
||
|
this.edInputFile = new System.Windows.Forms.TextBox();
|
||
|
this.sbBrowseInputFile = new System.Windows.Forms.Button();
|
||
|
this.btnSign = new System.Windows.Forms.Button();
|
||
|
this.dlgOpen = new System.Windows.Forms.OpenFileDialog();
|
||
|
this.edOutputFile = new System.Windows.Forms.TextBox();
|
||
|
this.sbBrowseOutputFile = new System.Windows.Forms.Button();
|
||
|
this.label2 = new System.Windows.Forms.Label();
|
||
|
this.dlgSave = new System.Windows.Forms.SaveFileDialog();
|
||
|
this.cbVisible = new System.Windows.Forms.CheckBox();
|
||
|
this.label1 = new System.Windows.Forms.Label();
|
||
|
this.cbLevel = new System.Windows.Forms.ComboBox();
|
||
|
this.btnLoadCert = new System.Windows.Forms.Button();
|
||
|
this.edStoragePIN = new System.Windows.Forms.TextBox();
|
||
|
this.label6 = new System.Windows.Forms.Label();
|
||
|
this.label7 = new System.Windows.Forms.Label();
|
||
|
this.groupBox5 = new System.Windows.Forms.GroupBox();
|
||
|
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.dlgOpenDLL = new System.Windows.Forms.OpenFileDialog();
|
||
|
this.groupBox5.SuspendLayout();
|
||
|
this.SuspendLayout();
|
||
|
//
|
||
|
// lbInputFile
|
||
|
//
|
||
|
this.lbInputFile.Location = new System.Drawing.Point(5, 33);
|
||
|
this.lbInputFile.Name = "lbInputFile";
|
||
|
this.lbInputFile.Size = new System.Drawing.Size(60, 13);
|
||
|
this.lbInputFile.TabIndex = 0;
|
||
|
this.lbInputFile.Text = "Input file:";
|
||
|
//
|
||
|
// edInputFile
|
||
|
//
|
||
|
this.edInputFile.Location = new System.Drawing.Point(70, 30);
|
||
|
this.edInputFile.Name = "edInputFile";
|
||
|
this.edInputFile.Size = new System.Drawing.Size(334, 20);
|
||
|
this.edInputFile.TabIndex = 1;
|
||
|
//
|
||
|
// sbBrowseInputFile
|
||
|
//
|
||
|
this.sbBrowseInputFile.Location = new System.Drawing.Point(410, 27);
|
||
|
this.sbBrowseInputFile.Name = "sbBrowseInputFile";
|
||
|
this.sbBrowseInputFile.Size = new System.Drawing.Size(75, 25);
|
||
|
this.sbBrowseInputFile.TabIndex = 2;
|
||
|
this.sbBrowseInputFile.Text = "Browse...";
|
||
|
this.sbBrowseInputFile.Click += new System.EventHandler(this.sbBrowseInputFile_Click);
|
||
|
//
|
||
|
// btnSign
|
||
|
//
|
||
|
this.btnSign.Location = new System.Drawing.Point(620, 389);
|
||
|
this.btnSign.Name = "btnSign";
|
||
|
this.btnSign.Size = new System.Drawing.Size(75, 25);
|
||
|
this.btnSign.TabIndex = 8;
|
||
|
this.btnSign.Text = "Sign";
|
||
|
this.btnSign.Click += new System.EventHandler(this.btnSign_Click);
|
||
|
//
|
||
|
// edOutputFile
|
||
|
//
|
||
|
this.edOutputFile.Location = new System.Drawing.Point(70, 60);
|
||
|
this.edOutputFile.Name = "edOutputFile";
|
||
|
this.edOutputFile.Size = new System.Drawing.Size(334, 20);
|
||
|
this.edOutputFile.TabIndex = 3;
|
||
|
//
|
||
|
// sbBrowseOutputFile
|
||
|
//
|
||
|
this.sbBrowseOutputFile.Location = new System.Drawing.Point(410, 57);
|
||
|
this.sbBrowseOutputFile.Name = "sbBrowseOutputFile";
|
||
|
this.sbBrowseOutputFile.Size = new System.Drawing.Size(75, 25);
|
||
|
this.sbBrowseOutputFile.TabIndex = 4;
|
||
|
this.sbBrowseOutputFile.Text = "Browse...";
|
||
|
this.sbBrowseOutputFile.Click += new System.EventHandler(this.sbBrowseOutputFile_Click);
|
||
|
//
|
||
|
// label2
|
||
|
//
|
||
|
this.label2.Location = new System.Drawing.Point(5, 63);
|
||
|
this.label2.Name = "label2";
|
||
|
this.label2.Size = new System.Drawing.Size(60, 13);
|
||
|
this.label2.TabIndex = 18;
|
||
|
this.label2.Text = "Output file:";
|
||
|
//
|
||
|
// cbVisible
|
||
|
//
|
||
|
this.cbVisible.AutoSize = true;
|
||
|
this.cbVisible.Checked = true;
|
||
|
this.cbVisible.CheckState = System.Windows.Forms.CheckState.Checked;
|
||
|
this.cbVisible.Location = new System.Drawing.Point(203, 32);
|
||
|
this.cbVisible.Name = "cbVisible";
|
||
|
this.cbVisible.Size = new System.Drawing.Size(102, 17);
|
||
|
this.cbVisible.TabIndex = 3;
|
||
|
this.cbVisible.Text = "Visible signature";
|
||
|
//
|
||
|
// label1
|
||
|
//
|
||
|
this.label1.AutoSize = true;
|
||
|
this.label1.Location = new System.Drawing.Point(7, 33);
|
||
|
this.label1.Name = "label1";
|
||
|
this.label1.Size = new System.Drawing.Size(36, 13);
|
||
|
this.label1.TabIndex = 34;
|
||
|
this.label1.Text = "Level:";
|
||
|
//
|
||
|
// cbLevel
|
||
|
//
|
||
|
this.cbLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||
|
this.cbLevel.FormattingEnabled = true;
|
||
|
this.cbLevel.Items.AddRange(new object[] {
|
||
|
"Generic/Legacy",
|
||
|
"Baseline B",
|
||
|
"Baseline T",
|
||
|
"Baseline LT",
|
||
|
"Baseline LTA",
|
||
|
"BES",
|
||
|
"EPES",
|
||
|
"LTV"});
|
||
|
this.cbLevel.Location = new System.Drawing.Point(54, 30);
|
||
|
this.cbLevel.Name = "cbLevel";
|
||
|
this.cbLevel.Size = new System.Drawing.Size(121, 21);
|
||
|
this.cbLevel.TabIndex = 2;
|
||
|
//
|
||
|
// btnLoadCert
|
||
|
//
|
||
|
this.btnLoadCert.Location = new System.Drawing.Point(524, 67);
|
||
|
this.btnLoadCert.Name = "btnLoadCert";
|
||
|
this.btnLoadCert.Size = new System.Drawing.Size(160, 25);
|
||
|
this.btnLoadCert.TabIndex = 5;
|
||
|
this.btnLoadCert.Text = "Load certificates...";
|
||
|
this.btnLoadCert.Click += new System.EventHandler(this.btnLoadCert_Click);
|
||
|
//
|
||
|
// edStoragePIN
|
||
|
//
|
||
|
this.edStoragePIN.Location = new System.Drawing.Point(202, 70);
|
||
|
this.edStoragePIN.Name = "edStoragePIN";
|
||
|
this.edStoragePIN.PasswordChar = '*';
|
||
|
this.edStoragePIN.Size = new System.Drawing.Size(319, 20);
|
||
|
this.edStoragePIN.TabIndex = 4;
|
||
|
//
|
||
|
// label6
|
||
|
//
|
||
|
this.label6.AutoSize = true;
|
||
|
this.label6.Location = new System.Drawing.Point(7, 73);
|
||
|
this.label6.Name = "label6";
|
||
|
this.label6.Size = new System.Drawing.Size(186, 13);
|
||
|
this.label6.TabIndex = 44;
|
||
|
this.label6.Text = "PIN to the PKI Proxy PKCS#11 driver:";
|
||
|
//
|
||
|
// label7
|
||
|
//
|
||
|
this.label7.AutoSize = true;
|
||
|
this.label7.ForeColor = System.Drawing.SystemColors.Highlight;
|
||
|
this.label7.Location = new System.Drawing.Point(5, 5);
|
||
|
this.label7.Name = "label7";
|
||
|
this.label7.Size = new System.Drawing.Size(643, 13);
|
||
|
this.label7.TabIndex = 45;
|
||
|
this.label7.Text = "This sample illustrates the use of PDFSigner component for signing PDF documents." +
|
||
|
" Please pick the signing certificate and click \'Sign\'. ";
|
||
|
//
|
||
|
// groupBox5
|
||
|
//
|
||
|
this.groupBox5.Controls.Add(this.lvCerts);
|
||
|
this.groupBox5.Controls.Add(this.cbLevel);
|
||
|
this.groupBox5.Controls.Add(this.cbVisible);
|
||
|
this.groupBox5.Controls.Add(this.label6);
|
||
|
this.groupBox5.Controls.Add(this.btnLoadCert);
|
||
|
this.groupBox5.Controls.Add(this.label1);
|
||
|
this.groupBox5.Controls.Add(this.edStoragePIN);
|
||
|
this.groupBox5.Location = new System.Drawing.Point(5, 95);
|
||
|
this.groupBox5.Name = "groupBox5";
|
||
|
this.groupBox5.Size = new System.Drawing.Size(690, 283);
|
||
|
this.groupBox5.TabIndex = 5;
|
||
|
this.groupBox5.TabStop = false;
|
||
|
this.groupBox5.Text = "Signing options ";
|
||
|
//
|
||
|
// 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.Bottom;
|
||
|
this.lvCerts.FullRowSelect = true;
|
||
|
this.lvCerts.Location = new System.Drawing.Point(3, 101);
|
||
|
this.lvCerts.MultiSelect = false;
|
||
|
this.lvCerts.Name = "lvCerts";
|
||
|
this.lvCerts.Size = new System.Drawing.Size(684, 179);
|
||
|
this.lvCerts.TabIndex = 8;
|
||
|
this.lvCerts.UseCompatibleStateImageBehavior = false;
|
||
|
this.lvCerts.View = System.Windows.Forms.View.Details;
|
||
|
//
|
||
|
// chSubject
|
||
|
//
|
||
|
this.chSubject.Text = "Subject";
|
||
|
this.chSubject.Width = 170;
|
||
|
//
|
||
|
// chIssuer
|
||
|
//
|
||
|
this.chIssuer.Text = "Issuer";
|
||
|
this.chIssuer.Width = 170;
|
||
|
//
|
||
|
// chValidFrom
|
||
|
//
|
||
|
this.chValidFrom.Text = "Valid from";
|
||
|
this.chValidFrom.Width = 100;
|
||
|
//
|
||
|
// chValidTo
|
||
|
//
|
||
|
this.chValidTo.Text = "Valid to";
|
||
|
this.chValidTo.Width = 100;
|
||
|
//
|
||
|
// chAlgorithm
|
||
|
//
|
||
|
this.chAlgorithm.Text = "Algorithm";
|
||
|
this.chAlgorithm.Width = 130;
|
||
|
//
|
||
|
// dlgOpenDLL
|
||
|
//
|
||
|
this.dlgOpenDLL.Filter = "PKCS #11 Library (*.dll)|*.dll";
|
||
|
//
|
||
|
// MainForm
|
||
|
//
|
||
|
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
|
||
|
this.ClientSize = new System.Drawing.Size(699, 426);
|
||
|
this.Controls.Add(this.groupBox5);
|
||
|
this.Controls.Add(this.label7);
|
||
|
this.Controls.Add(this.edOutputFile);
|
||
|
this.Controls.Add(this.sbBrowseOutputFile);
|
||
|
this.Controls.Add(this.label2);
|
||
|
this.Controls.Add(this.edInputFile);
|
||
|
this.Controls.Add(this.btnSign);
|
||
|
this.Controls.Add(this.sbBrowseInputFile);
|
||
|
this.Controls.Add(this.lbInputFile);
|
||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||
|
this.MaximizeBox = false;
|
||
|
this.Name = "MainForm";
|
||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||
|
this.Text = "PDF Signer Demo (PKI Proxy)";
|
||
|
this.groupBox5.ResumeLayout(false);
|
||
|
this.groupBox5.PerformLayout();
|
||
|
this.ResumeLayout(false);
|
||
|
this.PerformLayout();
|
||
|
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
/// <summary>
|
||
|
/// The main entry point for the application.
|
||
|
/// </summary>
|
||
|
[STAThread]
|
||
|
static void Main()
|
||
|
{
|
||
|
Application.Run(new MainForm());
|
||
|
}
|
||
|
|
||
|
private void sbBrowseInputFile_Click(object sender, System.EventArgs e)
|
||
|
{
|
||
|
//dlgOpen.InitialDirectory = Application.StartupPath;
|
||
|
dlgOpen.FileName = edInputFile.Text;
|
||
|
if (dlgOpen.ShowDialog() == DialogResult.OK)
|
||
|
edInputFile.Text = dlgOpen.FileName;
|
||
|
}
|
||
|
|
||
|
private void sbBrowseOutputFile_Click(object sender, EventArgs e)
|
||
|
{
|
||
|
//dlgSave.InitialDirectory = Application.StartupPath;
|
||
|
dlgSave.FileName = edInputFile.Text;
|
||
|
if (dlgSave.ShowDialog() == DialogResult.OK)
|
||
|
edOutputFile.Text = dlgSave.FileName;
|
||
|
}
|
||
|
|
||
|
private void btnSign_Click(object sender, System.EventArgs e)
|
||
|
{
|
||
|
if (lvCerts.SelectedIndices.Count == 0)
|
||
|
{
|
||
|
MessageBox.Show("Select certificate for signing", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
signer.InputFile = edInputFile.Text;
|
||
|
signer.OutputFile = edOutputFile.Text;
|
||
|
|
||
|
signer.SigningCertificate = certstorage.Certificates[lvCerts.SelectedIndices[0]];
|
||
|
|
||
|
if (signer.SigningCertificate.KeyAlgorithm.Contains("id-dsa"))
|
||
|
{
|
||
|
MessageBox.Show("The certificate was found to contain a DSA key. The hash algorithm has been switched to SHA1.");
|
||
|
|
||
|
signer.NewSignature.HashAlgorithm = "SHA1";
|
||
|
}
|
||
|
|
||
|
signer.NewSignature.SignatureType = PDFSignatureTypes.pstPAdES;
|
||
|
|
||
|
switch (cbLevel.SelectedIndex)
|
||
|
{
|
||
|
case 0: signer.NewSignature.Level = PAdESSignatureLevels.paslGeneric; break;
|
||
|
case 1: signer.NewSignature.Level = PAdESSignatureLevels.paslBaselineB; break;
|
||
|
case 2: signer.NewSignature.Level = PAdESSignatureLevels.paslBaselineT; break;
|
||
|
case 3: signer.NewSignature.Level = PAdESSignatureLevels.paslBaselineLT; break;
|
||
|
case 4: signer.NewSignature.Level = PAdESSignatureLevels.paslBaselineLTA; break;
|
||
|
case 5: signer.NewSignature.Level = PAdESSignatureLevels.paslBES; break;
|
||
|
case 6: signer.NewSignature.Level = PAdESSignatureLevels.paslEPES; break;
|
||
|
case 7: signer.NewSignature.Level = PAdESSignatureLevels.paslLTV; break;
|
||
|
}
|
||
|
signer.Widget.Invisible = !cbVisible.Checked;
|
||
|
signer.Config("IgnoreChainValidationErrors=true");
|
||
|
try
|
||
|
{
|
||
|
signer.Sign();
|
||
|
|
||
|
MessageBox.Show("PDF file successfully signed");
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
MessageBox.Show(ex.Message);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void btnLoadCert_Click(object sender, EventArgs e)
|
||
|
{
|
||
|
if (dlgOpenDLL.ShowDialog() == DialogResult.OK)
|
||
|
LoadCertificates(dlgOpenDLL.FileName);
|
||
|
}
|
||
|
|
||
|
public int StrToIntDef(string s, int @default)
|
||
|
{
|
||
|
int number;
|
||
|
if (int.TryParse(s, out number))
|
||
|
return number;
|
||
|
return @default;
|
||
|
}
|
||
|
|
||
|
private void LoadCertificates(string storageFilename)
|
||
|
{
|
||
|
CloseStorage();
|
||
|
|
||
|
try
|
||
|
{
|
||
|
certstorage.Open("pkcs11:///" + storageFilename + "?slot=-1");
|
||
|
|
||
|
int slotNum = -1;
|
||
|
int slotCount = StrToIntDef(certstorage.Config("PKCS11SlotCount"), 0);
|
||
|
|
||
|
for (int i = 0; i < slotCount; i++)
|
||
|
{
|
||
|
if (certstorage.Config("PKCS11SlotTokenPresent[" + i.ToString() + "]").ToUpper() == "TRUE")
|
||
|
{
|
||
|
slotNum = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (slotNum != -1)
|
||
|
{
|
||
|
certstorage.Config("PKCS11Slot=" + slotNum.ToString());
|
||
|
certstorage.Login(1, edStoragePIN.Text, true);
|
||
|
|
||
|
Certificate Cert;
|
||
|
ListViewItem Item;
|
||
|
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.KeyBits.ToString() + " bits)");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
CloseStorage();
|
||
|
MessageBox.Show("Active slot not found", "", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
catch (Exception E)
|
||
|
{
|
||
|
CloseStorage();
|
||
|
MessageBox.Show("Error opening storage: " + storageFilename + "\r\n" + E.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void CloseStorage()
|
||
|
{
|
||
|
if (certstorage.Opened)
|
||
|
certstorage.Close(false);
|
||
|
|
||
|
lvCerts.Items.Clear();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|