1

So, here's my dilemma, I'm working on a self-update mechanism in C++, and I can't figure out how to get OpenSSL to accept an int socket that's already been initialized in the previous version, and renegotiate the connection. I've tried SSL_connect() on the off chance that'd work again, SSL_renegotiate and SSL_do_handshake(), but I can't get anything working.

I imagine it's because OpenSSL doesn't know that the socket is already set up as TLS, but how do I tell it that?

In summary, I'm trying to re-establish a TLS connection after inheriting the raw 'int' socket descriptor from a previous version of the same program via an exec*() function.

Thanks.

Subsentient
  • 554
  • 3
  • 12
  • 1
    I looked into this once upon a time and couldn't find a way. Ended up writing a proxy process that used unix sockets to pipe data between SSL connections and the process that did the actual work. – Shawn Sep 30 '18 at 10:33
  • May I ask why the parent can't pass the child enough information to establish its own connection? What does the parent know that the child doesn't know? OR if you `fork` the child, maybe it inherits enough state... – Paul Sanders Sep 30 '18 at 11:16

2 Answers2

3

If your platform is linux: Since Linux 4.13 it is possible to do TLS in kernel space. If you switch to this mechanism, the SSL state is held in the socket in kernel space, so you can handle your file descriptor as if it would be an unencrypted connection; especially you can use it in your child process without additional effort.

See the Kernel TLS documentation for further information.

Ctx
  • 18,090
  • 24
  • 36
  • 51
2

An established SSL in OpenSSL socket contains a user-space SSL state. When doing an exec this state is lost since the previous process and its memory is replace with the new one. While it could in theory be possible to somehow serialize the full SSL state in one process and unserialize it in the new process I don't think there is an OpenSSL API which does this. And it can probably also not be simply done by saving and restoring some memory block but likely depends on the current memory layout of the process which is different in the new one.

The usual way to handle an existing SSL state by a new process is not to exec a new process but instead fork the existing process and exec the new one as a child and then transfer the data from the child process by using the original (parent) process which still has the established SSL state.

Another way would be to explicitly shutdown the SSL session with SSL_shutdown before doing the exec and creating a new SSL session on the same TCP connection with SSL_connect in the new process. Of course, this needs kind of downgrade to plain TCP and upgrade to TLS again needs support on the other end of the TCP connection too.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • How would a fork eork with a self update? – Yakk - Adam Nevraumont Sep 30 '18 at 11:38
  • @Yakk-AdamNevraumont: I'm not sure how your exact use case works but if it is really essential that the same TCP connection is used you might need to have some wrapper process around your self-updating applications which cares about the communication. Apart from that I'm not sure why one would need to have the updated process use exactly the same TCP/TLS connection in the first place. – Steffen Ullrich Sep 30 '18 at 11:44