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.