~~NOTOC~~
====== Scenario 5.4: Validazione Policy ======
**Categoria:** [[.:start|Validazione e fiducia]] \\
**Complessità:** Alta \\
**Prerequisiti:** Catena certificati con estensioni Policy \\
**Tempo stimato:** 15-20 minuti
----
===== Descrizione =====
Questo scenario descrive la **validazione delle Certificate Policies** secondo RFC 5280. La validazione delle policy assicura che i certificati soddisfino i requisiti organizzativi:
* **Certificate Policies** (OID 2.5.29.32) - Quali policy si applicano?
* **Policy Mappings** (OID 2.5.29.33) - Traduzioni di policy tra CA
* **Policy Constraints** (OID 2.5.29.36) - Restrizioni sull'ereditarietà delle policy
* **Inhibit anyPolicy** (OID 2.5.29.54) - Disattivare anyPolicy
----
===== Workflow =====
flowchart TD
CHAIN[Catena certificati] --> EXTRACT[Estrarre policies]
EXTRACT --> MAP[Applicare Policy Mappings]
MAP --> INHERIT[Verificare ereditarietà policy]
INHERIT --> CONSTRAINT[Verificare constraints]
CONSTRAINT --> ANY{anyPolicy consentita?}
ANY -->|Si| MATCH[Verificare corrispondenza policy]
ANY -->|No| EXPLICIT[Richiesta policy esplicita]
MATCH --> OK{Policy soddisfatta?}
EXPLICIT --> OK
OK -->|Si| VALID[Policy valida]
OK -->|No| INVALID[Policy violata]
style VALID fill:#e8f5e9
style INVALID fill:#ffebee
----
===== Esempio codice (C#) =====
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Security.Cryptography.X509Certificates;
using var ctx = PqCryptoContext.Initialize();
// Caricare certificati
var serverCert = ctx.LoadCertificate("server.crt.pem");
var intermediate = ctx.LoadCertificate("intermediate-ca.crt.pem");
var root = ctx.LoadCertificate("root-ca.crt.pem");
// Definire policy richiesta
var requiredPolicy = new Oid("1.3.6.1.4.1.99999.1.1"); // OID esempio
// Chain con verifica policy
var chain = new X509Chain();
chain.ChainPolicy.ExtraStore.Add(intermediate);
chain.ChainPolicy.ExtraStore.Add(root);
// Aggiungere Certificate Policies
chain.ChainPolicy.CertificatePolicy.Add(requiredPolicy);
// Costruire e validare chain
bool isValid = chain.Build(serverCert);
// Verificare errori policy
var policyErrors = chain.ChainElements
.SelectMany(e => e.ChainElementStatus)
.Where(s => s.Status == X509ChainStatusFlags.InvalidPolicyConstraints ||
s.Status == X509ChainStatusFlags.NoIssuanceChainPolicy)
.ToList();
if (policyErrors.Any())
{
Console.WriteLine("Validazione policy fallita:");
foreach (var error in policyErrors)
{
Console.WriteLine($" {error.StatusInformation}");
}
}
else
{
Console.WriteLine("Validazione policy riuscita");
}
----
===== Estrarre policies dal certificato =====
public class PolicyExtractor
{
public List ExtractPolicies(X509Certificate2 cert)
{
var policies = new List();
// Estensione Certificate Policies (2.5.29.32)
var policyExt = cert.Extensions["2.5.29.32"];
if (policyExt == null) return policies;
// Parsare ASN.1
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
};
// Opzionale: 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;
}
}
----
===== OID Policy importanti =====
^ OID ^ Nome ^ Utilizzo ^
| **2.5.29.32.0** | anyPolicy | Tutte le policy consentite |
| **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 Persona naturale |
| **0.4.0.194112.1.2** | QCP | EU Certificato qualificato |
| **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
{
// Estrarre Policy Mappings dal certificato CA
public Dictionary ExtractMappings(X509Certificate2 caCert)
{
var mappings = new Dictionary();
// Estensione Policy Mappings (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;
}
// Propagare policy attraverso la chain
public HashSet PropagatePolicy(
X509Certificate2[] chain,
string requiredPolicy)
{
var validPolicies = new HashSet { requiredPolicy };
// Da Root a 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;
}
}
----
===== Policy specifiche per settore =====
^ Settore ^ Policy ^ Ambito OID ^ Requisiti ^
| **eIDAS** | QCP-n, QCP-l | 0.4.0.194112.* | Certificati qualificati |
| **PSD2** | PSD2-QWAC | 0.4.0.19495.* | Payment Services |
| **US Federal** | FBCA | 2.16.840.1.101.3.* | Federal Bridge CA |
| **Sanità DE** | gematik | 1.2.276.0.76.4.* | Infrastruttura telematica |
----
===== Controllo accessi basato su policy =====
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
}
----
===== Scenari correlati =====
^ Relazione ^ Scenario ^ Descrizione ^
| **Prerequisito** | [[.:chain_validation|5.2 Validazione Chain]] | Validare chain |
| **Passo successivo** | [[.:name_constraints|5.5 Name Constraints]] | Verifica nomi |
| **Correlato** | [[it:int:pqcrypt:szenarien:pki:certificate_policy_definieren|1.5 Certificate Policy]] | Definire policy |
----
<< [[.:revocation_check|← 5.3 Controllo revoca]] | [[.:start|↑ Panoramica validazione]] | [[.:name_constraints|5.5 Name Constraints →]] >>
{{tag>scenario validazione policy x509 rfc5280}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//