hc-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Thuy Tran (JIRA)" <j...@apache.org>
Subject [jira] Commented: (HTTPCLIENT-1070) misleading javax.net.ssl.SSLPeerUnverifiedException thrown when cause is due to non SSL related IOException (e.g. java.net.SocketException: Connection reset)
Date Fri, 11 Mar 2011 01:18:59 GMT

    [ https://issues.apache.org/jira/browse/HTTPCLIENT-1070?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13005444#comment-13005444

Thuy Tran commented on HTTPCLIENT-1070:

Although it's thrown from the JRE's internal class, couldn't the code could be updated to
do the ssl handshake another way to bypass the use of SSLSessionImpl.getPeerCertificates().
 Disabling hostname verification is not an option for those who need to verify the hostname
since this would make their applications less secure.  With the code kept as is, those who
need server cert authentication will not be able to distinguish if a certificate is missing
from the trusstore or if it's connection issue.  Unfortunately, in my case, this significantly
affects my application and therefore, I'll have to rethink using HttpClient.  

> misleading javax.net.ssl.SSLPeerUnverifiedException thrown when cause is due to non SSL
related IOException (e.g. java.net.SocketException: Connection reset)
> -------------------------------------------------------------------------------------------------------------------------------------------------------------
>                 Key: HTTPCLIENT-1070
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1070
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpClient
>    Affects Versions: 4.1 Final
>         Environment: mac os x
>            Reporter: Thuy Tran
>              Labels: security
> I have code that continually executes an http get request to a web server that requires
server side authentication.  I have the appropriate certificate in the truststore and generally,
it executes without a problem.
> System.setProperty("javax.net.ssl.trustStore", sslTrustStore);
> HttpGet httpGet = new HttpGet(uri);
> DefaultHttpClient client = new DefaultHttpClient();
> HttpResponse response = null;
> try {
>   response = httpClient.execute(httpGet);
>   //do something with response
> } catch (IOException e) {
> // have caught SSLPeerUnverifiedException
> } catch (ClientProtocolException e) {
> //log it
> }
> However, even after many successful requests, it can still get a javax.net.ssl.SSLPeerUnverifiedException.
I turned ssl debug on (-Djavax.net.debug=ssl) and noticed that this can occur if during the
ssl handshake, it gets a "java.net.SocketException: Connection reset":
> Thread-1, WRITE: TLSv1 Handshake, length = 113
> Thread-1, handling exception: java.net.SocketException: Connection reset
> Thread-1, SEND TLSv1 ALERT:  fatal, description = unexpected_message
> Thread-1, WRITE: TLSv1 Alert, length = 2
> Thread-1, Exception sending alert: java.net.SocketException: Broken pipe
> Thread-1, called closeSocket()
> Thread-1, IOException in getSession():  java.net.SocketException: Connection reset
> Thread-1, called close()
> Thread-1, called closeInternal(true)
> The stack trace shows that it's due to the use of com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates():
> 03/01/11 15:48:56 PM EST [Thread-1] WARN -  IOException sending request to server
> javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
>     at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
>     at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
>     at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
>     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
>     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
>     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
>     at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:562)
>     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
>     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
>     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
>     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
>     at mil.disa.common.http.HttpUtil.executeHttpRequest(HttpUtil.java:253)
> So I swapped out the code to use java.net.URLConnection class to send the request rather
than HttpClient and noticed that if a SocketException occurs during the handshake, I get the
appropriate SocketException error rather than SSLPeerUnverifiedException:
> Thread-12, WRITE: TLSv1 Handshake, length = 113
> Thread-12, handling exception: java.net.SocketException: Connection reset
> Thread-12, SEND TLSv1 ALERT:  fatal, description = unexpected_message
> Thread-12, WRITE: TLSv1 Alert, length = 2
> Thread-12, Exception sending alert: java.net.SocketException: Broken pipe
> Thread-12, called closeSocket()
> Thread-12, called close()
> Thread-12, called closeInternal(true)
> 03/10/11 13:29:59 PM EST [Thread-12] FATAL - IOException sending request to server
> java.net.SocketException: Connection reset
>     at java.net.SocketInputStream.read(SocketInputStream.java:168)
>     at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
>     at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
>     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
>     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
>     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
>     at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149)
>     at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
>     at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
>     at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1019)
>     at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
>     at mil.disa.common.http.HttpUtil.executeHttpRequest2(HttpUtil.java:589)
> The SSLPeerUnverifiedException is misleading since if an IOException occurs, I want to
retry sending the request if it's not SSL related.  This makes it difficult in debugging the
error and I would only know that it's not SSLPeerUnverifiedException if I set -Djavax.net.debug=ssl.

This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

To unsubscribe, e-mail: dev-unsubscribe@hc.apache.org
For additional commands, e-mail: dev-help@hc.apache.org

View raw message