Return-Path: X-Original-To: apmail-hc-httpclient-users-archive@www.apache.org Delivered-To: apmail-hc-httpclient-users-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6EFBFD23C for ; Thu, 30 May 2013 19:08:24 +0000 (UTC) Received: (qmail 97112 invoked by uid 500); 30 May 2013 19:08:24 -0000 Delivered-To: apmail-hc-httpclient-users-archive@hc.apache.org Received: (qmail 97025 invoked by uid 500); 30 May 2013 19:08:23 -0000 Mailing-List: contact httpclient-users-help@hc.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpClient User Discussion" Delivered-To: mailing list httpclient-users@hc.apache.org Received: (qmail 97015 invoked by uid 99); 30 May 2013 19:08:23 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 30 May 2013 19:08:23 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of sanikumbh@gmail.com designates 209.85.214.177 as permitted sender) Received: from [209.85.214.177] (HELO mail-ob0-f177.google.com) (209.85.214.177) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 30 May 2013 19:08:15 +0000 Received: by mail-ob0-f177.google.com with SMTP id ta17so1372633obb.36 for ; Thu, 30 May 2013 12:07:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=pS9rMhnLtaV81NJPuQ7PsebFI9iWfooQxfU0qfHFCR0=; b=luviKU65yVZMgLq1fcKJW1ZKaFaiGeiKCYyRAVUeE/Wb2juM1Kzpp1HdfaOK4IE8Bq DIrmlF47w6t5NKG5C6x+w9ozMqDXiSRZpaWLbkTHhA8OKWv4nn6aaT/hK2mC1dpbpKTO t2qCRTiXT/0r7jX4zK3Ica3G2SFmaWLT94omGkflLfVN+4SHra9jL1w99qQTYnIfhras yYNBD/SbgZM4B8OMPBchh/vK+TDiul/3Zf1BF2yGZyUaBPERcUiDZ3VI6kivnWFXDX6j /E5Khq4olD2O/HijoqoeR3JYqBxKW0NEu8r7dKi6jXwZnpOmr2TEogZvgq5H4uc+6oEd HAgg== MIME-Version: 1.0 X-Received: by 10.182.126.162 with SMTP id mz2mr4633019obb.30.1369940874321; Thu, 30 May 2013 12:07:54 -0700 (PDT) Received: by 10.182.119.166 with HTTP; Thu, 30 May 2013 12:07:54 -0700 (PDT) In-Reply-To: <1368624118.27356.4.camel@ubuntu> References: <1367318808.2155.13.camel@ubuntu> <1368624118.27356.4.camel@ubuntu> Date: Thu, 30 May 2013 15:07:54 -0400 Message-ID: Subject: Re: HTTP async client and accessing server certificate (SSL) From: Sachin Nikumbh To: HttpClient User Discussion Content-Type: multipart/alternative; boundary=089e01634bf82d6d6004ddf437b7 X-Virus-Checked: Checked by ClamAV on apache.org --089e01634bf82d6d6004ddf437b7 Content-Type: text/plain; charset=ISO-8859-1 Hi Oleg, Thanks for your reply. I started digging through the Apache async client code and have come with a way to access the server certificate immediately after the SSL handshake in the verify method of SSLSetupHandler, To achieve this, I created my own MySSLLayeringStrategy class that extends SSLLayeringStrategy as shows below : ******************************************************** class MySSLLayeringStrategy extends SSLLayeringStrategy{ private SSLContext sslContext; public MySSLLayeringStrategy(SSLContext context){ super(context); this.sslContext = context; } protected void initializeEngine(final SSLEngine engine) { super.initializeEngine(engine); } protected void verifySession(final IOSession iosession, final SSLSession sslsession) throws SSLException { super.verifySession(iosession, sslsession); } public SSLIOSession layer(final IOSession iosession) { SSLIOSession ssliosession = new SSLIOSession(iosession, SSLMode.CLIENT, this.sslContext, new MySSLSetupHandler()); iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession); return ssliosession; } class MySSLSetupHandler implements SSLSetupHandler { public void initalize( final SSLEngine sslengine) throws SSLException { initializeEngine(sslengine); } public void verify( final IOSession iosession, final SSLSession sslsession) throws SSLException { verifySession(iosession, sslsession); // Now that basic hostname verification is done, perform extra authorization based on peer DN String peerDN = sslsession.getPeerPrincipal().getName(); if ( !authorizedPeer(peerDN) ){ throw new RuntimeException("Authorization failed"); } } } } ******************************************************** Now, I am using MySSLLayeringStrategy to create AsyncScheme ******************************************************** AsyncScheme scheme = new AsyncScheme( "https", 443, new MySSLLayeringStrategy(sslContext) ); ******************************************************** This seems to be doing the job but the exception thrown in the verify method causes the DefaultHttpAsyncClient instance to close abnormally as I can see from the exception thrown: ******************************************************** .May 30, 2013 2:30:18 PM org.apache.http.impl.nio.client.InternalIOReactorExceptionHandler handle SEVERE: Fatal runtime error java.lang.RuntimeException: Authorization failed .... .... May 30, 2013 2:30:18 PM org.apache.http.impl.nio.client.AbstractHttpAsyncClient doExecute SEVERE: I/O reactor terminated abnormally org.apache.http.nio.reactor.IOReactorException: I/O dispatch worker terminated abnormally at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:382) at org.apache.http.impl.nio.conn.PoolingClientAsyncConnectionManager.execute(PoolingClientAsyncConnectionManager.java:108) .... .... Caused by: java.lang.RuntimeException: Authorization failed .... .... ******************************************************** Is my approach for accessing server certificate safe? If so, what is the safe way of throwing exception from the verify method? Thanks Sachin On Wed, May 15, 2013 at 9:21 AM, Oleg Kalnichevski wrote: > On Mon, 2013-05-13 at 22:10 -0400, Sachin Nikumbh wrote: > > Hi Oleg, > > > > Thanks a lot for the response. I have one more question. > > > > In my client application, I need to provide extra authorization based on > > the common name in the server certificate. I want to allow the > > request-response exchange (I am sending a POST request) only after the > > server passes this extra authorization step. > > > > Is using BasicAsyncResponseConsumer going be too late for me to access > the > > server certificate? > > > > I want the behavior similar to following sample code based > > on HttpsURLConnection : > > > > > ************************************************************************************************************ > > HttpsURLConnection urlConnection = > > (HttpsURLConnection)madsUrl.openConnection(); > > urlConnection.setRequestMethod("POST"); > > ... > > ... > > urlConnection.connect(); //Establish connection for initial SSL handshake > > String peerDN = urlConnection.getPeerPrincipal().getName(); > > if( isAuthorizedPeer(peerDN) ){ > > // Now it's safe to write request data > > OutputStream oStream = urlConnection.getOutputStream(); > > ... > > ... > > } > > > ************************************************************************************************************ > > > > Thanks once again > > Sachin > > > > > > Hi Sachin > > There is currently no easy way of obtaining the SSL session details > prior to issuing a request. Feel free to raise an improvement request in > JIRA for this problem. > > Oleg > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org > For additional commands, e-mail: httpclient-users-help@hc.apache.org > > --089e01634bf82d6d6004ddf437b7--