Root certificates on Linux
От: Pzz Россия https://github.com/alexpevzner
Дата: 17.10.12 13:16
Оценка:
Где их, собственно, искать-то в линухе, так, чтобы на любом дистрибутиве работало? Желательно в формате, понятном OpenSSL.
Re: Root certificates on Linux
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.10.12 13:36
Оценка: 9 (1)
Здравствуйте, Pzz, Вы писали:

Pzz>Где их, собственно, искать-то в линухе, так, чтобы на любом дистрибутиве работало? Желательно в формате, понятном OpenSSL.


Чтобы на любом — сомневаюсь, есть всё-таки разные стили путей. Можно только перепробовать несколько стандартных. А касательно формата — так только OpenSSL по сути и есть.

Процитирую себя из внутреннего тикета. Специфика фирмы и ликбез для чайников срезаны. Разборки с путями со второй части.

  Скрытый текст

I.
[...]

Ресурсы для самостоятельного изучения (по всей теме тикета):

http://datatracker.ietf.org/wg/pkix/charter/
официальщина о том, как космические корабли... (skipped)

http://www.ietf.org/rfc/rfc5280.txt
относительно внятный и доступный пересказ хотя бы одной формы, на которую
можно положиться хотя бы вначале. хотя по уровню запутанности плавно
приближается к описанию SIP.

http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
эротический триллер о том, какие реальные грабли стоят на пути.
не рекомендуется к чтению на ночь.

http://luca.ntop.org/Teaching/Appunti/asn1.html
почти букварь к предыдущему.

http://www.inssl.com/x509-open-key-specifications.html
http://www.nixp.ru/articles/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B-%D1%81-OpenSSL.html
http://www.sys-adm.org.ua/security/ssl-howto.php
http://it-profity.ru/ssl-virtual-host-na-apache-2-2-mod_ssl-i-samopodpisannyie-sertifikatyi/
целая пачка howto с общим принципом "делай как я, и скорее всего
заработает".

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

II. Посмотрим несколько примеров о том, какие бывают случаи в реальном
использовании в вебе. Во всех случаях сайт открывался в вебе, далее через
View page info -> Security -> View Certificate смотрелись сертификаты.
(NB: выбрав конкретный сертификат в цепочке, кнопкой Export его можно
сохранить в файл на диске в формате PEM.)

1. mail.google.com: видна цепочка из 3 сертификатов
Верхний:
C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority
версия: 1 (старая однако)
годы жизни: 1996-2028 (ух ты)
ограничений нет;
следующий:
C=ZA, O=Thawte Consulting (Pty) Ltd., CN=Thawte SGC CA
версия: 3
годы жизни: 2004-2014
уже ограничения (например, CA:TRUE, pathlen:0)
последний:
C=US, ST=California, L=Mountain View, O=Google Inc, CN=mail.google.com
версия: 3
срок жизни: 2011-2013 (точные даты облом переписывать)
ограничения: CA:FALSE

2. stat.volia.com:8443: хороший пример на тот же стиль, но тут записано
CN=*.volia.com, то есть групповой сертификат на все подддомены.
Участвующие "по дороге" сертификаты другие, но сконструированы схожим
образом. Мне этот пример интересен именно поддоменами, они нам могут быть
полезны.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Первый на пробу — OpenSuSE 11.4 (мой десктоп)

Пакеты с cert в названии:

$ rpm -qa | grep cert | sort
ca-certificates-1-9.1.noarch
ca-certificates-mozilla-1.76-1.3.1.noarch
java-ca-certificates-1-9.1.noarch
mozilla-nss-certs-3.13.1-0.2.1.x86_64
mozilla-nss-certs-32bit-3.13.1-0.2.1.x86_64

В них:
ca-certificates-1-9.1.noarch: даёт /etc/ssl/certs/ (про него чуть ниже)
и /var/lib/ca-certificates/ca-bundle.pem, на который симлинк
/etc/ssl/ca-bundle.pem и который представляет собой последовательность
сертификатов в PEM. Похоже, что это те же сертификаты, что разбросанно лежат
в ca-certificates-mozilla (первый по порядку в этом ca-bundle.pem это
Acedicom root). См. ниже про настройку CAfile.

1) каталог /etc/ssl/certs, который чуть более чем полностью заполнен
симлинками вида ddc328ff.0 -> Thawte_Server_CA.pem и именованных, идущих в
/usr/share/ca-certificates/mozilla/, в котором лежат файлы сертификатов в
PEM. Это уже из пакета ca-certificates-mozilla. Можно сделать из такого
сертификата текст и посмотреть, что там, например:

openssl x509 -in /usr/share/ca-certificates/mozilla/Thawte_Server_CA.pem -text

Можно также попросить вывести в DER (-outform der), это фактически снимет
base64 и даст чистую двоичку (оно и видно: в начале идёт 30 82 03 13 —
указание на sequence размером в 787 байт). В общем, тут уже много вариантов.

Число в линке — это subject hash. Наиболее внятная цитата из verify(1ssl):
===
-CApath directory
A directory of trusted certificates. The certificates should have
names of the form: hash.0 or have symbolic links to them of this
form ("hash" is the hashed certificate subject name: see the -hash
option of the x509 utility). Under Unix the c_rehash script will
automatically create symbolic links to a directory of certificates.
===

Для иллюстрации:

$ ls -l /etc/ssl/certs/2fa87019.0
lrwxrwxrwx 1 root root 43 Sep 1 10:53 /etc/ssl/certs/2fa87019.0 ->
Network_Solutions_Certificate_Authority.pem
$ openssl x509 -in /etc/ssl/certs/2fa87019.0 -hash | head -1
2fa87019

NB: все корневые сертификаты должны быть самоподписанными (это видно по
тому, что в выводе по -text совпадают значения Issuer: и Subject, и
доверие такому сертификату исходно (в отличие от тех, где эти значения
расходятся и тогда доверие смотрится через другой сертификат), и иметь в
X509v3 Basic Constraints — CA:TRUE (причём у constraint'а должен быть флаг
critical, то есть без его понимания софт не имеет права работать с
сертификатом). В отличие от них, целевые сертификаты сайтов выдаются с
CA:FALSE. В принципе можно увидеть сертификат, который и для сайта, и для
прочего, но это нетипично.

Остальные три пакета (на моей suse) — или so'шки, или что-то очень
специфическое как JAR с кодом. Итого, реальный комплект сертификатов —
первые два.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

IV. Попробуем сделать проверку верификации в клиенте.
Два опробованных пути:
1. Питоновский модуль ssl (враппер вокруг OpenSSL'ной libssl.so)
основной вызов:
c1pem = ssl.get_server_certificate(('google.com', 443), ssl.PROTOCOL_TLSv1)
2. Штатная команда:
openssl s_client -showcerts -verify 4 -connect mail.google.com:443 </dev/null
(или другой сайт)

Тут результаты такие. Если у ssl.get_server_certificate() сделать вызов,
как указан выше, то цепочка сертификатов получается от сервера, а локальная
проверка даже не начинается (strace показывает, что никакие штатные пути
не смотрятся). Если же добавить параметр в вызов функции:

ca_certs = '/etc/ssl/ca-bundle.pem'

то с mail.google.com всё проходит, а с netmon.**** (это мой тестовый
пример, про который я знаю, что там самоподписанный сертификат) получается
облом со следующим исключением:

ssl.SSLError: [Errno 1] _ssl.c:499: error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Для s_client аналогично. Без дополнительных параметров проверка с
mail.google.com пишет:

Verify return code: 27 (certificate not trusted)

Но если я добавлю одно из двух:
-CAfile /etc/ssl/ca-bundle.pem
или:
-CApath /etc/ssl/certs

то получится:

Verify return code: 0 (ok)

Для самоподписанного netmon.****:443: во всех случаях отдаёт

Verify return code: 18 (self signed certificate)

Второй хост на пробу — взял debian имени ****@, сравнил пакеты и проверку
через s_client.

$ dpkg -l | grep cert
ii ca-certificates 20090814+nmu3squeeze1
Common CA certificates
ii ca-certificates-java 20100412
Common CA certificates (JKS keystore)
ii ssl-cert 1.0.28
simple debconf wrapper for OpenSSL

Очевидно, к делу имеет отношение только первый. В нём:

$ dpkg-query -L ca-certificates | less

вывод скипнут. в общем видим всё то же, а именно: ссылки из 8 hex-цифр с
добавкой .0 (хотя иногда и без неё); симлинки в
/usr/share/ca-certificates/mozilla/, которые (вот тут другая нарезка на
пакеты) присутствуют именно в этом ca-certificates. Но тут есть
несколько сертификатов не в каталоге mozilla, это уже интереснее
(например, spi-inc.org и debconf.org). Суффиксы у файлов — .crt, а не
.pem (но у симлинков в /etc/ssl/certs — именно .pem). Состав сертификатов
отличается (например, в opensuse для Thawte их 2, а в дебиане 6 — добавлено
ещё 3 группы personal и один time stamping).

Вывод — авторы дистрибутивов в основном базируются на авторитете Mozilla
Foundation о том, какие корни правильные и кому можно верить.

Проверка через s_client показывает то же самое — локальной верификации
не производится, если явно не указано, просто принимается на веру цепочка от
клиента. Отличия от OpenSuSE в том, что файла с сертификатами нет,
то есть вариант -CAfile не пройдёт, сработает только -CApath.
Но их можно задавать несколько раз. Я сделал пробу, написав так:
-CApath /var/tmp -CApath /etc/ssl/certs -CApath /tmp
и увидел, что оно делает stat() по этим путям (причём в обратном порядке,
начало с /tmp), и берёт первый попавшийся сертификат:
19767 10:57:13.740192 stat("/tmp/415660c1.0", 0x7fffb04e6b00) = -1 ENOENT (No
such file or directory)
19767 10:57:13.740245 stat("/etc/ssl/certs/415660c1.0", {st_mode=S_IFREG|0644,
st_size=1003, ...}) = 0
Для -CAfile подобный эксперимент не прошёл — оно берёт только последний файл
из перечисленных

Вывод из рассмотренного — что есть бардак в том, использовать, в
терминах утилиты s_client, CAfile или CApath, надо быть готовым к тому, что
разные средства требуют разное из этих двух, с их спецификой.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

V. Начальные конструктивные тесты на тему "абы хоть как-то работало".

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

Совершенно минимальный подход для сертификата "лишь бы проходил проверку"
выглядит так:

openssl genrsa -out k1.key 2048
openssl req -outform pem -out root.crt -new \
-subj '/DC=qqq/DC=rrr' -key k1.key -x509 -days 3650

Получается живой сертификат (в файле root.crt), у которого даже CA:TRUE
выставлено, как положено. Он может использоваться как самоподписанный для
отдельного сайта (при этом надо вместо таких DC нарисовать CN=сайт) или
корень иерархии.

Аналогичный путь, но чуть длиннее:
openssl genrsa -out k1.key 2048
openssl req -outform pem -out root.req -new \
-subj '/DC=qqq/DC=rrr' -key k1.key -days 3650
openssl x509 -req -days 3650 -in root.req -signkey k1.key -out root.crt

(но делает при этом версию 1, а не версию 3! тут в мелочах начинают
бродить очень противные чёртики)

Для более сложного пути надо рисовать конфиг-файл (попытки заставить
работать `openssl ca' без него провалились) или использовать модули в
языках. Я в общем случае предпочёл бы это опитонить, а коммандлайновые
средства с генерацией конфига использовать только в самом крайнем случае.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

RFC5280 описывает всю систему сертификации, но язык у него такой, что через
него надо ещё продираться (что неизбежно для стандарта на такой механизм).

The God is real, unless declared integer.
Отредактировано 10.03.2020 13:58 netch80 . Предыдущая версия . Еще …
Отредактировано 22.04.2015 9:21 netch80 (misediting fix) . Предыдущая версия .
Re[2]: Root certificates on Linux
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 17.10.12 13:37
Оценка:
Здравствуйте, netch80, Вы писали:

N>Специфика и ликбез для чайников фирмы срезаны.


Тут должно было быть "специфика фирмы и ликбез для чайников"
The God is real, unless declared integer.
Re: Root certificates on Linux
От: MescalitoPeyot Украина  
Дата: 20.10.12 07:07
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Где их, собственно, искать-то в линухе, так, чтобы на любом дистрибутиве работало? Желательно в формате, понятном OpenSSL.


Я брал здесь http://curl.haxx.se/docs/caextract.html
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.