ли OpenSSL позволяет несколько SSL_CTX для каждого процесса, один SSL_CTX используется для серверных сеансов ...
Да, и это довольно распространенное явление. Его общее значение при использовании имени сервера. В случае SNI у вас есть значение по умолчанию SSL_CTX
, а затем SSL_CTX
для каждого сервера. Затем вы возвращаете по умолчанию SSL_CTX
или специализированный SSL_CTX
в обратном вызове SNI , если клиент включил расширение имени сервера в своем ClientHello
.
SSL_CTX
ссылаются на библиотеку, поэтому они не освобождаются до тех пор, пока счетчик ссылок не упадет до 0 в одном из вызовов SSL_CTX_free
.
Вот некоторые вопросы по SNI, если интересно:
Первый даже предоставляет вам код обратного вызова. GetServerContext
возвращает новый (или существующий) контекст, основанный на имени сервера:
/* Need a new certificate for this domain */
SSL_CTX* ctx = GetServerContext(servername);
if(ctx == NULL) handleFailure();
...
/* Set new context */
SSL_CTX* v = SSL_set_SSL_CTX(ssl, ctx);
позволяет ли OpenSSL несколько SSL_CTX в процессе, ... другой SSL_CTX для клиентских сеансов?
Да, но вы обычно не пользуетесь им. Клиент делает не обычно меняет свой SSL_CTX
, как на сервере.
В случае, если клиент подключается к нескольким серверам, вы обычно устанавливаете параметры своего канала с помощью SSL_CTX_set_options
и используете это для каждого подключения к каждому серверу (даже по-разному). Параметрами будут такие вещи, как протоколы (TLS 1.1, TLS 1.2), комплекты шифров (удаление анонимных наборов шифров) и сжатие. См. Обсуждение ниже окружающего SSL/TLS Client для более подробной информации.
Клиент должен установить имя хоста сервера, но это делается на SSL*
с использованием SSL_set_tlsext_host_name
, а не SSL_CTX*
.
Или, если вы используете BIO
, это будет выглядеть так. Обратите внимание, что BIO
эффективно обертывания SSL*
, так что вы не модифицируя SSL_CTX*
:
BIO* web = BIO_new_ssl_connect(ctx);
if(web == NULL) handleFailure();
res = BIO_set_conn_hostname(web, HOST_NAME ":" HOST_PORT);
if(res != 1) handleFailure();
... один вызывается с помощью методов сервера, а другой с помощью методов клиента
Не необходимо. Единственная разница между ними (например, SSLv23_client_method
и SSLv23_server_method
) - это пара указателей на функции, такие как connect
и accept
в невидимых структурах. Клиенты звонят connect
, а серверы звонят accept
.
Вместо этого используйте общий SSLv23_method
, и все будет хорошо. Вам все равно придется настраивать контекст с помощью SSL_CTX_set_options
, потому что контекст по умолчанию, предоставляемый SSL_CTX_new
, включает слабые/раненые/сломанные протоколы и шифры.
В вики-странице OpenSSL SSL/TLS Client показано, как настроить объект SSL_CTX
. Он выполняет следующие действия, и ее можно использовать обоими клиентами и серверами:
- Отключить SSLv2
- Отключить SSLv3
- Отключить Сжатие
- Отключить анонимные протоколы
- Используйте «сильные» шифры
Использование настраиваемого списка шифров, например "HIGH: ... : !SRP:!PSK"
, удаляет много слабых/раненых шифров и удаляет кучу шифрования sui tes, которые, вероятно, не поддерживаются на сервере (поэтому у клиента нет никаких причин для рекламы). SRP - это безопасный удаленный пароль Thomas Wu, а PSK - ключ Preshared. IANA reserves 87 cipher suites, основанный на них, поэтому он сохраняет почти 180 байтов в ClientHello
.
ли такое двойное использование OpenSSL в рамках одного процесса поддерживается?
Да.
Моя надежда состоит в том, что OpenSSL использует ручку SSL_CTX - и не полагаться на глобальные или статические локальные переменные
Ну, вы не повезло там. Есть много глобалов, некоторые из них динамически распределены, а некоторые из них не освобождаются.
И если вы работаете на Java или C#, они просачиваются каждый раз, когда общий объект загружается/выгружается.Таким образом, ваша Java или C# программа накапливает все больше и больше памяти с течением времени. Разработчики OpenSSL не чувствуют себя достойными своего времени. См., Например, Small memory leak on multithreaded server в списке рассылки OpenSSL.
Всеобъемлющий ответ. Благодаря! Мне пришлось немного почитать о СНИ. Похоже, что единственный SSL_CTX_new (SSL_v23_method) - это все, что мне нужно для использования в качестве клиента (с помощью вызовов connect()) и сервера (с помощью accept()) вызовов. Верный? – perplexed
Использование глобальных переменных и статических переменных в OpenSSL - это действительно деталь реализации, о которой я не должен беспокоиться. Я упомянул их только из-за моего опасения, что глобальные переменные могут содержать контекстно-зависимую информацию, которая предотвратила бы использование нескольких SSL_CTX. – perplexed
Мне любопытно, как насчет использования одного SSL_CTX из нескольких потоков на несколько хостов в качестве клиента? Скажите, если я слишком не по теме, но этот поток, кажется, наиболее близок к моему вопросу/проблеме. Скажем, если бы я использовал openSSL в ситуации обратного прокси-сервера, было бы безопасно/работать, чтобы использовать один CTX, который был настроен с необходимыми сертификатами проверки/путями, разделяемыми несколькими потоками/хостами? Я пытаюсь определить, связано ли это с моим недавно найденным «дешифрование с ошибкой или плохой записью mac». –