- From: Henry Story <henry.story@gmail.com>
- Date: Sat, 22 Oct 2011 21:10:29 +0200
- To: unfiltered-scala@googlegroups.com
- Message-Id: <36CDCF8B-A0BA-47A4-B0C6-B061AC346C97@gmail.com>
It turns out that one can do some really neat things with TLS renegotiation in very few lines of code. I wrote a little program on read-write-web project in Scala with the very light weight netty server. The whole server is written in one page of code [1] of which below are some extracts. Here is a simple web page that shows the user his x500 certificate. case req @ Path("/test/login") => { 57 58 req.underlying.context.getPipeline.get(classOf[org.jboss.netty.handler.ssl.SslHandler]) match { 59 case sslh: SslHandler => { 60 sslh.setEnableRenegotiation(true) 61 sslh.getEngine.setWantClientAuth(true) 62 val future = sslh.handshake() 63 future.await(50000) 64 val res = if (future.isDone) { 65 var r ="We are in login & we have an https handler! " 66 if (future.isSuccess) 67 r += "\r\n"+"SSL handchake Successful. Did we get the certificate? \r\n\r\n"+certAvailable(sslh) 68 else { 69 r += "\r\n handshake failed. Cause \r\n" +future.getCause 70 } 71 r 72 } else { 73 "Still waiting for requested certificate" 74 } 75 ResponseString(res) 76 } 77 case _ =>ResponseString("We are in login but no https handler!") 78 } 79 80 } What is really nice is that at line 60 the user may not have sent the server his certificate, whereas he may have done so my line 65. That is with TLS one can request authentication as the request is coming in! So imagine that someone PUTs a huge video to the server. The server can authenticate the user without interrupting the connection, on the same TCP channel. This is extremely flexible. For example it means that the server can find out what user agent someone is using and decide based on that whether it is worth asking the client for TLS authentication. For example TLS renegotiation does not work with Opera currently [2] so the server could decide instead to break the connection and ask the user to authenticate instead with some other method - OpenID for example. Of course the code written can be a lot nicer that what is shown above. It is easy in the unfiltered framework to hide that type of complexity. With scala pattern matching the above can be rewritten in an easy to read way like this def intent: Cycle.Intent[Request, Response] = { 47 case req @ Path(path) if path startsWith "/test/auth/x509" => 48 Ok ~> ContentType("text/html") ~> Html( 49 <html><head><title>Authentication Page</title></head> 50 { req match { 51 case X509Claim(xclaim) => <body> 52 <h1>Authentication Info received</h1> 53 <p>You were identified with the following WebIDs</p> 54 <ul>{xclaim.webidclaims.filter(cl=>cl.verified).map(p=> <li>{p.webId}</li>)}</ul> 55 <p>You sent the following certificate</p> 56 <pre>{xclaim.cert.toString}</pre> 57 </body> 58 case _ => <body><p>We received no Authentication information</p></body> 59 } 60 }</html>) 61 62 } 63 That is the X509Claim(xclaim) on line 51 hides all the TLS stuff for the programmer. He can then do pattern matching on the existence of x500 claims, at the point where it may be needed and not one second before. He can for example check headers before to see what brower is being used, or if the agent on the other side is a robot. Robots after all may prefer to authenticate immediately with TLS, rather than waiting for another connection. It is nice that all this comes out of the box with TLS! Henry [1] https://dvcs.w3.org/hg/read-write-web/file/57279f08e70b/src/main/scala/netty/SslLoginTest.scala [2] the problem with Opera is probably due to the TLS issue that came up a couple of years ago. But this has now been fixed, so hopefully they will allow this again soon http://download.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#workarounds
Attachments
- application/pkcs7-signature attachment: smime.p7s
Received on Monday, 24 October 2011 00:12:59 UTC