-
Notifications
You must be signed in to change notification settings - Fork 182
Description
Prerequisites
- OpenSSL version
> gem list openssl *** LOCAL GEMS *** openssl (3.2.0, default: 3.1.0)irb(main):003:0> OpenSSL::VERSION => "3.2.0" - OpenSSL Library Version
irb(main):004:0> OpenSSL::OPENSSL_VERSION => "OpenSSL 3.1.0 14 Mar 2023" - Ruby version
> ruby -v ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin23] - I checked previous issues and did not find anything similar
Issue
Hi, I am trying to run the following script in irb on Ruby 3.2.2. I am using OpenSSL 3.2.0. This web request works in Python and also in JRuby but is failing in CRuby. I believe it's a bug in the underlying C implementation of the openssl gem but I've hit my limit in terms of debugging it. Can anyone please investigate if it is indeed a bug or if it's a server-side implementation quirk?
require "net/http"
require "openssl"
begin
url = "https://payments.cat.uk.pt-x.com/payments-service/api/security/handshake"
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.min_version = OpenSSL::SSL::TLS1_3_VERSION
http.max_version = OpenSSL::SSL::TLS1_3_VERSION
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # OpenSSL::SSL::VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE
resp = http.get(uri.request_uri)
rescue => exception
puts exception.backtrace
raise exception
end
This gives me
/Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/openssl-3.2.0/lib/openssl/buffering.rb:211:in `sysread_nonblock': Connection reset by peer (Errno::ECONNRESET)
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/openssl-3.2.0/lib/openssl/buffering.rb:211:in `read_nonblock'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/protocol.rb:218:in `rbuf_fill'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/protocol.rb:199:in `readuntil'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/protocol.rb:209:in `readline'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http/response.rb:158:in `read_status_line'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http/response.rb:147:in `read_new'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1862:in `block in transport_request'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1853:in `catch'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1853:in `transport_request'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1826:in `request'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1819:in `block in request'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1238:in `start'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1817:in `request'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/3.2.0/net/http.rb:1575:in `get'
from (irb):14:in `<main>'
from /Users/abhishek/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.6.2/exe/irb:11:in `<top (required)>'
... 2 levels...
on all my machines. Setting min and max version to TLS 1.2, however, works on all installed Ruby versions and all machines.
I checked JRuby's ruby interface of the openssl gem, and it seems to be a nearly identical copy. I tried using their buffering.rb in lieu of this one, but I ran into the same connection reset issue. If I were to hazard a guess, the sysread_nonblock implementation behavior differs here in this gem's implementation vs the JRuby implementation, which leads to the difference in behavior. I've also attached a pcap file of the call when I attempt it through Ruby, and it resets. I don't see any obvious issues but I am no network expert.
(TIL GitHub doesn't like pcap so it's attached as a tar 🤷♂️)
tls13github.tar.gz