2014-12-25 2 views
3

У меня есть процесс Linux, который должен действовать как сервер SSL (принимать и обслуживать подключения от других клиентов), но также необходимо - в том же процессе - инициировать сеансы клиентов с другими серверами SSL.Предоставляет ли OpenSSL несколько SSL_CTX для каждого процесса, один SSL_CTX, используемый для сеансов сервера, и другой SSL_CTX для клиентских сеансов?

Я намерен создать две отдельные ручки SSL_CTX, используя два вызова функций SSL_CTX_new(), один из которых вызывается с помощью методов сервера, а другой - с помощью клиентских методов. Поддерживается ли такое двойное использование OpenSSL в рамках одного процесса? Я надеюсь, что OpenSSL использует дескриптор SSL_CTX и не полагается на глобальные или статические локальные переменные - для всей информации контекста, которая может потребоваться для создания и обслуживания новых сеансов. Это хорошее предположение?

ответ

1

Из моего опыта: вы можете свободно создавать несколько контекстов до тех пор, пока вы правильно инициализировали библиотеку OpenSSL. Я использовал два разных контекста в одном приложении без каких-либо проблем после настройки блокировки потоков, как описано в man-странице OpenSSL: http://www.openssl.org/docs/crypto/threads.html. Если ваше приложение не использует потоки, вам совсем не нужна такая настройка.

6

ли 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.

+0

Всеобъемлющий ответ. Благодаря! Мне пришлось немного почитать о СНИ. Похоже, что единственный SSL_CTX_new (SSL_v23_method) - это все, что мне нужно для использования в качестве клиента (с помощью вызовов connect()) и сервера (с помощью accept()) вызовов. Верный? – perplexed

+0

Использование глобальных переменных и статических переменных в OpenSSL - это действительно деталь реализации, о которой я не должен беспокоиться. Я упомянул их только из-за моего опасения, что глобальные переменные могут содержать контекстно-зависимую информацию, которая предотвратила бы использование нескольких SSL_CTX. – perplexed

+0

Мне любопытно, как насчет использования одного SSL_CTX из нескольких потоков на несколько хостов в качестве клиента? Скажите, если я слишком не по теме, но этот поток, кажется, наиболее близок к моему вопросу/проблеме. Скажем, если бы я использовал openSSL в ситуации обратного прокси-сервера, было бы безопасно/работать, чтобы использовать один CTX, который был настроен с необходимыми сертификатами проверки/путями, разделяемыми несколькими потоками/хостами? Я пытаюсь определить, связано ли это с моим недавно найденным «дешифрование с ошибкой или плохой записью mac». –

Смежные вопросы