~~NOTOC~~
====== Scenario 5.1: Chain Building ======
**Category:** [[.:start|Validation & Trust]] \\
**Complexity:** *** (Medium) \\
**Prerequisites:** Certificates, Trust Store \\
**Estimated Time:** 10-15 minutes
----
===== Description =====
This scenario describes **building a certificate chain** (Chain Building) from an end-entity certificate to the trust anchor. Chain building is the first step in certificate validation.
**Process:**
- End-entity certificate -> Find issuer
- Issuer -> Find its issuer
- Repeat until trust anchor is reached
----
===== Workflow =====
flowchart BT
EE[End-Entity Certificate] --> INT[Intermediate CA]
INT --> ROOT[Root CA]
ROOT --> TRUST{In Trust Store?}
TRUST -->|Yes| OK[Chain complete]
TRUST -->|No| FAIL[Chain incomplete]
style OK fill:#e8f5e9
style FAIL fill:#ffebee
----
===== Code Example (C#) =====
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Security.Cryptography.X509Certificates;
using var ctx = PqCryptoContext.Initialize();
// Load certificate to validate
var serverCert = ctx.LoadCertificate("server.crt.pem");
// Configure trust store
using var trustStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
trustStore.Open(OpenFlags.ReadOnly);
// Intermediate certificates (optional)
var intermediates = new X509Certificate2Collection();
intermediates.Add(ctx.LoadCertificate("intermediate-ca.crt.pem"));
// Configure chain builder
var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.AddRange(intermediates);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // Only chain building first
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; // Only build chain
// Build chain
bool built = chain.Build(serverCert);
Console.WriteLine($"Chain Building: {(built ? "Successful" : "Failed")}");
Console.WriteLine($"Chain length: {chain.ChainElements.Count}");
foreach (var element in chain.ChainElements)
{
Console.WriteLine($" {element.ChainElementStatus.Length} Status");
Console.WriteLine($" Subject: {element.Certificate.Subject}");
Console.WriteLine($" Issuer: {element.Certificate.Issuer}");
}
----
===== Automatic AIA Fetching =====
Authority Information Access (AIA) enables automatic downloading of missing intermediate certificates:
public X509Certificate2Collection FetchIntermediatesViaAia(X509Certificate2 cert)
{
var intermediates = new X509Certificate2Collection();
var current = cert;
while (true)
{
// Read AIA extension
var aiaUrl = GetCaIssuersUrl(current);
if (string.IsNullOrEmpty(aiaUrl)) break;
// Download issuer certificate
using var http = new HttpClient();
var certData = http.GetByteArrayAsync(aiaUrl).Result;
var issuer = new X509Certificate2(certData);
intermediates.Add(issuer);
// Self-signed = Root reached
if (issuer.Subject == issuer.Issuer) break;
current = issuer;
}
return intermediates;
}
private string? GetCaIssuersUrl(X509Certificate2 cert)
{
var aia = cert.Extensions["1.3.6.1.5.5.7.1.1"]; // AIA OID
if (aia == null) return null;
// Parse AIA (simplified)
var asnData = new AsnReader(aia.RawData, AsnEncodingRules.DER);
// ... Extract CA Issuers URL
return null; // Implementation depends on ASN.1 structure
}
----
===== Chain Building with PQ Certificates =====
public class PqChainBuilder
{
public X509Chain BuildPqChain(X509Certificate2 endEntity, PqCryptoContext ctx)
{
var chain = new X509Chain();
// Enable PQ-specific validation
chain.ChainPolicy.ApplicationPolicy.Add(new Oid("1.3.6.1.5.5.7.3.1")); // serverAuth
chain.ChainPolicy.CertificatePolicy.Add(new Oid("2.5.29.32.0")); // anyPolicy
// Custom trust store with PQ root CAs
var pqTrustStore = new X509Certificate2Collection();
pqTrustStore.Add(ctx.LoadCertificate("pq-root-ca.crt.pem"));
chain.ChainPolicy.CustomTrustStore.AddRange(pqTrustStore);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.Build(endEntity);
return chain;
}
}
----
===== Chain Building Troubleshooting =====
^ Status ^ Meaning ^ Solution ^
| **PartialChain** | Intermediate missing | Use AIA or add manually |
| **UntrustedRoot** | Root not in trust store | Add root to trust store |
| **NotSignatureValid** | Signature invalid | Certificate corrupted/wrong |
| **RevocationStatusUnknown** | CRL/OCSP unreachable | Adjust revocation check |
// Analyze chain status
foreach (var element in chain.ChainElements)
{
foreach (var status in element.ChainElementStatus)
{
Console.WriteLine($" {element.Certificate.Subject}");
Console.WriteLine($" Status: {status.Status}");
Console.WriteLine($" Info: {status.StatusInformation}");
}
}
----
===== Industry-Specific Requirements =====
^ Industry ^ Chain Depth ^ Trust Store ^ Specifics ^
| **WebPKI** | Max. 3 | Browser Root Store | CA/B Forum Rules |
| **Enterprise** | Variable | Custom Root Store | Own hierarchy |
| **Energy/SCADA** | 2-3 | Offline Store | Air-gap systems |
| **Healthcare** | 3-4 | Qualified TSP | eIDAS-compliant |
----
===== Related Scenarios =====
^ Relationship ^ Scenario ^ Description ^
| **Next Step** | [[.:chain_validation|5.2 Chain Validation]] | Complete validation |
| **Prerequisite** | [[en:int:pqcrypt:szenarien:pki:trust_store_konfigurieren|1.4 Trust Store]] | Trust anchors |
| **Related** | [[.:revocation_check|5.3 Revocation Check]] | Revocation verification |
----
<< [[.:start|<- Validation Overview]] | [[en:int:pqcrypt:szenarien:start|^ Scenarios]] | [[.:chain_validation|5.2 Chain Validation ->]] >>
{{tag>scenario validation chain-building x509 trust}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//