Certificate Authority

A Certificate Authority (often abbreviated CA) is an organization that authenticates by digitally signing X.509 certificates, that they are from whom they claim to be.

The DidiSoft.OpenSsl.X509.CertificateAuthority class is an abstraction that simplifies the technical aspect of such organization and is designed to help you build your own in-house CA.
Note: the legal aspect of a Certificate Authority operations is not covered here

Table of contents

  • Initialize
  • Sign CSR
  • Create intermediate CA certificate

Initialize

In order to construct a DidiSoft.OpenSsl.X509.CertificateAuthority class we need a Certificate (CA root certificate) and the private key corresponding to the public key inside the certificate. A Root Certificate Authority is every CA which has a self-signed certificate.
For this example the private key is loaded from an unprotected file, but it is recommended to use a protected storage.

1
2
3
4
DidiSoft.OpenSsl.X509.Certificate caCertificate = Certificate.Load("cacert.crt");
DidiSoft.OpenSsl.PrivateKey caKey = PrivateKey.Load("caprivate.key");
 
DidiSoft.OpenSsl.X509.CertificateAuthority ca = new CertificateAuthority(caCertificate, caKey);

Next, we can set some Certificate Authority information that will be added later to each produced certificate:

1
2
3
4
5
// these will be written afterwards in the produced certificates
ca.UrlOfCACertificate = @"https://myca.com/myca.crt";
ca.UrlOfCertificatePolicies = @"https://myca.com/terms";
ca.UrlOfCrlList = @"https://myca.com/crl.list";
ca.UrlOfOcsp = @"https://myca.com/ocsp";

Sign CSR

The Certificate Authority can process certificate signing requests and produce certificates like:

1
2
3
4
CertificateSigningRequest csr = CertificateSigningRequest.Load("john_doe.csr");
 
long serialNumber = GetNextId();
Certificate newCert = ca.CreateCertificate(csr, serialNumber, DateTime.UtcNow.AddYears(1));

You may notice the serialNumber parameter above. This serial number in a real world scenario will be an auto generated ID column in a table with record of the issued certificates.

Create intermediate CA certificate

An Intermediate Certificate Authority is just a division or partner entity of the Root CA. Its certificate is signed from a CA above it with rights to sign other certificates. When a certificate is signed with Intermediate Certificate Authority rights a certification chain depth/length can also be set, which limits how many steps downward can be extended this distribution of Certification rights.

Here is how to create a certificate for an Intermediate CA, with zero allowed certification chain length, which means that it can sign only end user certificates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using DidiSoft.OpenSsl;
using DidiSoft.OpenSsl.X509;
 
public class CreateIntermediateCACertificate
{
 public static void Demo()
 {
  Certificate caCertificate = Certificate.Load("cacert.crt");
  PrivateKey caKey = PrivateKey.Load("caprivate.key");
  CertificateAuthority ca = new CertificateAuthority(caCertificate, caKey);
 
  PublicKey intermediatePublicKey = PublicKey.Load("intermediate.pub");
  Properties intermediateProperties = new Properties("My Intermediate CA");
 
  AlternativeName[] altNames = new AlternativeName[] { new AlternativeName(AlternativeNameType.DnsName, "myintermca.com") };
 
  int allowedCertChainLen = 0; // only end user certificates, no intermediate CA's below this one
  Certificate intermCert = ca.CreateIntermediateCACertificate(intermediatePublicKey, 
                                                              intermediateProperties, 
                                                              Certificate.CreateRandomSearialNumber(), 
                                                              altNames, 
                                                              allowedCertChainLen, 
                                                              DateTime.UtcNow.AddYears(5));
  intermCert.Save("interm.cert");
 }
}

VB.NET example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Imports System
Imports DidiSoft.OpenSsl
Imports DidiSoft.OpenSsl.X509
 
Public Class CreateIntermediateCACertificate
 Public Shared Sub Demo()
  CreateCACertificate.Demo()
 
  Dim caCertificate As Certificate = Certificate.Load("cacert.crt")
  Dim caKey As PrivateKey = PrivateKey.Load("caprivate.key")
  Dim ca As New CertificateAuthority(caCertificate, caKey)
 
  Dim intermediatePublicKey As PublicKey = PublicKey.Load("intermediate.pub")
  Dim intermediateProperties As New Properties("My Intermediate CA")
 
  Dim altNames As AlternativeName() = New AlternativeName() {New AlternativeName(AlternativeNameType.DnsName, "myintermca.com")}
 
  Dim allowedCertChainLen As Integer = 0
  ' can only sign end user certificates, no intermediate CA's below this one
  Dim intermCert As Certificate = ca.CreateIntermediateCACertificate(intermediatePublicKey, _
                                                                   intermediateProperties, _
                                                                   Certificate.CreateRandomSearialNumber(), _
                                                                   altNames, _
                                                                   allowedCertChainLen, _
                                                                   DateTime.UtcNow.AddYears(5))
 
  intermCert.Save("interm.cert")
 End Sub
End Class

 

Summary

This article is a starting point for creating a custom in-house Certificate Authority.