Ssl httpclient savon httpi

If anyone can shed any light on what’s going on here I’d be more than
grateful. I’m connecting to a BizTalk SOAP API and have been given a
self signed root certificate(certfile) from the windows box.

openssl verify certfile
certfile: /CN=UOG ESBDEV
error 18 at 0 depth lookup:self signed certificate
OK

ruby 1.9.2
rails 3.0.4,
httpclient (2.2.0)
httpi (0.9.2)
savon (0.9.1)
Mac OS X 10.6.7
OpenSSL 0.9.8l
curl 7.19.7 (universal-apple-darwin10.0) libcurl/7.19.7 OpenSSL/0.9.8l
zlib/1.2.3

curl

This works as expected

curl --cacert certfile https://doodaa

If I don’t supply the cacert, I get the error I would expect

curl: (60) SSL certificate problem, verify that the CA cert is OK.
Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate
verify failed

openssl

This works as expected

openssl s_client -CAfile certfile -connect machinename:443

Altering the certfile, not specifying the certfile results in Verify
return code: 21 (unable to verify the first certificate)

httpclient

This works as expected

#!/usr/bin/env ruby
require ‘rubygems’
require ‘httpclient’
client = HTTPClient.new
client.ssl_config.set_trust_ca(‘certfile’)
url = “https://doodaa
resp = client.get(url)
puts resp.content
puts resp.status

If I edit the certfile or point to another certfile, it fails as I would
expect

httpi

This does not work as expected

#!/usr/bin/env ruby
require ‘rubygems’
require ‘httpi’
request = HTTPI::Request.new
request.url = “https://doodaa
request.auth.ssl.cert_file = “certfile”
request.auth.ssl.verify_mode = :peer
response = HTTPI.get request
puts response.body

Fails with

D, [2011-04-13T13:04:18.475665 #5711] DEBUG – : HTTPI executes HTTP GET
using the httpclient adapter
at depth 0 - 20: unable to get local issuer certificate
/Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient/session.rb:276:in
connect': SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError) from /Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient/session.rb:276:inssl_connect’
from
/Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient/session.rb:712:in
block in connect' from /Users/me/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/timeout.rb:57:intimeout’
from
/Users/me/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/timeout.rb:87:in
timeout' from /Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient/session.rb:704:inconnect’
from
/Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient/session.rb:568:in
query' from /Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient/session.rb:158:inquery’
from
/Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient.rb:1041:in
do_get_block' from /Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient.rb:850:inblock in do_request’
from
/Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient.rb:937:in
protect_keep_alive_disconnected' from /Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient.rb:849:indo_request’
from
/Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient.rb:737:in
request' from /Users/me/.rvm/gems/[email protected]/gems/httpclient-2.2.0/lib/httpclient.rb:642:inget’
from
/Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi/adapter/httpclient.rb:24:in
block in get' from /Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi/adapter/httpclient.rb:64:indo_request’
from
/Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi/adapter/httpclient.rb:23:in
get' from /Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi.rb:86:inblock in get’
from
/Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi.rb:189:in
with_adapter' from /Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi.rb:84:inget’
from httpitest.rb:19:in `’

I’ve tried Rolle’s solution he outlines here,
https://github.com/rubiii/httpi/issues/26 and edited this file

/Users/me/.rvm/gems/[email protected]/gems/httpi-0.9.2/lib/httpi/adapter/httpclient.rb

Still get the same error

If anyone has any ideas I’m all ears

Any help, greatly appreciated.

Some reading I’ve done so far



http://rubiii.github.com/savon/



http://savonrb.com
http://fagiani.github.com/savon/#the_http_object
http://rubydoc.info/gems/httpi/0.9.2/frames
https://github.com/rubiii/httpi
http://www.eggheadcafe.com/software/aspnet/36211232/httpclient-suddenly-fails--cannot-verify-certificate-file.aspx
http://www.ruby-forum.com/topic/198335#new

Hi,
try
request.auth.ssl.ca_cert_file=“certfile”
instead of
request.auth.ssl.cert_file = “certfile”

I think it is a bug in httpi, as you have already seen on
https://github.com/rubiii/httpi/issues/26

Regards,
Rolle

PS:
Have much fun with BizTalk, we are using it too.

Hi Roland

I’ve edited it now to use

request.auth.ssl.ca_cert_file=“certfile”

no joy, so I went with your suggestion and changed the adapter to use

client.ssl_config.set_trust_ca(ssl.ca_cert_file) if ssl.ca_cert_file

instead of

client.ssl_config.client_ca = ssl.ca_cert if ssl.ca_cert_file

Still no joy :frowning:

I begged the biztalk people to put a RESTFUL API on it, no no, they
wanted to use SOAP, and here we are, happy as can be.

If you knew what the biztalk server is actually doing with the
information we are passing it from our rails app you would fall off your
chair laughing.

Any chance of seeing your successful connect code with SSL ca cert and
your amendment in the adapter in place?

Thanks Rolle

Yeah, not using the cert_key_file or the cert_file, do have the
verify_mode in as peer, and tried using the net/http option. No joy
still :slight_smile:

I’m not even sure httpi allows this type of ssl server authentication.

I’m going to leave your fix in as it makes sense, the other code is an
error I think.

My next avenue of thought is that somehow, httpi is not seeing the same
set of trusted anchors as the other programs are. I’m not entirely sure
what that means, but I’m going to find out :slight_smile:

Thanks for your suggestions Rolle, I will post back once I’ve sorted it.

Hi,

sad to hear. BizTalk uses IIS in the soap adapter, so it is no easy
thing to make restful API.
Here is my complete client code:

#require “net/http”
require “httpi”
request = HTTPI::Request.new
request.auth.ssl.cert_key_file=‘clientcert_key’
request.auth.ssl.cert_file=‘clientcert’
request.auth.ssl.ca_cert_file=‘CAfile.pem’
request.auth.ssl.verify_mode=:peer
request.url=‘https://testhost/test.asmx
response = HTTPI.get request
puts response.body

Despite this the change in the httpi client adapter file “httpclient.rb”
is necessary.
I my scenario we are using client certificates, so i think that you
don’t need to set cert_key_file and cert_file.
Another guess is that you are missing the verify_mode setting?
And one tip you can also try is not to use the httpclient but instead
use net_http. For this just add "require “net/http” before the require
for httpi (uncommented in the sample code above).

Good luck!

Rolle

I’ve got it :slight_smile:

I’m attaching the httpclient.rb adapter with the changes I needed to
make

Your fix Rolle, line 88, and the fix for my particular problem, line 71

When I was debugging I noticed that def setup_ssl_auth(ssl) was never
being run.

Maybe it’s because I’m only setting the ca_cert_file and not the other 2
options that removing the ? makes it work?

I’ll put this into the bug list for httpi, I know it’s a new project.

Thanks again Rolle

Hi,
internally httpi uses httpclient for the request as you can see in the
httpclient.rb file in the adapter directory.
If httpclient works with your CA file, then httpi should work also.
The call in your httpclient program
client.ssl_config.set_trust_ca(‘certfile’)
is the same that will be performed from httpi if you have changed the
file in the adapter folder of httpi. So if httpclient is working httpi
should work also.
And because httpi/httpclient uses the openssl bindings the error
messages are nearly identical.
“unable to get local issuer certificate” means that your program can not
verify the servers certificate. Then two possibilities: your CA file is
wrong or your client does not use it for verification of the server
cert.

What i have not understand is what type of authentication you are using.
If it is only plain SSL for encryption you must not provide any certs:

require “httpi”
request = HTTPI::Request.new
request.url=“https://github.com/rubiii/httpi
HTTPI.get request

Regards
Rolle

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs