~~NOTOC~~ ====== Szenario 5.4: Policy Validation ====== **Kategorie:** [[.:start|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 ExtractPolicies(X509Certificate2 cert) { var policies = new List(); // 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 ExtractMappings(X509Certificate2 caCert) { var mappings = new Dictionary(); // 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 PropagatePolicy( X509Certificate2[] chain, string requiredPolicy) { var validPolicies = new HashSet { 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(); 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 _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** | [[.:chain_validation|5.2 Chain Validation]] | Chain validieren | | **Nächster Schritt** | [[.:name_constraints|5.5 Name Constraints]] | Name-Prüfung | | **Verwandt** | [[de:int:pqcrypt:szenarien:pki:certificate_policy_definieren|1.5 Certificate Policy]] | Policy definieren | ---- << [[.:revocation_check|← 5.3 Revocation Check]] | [[.:start|↑ Validierung-Übersicht]] | [[.:name_constraints|5.5 Name Constraints →]] >> {{tag>szenario validierung policy x509 rfc5280}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//