====== Classe RevocationExtensions ====== Metodi di estensione per la verifica della revoca dei certificati. ---- ===== Definizione ===== namespace WvdS.System.Security.Cryptography.X509Certificates; public static class RevocationExtensions ---- ===== Metodi ===== ^ Metodo ^ Descrizione ^ | IsRevoked | Verifica se un certificato è revocato | | FetchCrlAsync | Scarica la CRL dall'URL (dall'estensione del certificato) | | CheckRevocationAsync | Combinato: scarica CRL e verifica la revoca | | GetCrlDistributionPoints | Estrae gli URL CRL dal certificato | | GetOcspUrls | Estrae gli URL OCSP dal certificato | ---- ===== Verifica della revoca ===== **Con CRL esistente:** using System.Security.Cryptography.X509Certificates; using WvdS.System.Security.Cryptography.X509Certificates; var certificate = new X509Certificate2("user.cer"); byte[] crlData = File.ReadAllBytes("ca.crl"); var caCert = new X509Certificate2("ca.cer"); // Verifica con verifica della firma RevocationResult result = certificate.IsRevoked(crlData, caCert, CryptoMode.Hybrid); if (result.Success) { if (result.IsRevoked) { Console.WriteLine($"Certificato revocato il: {result.RevocationDate}"); Console.WriteLine($"Motivo: {result.Reason}"); } else { Console.WriteLine("Il certificato è valido"); } } else { Console.WriteLine($"Errore: {result.ErrorMessage}"); } **Caricamento automatico della CRL:** // Scarica la CRL dall'URL nell'estensione CDP del certificato RevocationResult result = await certificate.CheckRevocationAsync( caCert, mode: CryptoMode.Hybrid); ---- ===== Caricamento CRL ===== // Solo caricamento CRL, senza verifica byte[]? crlData = await certificate.FetchCrlAsync(); if (crlData != null) { File.WriteAllBytes("downloaded.crl", crlData); } **Con HttpClient personalizzato:** using var httpClient = new HttpClient(); httpClient.Timeout = TimeSpan.FromSeconds(10); byte[]? crlData = await certificate.FetchCrlAsync(httpClient); ---- ===== Lettura dei CRL Distribution Points ===== IReadOnlyList crlUrls = certificate.GetCrlDistributionPoints(); foreach (var url in crlUrls) { Console.WriteLine($"URL CRL: {url}"); } // Verifica rapida bool hasCdp = certificate.HasCrlDistributionPoints(); ---- ===== Lettura degli URL OCSP ===== IReadOnlyList ocspUrls = certificate.GetOcspUrls(); foreach (var url in ocspUrls) { Console.WriteLine($"OCSP Responder: {url}"); } // Verifica rapida bool hasOcsp = certificate.HasOcspUrls(); ---- ===== Classe RevocationResult ===== ^ Proprietà ^ Tipo ^ Descrizione ^ | ''IsRevoked'' | bool | Il certificato è revocato | | ''RevocationDate'' | DateTimeOffset? | Data della revoca | | ''Reason'' | CrlReason? | Motivo della revoca | | ''CrlVerified'' | bool | La firma CRL è stata verificata | | ''ErrorMessage'' | string? | Messaggio di errore (se la verifica è fallita) | | ''Success'' | bool | La verifica è stata completata con successo | ---- ===== Cache CRL ===== Per verifiche frequenti con caching automatico: using var cache = new CrlCache(defaultCacheDuration: TimeSpan.FromHours(1)); // Verifica con caching CRL automatico RevocationResult result1 = await cache.CheckRevocationAsync(cert1, caCert); RevocationResult result2 = await cache.CheckRevocationAsync(cert2, caCert); // CRL dalla cache // Svuotare la cache cache.Clear(); **Con HttpClient personalizzato:** using var httpClient = new HttpClient(); using var cache = new CrlCache(httpClient, TimeSpan.FromMinutes(30)); // Verificare più certificati foreach (var cert in certificates) { var result = await cache.CheckRevocationAsync(cert, caCert, CryptoMode.Hybrid); // ... } ---- ===== Integrazione con X509Chain ===== Per la validazione completa della catena con verifica CRL: using var chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; bool valid = chain.Build(certificate, CryptoMode.Hybrid); if (!valid) { foreach (var status in chain.ChainStatus) { if (status.Status == X509ChainStatusFlags.Revoked) { Console.WriteLine("Certificato nella catena revocato"); } } } ---- ===== Verifica offline ===== Per sistemi air-gapped senza accesso alla rete: // Scaricare e salvare le CRL in anticipo var crlFiles = new Dictionary { ["CN=Root CA"] = File.ReadAllBytes("root.crl"), ["CN=Issuing CA"] = File.ReadAllBytes("issuing.crl") }; // Verifica offline RevocationResult result = certificate.IsRevoked(crlFiles["CN=Issuing CA"], caCert); ---- ===== Best Practice ===== * **Attivare il caching CRL:** Usare ''CrlCache'' per verifiche ripetute * **Impostare i timeout:** Configurare i timeout HttpClient per le operazioni di rete * **Implementare fallback:** Verificare OCSP se la CRL non è disponibile * **Copie offline:** Mantenere copie CRL locali per sistemi critici ---- ===== Vedere anche ===== * [[.:certificaterevocationlistextensions|CertificateRevocationListExtensions]] - Creazione CRL * [[.:x509chainextensions|X509ChainExtensions]] - Validazione della catena * [[it:int:pqcrypt:konzepte:revocation|Concetto di Revoca]] ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional// {{tag>crl revoca revocation ocsp}}