~~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//