Contents of this directory is archived and no longer updated.

В первой части управления Certification Authority (CA) мы рассмотрели метод GetCAProperty, при помощи которого мы можем получать различные сведения про сервер CA. Сегодня мы посмотрим ещё несколько интересных моментов, которые будут связаны с CRL и опять будет немного треша с CryptoAPI, а именно:

  • Получение статуса публикации CRL;
  • Получение Base и Delta CRL из CA в виде файлов;
  • Отзыв сертификатов;
  • Извлечение сертификатов из CRL;
  • Публикация новых CRL.

Начало работы

Для начала мы должны будем создать ICertAdmin2 COM объект для управления CA, который будет использоваться нами для всех сегодняшних операций:

PS C:\> $CertAdmin = New-Object -ComObject "CertificateAuthority.Admin.1"

Получение Base и Delta CRL из CA в виде файлов

Далее мы должны узнать 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

Но мы можем кое что узнать о статусе наших 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:

  • CR_PROP_BASECRLPUBLISHSTATUS (0x1E)
  • CR_PROP_DELTACRLPUBLISHSTATUS (0x1F)

Для этих 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 часа после выполнения команды. Да, именно этим методом можно отзывать корневые сертификаты :-).

Извлечение сертификатов из CRL

Примечание: хоть Microsoft и поддерживает извлечение сертификатов из CRL (отмена статуса Revoked), этой возможностью не следует пользоваться в силу определённых причин, как невозможность определеления в какое время сертификат был помещён и извлечён из CRL.

Если сертификат был отозван со статусом Certificate Hold (6), то его можно в любое время вернуть обратно. Для всех остальных типов отзыва такая возможность не поддерживается. Для отмены статуса Revoked нужно использовать этот же метод, только в качестве причины отзыва указать значение MAX_DWORD, которое является 0xffffffff или просто –1:

$CertAdmin.RevokeCertificate("ServerName\CA Name", 0123456789,-1,0)

Публикация новых CRL

Если вы хотите опубликовать новые CRL вручную (т.е. в промежутке между плановой публикацией CRL), то мы должны воспользоваться методом PublishCRLs(). Его синтаксис достаточно простой:

$CertAdmin.PublishCRLs("ServerName\CA Name",0,0)

Эта команда переопубликует как основной, так и инкрементальный CRL (при публикации Base CRL инкрементальный CRL публикуется всегда, потому что Effective Date у него не может быть меньше, чем у Base CRL). Что касается последнего аргумента, то он бывает ещё полезен, если по каким-то причинам потерялся какой-то файл CRL. Тогда вы можете выставить CRLFlags в 4 (0x4) и тогда CA переопубликует текущие CRL без обновления их содержимого и дат.

На сегодня это всё.


Share this article:

Comments:

Comments are closed.