Renegotiation callback appears to be called for initial connection
https://ruby-doc.org/stdlib-2.5.0/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html specifies for renegotiation_cb:
A callback invoked whenever a new handshake is initiated. May be used to disable renegotiation entirely.
This docstring appears to be either misleading or incorrect, as it seems to imply that the callback is called for the initial connection as well as for any renegotiations. However, as the name suggests, renegotiation callback is NOT called for the original connection by MRI.
The code sample given to disable renegotiation under https://ruby-doc.org/stdlib-2.5.0/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#attribute-i-renegotiation_cb-label-Disable+client+renegotiation, reproduced here:
num_handshakes = 0
ctx.renegotiation_cb = lambda do |ssl|
num_handshakes += 1
raise RuntimeError.new("Client renegotiation disabled") if num_handshakes > 1
end
... leads to no connections succeeding under jruby, because jruby's openssl implementation appears to invoke renegotiation_cb on initial connection which MRI does not.
Our current workaround: https://github.com/mongodb/mongo-ruby-driver/pull/1376
for the record, there aren't any good option here - we can not hook into the internals of the Java SSL engine the same way as OpenSSL allows (at least for now - Java 14). looked around BC's TLS provider and there also isn't an easy option other than changing a few bits (effectively JOSSL maintaining a provider build of its own).
we could remove renegotiation_cb callback support, but I guess it's better than not having the callback.
Calling it negotiation_cb instead of renegotiation_cb would (at least in theory) be a plausible solution, I think.
This does mean JRuby won't support MRI's API but the current behavior isn't exactly usable - prohibiting renegotiation via the callback would make JRuby fail every single connection.