nahi / httpclient

'httpclient' gives something like the functionality of libwww-perl (LWP) in Ruby.
https://github.com/nahi/httpclient
703 stars 291 forks source link

OpenSSL Certificate Dir not honored #335

Open hotgazpacho opened 8 years ago

hotgazpacho commented 8 years ago

HTTPClient does not honor OpenSSL's certificate dir configuration. Specifically, I have a couple of certificates, issued by a company's CA and trusted by my system, that I explicitly wish for Ruby http clients to trust. So, I put them in the directory that OpenSSL expects them to be in (which, according to my ruby installation, is /usr/local/etc/openssl/certs):

$ ruby -ropenssl -e 'puts OpenSSL::X509::DEFAULT_CERT_DIR'
/usr/local/etc/openssl/certs

Net::HTTP trusts these certificates:

$ ruby -rnet/http -e "puts Net::HTTP.get URI('https://idp.example.com/.well-known/openid-configuration')"
{"issuer":"https://idp.example.com","authorization_endpoint":"https://console.example.com/auth/login","token_endpoint":"https://idp.example.com/api/v1/oidc/token","userinfo_endpoint":"https://idp.example.com/api/v1/oidc/userinfo","revocation_endpoint":"https://idp.example.com/api/v1/oidc/revoke","jwks_uri":"https://idp.example.com/api/v1/oidc/keys","service_documentation":"https://docs.example.com/iam/oidc","response_types_supported":["code","token","id_token","code token","code id_token","token id_token","code token id_token","none"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"],"scopes_supported":["openid","email","profile"],"token_endpoint_auth_methods_supported":["client_secret_post"],"claims_supported":["aud","exp","iat","iss","sub","user_id","org_id"]}

HTTPClient does not:

$ ruby -rhttpclient -e "puts HTTPClient.new.get_content('https://idp.example.com/.well-known/openid-configuration')"
/usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/ssl_socket.rb:46:in `connect': SSL_connect returned=1 errno=0 state=error: certificate verify failed (OpenSSL::SSL::SSLError)
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/ssl_socket.rb:46:in `ssl_connect'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/ssl_socket.rb:24:in `create_socket'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/session.rb:746:in `block in connect'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/2.3.0/timeout.rb:91:in `block in timeout'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/2.3.0/timeout.rb:101:in `timeout'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/session.rb:742:in `connect'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/session.rb:504:in `query'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient/session.rb:174:in `query'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient.rb:1240:in `do_get_block'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient.rb:1017:in `block in do_request'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient.rb:1131:in `protect_keep_alive_disconnected'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient.rb:1012:in `do_request'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient.rb:1102:in `follow_redirect'
    from /usr/local/opt/rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/httpclient-2.8.2.4/lib/httpclient.rb:653:in `get_content'

HTTPClient, upon which the openid_connect gem sits (via rack-oauth2, swd, and webfinger), should honor the Ruby OpenSSL configuration.

swalberg commented 7 years ago

I'm seeing something similar on CentOS 6.

$ ruby -r httpclient -e "puts  HTTPClient.new.get_content('https://ertw.nationbuilder.com')"
/home/campaign/.gem/ruby/2.2.3/gems/httpclient-2.8.2.4/lib/httpclient/ssl_socket.rb:46:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)

If I overwrite the gem's certificate bundle it works:

cp /etc/pki/tls/cert.pem /home/campaign/.gem/ruby/2.2.3/gems/httpclient-2.8.2.4/lib/httpclient/cacert.pem
modx-space commented 7 years ago

Hi @swalberg ,

I am facing the same issue, and here is the root cause for my case: the httpclient forces to use RSA 2048bit CA cert set since the commit https://github.com/nahi/httpclient/commit/b9bb08fdfec46b4a18c9af16630cfef4f553542d

Also the fix to to call HTTPClient.new.ssl_config.set_default_paths because set_default_paths will use OS's trusted CA certificates.

swalberg commented 7 years ago

Thanks @shawzt. I didn't realize set_default_paths was an option. I ended up using

http_client.ssl_config.add_trust_ca CA_BUNDLE_LOCATION if CA_BUNDLE_LOCATION
vfazio commented 5 years ago

Updates on this?