After spending a day fixing this bug, I have
to wonder, why is SSLv2 still active in the
code?
I gather SSLv2 is usually kept around as a way to
force older software peers to negotiate to SSLv3
or TLS. However Tor OR relays only communicate
with other OR relays and since SSLv2 has been
deprecated for so long, why not just disable
it entirely?
Or is this bit of code strictly internal and
exists to underpin the newer protocols?
The SSLv23_method() call is later modified by the SSL_OP_NO_SSLv2 flag.
Also: Using SSLv3_method() for our SSL objects would mean (IIUC) no TLS1; and using TLSv1_method() would mean no accepting SSLv3. ISTR we had a ticket about that long ago.
But IIUC, using SSLv3_method() or TLSv1_method() in prune_v2_cipher_lists() would seem to be a fine thing to do.
get_cipher_by_char for SSLv23 is wrong and shouldn't be used. It messes bytes and the same bytes shifts differently inside of cipher id.
Can we just switch prune_v2_cipher_list() to use SSLv3_method or TLSv1_method() ? It looks to me like that would work, but it's late, my brain is tired, and I haven't tested it yet.
It looks to me like that would work
I think it must to work. The only thing is about updating openssl code in future? What if new methods for new tls version will use something different than ssl3_get_cipher_by_char. With SSLv23_method we at least sure it will support any new tls version while openssl exist.
But SSLv23_method() exposes ssl23_get_cipher_by_char(). To get ssl3_get_cipher_by_char(), we either need to poke inside openssl internals, or get it from SSLv3_method() or TLSv1_method(), I think.
(In the long term, I think the right decision is to drop support for the Tor V2 link protocol handshake entirely, so we can remove this whole function.)
In the long term, I think the right decision is to drop support for the Tor V2 link protocol handshake entirely, so we can remove this whole function.
Then no difference to use SSLv3_method() or to pass 3 bytes if SSLv23_method() used. Both are kludge.
It can. But replaced htons() because it is
logically incompatible with the SSLv2
char cipher ID construction. Was mislead
at first and thought changing it to
set_uint32(cipherid, htonl(*inp))
would work but this is incorrect. Never
liked those BSD byte-order functions
and don't use them myself. The proposed
patch is clearer.