You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Julius Davies <ju...@cucbc.com> on 2006/10/06 22:22:52 UTC

Re: [SPAM] - Re: How come my http-client is not presenting the certificate? - Email has different SMTP TO: and MIME TO: fields in the email addresses

ps.  If you can get your server to set itself into WANT-CLIENT-AUTH mode
from the very beginning, things might work better.  WANT-CLIENT-AUTH
mode still allows sockets that don't have client certificates to be
established.

Only NEED-CLIENT-AUTH mode disallows socket creation in those cases.

So if your server was setup with WANT-CLIENT-AUTH mode right from the
beginning, httpclient would be able to send the client cert on all
requests, and not have to worry about this situation where a client cert
is asked for right in the middle of a request (after the GET or POST
line has been sent!).

But I would still like to see what it takes to get commons-ssl and
httpclient to work flawlessly with the scenario you've identified.


yours,

Julius


On Fri, 2006-06-10 at 13:09 -0700, Julius Davies wrote:
> Hi, James,
> 
> Wow!  A person can call the following in the middle of a TCP/IP session:
> 
> // This happens in the server:
> // SSLSocket "s" came from an serverSocket.accept() call.
> s.setNeedClientAuth( true );
> s.getSession().invalidate();
> s.startHandshake();
> 
> I didn't know that.
> 
> But commons-ssl didn't seem to mind at all.  I just needed to alter the
> test code a little to see that it worked.  Add this at the top:
> 
> final SSLSocket[] socket = new SSLSocket[ 1 ];
> 
> Inside the "SSLWrapperFactory" anonymous inner class, add this:
> 
> socket[ 0 ] = s;
> 
> After everything is done, take a look at the client certs yet again:
> 
> Certificate[] certs = socket[ 0 ].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" );
> }
> 
> 
> yours,
> 
> Julius
> 
> 
> 
> On Fri, 2006-06-10 at 11:46 -0700, James Vu wrote:
> > Julius:
> > 
> > I just want to reemphasize that the server DOES NOT
> > lock down the port.  It only lock dow a certain path.
> > So the server will not send a certificcate request
> > until the client send the GET /whatever HTTP/1.1
> > 
> > Anyhow, I ran your code and I got the "client certs:
> > null" message.
> > 
> > thanks again,
> > JT 
> > 
> > 
> > --- Julius Davies <ju...@cucbc.com> wrote:
> > 
> > > 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 <ju...@cucbc.com> wrote:
> > > > 
> > > 
> > === message truncated ===
> > 
> > 
> > __________________________________________________
> > Do You Yahoo!?
> > Tired of spam?  Yahoo! Mail has the best spam protection around 
> > http://mail.yahoo.com 
-- 
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