I have a Linux process that needs to act as an SSL server (accept and service connections from other clients) but also needs to - in the same process - initiate client sessions with other SSL servers.
I intend to create two separate SSL_CTX handles using two SSL_CTX_new() function calls, one invoked with server methods and the other with client methods. Is such dual-use of OpenSSL within a single process supported? My hope is that OpenSSL uses the SSL_CTX handle - and does not rely on global or static local variables - for all context information it may need to create and service new sessions. Is this a good assumption?
From my experience: you can freely create several contexts as long as you properly initialized OpenSSL library. I have used two different contexts in the same application with no problems after having set up threading locks as described in OpenSSL man page: http://www.openssl.org/docs/crypto/threads.html. If your app doesn't use threads you won't need such setup at all.
Yes, and this is quite common. Its common when using Server Name Indication. In the case of SNI, you have a default
SSL_CTX
and then aSSL_CTX
for each server. You then return the defaultSSL_CTX
or a specializedSSL_CTX
in the SNI callback if the client included the server name extension in itsClientHello
.SSL_CTX
are referenced counted by the library, so they are not truly freed until the reference count drops to 0 in one of theSSL_CTX_free
calls.Here are some related questions on SNI, if interested:
The first even provides you with the callback code.
GetServerContext
returns a new (or existing) context based on the server name:Yes, but you usually don't use it. The client does not usually change its
SSL_CTX
like the server does.In the case that a client connects to multiple servers, usually you set your channel parameters with
SSL_CTX_set_options
and use that for every connection to every server (even different ones). Parameters would be things like protocols (TLS 1.1, TLS 1.2), cipher suites (removing anonymous cipher suites) and compression. See the discussion below surrounding SSL/TLS Client for more details.The client does need to set the server's hostname, but that's done on the
SSL*
usingSSL_set_tlsext_host_name
, and not theSSL_CTX*
.Or, if you are using
BIO
's, it would look like this. Notice theBIO
effectively wraps aSSL*
, so you're not modifying theSSL_CTX*
:Not needed. The only difference between them (like
SSLv23_client_method
andSSLv23_server_method
), is a couple of function pointers for functions likeconnect
andaccept
in unseen structures. Clients callconnect
and servers callaccept
.Instead, just use the generic
SSLv23_method
and everything will be fine. You still have to tune the context withSSL_CTX_set_options
because the default context provided bySSL_CTX_new
includes weak/wounded/broken protocols and ciphers.OpenSSL's wiki page SSL/TLS Client shows you how to tune a
SSL_CTX
object. It performs the following, and its can be used by both clients and servers:Using a custom cipher list like
"HIGH: ... : !SRP:!PSK"
removes many weak/wounded ciphers, and removes a bunch of cipher suites that are probably not supported at the server (so there's no reason for the client to advertise them). SRP is Thomas Wu's Secure Remote Password, and PSK is Preshared Key. IANA reserves 87 cipher suites based on them, so it saves nearly 180 bytes in theClientHello
.Yes.
Well, you're out of luck there. There are a lot of globals, some of them are dynamically allocated, and some of them are not freed.
And if you're working in Java or C#, they are leaked each time the shared object is loaded/unloaded. So your Java or C# program accumulates more and more memory over time. The OpenSSL devs don't feel its worthy of their time. See, for example, Small memory leak on multithreaded server on the OpenSSL mailing list.