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