Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
469 views
in Technique[技术] by (71.8m points)

c - 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...