typhoeus / ethon

Very simple libcurl wrapper.
MIT License
137 stars 139 forks source link

SSL_CACERT Error: Peer certificate cannot be authenticated with known CA certificates #155

Open saravanabalagi opened 5 years ago

saravanabalagi commented 5 years ago

ssl_cacert error

I get ssl_cacert error -> Peer certificate cannot be authenticated with known CA certificates

Started GET "/" for 127.0.0.1 at 2019-02-23 17:42:55 +0000
Processing by HelloController#index as HTML
ETHON: Libcurl initialized
ETHON: performed EASY effective_url=https://www.linkedin.com/ response_code=301 return_code=ssl_cacert total_time=0.123962
  Rendering hello/index.html.erb within layouts/application
  Rendered hello/index.html.erb within layouts/application (1.8ms)
Completed 200 OK in 406ms (Views: 273.2ms | ActiveRecord: 0.0ms)

Steps to Reproduce

Ruby: 2.6.0 Rails: 5.2.2 Windows 10 [Version 10.0.17134.590]

* Manually created a `index.html.erb` file in `views` with content

Hello, Rails!

<%= raw(@response.response_body) %>


## What I also tried

Tried the same with Faraday and did not get any errors: See the commented code in the controller. I had to change `@response.response_body` to `@response.body` in the views. Linkedin page was rendered.

But with `ethon`, I get `ssl_cacert`.
diachedelic commented 4 years ago

Problem

Running the command pod install started failing a couple of days ago, seemingly for no reason, with the error mentioned in the issue title. cocoapods uses typhoeus under the hood, and I was able to reproduce the error using ethon.

Reproduction

require 'net/http'
require 'pp'
require 'ethon'

file_remote_url = "https://wtfismyip.com/text"

puts "trying with net/http:"
puts Net::HTTP.get(URI(file_remote_url))

puts "trying with Ethon:"
easy = Ethon::Easy.new(url: file_remote_url)
if easy.perform == :ok
  puts easy.response_body
else
  pp easy
end

Output

trying with net/http:
118.127.60.51
trying with Ethon:
#<Ethon::Easy:0x00007fad891c6e28
 @body_write_callback=
  #<Proc:0x00007fad891c69c8 /usr/local/lib/ruby/gems/2.7.0/gems/ethon-0.12.0/lib/ethon/easy/callbacks.rb:38>,
 @debug_callback=
  #<Proc:0x00007fad891c6810 /usr/local/lib/ruby/gems/2.7.0/gems/ethon-0.12.0/lib/ethon/easy/callbacks.rb:67>,
 @debug_info=#<Ethon::Easy::DebugInfo:0x00007fad891c6770 @messages=[]>,
 @handle=#<FFI::AutoPointer address=0x00007fad88fef000>,
 @header_write_callback=
  #<Proc:0x00007fad891c68b0 /usr/local/lib/ruby/gems/2.7.0/gems/ethon-0.12.0/lib/ethon/easy/callbacks.rb:53>,
 @headers_called=false,
 @response_body="",
 @response_headers="",
 @return_code=:ssl_cacert,
 @url="https://wtfismyip.com/text">

Versions

$ sw_vers -productVersion
10.15.6 # macOS

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]

$ gem -v
3.1.4

$ gem list --local ethon

*** LOCAL GEMS ***

ethon (0.12.0)

$ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
OpenSSL 1.1.1f  31 Mar 2020

Investigation

It appears that ethon loads an older version of openssl than net/http does, as evidenced by file accesses obtained by running dtrace:

# net/http
/usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib
/usr/local/opt/openssl@1.1/lib/libcrypto.1.1.dylib
/usr/local/etc/openssl@1.1/openssl.cnf
/usr/local/etc/openssl@1.1/cert.pem

# ethon
/opt/local/lib/libssl.1.0.0.dylib
/opt/local/lib/libcrypto.1.0.0.dylib
/opt/local/etc/openssl/openssl.cnf
/usr/local/lib/libcurl.dylib
/opt/local/lib/libffi.6.dylib
/opt/local/lib/libidn.11.dylib
/opt/local/lib/libz.1.dylib
/opt/local/lib/libintl.8.dylib
/opt/local/lib/libiconv.2.dylib

Notably, using ethon does not cause a .pem file to be read.

Solution

It seems ethon was using a version of libcurl.dylib I had installed, last updated in 2014! I was able to force ethon to load the latest version of libcurl by removing my old version like so:

sudo rm /usr/local/lib/libcurl*
brew install curl