Страницы

Поиск по вопросам

воскресенье, 12 января 2020 г.

Установка списка отзывов (*.crl) в хранилище компьютера

#c_sharp #сертификат


Ребята, подскажите пожалуйста как в C# установить *.crl в хранилище компьютера.
Есть код для установки сертификата в корневые сертификаты:

private static void InstallRootCertificate(string cerFileName)
{
   X509Store store = new X509Store(StoreName.AuthRoot, StoreLocation.LocalMachine);
   X509Certificate2 certificate = new X509Certificate2(cerFileName);
   store.Open(OpenFlags.ReadWrite);
   store.Add(certificate);
   store.Close();
}


Но он, по понятным причинам не подходит для crl.
Заранее спасибо.
    


Ответы

Ответ 1



Хотя вопрос был задан очень давно, и уже, возможно, не актуален, все же предложу решение, поскольку проблема интересная. Ее решение может быть полезно, например, когда нужно автоматизировать обновление списков отозванных сертификатов на десятках серверов. К сожалению, никаких стандартных средств для решения этой задачи .NET не предоставляет. Придется использовать обертки для crypt32.dll и unsafe-код. Ниже приведет пример решения. Его основу составляет класс CrlFile, который позволят открыть crl-файл и импортировать его в стандартное хранилище (класс System.Security.Cryptography.X509Certificates.X509Store). Дополнительная информация: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376011(v=vs.85).aspx https://blogs.msdn.com/b/gproano/archive/2005/03/22/400645.aspx?Redirected=true class Program { static void Main(string[] args) { var store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); var crl = new CrlFile(@"d:\tmp\ca\root.crl"); crl.Import(store, CrlAddDisposition.CERT_STORE_ADD_REPLACE_EXISTING); store.Close(); } } public class CrlFile { // по уму здесь нужна реализация SafeHandle, // но чтобы не удлинять код оставим, как есть private IntPtr _context; private readonly string _file; public CrlFile(string file) { _file = file; } public bool Import(X509Store store, CrlAddDisposition disp, ref IntPtr storeContext) { EnsureCrlContext(); return Crypto32Interop.CertAddCRLContextToStore(store.StoreHandle, _context, (uint)disp, storeContext); } public bool Import(X509Store store, CrlAddDisposition disp) { var storeContext = IntPtr.Zero; return Import(store, disp, ref storeContext); } private unsafe void EnsureCrlContext() { if (_context != IntPtr.Zero) return; var context = new IntPtr(Crypto32Interop.CERT_QUERY_CONTENT_CRL); var handle = GCHandle.Alloc(_file, GCHandleType.Pinned); var data = handle.AddrOfPinnedObject(); bool ret = Crypto32Interop.CryptQueryObject( Crypto32Interop.CERT_QUERY_OBJECT_FILE, data, Crypto32Interop.CERT_QUERY_CONTENT_FLAG_CRL, Crypto32Interop.CERT_QUERY_FORMAT_FLAG_ALL, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, new IntPtr(&context)); _context = Crypto32Interop.CertDuplicateCRLContext(context); Crypto32Interop.CertFreeCRLContext(context); handle.Free(); } ~CrlFile() { if (_context != IntPtr.Zero) Crypto32Interop.CertFreeCRLContext(_context); } } public static class Crypto32Interop { public const uint CERT_QUERY_CONTENT_CTL = 2; public const uint CERT_QUERY_CONTENT_CRL = 3; public const uint CERT_QUERY_OBJECT_FILE = 1; public const uint CERT_QUERY_FORMAT_BINARY = 1; public const uint CERT_QUERY_FORMAT_BASE64_ENCODED = 2; public const uint CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED = 3; public const uint CERT_QUERY_CONTENT_FLAG_CRL = (1 << (int)CERT_QUERY_CONTENT_CRL); public const uint CERT_QUERY_CONTENT_FLAG_CTL = (1 << (int)CERT_QUERY_CONTENT_CTL); public const uint CERT_QUERY_FORMAT_FLAG_BINARY = (1 << (int)CERT_QUERY_FORMAT_BINARY); public const uint CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED = (1 << (int)CERT_QUERY_FORMAT_BASE64_ENCODED); public const uint CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED = (1 << (int)CERT_QUERY_FORMAT_ASN_ASCII_HEX_ENCODED); public const uint CERT_QUERY_FORMAT_FLAG_ALL = (CERT_QUERY_FORMAT_FLAG_BINARY | CERT_QUERY_FORMAT_FLAG_BASE64_ENCODED | CERT_QUERY_FORMAT_FLAG_ASN_ASCII_HEX_ENCODED); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr CertDuplicateCRLContext(IntPtr pCrlContext); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertFreeCRLContext(IntPtr pCrlContext); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CertAddCRLContextToStore( [In] IntPtr hCertStore, [In] IntPtr pCrlContext, [In] uint dwAddDisposition, [Out] IntPtr ppStoreContext); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CryptQueryObject( [In] uint dwObjectType, [In] IntPtr pvObject, [In] uint dwExpectedContentTypeFlags, [In] uint dwExpectedFormatTypeFlags, [In] uint dwFlags, [Out] IntPtr pdwMsgAndCertEncodingType, [Out] IntPtr pdwContentType, [Out] IntPtr pdwFormatType, [In, Out] IntPtr phCertStore, [In, Out] IntPtr phMsg, [In, Out] IntPtr ppvContext); } public enum CrlAddDisposition : uint { CERT_STORE_ADD_NEW = 1, CERT_STORE_ADD_USE_EXISTING = 2, CERT_STORE_ADD_REPLACE_EXISTING = 3, CERT_STORE_ADD_ALWAYS = 4, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES = 5, CERT_STORE_ADD_NEWER = 6, CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES = 7, }

Комментариев нет:

Отправить комментарий