Wednesday, January 4, 2012

Workaround for "certificate verify failed" and "undefined method 'read_nonblock'"

As Bob Aman points out in a comment, this is not recommended as it opens up a nasty security hole. It is temporary stopgap for the purpose of development, should not be used in production or any environment where it could open up a risk to security. And it is recommended to upgrade JRuby to 1.6.6 or later version to fix.

If you are getting the error "NoMethodError: undefined method `read_nonblock' for #<OpenSSL::SSL::SSLSocket:...>" or "OpenSSL::SSL::SSLError: certificate verify failed" using JRuby 1.6.5/Ruby 1.9, update JRuby to 1.6.6 or later for the former error, or check out the following.

Thanks to Jeremy for finding the related monkey patch BufferedIO monkeypatch that works in JRuby 1.6.5/Ruby 1.9:

require 'net/http'
require 'net/https'
require 'uri'
require 'openssl'

# Avoid error: NoMethodError: undefined method `read_nonblock' for #<OpenSSL::SSL::SSLSocket:...>
# See: http://jira.codehaus.org/browse/JRUBY-5529
Net::BufferedIO.class_eval do
    BUFSIZE = 1024 * 16
 
    def rbuf_fill
      timeout(@read_timeout) {
        @rbuf << @io.sysread(BUFSIZE)
      }
    end
end

uri = URI.parse('https://host.with.bad.cert/some/path?a=1')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
# Avoid error, if unavoidable: "OpenSSL::SSL::SSLError: certificate verify failed"
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
puts response.body

Note: The "read_nonblock" error is fixed in JRuby 1.6.6.

2 comments:

Bob Aman said...

You should never, ever use `http.verify_mode = OpenSSL::SSL::VERIFY_NONE` for any reason.

Gary S. Weaver said...

Bob: Thanks for your feedback. Agreed that it should not be used as it opens up some very bad security scenarios, and will edit to make that clearer in the post.