Проверка домена сертификата в OpenSSL

Мне нужно проверить домен сертификата X509, используя C-land OpenSSL.

Насколько я понимаю, библиотека не делает этого за меня, и мне нужно реализовать примерно следующий алгоритм:

  1. Если поле dnsName расширения subjectAlternativeName присутствует, установите name в это значение.
  2. В противном случае установите name в поле CN темы.
  3. Сравните name с запрошенным именем хоста, позволяя каждой звездочке соответствовать [A-Za-z0-9_]+, но не 'точке' (.).

Мне кажется, что для этого должно быть много кода, но я его не нашел.

Может ли кто-нибудь найти пример этого? Или, в качестве альтернативы, проверить мой алгоритм на вменяемость?

РЕДАКТИРОВАТЬ: вот что я придумал: https://gist.github.com/2821083. Кажется действительно странным, что OpenSSL оставил это на усмотрение вызывающего кода.


person Community    schedule 28.05.2012    source источник
comment
Вместо того, чтобы устанавливать значение на основе того, что вы найдете в сертификате, вы должны сделать это наоборот: проверить, имеет ли то, что вы ожидаете, совпадающую запись SAN DNS. Это связано с тем, что в расширении SAN может быть несколько записей DNS. (Кстати, теперь в RFC 6125 есть более точные правила сопоставления подстановочных знаков.)   -  person Bruno    schedule 28.05.2012


Ответы (2)


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

BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)

и похожие друзья из http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ssl/ssl_util_ssl.c и вызываемый объект в ssl_engine_init.c (который, кстати, является серверной стороной) для всех параметров.

Поскольку вы работаете с обратным вызовом openssl, также учитывайте дату и время и цепочку, если вы еще не указали это в CTX.

Dw.

person Dirk-Willem van Gulik    schedule 01.06.2012

Кажется действительно странным, что OpenSSL оставил это на усмотрение вызывающего кода.

Да, это очень проблематичное упущение на практике, потому что многие приложения не понимают, что они должны вручную выполнять проверку.

OpenSSL 1.1.0 будет включать проверку имени хоста (сейчас это HEAD (по состоянию на сентябрь 2013 г.)). Согласно журналам изменений, есть вариант -verify_name, а apps.c отвечает на переключатель -verify_hostname. Но s_client не отвечает ни на один переключатель, поэтому неясно, как будет реализована или вызвана проверка имени хоста для клиента.


Если поле dnsName расширения subjectAlternativeName присутствует, установите для имени это значение.

Альтернативных имен субъекта (SAN) может быть несколько, поэтому будьте готовы к более чем одному.

В противном случае установите имя в поле CN темы.

Я считаю, что вам нужно проверить это для матча тоже.

Сравните имя с запрошенным именем хоста, позволяя каждой звездочке соответствовать [A-Za-z0-9_]+, но не «точке» (.).

Это гораздо более болезненно. Вы также должны убедиться, что вы не соответствуете gTLD или ccTLD. Например, вы не хотите сопоставлять сертификат, выданный для gTLD *.com. Этот сертификат, вероятно, был выдан плохим парнем;)

ccTLD похожи на *.eu, *.us или இலங்கை (nic.lk). Их около 5000, и Mozilla предлагает список на http://publicsuffix.org/. Необработанный список находится по адресу https://mxr.mozilla.org/mozilla-central/source/netwerk/dns/Effective_tld_names.dat?raw=1.


Мне кажется, что для этого должно быть много кода, но я его не нашел.

В дополнение к предложению ван Гулика вы также можете попробовать Curl. Я совершенно уверен, что Curl содержит код соответствия имени хоста.


Вы даже можете проверить, правильно ли сформированы сертификаты. Ответственной группой в контексте Интернета являются форумы CA/Browser. У них есть базовые и расширенные требования для создания сертификатов:

В базовых документах вы обнаружите, например, что IP-адрес, указанный как общее имя (CN), также должен быть указан в альтернативных именах субъекта (SAN).

В расширенной документации вы обнаружите, что зарезервированные IP-адреса (RFC 1918) не могут присутствовать в сертификате расширенной проверки (EV); сертификаты EV не могут содержать подстановочные знаки.

person jww    schedule 02.12.2013