Szenario 5.4: Policy Validation

Kategorie: Validierung & Vertrauen
Komplexität: ⭐⭐⭐⭐ (Hoch)
Voraussetzungen: Zertifikatskette mit Policy Extensions
Geschätzte Zeit: 15-20 Minuten


Beschreibung

Dieses Szenario beschreibt die Validierung von Certificate Policies nach RFC 5280. Policy Validation stellt sicher, dass Zertifikate den organisatorischen Anforderungen entsprechen:

  • Certificate Policies (OID 2.5.29.32) - Welche Policies gelten?
  • Policy Mappings (OID 2.5.29.33) - Policy-Übersetzungen zwischen CAs
  • Policy Constraints (OID 2.5.29.36) - Einschränkungen der Policy-Vererbung
  • Inhibit anyPolicy (OID 2.5.29.54) - anyPolicy deaktivieren

Workflow

flowchart TD CHAIN[Zertifikatskette] --> EXTRACT[Policies extrahieren] EXTRACT --> MAP[Policy Mappings anwenden] MAP --> INHERIT[Policy-Vererbung prüfen] INHERIT --> CONSTRAINT[Constraints prüfen] CONSTRAINT --> ANY{anyPolicy erlaubt?} ANY -->|Ja| MATCH[Policy-Match prüfen] ANY -->|Nein| EXPLICIT[Explizite Policy nötig] MATCH --> OK{Policy erfüllt?} EXPLICIT --> OK OK -->|Ja| VALID[Policy gültig] OK -->|Nein| INVALID[Policy verletzt] style VALID fill:#e8f5e9 style INVALID fill:#ffebee


Code-Beispiel (C#)

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Security.Cryptography.X509Certificates;
 
using var ctx = PqCryptoContext.Initialize();
 
// Zertifikate laden
var serverCert = ctx.LoadCertificate("server.crt.pem");
var intermediate = ctx.LoadCertificate("intermediate-ca.crt.pem");
var root = ctx.LoadCertificate("root-ca.crt.pem");
 
// Erforderliche Policy definieren
var requiredPolicy = new Oid("1.3.6.1.4.1.99999.1.1");  // Beispiel-OID
 
// Chain mit Policy-Prüfung
var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.Add(intermediate);
chain.ChainPolicy.ExtraStore.Add(root);
 
// Certificate Policies hinzufügen
chain.ChainPolicy.CertificatePolicy.Add(requiredPolicy);
 
// Chain bauen und validieren
bool isValid = chain.Build(serverCert);
 
// Policy-Fehler prüfen
var policyErrors = chain.ChainElements
    .SelectMany(e => e.ChainElementStatus)
    .Where(s => s.Status == X509ChainStatusFlags.InvalidPolicyConstraints ||
                s.Status == X509ChainStatusFlags.NoIssuanceChainPolicy)
    .ToList();
 
if (policyErrors.Any())
{
    Console.WriteLine("Policy-Validierung fehlgeschlagen:");
    foreach (var error in policyErrors)
    {
        Console.WriteLine($"  {error.StatusInformation}");
    }
}
else
{
    Console.WriteLine("Policy-Validierung erfolgreich");
}

Policies aus Zertifikat extrahieren

public class PolicyExtractor
{
    public List<CertificatePolicy> ExtractPolicies(X509Certificate2 cert)
    {
        var policies = new List<CertificatePolicy>();
 
        // Certificate Policies Extension (2.5.29.32)
        var policyExt = cert.Extensions["2.5.29.32"];
        if (policyExt == null) return policies;
 
        // ASN.1 parsen
        var reader = new AsnReader(policyExt.RawData, AsnEncodingRules.DER);
        var sequence = reader.ReadSequence();
 
        while (sequence.HasData)
        {
            var policyInfo = sequence.ReadSequence();
            var policyOid = policyInfo.ReadObjectIdentifier();
 
            var policy = new CertificatePolicy
            {
                PolicyIdentifier = policyOid
            };
 
            // Optional: Policy Qualifiers
            if (policyInfo.HasData)
            {
                var qualifiers = policyInfo.ReadSequence();
                while (qualifiers.HasData)
                {
                    var qualifier = qualifiers.ReadSequence();
                    var qualifierId = qualifier.ReadObjectIdentifier();
 
                    // CPS URI (1.3.6.1.5.5.7.2.1)
                    if (qualifierId == "1.3.6.1.5.5.7.2.1")
                    {
                        policy.CpsUri = qualifier.ReadCharacterString(UniversalTagNumber.IA5String);
                    }
                    // User Notice (1.3.6.1.5.5.7.2.2)
                    else if (qualifierId == "1.3.6.1.5.5.7.2.2")
                    {
                        policy.UserNotice = ParseUserNotice(qualifier);
                    }
                }
            }
 
            policies.Add(policy);
        }
 
        return policies;
    }
}

Wichtige Policy OIDs

OID Name Verwendung
2.5.29.32.0 anyPolicy Alle Policies erlaubt
2.16.840.1.101.3.2.1.3.13 id-fpki-common-policy US Federal PKI
0.4.0.194121.1.2 NCP EU Natural Person
0.4.0.194112.1.2 QCP EU Qualified Certificate
2.23.140.1.2.1 DV-SSL Domain Validated
2.23.140.1.2.2 OV-SSL Organization Validated
2.23.140.1.1 EV-SSL Extended Validation

Policy Mappings

public class PolicyMapper
{
    // Policy Mappings aus CA-Zertifikat extrahieren
    public Dictionary<string, string> ExtractMappings(X509Certificate2 caCert)
    {
        var mappings = new Dictionary<string, string>();
 
        // Policy Mappings Extension (2.5.29.33)
        var mappingExt = caCert.Extensions["2.5.29.33"];
        if (mappingExt == null) return mappings;
 
        var reader = new AsnReader(mappingExt.RawData, AsnEncodingRules.DER);
        var sequence = reader.ReadSequence();
 
        while (sequence.HasData)
        {
            var mapping = sequence.ReadSequence();
            var issuerPolicy = mapping.ReadObjectIdentifier();
            var subjectPolicy = mapping.ReadObjectIdentifier();
 
            mappings[issuerPolicy] = subjectPolicy;
        }
 
        return mappings;
    }
 
    // Policy durch Chain propagieren
    public HashSet<string> PropagatePolicy(
        X509Certificate2[] chain,
        string requiredPolicy)
    {
        var validPolicies = new HashSet<string> { requiredPolicy };
 
        // Von Root zu End-Entity
        for (int i = chain.Length - 1; i > 0; i--)
        {
            var ca = chain[i];
            var mappings = ExtractMappings(ca);
 
            var newPolicies = new HashSet<string>();
            foreach (var policy in validPolicies)
            {
                if (mappings.TryGetValue(policy, out var mapped))
                {
                    newPolicies.Add(mapped);
                }
                else
                {
                    newPolicies.Add(policy);
                }
            }
            validPolicies = newPolicies;
        }
 
        return validPolicies;
    }
}

Branchenspezifische Policies

Branche Policy OID-Bereich Anforderungen
eIDAS QCP-n, QCP-l 0.4.0.194112.* Qualifizierte Zertifikate
PSD2 PSD2-QWAC 0.4.0.19495.* Payment Services
US Federal FBCA 2.16.840.1.101.3.* Federal Bridge CA
Healthcare DE gematik 1.2.276.0.76.4.* Telematikinfrastruktur

Policy-basierte Zugriffskontrolle

public class PolicyBasedAccess
{
    private readonly Dictionary<string, AccessLevel> _policyAccessMap = new()
    {
        ["2.23.140.1.1"] = AccessLevel.HighSecurity,      // EV
        ["2.23.140.1.2.2"] = AccessLevel.MediumSecurity,  // OV
        ["2.23.140.1.2.1"] = AccessLevel.LowSecurity,     // DV
        ["2.5.29.32.0"] = AccessLevel.Minimal             // anyPolicy
    };
 
    public AccessLevel DetermineAccessLevel(X509Certificate2 cert)
    {
        var policies = new PolicyExtractor().ExtractPolicies(cert);
 
        var highestLevel = AccessLevel.None;
 
        foreach (var policy in policies)
        {
            if (_policyAccessMap.TryGetValue(policy.PolicyIdentifier, out var level))
            {
                if (level > highestLevel)
                {
                    highestLevel = level;
                }
            }
        }
 
        return highestLevel;
    }
}
 
public enum AccessLevel
{
    None = 0,
    Minimal = 1,
    LowSecurity = 2,
    MediumSecurity = 3,
    HighSecurity = 4
}

Verwandte Szenarien

Beziehung Szenario Beschreibung
Voraussetzung 5.2 Chain Validation Chain validieren
Nächster Schritt 5.5 Name Constraints Name-Prüfung
Verwandt 1.5 Certificate Policy Policy definieren

« ← 5.3 Revocation Check | ↑ Validierung-Übersicht | 5.5 Name Constraints → »


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

Zuletzt geändert: den 29.01.2026 um 15:13