Сбой проверки цепочки сертификатов на листовом сертификате

Я создал цепочку сертификатов PEM (CA, промежуточный и конечный), используя pyopenssl, и я хотел подтвердить, что все правильно определил.

Вот шаги, которые я предпринял:

  1. Я сделал три сертификата PEM, сам подписал CA и определил базовое ограничение crypto.X509Extension(b'basicConstraints', False, b'CA:TRUE') после этого вопроса
  2. Я скопировал CA и промежуточные сертификаты в /usr/local/share/ca-certificates (как файлы crt) и запустил sudo update-ca-cert
  3. Я установил простой сервер на основе этого примера OpenSSL
  4. Я попробовал запустить сервер с сертификатом CA и выполнил openssl s_client -connect localhost:4433 -CApath /etc/ssl/certs - отлично сработал, получил Verify return code: 0 (ok)
  5. Сделал то же самое, но на этот раз сервер использовал промежуточный сертификат - тоже отлично, Verify return code: 0 (ok)
  6. Сделал то же самое, но на этот раз сервер использовал листовой сертификат - на этот раз я получил Verify return code: 24 (invalid CA certificate)

Кроме того, я попытался проверить сертификаты и получил следующее:

$ openssl verify 1-ca.pem
1-ca.pem: OK
$ openssl verify 2-intermediate.pem
2-intermediate.pem: OK
$ openssl verify 3-leaf.pem
C = NL, ST = Amsterdam, L = Zaandam, O = FakeDigiCert, OU = FakeFake, CN = www.fakedigicert.nl
error 24 at 1 depth lookup: invalid CA certificate
error 3-leaf.pem: verification failed

Почему сертификат CA внезапно становится недействительным, когда сертификат сервера находится более чем в одном шаге от CA?


person GabeL    schedule 30.07.2020    source источник
comment
Вы не уточняете, что именно вы вставляете в какой сертификат, но вы говорите «CA и промежуточный», как если бы промежуточное звено не было CA, а это так. У вас есть корневой ЦС, один промежуточный ЦС и конечный объект, известный как лист. OpenSSL требует / у каждого промежуточного центра сертификации есть BasicConstraints.ca = true, иначе вы получите ошибку проверки 24; по крайней мере, на данный момент это не требуется для корневого ЦС, если код не устанавливает «строгий» флаг, но корневой должен тем не менее иметь его.   -  person dave_thompson_085    schedule 31.07.2020
comment
@ dave_thompson_085 Это действительно была проблема. Я предположил, что промежуточный сертификат не обязательно является ЦС. Как только я добавил базовое ограничение, проверка прошла. Спасибо!   -  person GabeL    schedule 02.08.2020


Ответы (1)


Кажется, это обычная ловушка, которую большинство людей постоянно делают при настройке веб-сервера https. Вам также необходимо предоставить все промежуточные сертификаты веб-серверу (обычно путем объединения конечных и промежуточных файлов pem в один файл pem). Поэтому, когда веб-браузеры переходят на ваш сайт, настройка SSL должна возвращать как листовые, так и промежуточные сертификаты с веб-сервера.

Вы можете увидеть это на всех веб-сайтах, которые предоставляют промежуточные сертификаты, когда вы используете параметр -showcerts с помощью opensll команда s_client:

openssl s_client -connect www.example.com:443 -showcerts

То же самое верно и для команды openssl verify как Что ж.

Из документов:

-недоверный файл

Файл дополнительных ненадежных сертификатов (промежуточные ЦС эмитента), используемый для построения цепочки сертификатов от сертификата субъекта до якоря доверия. Файл должен содержать один или несколько сертификатов в формате PEM. Этот параметр можно указать несколько раз, чтобы включить ненадежные сертификаты из нескольких файлов.

Итак, в приведенном выше примере вам нужно сделать:

openssl verify 3-leaf.pem -untrusted 2-intermediate.pem
person Shane Powell    schedule 30.07.2020
comment
Пропуск промежуточного звена действительно является распространенной ошибкой, но НЕ МОЖЕТ вызвать конкретную ошибку, показанную в этом вопросе. - person dave_thompson_085; 31.07.2020
comment
@ dave_thompson_085 Означает ли это, что листовой сертификат настроен с CA: TRUE, хотя этого не должно быть? - person Shane Powell; 31.07.2020
comment
@ShanePowell Кажется, что решение dave_thompson_085 решило проблему, однако я был бы признателен за разъяснения по поводу того, что вы сказали. Если я установлю корневой сертификат на хосте моего клиента, а затем предоставлю связанный файл, содержащий все три сертификата, проверка s_client будет в порядке? Потому что, когда я удалил промежуточный сертификат, я получил код возврата Verify: 21 (невозможно проверить первый сертификат) - person GabeL; 02.08.2020
comment
@GabeL: по стандарту сервер SSL / TLS должен отправлять всю цепочку, за исключением того, что он может опустить (нетривиальный) корень; в вашем случае он должен отправить хотя бы лист и имед. Большинство серверов отправляют то, что вы настроили (только), но некоторые различаются. Если сервер ошибочно отправляет только лист, то, что делает клиент, стандарт не определяет; openssl s_client в частности, если у вас есть как root, так и imed в его хранилище доверенных сертификатов (-CAfile и / или -CApath или их значения по умолчанию), использует imed из хранилища доверенных сертификатов для построения цепочки, и проверка будет успешной (если / когда сертификаты верны). - person dave_thompson_085; 04.08.2020
comment
Шейн: нет. Как я прокомментировал в вопросе Q, причина verify 24 - это промежуточное звено, которому не хватает ca = true. OpenSSL принимает «лист» с ca = true, включая, помимо прочего, самозаверяющий сертификат, в котором лист также является корневым и требует прямого доверия. - person dave_thompson_085; 04.08.2020