Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssl_handshake_completed not being called #362

Closed
alexkwolfe opened this issue Sep 2, 2012 · 21 comments
Closed

ssl_handshake_completed not being called #362

alexkwolfe opened this issue Sep 2, 2012 · 21 comments

Comments

@alexkwolfe
Copy link

I am having trouble connecting to one specific server over SSL. The connection is being unbound prior to the ssl_connection_completed method being called, and thus the connection fails. No unbind reason is given, so I can't tell what's going amiss. The SSL cert looks OK to me.

Anyone have any idea what could cause this sort of behavior?

require 'test/unit'
require 'eventmachine'

class SSLHandshakeCompletedTest < Test::Unit::TestCase

  module Handler
    attr_accessor :post_init_called, :ssl_handshake_completed_called, :unbind_reason

    def post_init
      @post_init_called = true
      start_tls(verify_peer: false)
    end

    def ssl_handshake_completed
      @ssl_handshake_completed_called = true
      close_connection
    end

    def unbind(reason=nil)
      @unbind_reason = reason
    end
  end

  def test_ssl_handshake_completed
    EM.run {
      handler = EventMachine::connect "intelidataexpress.datamyx.com", 443, Handler
      EM::Timer.new(5) do
        assert handler.post_init_called, "Expected post_init to have been called"
        assert handler.ssl_handshake_completed, "Expected ssl_handshake_completed to have been called. Error: #{handler.unbind_reason.inspect}"
      end

      EM.error_handler { |e| fail(e) }
    }
  end
end
@ibc
Copy link
Contributor

ibc commented Sep 3, 2012

The server TLS/SSL connection uses TLS1.0 (check the TLS information by accesing to that site with a browser). EventMachine uses SSLv2.3 in SSL/TLS handshakes.

However I added a param :use_tls in EventMachine-LE for using TLSv1.0 (commit) but using it does not solve the issue. Maybe it's a problem in the cipher? I'm able to connect by using Ruby OpenSSL::SSL::SSLSocket.new.

@alexkwolfe
Copy link
Author

I wonder what sort of effort it might take to add EM support for SSL v3. Do you have any sense of that?

@ibc
Copy link
Contributor

ibc commented Sep 4, 2012

OpenSSL has methods for that: http://www.openssl.org/docs/ssl/SSL_CTX_new.html

I will include it in EventMachine-LE. News soon.

@ibc
Copy link
Contributor

ibc commented Sep 4, 2012

I've added it is master branch: ibc@41dabd3

However ever using SSLv3 (or TLSv1) I cannot establish the SSL/TLS handshake with your given website.

@alexkwolfe
Copy link
Author

Wow. Thanks for the quick patch!

I can't seem to get it to work for any sites that require SSLv3. Here's my test again, this time using EventMachine-LE and connecting to github.com.

require 'test/unit'
require 'eventmachine-le'

class SSLHandshakeCompletedTest < Test::Unit::TestCase

  module Handler

    attr_accessor :post_init_called, :ssl_handshake_completed_called, :unbind_reason

    def post_init
      @post_init_called = true
      start_tls(verify_peer: false, ssl_version: :SSLv3)
    end

    def ssl_handshake_completed
      @ssl_handshake_completed_called = true
      close_connection
    end

    def unbind(reason=nil)
      @unbind_reason = reason
    end
  end

  def test_ssl_handshake_completed
    EM.run {
      handler = EventMachine::connect "github.com", 443, Handler
      EM::Timer.new(5) do
        assert handler.post_init_called, "Expected post_init to have been called"
        assert handler.ssl_handshake_completed, "Expected ssl_handshake_completed to have been called. Error: #{handler.unbind_reason.inspect}"
      end

      EM.error_handler { |e| fail(e) }
    }
  end
end

@ibc
Copy link
Contributor

ibc commented Sep 5, 2012

It's really annoying but with your script I don't get the ssl_handshake_completed method to be called NEVER, testing with any SSL/TLS server. Annoying since in my EM based projects I get it... I must give it some time...

@ibc
Copy link
Contributor

ibc commented Sep 5, 2012

Opssss!!!! you must return true in ssl_verify_peer() method!!! otherwise the handshake is aborted!

@ibc
Copy link
Contributor

ibc commented Sep 5, 2012

Well, that's just true if :verify_peer => true so forget it please...

@ibc
Copy link
Contributor

ibc commented Sep 5, 2012

I do can connect to giyhub.com:443 using :SSv23, :SSLv3 and :TLSv1. My script is as follows:

#!/usr/bin/ruby

require 'eventmachine-le'


$ssl_version = (ARGV[0] || :SSLv23).to_sym
$host = ARGV[1] || "intelidataexpress.datamyx.com"
$port = (ARGV[2] || 443).to_i


class TlsClient < EM::Connection

  def post_init
    puts "--- post_init()"
    start_tls(
      :verify_peer => true,
      :ssl_version => $ssl_version
    )
  end

  def ssl_verify_peer pem
    puts "--- ssl_verify_peer(pem = #{pem.inspect}"
    true
  end

  def ssl_handshake_completed
    puts "--- ssl_handshake_completed()"
    close_connection
    exit true
  end

  def unbind(reason=nil)
    puts "--- unbind(reason=#{reason.inspect})"
    exit false
  end

end


EM.run do
  puts "Connecting to #{$host}:#{$port} using #{$ssl_version.inspect}..."
  handler = EM.connect $host, $port, TlsClient
end

Usage:

./script.rb  SSL_VERSION HOST PORT
- SSL_VERSION:   SSLv23, SSLv3, TLSv1

@alexkwolfe
Copy link
Author

Yeah. You're right. My test is broken. It does work with Github.

The only difference I can see between the two is that Github is encrypted with RC4_128 and intelidataexpress.datamyx.com is encrypted with 3DES_EDE_CBC.

Can you think of any other way to ascertain why EventMachine is bailing out on intelidataexpress.datamyx.com? I'd think if there were something wrong with the server setup or cert that other HTTP clients would bonk too. But that doesn't seem to be happening.

@ibc
Copy link
Contributor

ibc commented Sep 5, 2012

Hi, honestly no idea, I expect it's something related to the used cipher. Indeed TLS connection can be done by using the Ruby OpenSSL class.

@alexkwolfe
Copy link
Author

After additional investigation, it seems that this is related to the cipher used by the server. I'm not sure why, but EventMachine can't communicate with 3DES_EDE_CBC despite the fact that it's available in OpenSSL. Should EventMachine be able to use any of the ciphers provided by OpenSSL? I'm wondering if maybe the change proposed in ibc#7 would allow me to specify the desired cipher.

@ibc
Copy link
Contributor

ibc commented Sep 30, 2012

Maybe that's the point since EM uses:

SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH")

It seems that there is no 3DES_EDE_CBC there, but I don't know what "ALL" means.

@alexkwolfe
Copy link
Author

Well the reason it's probably not working is because the server doesn't have that cipher available. Duh.

@alexkwolfe
Copy link
Author

As it turns out, it still doesn't work even when OpenSSL is endowed with the correct ciphers. "ALL" seems to include all the ciphers that the OpenSSL library has available. I'd think that if the openssl binary told us that the cipher was available, then the same cipher would be available to EventMachine. I'm perplexed.

$ openssl ciphers -V 'ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH' | grep EDE
          0xC0,0x1C - SRP-DSS-3DES-EDE-CBC-SHA SSLv3 Kx=SRP      Au=DSS  Enc=3DES(168) Mac=SHA1
          0xC0,0x1B - SRP-RSA-3DES-EDE-CBC-SHA SSLv3 Kx=SRP      Au=RSA  Enc=3DES(168) Mac=SHA1
          0xC0,0x1A - SRP-3DES-EDE-CBC-SHA    SSLv3 Kx=SRP      Au=None Enc=3DES(168) Mac=SHA1
          0x00,0x8B - PSK-3DES-EDE-CBC-SHA    SSLv3 Kx=PSK      Au=PSK  Enc=3DES(168) Mac=SHA1

Do you know if there a way to get EventMachine to cough up the list of ciphers that OpenSSL makes available (analogous to the above command)?

@alexkwolfe alexkwolfe reopened this Oct 4, 2012
@alexkwolfe
Copy link
Author

Sorry for over-communicating here, but some additional investigation revealed that I was wrong about the cipher being used by the remote server. The cipher being used is actually the one explicitly disallowed by the cipher string provided in this call, which would certainly explain why it doesn't work.

SSL_CTX_set_cipher_list (pCtx, "ALL:!ADH:!LOW:!EXP:!DES-CBC3-SHA:@STRENGTH")

@ibc
Copy link
Contributor

ibc commented Oct 5, 2012

Opss, good point!

@ibc
Copy link
Contributor

ibc commented Oct 8, 2012

Hi @alexkwolfe. IMHO the issue can be closed as we already know why it does not work with EventMachine (which denies the SSL exact cipher used by that website).

@alexkwolfe
Copy link
Author

Agreed. Thanks so much for your help with this.

@ptitfred
Copy link

ptitfred commented Mar 7, 2013

@ibc @alexkwolfe sorry to reply to this so lately .. I'm facing this issue too and your conclusions aren't clear for me

Did you close the issue because it will never work with EventMachine ? In that case, is EventMachine-LE the only workaround ? And will it work with EM-HttpRequest ?

@alexkwolfe
Copy link
Author

The original EventMachine excludes certain ciphers (such as DES-CBC3-SHA) and does not provide a way to override that behavior.

EventMachine-LE, however, provides the ssl option which allows you to set the cipher_list. And yes, it works with em-http-request.

require 'eventmachine-le'
require 'em-http-request'

# This works because all ciphers are allowed..
EM.run {
  http = EventMachine::HttpRequest.new('https://intelidataexpress.datamyx.com', 
                                       ssl: { cipher_list: 'ALL' }).get
  http.callback {
    puts "OK!"
    EM.stop
  }
  http.errback {
    puts "ERR!"
    EM.stop
  }
}

# This does not work, because the default EM cipher list is used...
EM.run {
  http = EventMachine::HttpRequest.new('https://intelidataexpress.datamyx.com').get
  http.callback {
    puts "OK!"
    EM.stop
  }
  http.errback {
    puts "ERR!"
    EM.stop
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants