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
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: [email protected]
For additional commands, e-mail: [email protected]