Реми ван Элст. OpenSSL: Ручная проверка сертификата по CRL, 2015

Перевод статьи: OpenSSL: Manually verify a certificate against a CRL

Автор: Реми ван Элст (Remy van Elst)

В этой статье будет показано, как можно вручную проверить сертификат по CRL. CRL означает Certificate Revocation List - список отозванных сертификатов - и является одним из способов проверки статуса сертификата. Этот способ является альтернативой для OCSP - Online Certificate Status Protocol - протокола интерактивного статуса сертификата.

Больше о CRL можно прочитать на Википедии.

Если нужно проверить сертификат по OCSP, обратитесь к другой моей статье.

Воспользуемся OpenSSL. Я использую такую версию:

$ openssl version
OpenSSL 1.0.2 22 Jan 2015

1. Получение сертификата с CRL

Для начала нужно получить сертификат проверяемого веб-сайта. Возьмём в качестве примера Википедию. Получить сертификат можно при помощи следующей команды:

openssl s_client -connect wikipedia.org:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p'

Сохраним вывод в файл, например, wikipedia.pem:

openssl s_client -connect wikipedia.org:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > wikipedia.pem

Теперь проверим, есть ли у этого сертификата URI CRL:

openssl x509 -noout -text -in wikipedia.pem | grep -A 4 'X509v3 CRL Distribution Points'
X509v3 CRL Distribution Points: # Точки распространения X509v3 CRL
    Full Name:                                                                           # Полное имя
      URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl

Если ничего не выведено, значит у сертификата нет URI CRL. Его нельзя проверить по CRL.

Скачиваем CRL:

wget -O crl.der http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl

CRL имеет двоичный формат DER. Команде OpenSSL нужен файл в формате PEM (base64-кодированный DER), поэтому преобразуем его:

openssl crl -inform DER -in crl.der -outform PEM -out crl.pem

2. Получение цепочки сертификатов

Кроме проверяемого сертификата нужна цепочка сертификатов. Поэтому нужно получить цепочку сертификатов для проверяемого домена - wikipedia.org. Воспользовавшись опцией -showcerts команды openssl s_client, можно увидеть все сертификаты, принадлежащие цепочке:

openssl s_client -connect wikipedia.org:443 -showcerts 2>&1 < /dev/null

Будет выведено много текста, но нас интересует в нём следующее:

1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance CA-3
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
-----BEGIN CERTIFICATE-----
MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR
CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv
KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5
BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf
1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs
zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d
32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w
ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3
LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH
AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy
AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj
AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg
AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ
AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt
AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj
AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl
AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm
MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB
hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln
aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl
cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME
GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB
INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a
vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j
CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X
dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE
JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY
Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E=
-----END CERTIFICATE-----

Как можно увидеть, это номер 1. Номер 0 - это сертификат Википедии, который у нас уже есть. Если у проверяемого сайта в цепочке имеется больше сертификатов, они все будут отображены. Сохраним все сертификаты в том порядке, в котором их вывел OpenSSL (первый, который непосредственно выпустил сертификат проверяемого сервера, затем тот, который выпустил этот сертификат и так далее с корневым или самым корневым в конце файла) в файл с именем chain.pem.

Можно использовать следующую команду для сохранения всех сертификатов, выведенных командой OpenSSL, в файл с именем chain.pem. Обратитесь к этой статье за более подробной информацией.

OLDIFS=$IFS; \
IFS=':' certificates=$(openssl s_client -connect wikipedia.org:443 -showcerts -tlsextdebug -tls1 2>&1 < /dev/null \
                         | sed -n '/-----BEGIN/,/-----END/ {/-----BEGIN/ s/^/:/; p}'); \
for certificate in ${certificates#:}; do \
  echo $certificate | tee -a chain.pem ; \
done; \
IFS=$OLDIFS

3. Объединение CRL и цепочки

Команде openssl для проверки нужны цепочка сертификатов и CRL в формате PEM, соединённые вместе. Можно пропустить CRL, но тогда проверка по CRL не будет выполнена, произойдёт проверка только сертификата по цепочке.

cat chain.pem crl.pem > crl_chain.pem

4. Проверка OpenSSL

Теперь у нас есть все данные, необходимые для проверки сертификата.

$ openssl verify -crl_check -CAfile crl_chain.pem wikipedia.pem
wikipedia.pem: OK

Результат показывает, что сертификат действительный.

5. Отозванный сертификат

Если имеется отозванный сертификат, его так же можете проверить способом, описанным выше. Ответ будет выглядеть следующим образом:

$ openssl verify -crl_check -CAfile crl_chain.pem revoked-test.pem
revoked-test.pem: OU = Domain Control Validated, OU = PositiveSSL, CN = xs4all.nl
error 23 at 0 depth lookup:certificate revoked                                    # ошибка 23 на 0 глубине поиска: сертификат отозван

Имея сертификат и цепочку, эти проверки можно выполнить странице Verisign для проверки отозванных сертификатов: https://test-sspev.verisign.com:2443/test-SSPEV-revoked-verisign.html.

Написать автору перевода