X.509 Certificates

Main reference: RFC5280

Also refer to my repository openssl cert commands to see example codes for generating X.509 certificates, with various combinations of CAs and CSRs

The flow

The entire flow can achieved using the openssl command.

The server private key

The server creates a static private key, using algorithms supported for Signing, such as RSA or Ed25519. The private key is stored as PEM file.
The PEM file contains the private key, the corresponding public key and other parameters. The structure / contents of the PEM files depend on the algorithm used, and are defined in the Public Key Cryptography Standards (PKCS), e.g. PKCS#1 gives structure of PEM for RSA.

Server CSR

Server creates Certificate Signing Request (CSR), which primarliy contains:

  1. The public key corresponding to static private key in PEM file
  2. Metadata about the server
  3. Other extensions (covred in later sections)

Also, the server digitally signs the CSR using its own private key.
The CSR is then sent to a Certificate Authority (CA)

Verifying the CSR and issuing a certificate

The CA verifies the signature present in the CSR, using the public key from the CSR.
If the signature is valid, then it verifies that the sender also owns the corresponding private key.
Then, based on the extensions in the CSR, and CA’s own config, CA issues the certificate with some additional properties like:

  1. Validity of the certificate
  2. Allowed key usage

Finally, the CA signs the X.509 certificate using CA’s private key.

FeatureCSR SignatureX.509 Certificate Signature
Who signs it?The requestor (using their private key).The Certificate Authority (CA) (using its private key).
What is signed?The CSR’s subject details and public key.The issued certificate’s subject, public key, and validity details.
What does it prove?The requestor owns the private key.The certificate was issued by a trusted CA and hasn’t been tampered with.

During the handshake

During the TLS handshake (Specifically TLS1.3), in the Certificate section, the server sends a list of certificates, which form the certificate chain.
Server’s own X.509 certificate (issues earlier by CA) is present as the first element in the list. The corresponding elements are other CA certificates in the chain.
In the chain, each certificate should validate the previous certificate in the chain.
Finally, root CA certificate is often ommited from the chain, as the client typically has those certificates, installed by the OS itself. Root CA are top of the chain, and they must be trusted by the client.

Once client verifies the entire chain, client can gets confirmation that the certificate is valid.
But, this still doesn’t prove that the sender really owns the private key. That’s why we need CertificateVerify message. The server signs the entire handshake message using its private key, and sends the signature as part of CertificateVerify message.

Client uses the public key from certificate, and the signature from CertificateVerify message, does some math, and if the signature is valid, then the server is succesfully authenticated.

Contents of a certificate

See the section 4.1 for a list of all fields in a X.509 certificate.

The important fields (from algorithmic POV) are:

  1. signatureAlgorithm and signatureValue
  2. subjectPublicKeyInfo

Along with that, a certificate may contains extensions, like Key usage.

Algorithm support

Main reference: RFC3279
Above reference contains which key usage extension is expected for each algorithm.

About static DH key support

In theory, “DH key exchange” certificates are possible but they aren’t used (almost at all)
See why dh can’t be used for signing? and static dh with openssl
Even openssl doesn’t directly support DH keys (without using -force_pubkey ).
Today many systems have moved to TLS 1.3 (which remove static keys altogether) or use TLS 1.2 with ephemeral keys.

Key usage extension

The Key usage extension determines for what purposes the public key of the subject can be used. Key usage restricts the use to some applications. But if this extension is absent, the key can be used without any restrictions.
e.g. RSA keys can (in theory) be used for key encipherment and for authentication (signature). If RSA public key is present in the certificate, we can restrict its usage with this extension.

Structure of Key usage extension is as follow:

KeyUsage ::= BIT STRING {
           digitalSignature        (0),
           nonRepudiation          (1), -- recent editions of X.509 have
                                -- renamed this bit to contentCommitment
           keyEncipherment         (2),
           dataEncipherment        (3),
           keyAgreement            (4),
           keyCertSign             (5),
           cRLSign                 (6),
           encipherOnly            (7),
           decipherOnly            (8) }

In a Certificate Requests, the subject can also request for specific KeyUsage extensions.
The Certificate Authority (CA) has the final say on which KeyUsage to allow.