Description
The following screenshot shows an example dialog for creating a new certificate. Press the button “Show Code” to display the corresponding code, and the button “Help” to show this documentation page.
This dialog is used in the .NET based OPC UA Demo Server and the Getting Started Client Example included in the SDK. On first start-up, the application checks for a certificate. If no certificate exists, the dialog for creating a new certificate shows up.
The input fields are filled with default values which can be changed to the user’s liking. On clicking the “Advanced” button, additional input fields show up, which can be hidden again by pressing the “Basic” button.
Clicking on “Create” stores the certificate, by clicking “Cancel” the process can be aborted.
Sample Code
Step 1: Tell the SDK to Automatically Create Certificates
Setting the AutoCreateCertificate to true tells the SDK to create a certificate automatically when the application starts. The MissingApplicationCertificate is the event that is raised when the SDK determines that a certificate needs to be created. This allows the application to customize the creation of the certificate.
ApplicationInstance.Default.AutoCreateCertificate = true;
Step 2: Implement the MissingApplicationCertificate Callback
private void Application_MissingApplicationCertificate(object sender, CreateCertificateEventArgs e)
{
try
{
CreateCertificateDialog dialog = new CreateCertificateDialog();
ICertificate certificate = dialog.ShowDialog(null, new CreateCertificateDialogSettings()
{
Application = e.Application,
Instructions = "The application does not have a certificate assigned.\r\nPlease specify the parameters for a new certificate."
});
if (certificate != null)
{
e.NewCertificate = certificate;
e.UpdateConfiguration = true;
}
}
catch (Exception exception)
{
ExceptionDlg.Show(this.Text, exception);
}
}
Step 3: CreateCertificateDialog
The CreateCertificateDialog displays the fields of the certificate and allows the user to change them. A certificate issued by a Certificate Authority (CA) can be created by specifying an issuer certificate. The certificate settings can be found here: CreateCertificateSettings.
public CreateCertificateDialog()
{
InitializeComponent();
Icon = Utils.GetDefaultIcon();
foreach (object value in Enum.GetValues(typeof(KeySize)))
{
KeySizeComboBox.Items.Add(value);
}
KeySizeComboBox.SelectedIndex = 0;
foreach (object value in Enum.GetValues(typeof(HashAlgorithm)))
{
HashAlgorithmComboBox.Items.Add(value);
}
HashAlgorithmComboBox.SelectedIndex = 0;
BasicButton_Click(this, null);
}
try
{
Cursor = Cursors.WaitCursor;
CreateCertificateSettings settings = new CreateCertificateSettings()
{
ApplicationName = ApplicationNameTextBox.Text.Trim(),
ApplicationUri = ApplicationUriTextBox.Text.Trim(),
SubjectName = SubjectNameTextBox.Text.Trim()
};
string storePath = StorePathTextBox.Text.Trim();
if (
String.IsNullOrEmpty(storePath))
{
throw new ArgumentException("Please specify a path to the certificate store.", "StorePath");
}
string issuerKeyFile = IssuerKeyFileTextBox.Text.Trim();
if (!
String.IsNullOrEmpty(issuerKeyFile))
{
string issuerPassword = IssuerPasswordTextBox.Text.Trim();
if (!File.Exists(issuerKeyFile))
{
throw new ArgumentException("Please specify a valid path to an issuer key file.", "IssuerKeyFile");
}
try
{
X509Certificate2 certificate = null;
if (
String.IsNullOrEmpty(issuerPassword))
{
certificate = new X509Certificate2(issuerKeyFile);
}
else
{
certificate = new X509Certificate2(issuerKeyFile, issuerPassword);
}
}
catch (CryptographicException exception)
{
throw new ArgumentException("Could not open the key file.", "IssuerKeyFile", exception);
}
settings.IssuerKeyFilePath = issuerKeyFile;
settings.IssuerKeyFilePassword = issuerPassword;
}
if (
String.IsNullOrEmpty(settings.ApplicationName))
{
throw new ArgumentException("Please specify an application name.", "ApplicationName");
}
if (
String.IsNullOrEmpty(settings.ApplicationUri))
{
throw new ArgumentException("Please specify an application URI.", "ApplicationUri");
}
if (!Uri.IsWellFormedUriString(settings.ApplicationUri, UriKind.Absolute))
{
throw new ArgumentException("Please specify a valid URI for the application URI.", "ApplicationUri");
}
List<string> fields = SecurityUtils.ParseDistinguishedName(settings.SubjectName);
StringBuilder buffer = new StringBuilder();
foreach (string field in fields)
{
if (buffer.Length > 0)
{
buffer.Append("/");
}
buffer.Append(field);
}
settings.SubjectName = buffer.ToString();
string[] domainNames = DomainNamesTextBox.Text.Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
for (int ii = 0; ii < domainNames.Length; ii++)
{
domainNames[ii] = domainNames[ii].Trim();
}
settings.DomainNames = domainNames;
switch ((KeySize)KeySizeComboBox.SelectedItem)
{
case KeySize.Rsa1024: { settings.KeySize = 1024; break; }
case KeySize.Rsa2048: { settings.KeySize = 2048; break; }
}
switch ((HashAlgorithm)HashAlgorithmComboBox.SelectedItem)
{
case HashAlgorithm.Sha1: { settings.HashSizeInBits = 0; break; }
case HashAlgorithm.Sha256: { settings.HashSizeInBits = 256; break; }
}
settings.LifetimeInMonths = (ushort)LifetimeUpDown.Value;
m_certificate = CertificateFactory.CreateCertificate(CertificateStoreType.Directory, storePath, settings);
Cursor = Cursors.Default;
DialogResult = DialogResult.OK;
}
catch (Exception exception)
{
Cursor = Cursors.Default;
ExceptionDlg.Show(this.Text, exception);
}