Scenario 5.2: Chain Validation

Category: 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:


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<Oid>? 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

Relationship Scenario Description
Prerequisite 5.1 Chain Building Build chain
Next Step 5.3 Revocation Check Revocation verification
Related 5.4 Policy Validation Policy verification

« <- 5.1 Chain Building | ^ Validation Overview | 5.3 Revocation Check -> »


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional