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

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

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

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


person Konstantin Shemyak    schedule 06.08.2014    source источник


Ответы (4)


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

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

На эту проблему обычно указывают сообщения журнала, в которых говорится что-то вроде «невозможно получить сертификат локального эмитента» или «самоподписанный сертификат». Когда сертификат проверен, его корневой ЦС должен быть «доверенным» для OpenSSL. Обычно это означает, что сертификат ЦС должен быть помещен в каталог или файл, а соответствующая программа должна быть настроена для его чтения. Программа 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 содержит множество ЦС:

$ 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)

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

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

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

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

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

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


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

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


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

person jww    schedule 06.08.2014
comment
OpenSSL, безусловно, автоматически доверяет определенным сертификатам: любым, которые находятся в каталоге файлов OpenSSL, либо в файле с именем cert.pem, либо в подкаталоге certs/. Источник: Какие центры сертификации распознает OpenSSL ?. Теперь может случиться так, что в вашей установке ничего нет в этом каталоге, но моя установка имеет символическую ссылку cert.pem на набор сертификатов корневого центра сертификации, поэтому моя установка OpenSSL автоматически доверяет многим сайтам. - person Jim DeLaHunt; 18.12.2017
comment
Этот ответ технически правильный, но неточный практически для любого фактического использования OpenSSL. Из приведенного ниже комментария: если вы устанавливаете OpenSSL из исходного кода, вы не будете устанавливать доверенное хранилище сертификатов. Если вы используете менеджер пакетов вашего дистрибутива, упаковка дистрибутива, вероятно, включает в себя зависимость от любого набора сертификатов, которому разработчики дистрибутива решили доверять, поэтому вы получаете заполненное хранилище доверия. Поскольку SSL/TLS довольно бесполезен, если вы не знаете, каким корневым сертификатам доверять, почти любая фактическая установка OpenSSL будет настроена с использованием доверенных корневых сертификатов. - person Jens Alfke; 09.07.2019
comment
Нет необходимости - плохой ответ. Хотелось бы увидеть реальный ответ на этот вопрос - person Alex; 10.06.2020

Недавно я изучал это и не нашел способа заставить 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 соответствующими командами.

person Jim DeLaHunt    schedule 18.12.2017

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

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

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

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

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

person em_bo    schedule 17.01.2017
comment
Здесь такое же поведение. На 4 разных клиентах Linux. Либо у OpenSSL есть список доверенных ЦС, либо он ищет список доверенных ЦС в папке по умолчанию. - person STM; 22.09.2017
comment
То же самое. Корневой сертификат такой: depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA. В моей системе есть файл /etc/ssl/certs/GeoTrust_Global_CA.pem, который, по-видимому, заставляет OpenSSL неявно доверять ему. Стоит отметить, что -showcerts по-прежнему не печатает этот корневой сертификат. - person Thomas; 03.10.2017
comment
Здесь происходит то, что мы говорим о двух разных ситуациях. Если вы устанавливаете OpenSSL из исходного кода, вы не будете устанавливать доверенное хранилище сертификатов. Если вы используете диспетчер пакетов вашего дистрибутива, то упаковка дистрибутива, вероятно, включает зависимость от любого пакета сертификатов, которому разработчики дистрибутива решили доверять, так что вы делаете получаете заполненное хранилище доверия. Сервер может отправить стек сертификатов, формирующих его путь проверки, но клиент не должен доверять корневому сертификату в этом стеке, потому что он может быть откуда угодно, не обязательно откуда-то вы доверяете. - person Mark Wood; 26.04.2018

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

person Konstantin Shemyak    schedule 25.12.2019