Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to accept SSL connection in one process and reuse the same SSL context in another process

I have spent quite some time doing my research on how to tackle this problem but could not find a working solution yet.

Problem: I am using OpenSSL library and linux. I have a server process P1 accepting SSL connection from SSL client. P1 does tcp_accept() and then SSL_accept() and exchanges some protocol data with client with SSL_read/SSL_write(). Everything is fine till this point. Now by design P1 needs to fork a child process C1 to serve the client from this point onwards. C1 uses execve call to re-image itself and spawn a different binary. C1 still needs to talk to the SSL client over the same SSL connection that was used in P1. The problem is since C1 is a completely different process now how it can re-use the existing SSL connection for that client? I am able to pass the underlying TCP socket descriptor from P1 to C1 as it is maintained in kernel but I can not pass the SSL context since it's maintained in the Openssl Library.

I saw this tread on stackoverflow but unfortunately no solution is mentioned. OpenSSL: accept TLS connection and then transfer to another process

Possible Solution: I am not sure if anybody has already solved this kind of problem but I tried following.

  1. I thought I can just create a new SSL conctext and do SSL renegotiation in the new child process. So in C1 I created a new SSL context over the same underlying tcp socket fd and tried to do SSL renegotiation. Here is what I did (Omiting the SSL_ctx initialization part)

    ssl = SSL_new(ctx) // ctx is initialized the same as it was done in P1 server
    SSL_set_fd(ssl, fd); // fd is the underlying tcp socket fd passed from P1 to C1
    SSL_set_accept_state(ssl);
    SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
    SSL_renegotiate(ssl);
    SSL_do_handshake(ssl);
    ssl->state=SSL_ST_ACCEPT;
    SSL_do_handshake(ssl);

But the renegotiation does not succeed and returns me an Openssl Internal error from first SSL_do_handshake() call. I am not even sure if this can really be done. The other solution that I can think of is following.

  1. Somehow transfer the whole SSL context for that client from P1 to C1. How efficiently this can be done? I can think of shared memory for this but not really sure about what all internal state OpenSSL maintains that needs to copied into the shared memory. This seems to be the most logical solution but I don't have much insight into OpenSSL code to do this.

Has anybody faced similar problem and solved it? I will really appreciate any help regarding this.

Thanks a lot

like image 948
ssen Avatar asked May 20 '14 18:05

ssen


2 Answers

A search online finds this discussion:

Passing TLS sessions between programs

Once you have the SSL_SESSION, convert it to ASN1 (via i2d_SSL_SESSION) and dump it to a file. Read that file in with your second program and convert it back from ASN1 to SSL_SESSION(via d2i_SSL_SESSION) and add it to the SSL_SESSION cache of the SSL_CTX (via SSL_CTX_add_session).

I found in doc/ssleay.txt :
[...]
The PEM_write_SSL_SESSION(fp,x) and PEM_read_SSL_SESSION(fp,x,cb) will write to a file pointer in base64 encoding. What you can do with this, is pass session information between separate processes.
[...]

So you need to serialize the SSL session data from P1 and pass it to C1 to deserialize, along with the socket descriptor. You can then create new SSL and SSL_CTX objects in C1 and associate them with the socket and deserialized session data so C1 can take over the conversation.

like image 147
Remy Lebeau Avatar answered Nov 06 '22 20:11

Remy Lebeau


I did a search for "tls kernel mode" and found a kernel patch to give a normal fd for a TLS connection. Thus the fd can be passed to other processes as a normal socket.

The page is titled "TLS in the kernel" on lwn.net. Towards the bottom there are interesting discussions about it. Hope it may get its way into the kernel mainline. Or else wish someone may come up with a production quality patch set so people can make real use of it.

If you know some real products are using it, probably it's a good idea to share it here.

Update: This open source project "TLSe" as a replacement to openssh is specially designed for exporting context to another process.

like image 26
minghua Avatar answered Nov 06 '22 20:11

minghua