Prior to TLS 1.3, the client always sends it certificate during the TLS handshake. As a result, the OpenSSL::SSL::SSLSocket#connect method only returns success if the server accepted our client cert. This way we can differentiate between connection errors and other types of errors, like HTTP 302, when processing our server list, finding a suitable server using SRV, etc. When using TLS 1.3, the client cert may be sent after the server completes its side of the TLS handshake. This is referred to as post handshake authentication. This means the client won't know if the server accepted its client cert until after SSLSocket#connect returns and we try to send application data. If the server rejected our cert, then we'll get a ECONNRESET. It also appears TLS 1.3 can send the client during the handshake, but prefers to send it after, to reduce the number of TLS packages that are needed to connect/resume. It appears ruby hardcodes the use of post_connection_auth. See https://github.com/ruby/openssl/pull/239 If there was a way to set disable that extension via Net::HTTP then we wouldn't need to account for the different protocol behaviors. |