I'm actually doing this kind of thing at work right now. A client has a piece of software written by a vendor that went belly-up in 2007. The software is a central part of their business (don't ask me why they didn't try harder earlier to replace this piece of software in the past 15 years), but only talks SSL 3.0 and talks to internet resources to function.
We had set up a shim for them to give them time to fix this mess, by setting up mitmproxy[0] explicitly enabling SSL 3.0 and upgrading the protocol for external requests. Since then, the shim has been killed by a careless upgrade, and it turns out that most SSL software (including OpenSSL) can't even be forced to talk SSL 3.0 anymore. If you want to get OpenSSL to talk SSL 3.0, you need an old version. The modern versions maintain the enable-ssl3 option, but it is always forced to no-ssl3 at configure time. I don't know if there's an easy way around this, so I've set up a docker image that pulls and builds and old version, and installs an old version of mitmproxy (along with python's cryptography and other dependencies).
It's not elegant, but it does technically work, for now. At some point, it's likely that the ciphers supported by it won't be supported by the modern internet, in which case I suppose you could daisy-chain mitmproxy instances, each upgrading the protocols for the last.
If somebody has a better idea for this kind of situation, I'd love to hear it. I hate this setup and would love to have a more elegant solution.
edit: I actually discovered that OpenSSL 1.1.1p doesn't force no-ssl if you do enable-ssl3 as well as enable-ssl3-method. That's a much more workable solution, and passes tests. I mentioned OpenSSL 3.0.4 in a previous edit of this comment, but it turns out that compiles, says it enables ssl3, but fails to complete an SSL 3.0 handshake.
edit 2: If anybody is curious, here's a working Dockerfile example for this, with configuration, volumes, and path stuff left as an exercise for the reader: https://paste.ofcode.org/uCyMuF6NtLKGyesT8FKYTB
Not really insecure, because all communication over the public Internet is done on TLS 1.2+. Really, it's at worst as insecure as just using HTTP to the mitm proxy and then having the proxy do the encryption to the outside world, given that the SSL3 connection is entirely contained in a private network. I had actually suggested that initially, but the software refuses to communicate without SSL (which was a fine policy at the time). Also, SSL3 isn't actually that insecure when there is no possibility of controlling any aspect of client communication.
> Why don't you modify the hard-coded `no-ssl3` config and try re-compiling?
I was actually missing an option, but it still doesn't work with OpenSSL 3.0. Fortunately, 1.1.1 works with it just fine, including the latest version released just today.
We had set up a shim for them to give them time to fix this mess, by setting up mitmproxy[0] explicitly enabling SSL 3.0 and upgrading the protocol for external requests. Since then, the shim has been killed by a careless upgrade, and it turns out that most SSL software (including OpenSSL) can't even be forced to talk SSL 3.0 anymore. If you want to get OpenSSL to talk SSL 3.0, you need an old version. The modern versions maintain the enable-ssl3 option, but it is always forced to no-ssl3 at configure time. I don't know if there's an easy way around this, so I've set up a docker image that pulls and builds and old version, and installs an old version of mitmproxy (along with python's cryptography and other dependencies).
It's not elegant, but it does technically work, for now. At some point, it's likely that the ciphers supported by it won't be supported by the modern internet, in which case I suppose you could daisy-chain mitmproxy instances, each upgrading the protocols for the last.
If somebody has a better idea for this kind of situation, I'd love to hear it. I hate this setup and would love to have a more elegant solution.
edit: I actually discovered that OpenSSL 1.1.1p doesn't force no-ssl if you do enable-ssl3 as well as enable-ssl3-method. That's a much more workable solution, and passes tests. I mentioned OpenSSL 3.0.4 in a previous edit of this comment, but it turns out that compiles, says it enables ssl3, but fails to complete an SSL 3.0 handshake.
edit 2: If anybody is curious, here's a working Dockerfile example for this, with configuration, volumes, and path stuff left as an exercise for the reader: https://paste.ofcode.org/uCyMuF6NtLKGyesT8FKYTB
[0]: https://mitmproxy.org/