Как составить список сертификатов, которым доверяет OpenSSL?

Как я понимаю, любое программное обеспечение, работающее с сертификатами X.509, может иметь собственную основу для принятия решения о том, является ли сертификат доверенным или нет.

AFAIK OpenSSL просто просматривает список (такой как, например, /etc/ssl/certs) и проверяет, присутствует ли там сертификат.

Есть ли способ для OpenSSL перечислить все сертификаты, которым он доверяет? Я знаю, что могу самостоятельно обратиться к этому файлу (на моей конкретной установке OpenSSL), но есть ли (независимый от установки) способ получить список доверенных от самого OpenSSL?

3 ответа

Решение

AFAIK OpenSSL просто просматривает список (например, /etc/ssl/certs) и проверяет, присутствует ли там сертификат.

Нет, OpenSSL по умолчанию ничего не доверяет. Вы должны дать ему указание, чему доверять. Есть даже тема часто задаваемых вопросов, покрывающая это: Почему <SSL program> сбой с сертификатом проверить ошибку?:

Эта проблема обычно указывается в сообщениях журнала, в которых говорится что-то вроде "невозможно получить сертификат локального эмитента" или "самозаверяющий сертификат". Когда сертификат проверен, его корневой CA должен быть "доверенным" OpenSSL, это обычно означает, что сертификат CA должен быть помещен в каталог или файл и соответствующая программа настроена для его чтения. Программа OpenSSL 'verify' ведет себя аналогичным образом и выдает похожие сообщения об ошибках: для получения дополнительной информации посетите страницу руководства программы verify(1).

Вы также можете проверить свое соединение с Google, чтобы увидеть, как ведет себя OpenSSL:

$ openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
...
Start Time: 1407377002
Timeout   : 300 (sec)
Verify return code: 20 (unable to get local issuer certificate)

Обратите внимание, что вышеперечисленное не работает, поскольку OpenSSL по умолчанию не доверяет GeoTrust Global CA. На самом деле, есть еще одна точка доверия в цепочке, и это Google Internet Authority G2.

Вы можете исправить ситуацию, сказав OpenSSL, чему доверять. Ниже я использую -CAfile вариант с Google Internet Authority G2:

$ openssl s_client -connect google.com:443 -CAfile google-ca.pem 
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377196
Timeout   : 300 (sec)
Verify return code: 0 (ok)

Далее вы можете вести себя как браузер, зайдя в cURL и загрузив cacert.pem, cacert.pem в нем много CA:

$ openssl s_client -connect google.com:443 -CAfile cacert.pem 
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
...
Start Time: 1407377356
Timeout   : 300 (sec)
Verify return code: 0 (ok)

Вы не так плохи, как браузер с его сотнями CA и подчиненными CA, но вы приближаетесь:

$ cat cacert.pem | grep -o "\-\-\-\-\-BEGIN" | wc -l
     153

Модель безопасности OpenSSL отличается от модели безопасности веб-приложения / браузера, где браузер содержит список якорей доверия или точек доверия, известных как центры сертификации (CA). Примечание: в этой модели неправильный центр сертификации может претендовать на сертификацию сайта, и браузер не будет мудрее.

Это происходило в прошлом, и, скорее всего, это произойдет снова в будущем. Хорошую историю забавного бизнеса PKIX см. В истории рисков CA cert. Например, вы знаете, что Google Internet Authority G2 и GeoTrust Global CA сертифицируют сайты Google. У голландского CA, называемого Diginotar, нет никаких оснований требовать их сертификации или у французского агентства по киберзащите требовать их сертификации.

Относительно моделей безопасности: другая проблема с моделью веб-приложения / браузера заключается в том, что вы не можете упаковать один доверенный якорь или CA, необходимый для вашего приложения, и использовать его (при условии, что у вас есть надежный канал распространения). Ваши сертификаты будут брошены в кучу с CA Zoo. Другие могут по-прежнему претендовать на сертификацию вашего сайта, а вы можете претендовать на сертификацию других сайтов.

Модель безопасности - одна из причин, по которой веб-приложения переводятся в низкоуровневые данные. Веб-приложения не должны обрабатывать данные среднего или высокого значения, потому что мы не можем разместить необходимые элементы управления безопасностью.


Есть ли способ для OpenSSL перечислить все сертификаты, которым он доверяет?

Нет необходимости, так как в списке 0 участников:)


Также см. Как узнать путь для доверенного сертификата openssl?,

Недавно я изучил это и не нашел способа заставить OpenSSL перечислить сертификаты в своем доверенном наборе. Лучший способ, который я нашел, - как вы указываете, "проконсультироваться с этим файлом [/etc/ssl/certs] самостоятельно (относительно моей конкретной установки OpenSSL)".

Вы можете быть более независимыми от установки, чтобы найти каталог, к которому обращается OpenSSL. openssl version -d печатает путь к нему.

% openssl version -d
OPENSSLDIR: "/opt/local/etc/openssl"

OpenSSL ищет здесь файл с именем cert.pem и подкаталог certs/, Сертификаты, которые он там находит, считаются доверенными openssl s_client а также openssl verify (источник: статья " Какие центры сертификации распознает OpenSSL?").

Итак, вы можете сделать что-то вроде:

% find -H `openssl version -d | sed -E 's/OPENSSLDIR: "([^"]*)"/\1/'`/(cert.pem|certs) \ 
-type f -exec cat {} \+  

Это распечатывает все содержимое файлов, которые OpenSSL ожидает содержать сертификаты. Если вы хотите меньше, чем весь файл, то замените cat с соответствующими командами.

Интересно, изменилось ли это каким-то образом с момента ответа jww?

Если я отправлю: $ openssl s_client -connect google.com:443

Он успешно работает, получает 4 сертификата и возвращает:

Start Time: 1484661709
Timeout   : 300 (sec)
Verify return code: 0 (ok)

Я считаю, что это потому, что серверы должны быть настроены для отправки вместе с сертификатом любых промежуточных и корневых сертификатов, необходимых для проверки полной цепочки, верно?

Самостоятельный ответ: этот текст предлагает позвонитьSSL_CTX_set_default_verify_paths() доверять сертификатам в системно-зависимом каталоге.

Другие вопросы по тегам