~~NOTOC~~ ====== Scenario 5.2: Chain Validation ====== **Category:** [[.:start|Validation & Trust]] \\ **Complexity:** **** (High) \\ **Prerequisites:** Built certificate chain \\ **Estimated Time:** 15-20 minutes ---- ===== Description ===== This scenario describes **complete validation of a certificate chain** according to RFC 5280. The validation checks: * **Signature validity** - Each certificate signed by issuer * **Time validity** - All certificates within validity period * **Key Usage** - Permitted usage purposes * **Path Length** - BasicConstraints pathLenConstraint * **Policy Constraints** - Certificate policies * **Name Constraints** - Permitted/excluded names ---- ===== Workflow ===== flowchart TD BUILD[Chain Building] --> SIG[Verify signature] SIG --> TIME[Time validity] TIME --> KU[Key Usage] KU --> PATH[Path Length] PATH --> POLICY[Policy Constraints] POLICY --> NAME[Name Constraints] NAME --> REV[Revocation Check] REV --> OK{All OK?} OK -->|Yes| VALID[Certificate valid] OK -->|No| INVALID[Certificate invalid] style VALID fill:#e8f5e9 style INVALID fill:#ffebee ---- ===== Code Example (C#) ===== using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Security.Cryptography.X509Certificates; using var ctx = PqCryptoContext.Initialize(); // Load certificate var serverCert = ctx.LoadCertificate("server.crt.pem"); // Complete chain validation var chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(30); chain.ChainPolicy.VerificationTime = DateTime.UtcNow; // Additional intermediate certificates chain.ChainPolicy.ExtraStore.Add(ctx.LoadCertificate("intermediate-ca.crt.pem")); // Build and validate chain bool isValid = chain.Build(serverCert); // Evaluate result Console.WriteLine($"Chain validation: {(isValid ? "VALID" : "INVALID")}"); if (!isValid) { foreach (var element in chain.ChainElements) { foreach (var status in element.ChainElementStatus) { Console.WriteLine($" {element.Certificate.Subject}"); Console.WriteLine($" Error: {status.Status}"); Console.WriteLine($" Details: {status.StatusInformation}"); } } } ---- ===== Detailed Validation ===== public class ChainValidator { public ValidationResult ValidateChain(X509Certificate2 certificate, ValidationOptions options) { var result = new ValidationResult { IsValid = true }; using var chain = new X509Chain(); ConfigureChainPolicy(chain.ChainPolicy, options); if (!chain.Build(certificate)) { result.IsValid = false; result.Errors = ExtractErrors(chain); } // Additional PQ checks if (options.RequirePostQuantum) { ValidatePqRequirements(chain, result); } return result; } private void ConfigureChainPolicy(X509ChainPolicy policy, ValidationOptions options) { policy.RevocationMode = options.CheckRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.VerificationTime = options.ValidationTime ?? DateTime.UtcNow; // Application Policies (Extended Key Usage) if (options.RequiredEku != null) { policy.ApplicationPolicy.Add(options.RequiredEku); } // Certificate Policies if (options.RequiredPolicies != null) { foreach (var policyOid in options.RequiredPolicies) { policy.CertificatePolicy.Add(policyOid); } } // Custom Trust Store if (options.CustomTrustStore != null) { policy.CustomTrustStore.AddRange(options.CustomTrustStore); policy.TrustMode = X509ChainTrustMode.CustomRootTrust; } } private void ValidatePqRequirements(X509Chain chain, ValidationResult result) { foreach (var element in chain.ChainElements) { var cert = element.Certificate; var algorithm = cert.PublicKey.Oid.Value; // Check if PQ algorithm is used if (!IsPqAlgorithm(algorithm)) { result.Warnings.Add($"{cert.Subject}: No PQ algorithm ({algorithm})"); } } } private bool IsPqAlgorithm(string oid) { return oid switch { "2.16.840.1.101.3.4.3.17" => true, // ML-DSA-44 "2.16.840.1.101.3.4.3.18" => true, // ML-DSA-65 "2.16.840.1.101.3.4.3.19" => true, // ML-DSA-87 _ => false }; } } ---- ===== Validation Options ===== public class ValidationOptions { // Validation time public DateTime? ValidationTime { get; set; } // Revocation check public bool CheckRevocation { get; set; } = true; // Extended Key Usage public Oid? RequiredEku { get; set; } // Certificate Policies public List? RequiredPolicies { get; set; } // Custom Trust Store public X509Certificate2Collection? CustomTrustStore { get; set; } // PQ requirements public bool RequirePostQuantum { get; set; } // Timeout for online checks public TimeSpan UrlTimeout { get; set; } = TimeSpan.FromSeconds(30); } // Example: TLS server validation var tlsOptions = new ValidationOptions { RequiredEku = new Oid("1.3.6.1.5.5.7.3.1"), // serverAuth CheckRevocation = true, RequirePostQuantum = true }; // Example: Code signing validation var codeSigningOptions = new ValidationOptions { RequiredEku = new Oid("1.3.6.1.5.5.7.3.3"), // codeSigning CheckRevocation = true, ValidationTime = signatureTimestamp // Time of signature }; ---- ===== Chain Status Codes ===== ^ Status ^ Meaning ^ Critical? ^ Solution ^ | **NoError** | No errors | No | - | | **NotTimeValid** | Expired/not yet valid | Yes | Renewal | | **NotTimeNested** | Time periods don't overlap | Yes | Correct chain | | **Revoked** | Revoked | Yes | New certificate | | **NotSignatureValid** | Signature invalid | Yes | Check chain | | **NotValidForUsage** | Wrong usage purpose | Yes | Correct certificate | | **UntrustedRoot** | Root not trusted | Yes | Trust Store | | **RevocationStatusUnknown** | CRL/OCSP unreachable | Warning | Offline check | | **PartialChain** | Chain incomplete | Yes | Add intermediates | ---- ===== Industry-Specific Validation ===== ^ Industry ^ Additional Checks ^ Policy OIDs ^ | **WebPKI** | CT Logs, EV Policies | CA/B Forum | | **eIDAS** | QC Statements, TSL Check | 0.4.0.194121.1.* | | **Healthcare** | Professional attributes | gematik OIDs | | **Automotive** | ECU Policies | V2X-specific | ---- ===== Related Scenarios ===== ^ Relationship ^ Scenario ^ Description ^ | **Prerequisite** | [[.:chain_building|5.1 Chain Building]] | Build chain | | **Next Step** | [[.:revocation_check|5.3 Revocation Check]] | Revocation verification | | **Related** | [[.:policy_validation|5.4 Policy Validation]] | Policy verification | ---- << [[.:chain_building|<- 5.1 Chain Building]] | [[.:start|^ Validation Overview]] | [[.:revocation_check|5.3 Revocation Check ->]] >> {{tag>scenario validation chain x509 rfc5280}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//