For the record the server was running within Apache Tomcat and the client was built using Apache HttpClient. The client code was mine but I didn't have direct access to the server, although I knew the guy who did.
At first I assumed the problem was of my own making, something I'd messed up or misconfigured in the client code. After all, the documentation for HttpClient does say things like this:
As of version 4.1 HttpClient automatically caches information about hosts it has successfully authenticated with. Please note that one must use the same execution context to execute logically related requests in order for cached authentication data to propagate from one request to another. Authentication data will be lost as soon as the execution context goes out of scope.I wanted my client code to be able to reuse an instance of HttpClient for each instance of this particular server it was connecting to, so I was sharing both that and the associated HttpContext object between calls. I thought that by using a fresh HttpContext object for each call I would solve the authentication caching problem. But that didn't help. Neither did all kinds of other tweaks I made to the HttpClient and HttpContext objects - if it offered so much as a hint of a solution, I tried it.
I got to the stage where I could pretty much recite back the API documentation to anyone who would listen when I decided I would have to see what was actually going out on the wire. So I installed Wireshark.
Sniffing SSL packets with Wireshark is easy enough so long as you have the server's private key. But when Tomcat is your server the private key is in a Java keystore, and keytool can't export private keys. There is a round about way though via keytool and OpenSSL.
First create a PKCS12 keystore from your server's JKS keystore:
$ keytool -importkeystore -srckeystore server.jks -destkeystore server.p12 -deststoretype PKCS12Then use OpenSSL to check that everything looks ok:
$ openssl pkcs12 -in server.p12 -infoYou can't just copy the private key from the output of this stage as it's still encrypted and Wireshark needs a plain key. Simply adding the -nodes switch sorts this out, but we might as well use a command that does all the splitting out into a file at the same time:
$ openssl pkcs12 -in server.p12 -nodes -nocerts -out server.pkfNow we have a private key in server.pkf that Wireshark can understand. The Wireshark documentation will show you how to use it.
Turns out the problem was with the server - not Tomcat itself, but the webapp running within it. Something deep inside was caching the authentication tokens. This has now been fixed.
No comments:
Post a Comment