В первой части управления Certification Authority (CA) мы рассмотрели метод GetCAProperty, при помощи которого мы можем получать различные сведения про сервер CA. Сегодня мы посмотрим ещё несколько интересных моментов, которые будут связаны с CRL и опять будет немного треша с CryptoAPI, а именно:
Для начала мы должны будем создать ICertAdmin2 COM объект для управления CA, который будет использоваться нами для всех сегодняшних операций:
PS C:\> $CertAdmin = New-Object -ComObject "CertificateAuthority.Admin.1"
Далее мы должны узнать PropID, который бы отвечал за показ CRL вот по этой ссылке: 3.2.1.4.2.2 ICertRequestD2::GetCAProperty (Opnum 7). Нас будет интересовать 2 этих ID: CR_PROP_BASECRL (0x11) и CR_PROP_DELTACRL (0x12). Поскольку тип возвращаемых данных будет Binary, то PropType будет равен 3, а Flags выставим в 0 (Base64CRLHeader). Можно и другой указать, от этого только зависит метод записи в файл.
Примечание: напоминаю, что индекс PropType начинается с 1, а Flags с 0 и их возможные значения описаны здесь: GetCAProperty. А так же то, что в Flags первые 2 значения перепутаны местами на MSDN.
И вот как мы их можем получить:
PS C:\> $BaseCRL = $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x11,0,3,0) PS C:\> $BaseCRL -----BEGIN X509 CRL----- MIIEDTCCAvUCAQEwDQYJKoZIhvcNAQEFBQAwRzETMBEGCgmSJomT8ixkARkWA2Nv bTEXMBUGCgmSJomT8ixkARkWB2NvbnRvc28xFzAVBgNVBAMTDmNvbnRvc28tREMy LUNBFw0wOTExMDkwNjI0NDlaFw0wOTExMTcwNjQ0NDlaMIIBzDAbAgpG7E9iAAAA AACSFw0wOTExMDgxODM5MDBaMCkCCm716aoAAAAAAI8XDTA5MTAyMjE2MjI1OVow DDAKBgNVHRUEAwoBBDAbAgpxOBcQAAAAAACLFw0wOTA5MjgwNjMzMDBaMBsCCl6/ ZbYAAAAAAIkXDTA5MDkyNDE3MTcwMFowGwIKXnVZiQAAAAAAiBcNMDkwOTI0MTUw MjAwWjApAgoggMu3AAAAAAAVFw0wOTA1MTcyMDE0MDBaMAwwCgYDVR0VBAMKAQUw KQIKYRZ2nAAAAAAADRcNMDkwNTAxMTk1MzAwWjAMMAoGA1UdFQQDCgEFMCkCCmJ0 33IAAAAAAAoXDTA5MDQxOTEzMDUwMFowDDAKBgNVHRUEAwoBBDApAgphINAVAAAA AAAHFw0wOTAzMzExMTEzMDBaMAwwCgYDVR0VBAMKAQUwKQIKYRT3zAAAAAAABhcN MDkwMzMxMTAzMTAwWjAMMAoGA1UdFQQDCgEFMCkCCmERwOwAAAAAAAUXDTA5MDMz MTEwMTgwMFowDDAKBgNVHRUEAwoBBDApAgphDxXgAAAAAAAEFw0wOTAzMzExMDE0 MDBaMAwwCgYDVR0VBAMKAQSggakwgaYwHwYDVR0jBBgwFoAUZiAsZ5wOPk1F8vmX BZdmE1QTJjYwEAYJKwYBBAGCNxUBBAMCAQAwCwYDVR0UBAQCAgDyMBwGCSsGAQQB gjcVBAQPFw0wOTExMTYwNjM0NDlaMEYGA1UdLgQ/MD0wO6A5oDeGNWh0dHA6Ly9k YzIuY29udG9zby5jb20vQ2VydEVucm9sbC9jb250b3NvLURDMi1DQSsuY3JsMA0G CSqGSIb3DQEBBQUAA4IBAQCCNVxtZbAbB5C1bI5Z6PF+Eph2MaRhl9pv0FjYhH/j Xlvffau1m5bW72No7FC2k8FFU2oHFSZvAVNKgjm6+ECb4iEpzREcHpwsot1TG0kn Pv+DRGjQ2ndes8OM11v3oYUJxlNOMqY6q03lj/BEJb+ocNerWRay8G0sycy1ABCD /UPvP9qq54WvwQnJyV5bZJcJG3WYtN7zkZZzf5MR3v+c4OODLiLw5pXgku49USFu kTuEh5DYcF5zbo6h5IqAW+OP6iMFepxkUEZUb/5VOYK8VcpXDwMzIRzlf+bITHyX 6PVugwm6TXkn9eVrAfJUd70S9LV7XVTz32IykC3tNXFY -----END X509 CRL----- PS C:\> $DeltaCRL = $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x12,0,3,0) PS C:\> $BaseCRL > base.crl PS C:\> $DeltaCRL > delta.crl PS C:\> & .\base.crl PS C:\> & .\delta.crl PS C:\>
последние 2 команды просто запускают эти CRL файлы. К сожалению не существует ни одного родного класса, который бы представлял собой объект CRL, поэтому как-то разбирать его на таком уровне пока не представляется возможным. Хотя существуют сторонние библиотеки (например, в Mono есть класс X509CRL).
Но мы можем кое что узнать о статусе наших CRL. Для этого существует PropID = CR_PROP_CRLSTATE (0x14). Тип возвращаемых данных будет Long, значит PropType будет 1, а Flags будет игнорироваться, поэтому поставим его в 0:
PS C:\> $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x14,0,1,0) 3
Расшифровку этого значения можно найти здесь: 3.2.1.4.2.2.20 PropID = 0x00000014 (CR_PROP_CRLSTATE) "CA CRL State". Число 3 означает, что с CRL у нас всё хорошо (CA_DISP_VALID (0x03)). В принципе, на данном этапе нам больше ничего и не нужно. Но мы можем посмотреть более детальные сведения по каждому типу CRL. Для получения более детальной ошибки мы должны использовать следующие PropID:
Для этих PropID тип данных так же указан Long, поэтому PropType выставим в 1, а Flags в 0:
PS C:\> $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x1E,0,1,0) 5 PS C:\> $certadmin.GetCAProperty("dc2\contoso-dc2-ca",0x1F,0,1,0) 6 PS C:\>
Мы получили число 5 для BaseCRL и 6 для DeltaCRL. Расшифровку этих значений можно посмотреть вот здесь: 3.2.1.4.2.2.30 PropID = 0x0000001E (CR_PROP_BASECRLPUBLISHSTATUS) "Base CRL Publishing Status". Поскольку вывод — не конкретное число, а результат двоичного оператора И (AND), то мы это число должны разбить на составляющие. И вот как это делается:
$Return = $certadmin.GetCAProperty("ServerName\CA Name",0x1E,0,1,0) $options = 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 | %{$Return -band $_} | ?{$_} # поскольку значения масок являются результаты возведения двойки в степень # начиная от 0 до 11, то эту строчку можно переписать более готично. # Напоминаю, что возведение любого числа в нулевую степень # всегда вернёт 1. Кажется, это из алгебры 5-6 класса. $options = 0..11| %{[Math]::Pow(2,$_)} | %{$Return -band $_} | ?{$_} switch ($options) { 1 {"The CRL is a base CRL"} 2 {"The CRL is a delta CRL"} 4 {"The last CRL publication that was completed and published to the locations specified in the CA"} 8 {"The CRL is a shadow delta CRL"} 16 {"The CA MAY publish the CRL to a local store that is not externally accessible. This error is returned when publishing to this intermediate store failed"} 32 {"An error occurred during publication of the CRL. The error indicates that the file schema cannot be recognized.The schema must be file: or ldap:"} 64 {"Publication of the CRL was manually initiated by an administrator"} 128 {"A CRL signature error was detected. The CSP was not correct"} 256 {"An error occurred during publication of the CRL to an LDAP URL"} 512 {"An error occurred during publication of the CRL to a file URL"} 1024 {"An error occurred during publication of the CRL to an FTP URL. FTP URLs are not supported"} 2048 {"The CA cannot publish CRLs to HTTP URLs. This error is returned if a CA administrator configured the CA to publish CRLs to HTTP URLs"} }
Следовательно число 5 (1+4) говорит нам о том, что это был Base CRL и он был опубликован успешно. А 6 (2+4) — Delta CRL был опубликован успешно.
Интерфейс IcertAdmin2 позволяет нам отзывать сертификаты на сервере CA. Для этого мы воспользуемся методом RevokeCertificate(). Метод достаточно простой и примерная команда для отзыва сертификата будет выглядеть так:
$CertAdmin.RevokeCertificate("ServerName\CA Name", 0123456789,4,(Get-Date).AddDays(1))
0123456789 будет обозначать серийный номер сертификата, 4 — причина отзыва будет Superseded и эффективная дата отзыва (когда сертификат будет помещён в Revoked Certificates) будет 24 часа после выполнения команды. Да, именно этим методом можно отзывать корневые сертификаты :-).
Примечание: хоть Microsoft и поддерживает извлечение сертификатов из CRL (отмена статуса Revoked), этой возможностью не следует пользоваться в силу определённых причин, как невозможность определеления в какое время сертификат был помещён и извлечён из CRL.
Если сертификат был отозван со статусом Certificate Hold (6), то его можно в любое время вернуть обратно. Для всех остальных типов отзыва такая возможность не поддерживается. Для отмены статуса Revoked нужно использовать этот же метод, только в качестве причины отзыва указать значение MAX_DWORD, которое является 0xffffffff или просто –1:
$CertAdmin.RevokeCertificate("ServerName\CA Name", 0123456789,-1,0)
Если вы хотите опубликовать новые CRL вручную (т.е. в промежутке между плановой публикацией CRL), то мы должны воспользоваться методом PublishCRLs(). Его синтаксис достаточно простой:
$CertAdmin.PublishCRLs("ServerName\CA Name",0,0)
Эта команда переопубликует как основной, так и инкрементальный CRL (при публикации Base CRL инкрементальный CRL публикуется всегда, потому что Effective Date у него не может быть меньше, чем у Base CRL). Что касается последнего аргумента, то он бывает ещё полезен, если по каким-то причинам потерялся какой-то файл CRL. Тогда вы можете выставить CRLFlags в 4 (0x4) и тогда CA переопубликует текущие CRL без обновления их содержимого и дат.
На сегодня это всё.
Comments: