Convert sslsocket python code to ruby
Question: I have such code on python connect to some software by socket:

    
    
    import socket, ssl
    
    host = '127.0.0.1'
    port = 8963
    sert_key = '../keys/key.pem'
    
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, True)
    sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, True)
    sock.settimeout(30.5)
    sock.connect((host, port))
    sock = ssl.wrap_socket(sock, server_side=True, certfile=sert_key,
    ssl_version=ssl.PROTOCOL_TLSv1)
    
    
    cert = "hello"
    
    cert = cert.encode('utf-8')
    req = ('%08x'%len(cert))+cert
    sock.sendall(req)
    print sock.recv(4096)
    

Output: "OK", so its work.

I try to convert such code on ruby, but it doesn't work:

    
    
    require 'socket'
    require 'openssl'
    
    host = '127.0.0.1'
    port = 8963
    sert_key = '../keys/key.pem'
    
    socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    address = Socket.pack_sockaddr_in(port, host)
    socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
    socket.setsockopt(Socket::SOL_TCP, Socket::TCP_NODELAY, true)
    socket.connect(address)
    
    #socket = TCPSocket.new(host, port) # not help also
    
    ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1)
    ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(sert_key))
    ssl_context.key = OpenSSL::PKey::RSA.new(File.open(sert_key))
    ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
    ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
    ssl_socket.sync_close = true
    ssl_socket.connect
    
    
    sert = "hello"                                                                                                                                                                                            
    sert = sert.force_encoding('UTF-8')                                                                                                                                                                        
    req = sprintf("%08x", sert.length) + sert                                                                                                                                                                  
    ssl_socket.write(req)                                                                                                                                                                                                                                                                                                                                                                                      
    puts ssl_socket.read(4096) 
    

But I have such error:

test1.rb:30:in `connect': SSL_connect returned=1 errno=0 state=SSLv3 read
server hello B: bad message type (OpenSSL::SSL::SSLError)

Help me please port this code on ruby. I don't understand what I miss (where
difference in codes).

P.S. Sorry, but software to which I want to connect not for sharing for now :(


Answer: Seems like you should use something like this:

    
    
    require 'socket'
    require 'openssl'
    
    host = '127.0.0.1'
    port = 8963
    sert_key = '../keys/key.pem'
    
    socket = TCPSocket.new(host, port) # not help also
    
    ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1)
    ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(sert_key))
    ssl_context.key = OpenSSL::PKey::RSA.new(File.open(sert_key))
    ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
    ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
    ssl_socket.sync_close = true
    ssl_socket.accept
    
    sert = "hello"                                                                                                                                                                                            
    sert = sert.force_encoding('UTF-8')                                                                                                                                                                        
    req = sprintf("%08x", sert.length) + sert                                                                                                                                                                  
    ssl_socket.write(req)
    puts ssl_socket.sysread(4096)
    

**EDIT:** Updated code yet another time.

