From youngh at caida.org Fri Jul 24 13:38:07 2009 From: youngh at caida.org (Young Hyun) Date: Fri, 24 Jul 2009 10:38:07 -0700 Subject: [Rev-talk] SSL on_connect must call super() Message-ID: By the way, it took me a fair amount of time to figure out that a subclass of Rev::SSLSocket must call super() in its overridden on_connect implementation or SSL will not work--specifically, Rev::SSLSocket#on_connect does essential SSL setup work by invoking ssl_client_start or ssl_server_start. I think this is definitely surprising behavior if not an outright bug, because one doesn't ordinarily think of having to call super() in a callback. --Young =============== class EchoServerConnection < Rev::SSLSocket def on_connect puts "#{remote_addr}:#{remote_port} connected" super() # MUST have! end # ... end event_loop = Rev::Loop.default Rev::TCPServer.new(ADDR, PORT, EchoServerConnection).attach(event_loop) From youngh at caida.org Fri Jul 24 13:24:56 2009 From: youngh at caida.org (Young Hyun) Date: Fri, 24 Jul 2009 10:24:56 -0700 Subject: [Rev-talk] SSL post_connection_check Message-ID: <33444F94-5DB3-4D9F-8C1C-E94D72AF1D21@caida.org> What is the most correct way of doing an SSL post_connection_check? For example, I can do it with the following: class EchoServerConnection < Rev::SSLSocket # ... def on_ssl_connect @_ssl_socket.post_connection_check @_ssl_socket.peeraddr[-1] end end event_loop = Rev::Loop.default Rev::TCPServer.new(ADDR, PORT, EchoServerConnection).attach(event_loop) However, that requires accessing the @_ssl_socket instance variable added by module Rev::SSL; it also requires assuming that @_ssl_socket is an instance of OpenSSL::SSL::SSLServer (via the actual class Rev::SSL::IO). I'd rather not be fiddling with an internal instance variable to accomplish this basic task. Perhaps Rev::SSLSocket can provide post_connection_check in some way? --Young From youngh at caida.org Fri Jul 24 19:54:21 2009 From: youngh at caida.org (Young Hyun) Date: Fri, 24 Jul 2009 16:54:21 -0700 Subject: [Rev-talk] SSL on_connect must call super() In-Reply-To: References: Message-ID: <8EFDBCBA-3AAC-4016-ADEA-501EA1DE14B8@caida.org> On Jul 24, 2009, at 4:34 PM, Tony Arcieri wrote: > That's why there's on_ssl_connect. Are you doing something > specifically where you need an on_connect event before SSL setup has > completed? If so I can try to find a workaround. No, I don't need an on_connect for SSL, since there's on_ssl_connect, as you pointed out. It was just that I had incrementally modified your echo server example to use SSL and hit this unexpected behavior. So it sounds like it's just an issue of properly documenting this. --Young From youngh at caida.org Fri Jul 24 20:12:21 2009 From: youngh at caida.org (Young Hyun) Date: Fri, 24 Jul 2009 17:12:21 -0700 Subject: [Rev-talk] SSL post_connection_check In-Reply-To: References: <33444F94-5DB3-4D9F-8C1C-E94D72AF1D21@caida.org> Message-ID: <1F13ECE1-6AC8-43E5-AA3E-6E7987EF25FF@caida.org> On Jul 24, 2009, at 4:35 PM, Tony Arcieri wrote: > What exactly are you trying to accomplish with a > "post_connection_check"? There are two levels of SSL certificate validation. First, you want to verify that a peer's certificate has valid contents (e.g., certificate isn't malformed, expired, or revoked) and is properly signed by a trusted CA. This is what the OpenSSL library does for you automatically when it receives a peer cert (if you've configured the context to require a peer cert). Second, you want to verify that the identify specified in the peer cert matches your peer. This is what post_connection_check does. What check you do depends on your application, but it might include things like checking that the common name stored in the cert matches the domain name or IP address of your peer. For example, if you connect to https://www.google.com, you want to make sure the cert is for www.google.com and not for some other random site (just because the cert is properly signed doesn't mean that it's valid for the particular connection). In my case, I need to make sure the cert provided by a client of my service is correct for the actual client host that connected to me (I do this by issuing client certs that have an IP address in the common name field). This sort of SSL certificate- based client authentication doesn't happen on the web because client authentication on the web happens in the application protocols (e.g., HTTP or higher level), but it's needed for closed, secured private services like mine. Please see the implementation of post_connection_check in $RUBY_SOURCE/ ext/openssl/lib/openssl/ssl.rb for further details. --Young From youngh at caida.org Mon Jul 27 13:08:27 2009 From: youngh at caida.org (Young Hyun) Date: Mon, 27 Jul 2009 10:08:27 -0700 Subject: [Rev-talk] SSL post_connection_check In-Reply-To: References: <33444F94-5DB3-4D9F-8C1C-E94D72AF1D21@caida.org> <1F13ECE1-6AC8-43E5-AA3E-6E7987EF25FF@caida.org> Message-ID: <1B783494-B138-4A3A-BA3E-19CCEF1EAB73@caida.org> On Jul 25, 2009, at 5:22 PM, Tony Arcieri wrote: > You might check out the Rev::SSLSocket#on_peer_cert callback and see > if it meets your needs: > > http://rev.rubyforge.org/rdoc/classes/Rev/SSLSocket.html No, the issue isn't (just) about retrieving the peer cert (I know about on_peer_cert). SSL already implements the post_connection_check method, and I'd like to use that rather than copying and pasting that check code from OpenSSL into my code (into my on_peer_cert implementation). One approach is to officially expose OpenSSL's post_connection_check as Rev::SSLSocket#post_connection_check. --Young