Return-Path: Delivered-To: apmail-jakarta-httpclient-user-archive@www.apache.org Received: (qmail 17165 invoked from network); 6 Oct 2006 18:04:35 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 6 Oct 2006 18:04:35 -0000 Received: (qmail 29901 invoked by uid 500); 6 Oct 2006 18:04:34 -0000 Delivered-To: apmail-jakarta-httpclient-user-archive@jakarta.apache.org Received: (qmail 29884 invoked by uid 500); 6 Oct 2006 18:04:34 -0000 Mailing-List: contact httpclient-user-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: "HttpClient User Discussion" Reply-To: "HttpClient User Discussion" Delivered-To: mailing list httpclient-user@jakarta.apache.org Received: (qmail 29873 invoked by uid 99); 6 Oct 2006 18:04:34 -0000 Received: from idunn.apache.osuosl.org (HELO idunn.apache.osuosl.org) (140.211.166.84) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 06 Oct 2006 11:04:34 -0700 X-ASF-Spam-Status: No, hits=0.0 required=5.0 tests= Received: from [64.114.5.49] ([64.114.5.49:3209] helo=c2kp01smtp.cucbc.com) by idunn.apache.osuosl.org (ecelerity 2.1.1.8 r(12930)) with ESMTP id 7D/18-24193-9AA96254 for ; Fri, 06 Oct 2006 11:04:27 -0700 Received: from c2kp01mail.cucbc.com ([172.17.68.166]) by c2kp01smtp.cucbc.com with Microsoft SMTPSVC(5.0.2195.6713); Fri, 6 Oct 2006 11:04:49 -0700 Received: from [172.18.0.1] ([172.18.0.1]) by c2kp01mail.cucbc.com with Microsoft SMTPSVC(5.0.2195.6713); Fri, 6 Oct 2006 11:04:15 -0700 Subject: Re: How come my http-client is not presenting the certificate? From: Julius Davies Reply-To: juliusdavies@cucbc.com To: James Vu Cc: httpclient-user@jakarta.apache.org In-Reply-To: <20061006150944.85397.qmail@web54208.mail.yahoo.com> References: <20061006150944.85397.qmail@web54208.mail.yahoo.com> Content-Type: text/plain Organization: Credit Union Central of British Columbia Date: Fri, 06 Oct 2006 11:04:13 -0700 Message-Id: <1160157853.5633.31.camel@angryarab.blogspot.com> Mime-Version: 1.0 X-Mailer: Evolution 2.6.3 Content-Transfer-Encoding: 7bit X-OriginalArrivalTime: 06 Oct 2006 18:04:15.0349 (UTC) FILETIME=[D5C23A50:01C6E971] X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Hi, James, I double checked that client certs are still working with "commons-ssl-0.3.0.jar". I used the code below. When I try connecting to an SSL server that doesn't require client certs, I get "client certs: null" (e.g. www.cucbc.com:443). When I try connecting to a server that does require client certs, they show up. If I remove this line, then the socket can't be established: // easy.setKeyMaterial( km ); But that's because the server I'm testing against REQUIRES client certs, rather than just merely WANTING client certs. Can you try the code below? I'm using the "SSLWrapperFactory" interface to look closely at the socket before it's returned up to HttpClient. If you're still having problems, I'll try setting up a proper WANT-CLIENT-AUTH server to further test. For now I'm being lazy and just relying on a NEED-CLIENT-AUTH server I have access to. yours, Julius http://juliusdavies.ca/ public static void main( String[] args ) throws Exception { EasySSLProtocolSocketFactory easy = new EasySSLProtocolSocketFactory(); SSLWrapperFactory w = new SSLWrapperFactory() { public SSLSocket wrap( SSLSocket s ) throws IOException { s.getSession().getPeerCertificates(); System.out.println( "wrap: " + s ); Certificate[] certs = s.getSession().getLocalCertificates(); if ( certs != null ) { System.out.println( "client certs:" ); for ( int i = 0; i < certs.length; i++ ) { X509Certificate c = (X509Certificate) certs[ i ]; System.out.println( Certificates.toString( c ) ); } } else { System.out.println( "client certs: null" ); } return s; } public SSLServerSocket wrap( SSLServerSocket s ) throws IOException { return s; } }; // These next three lines are where commons-ssl fits in: KeyMaterial km = new KeyMaterial( "/path/to/cert.p12", "changeit".toCharArray() ); easy.setSSLWrapperFactory( w ); easy.setKeyMaterial( km ); // Back to usual "EasySSLProtocolSocketFactory" as detailed in // httpclient-contrib javadocs: Protocol easyhttps = new Protocol( "https", easy, 443 ); Protocol.registerProtocol( "https", easyhttps ); HttpClient client = new HttpClient(); HeadMethod httpget = new HeadMethod( "https://www.cucbc.com:443/" ); client.executeMethod( httpget ); Header[] headers = httpget.getResponseHeaders(); for ( int i = 0; i < headers.length; i++ ) { Header h = headers[ i ]; System.out.println( h.getName() + ":" + h.getValue() ); } } On Fri, 2006-06-10 at 08:09 -0700, James Vu wrote: > Julius: > > Again thanks for your reply. I did use > EasySSLProtocolSocketFactory. This is why the client > was able to make thru the first SSL handshake because > it is able to trust any CA. (As a side note, I think > there is sufficient samples/docs for using > EasySSLProtocolSocketFactory.) > > I also tried the TrustSSLProtocolSocketFactory with > both the server certificate and the signer of the > server certificate as the trust chain. Here it also > passed thru the first SSL handshake but did not seem > to present the client certificate during the second > handshake. > > thanks, > JT > > Here is my test client code: > > mport org.apache.commons.httpclient.HttpClient; > import > org.apache.commons.httpclient.methods.GetMethod; > import > org.apache.commons.httpclient.protocol.Protocol; > import org.apache.commons.ssl.HttpSecureProtocol; > import org.apache.commons.ssl.TrustMaterial; > import org.apache.commons.ssl.KeyMaterial; > > import org.apache.commons.httpclient.contrib.ssl.*; > > import javax.net.ssl.SSLHandshakeException; > import java.net.URL; > > public class SslClientExample { > > /* argument 0: host > 1: port number */ > public static void main( String[] args ) > throws Exception > { > HttpSecureProtocol f = > new EasySSLProtocolSocketFactory(); > > //HttpSecureProtocol f = new HttpSecureProtocol(); > > // here's where we start trusting server's CA: > //f.addTrustMaterial(new TrustMaterial( > // "my_cacerts.jks", > // "changeit".toCharArray())); > f.setKeyMaterial (new KeyMaterial("mycert.p12", > "changeit".toCharArray())); > Protocol trustHttps = new Protocol("https", > f, > Integer.parseInt(args[1])); > Protocol.registerProtocol("https", trustHttps); > > HttpClient client = new HttpClient(); > GetMethod httpget = new GetMethod(args[0]); > client.executeMethod(httpget); > String s = httpget.getStatusLine().toString(); > System.out.println( "HTTPClient: " + s ); > System.out.println( > httpget.getResponseBodyAsString()); > } > } > > > --- Julius Davies wrote: > > > James, > > > > Hope you don't mind me switching this conversation > > to "httpclient-user" > > instead of "httpclient-dev". > > > > I think the results below show that commons-ssl is > > able to present the > > client certificate. I should probably fix things up > > a little to make > > doubly sure of that (the commons-ssl "ping" utility > > is only showing the > > server certs in its output), but for now let's focus > > on your code > > instead. > > > > #1. Are you using EasySSLProtocolSocketFactory like > > this? There is no > > documentation actually telling you to do this, so I > > don't blame you if > > you missed this: > > > > EasySSLProtocolSocketFactory easy = new > > EasySSLProtocolSocketFactory(); > > > > // These next two lines are where commons-ssl fits > > in: > > KeyMaterial km = new KeyMaterial( > > "/path/to/cert.jks" ); > > easy.setKeyMaterial( km ); > > > > // Back to usual "EasySSLProtocolSocketFactory" as > > detailed in > > // httpclient-contrib javadocs: > > Protocol easyhttps = new Protocol("https", easy, > > 443); > > Protocol.registerProtocol("https", easyhttps); > > HttpClient client = new HttpClient(); > > GetMethod httpget = new > > GetMethod("https://localhost/"); > > client.executeMethod(httpget); > > > > > > #2. I would actually recommend against using > > EasySSLProtocolSocketFactory in production > > environments. Instead I > > would use the Ping utility to download the server > > cert you want to trust > > (cut & paste the base64 PEM output into a separate > > file), and then use > > AuthSSLProtocolSocketFactory instead. > > > > But if you do that, you will have to also deal with > > server cert expiry, > > which can be annoying. Mind you, if you're using > > client certs, you > > already have to deal with client cert expiry! > > > > > > yours, > > > > Julius > > > > http://juliusdavies.ca/commons-ssl/ > > > > -- Julius Davies Senior Application Developer, Technology Services Credit Union Central of British Columbia http://www.cucbc.com/ Tel: 416-652-0183 Cel: 647-232-7571 1441 Creekside Drive Vancouver, BC Canada V6J 4S7 --------------------------------------------------------------------- To unsubscribe, e-mail: httpclient-user-unsubscribe@jakarta.apache.org For additional commands, e-mail: httpclient-user-help@jakarta.apache.org