[
https://issues.apache.org/jira/browse/HTTPCORE-322?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13499465#comment-13499465
]
Paul Donohue commented on HTTPCORE-322:
---------------------------------------
I suddenly had an epiphany ... I was wrong before - timing doesn't actually
have anything to do with this issue, so I was only occasionally accidentally
generating the proper conditions when I was messing around with timing.
Here's what actually happened:
- Connection was established and client sent the ClientHello and CloseNotify.
Exact timing doesn't matter except that the CloseNotify must be received before
the server processes the ClientHello and queues up the ServerHello,
ChangeCipherSpec, and Finished messages.
- isAppInputReady() called doHandshake(), which got NEED_UNWRAP and called
doUnwrap(), which processed the ClientHello (and queued the ServerHello,
ChangeCipherSpec, and Finished messages) but left the CloseNotify in the buffer
- The next loop in doHandshake() got NEED_WRAP, and called doWrap() which
processed the ServerHello but left the ChangeCipherSpec and Finished messages
in the queue.
- The next loop in doHandshake() got NEED_WRAP, and called doWrap() again
- SSLIOSession allocates SSLEngine.getSession().getPacketBufferSize() bytes for
outEncrypted and SSLEngine.wrap() returns BUFFER_OVERFLOW if
outEncrypted.remaining() < outputRecord.maxRecordSize, which basically means
that BUFFER_OVERFLOW is always returned if there is any data in outEncrypted
and any SSL records queued for wrapping
- So, doWrap() returned BUFFER_OVERFLOW and doHandshake() returned
- isAppInputReady() called decryptData()
- doUnwrap() calls SSLEngine.unwrap() calls SSLEngineImpl.readNetRecord() calls
SSLEngineImpl.getHSStatus(), which returns NEED_WRAP due to the pending
messages that need to be written out, which causes doUnwrap() to return with
Status.OK
- decryptData() loops forever calling doUnwrap(), which keeps returning
NEED_WRAP
I previously thought that HTTPCORE-319 was a separate (though similar) issue,
but I now think it is probably the same issue. I'm guessing that the server
writes out some messages as soon as it detects a bad client certificate and
before it finishes processing the client handshake messages, which leads to the
exact same infinite loop.
I'm attaching a test program which fakes out the SSLEngine and network Channel
to induce the conditions which led to the infinite loop.
> SSLIOSession infinite loop after alert during handshake
> -------------------------------------------------------
>
> Key: HTTPCORE-322
> URL: https://issues.apache.org/jira/browse/HTTPCORE-322
> Project: HttpComponents HttpCore
> Issue Type: Bug
> Components: HttpCore NIO
> Reporter: Paul Donohue
> Priority: Critical
> Fix For: 4.2.3
>
>
> I have an application using httpcore-nio that occasionally gets stuck in an
> infinite loop in SSLIOSession:
> "I/O dispatcher 1" prio=10 tid=0x00002aaab82da000 nid=0x5448 runnable
> [0x000000004271c000]
> java.lang.Thread.State: RUNNABLE
> at
> sun.security.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:767)
> - locked <0x00000000a4f03420> (a sun.security.ssl.SSLEngineImpl)
> at sun.security.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:719)
> - locked <0x00000000a51faaa0> (a java.lang.Object)
> at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:624)
> at
> org.apache.http.nio.reactor.ssl.SSLIOSession.doUnwrap(SSLIOSession.java:228)
> at
> org.apache.http.nio.reactor.ssl.SSLIOSession.decryptData(SSLIOSession.java:348)
> at
> org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:371)
> - locked <0x00000000a4f03498> (a
> org.apache.http.nio.reactor.ssl.SSLIOSession)
> at
> org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:118)
> at
> org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:160)
> at
> org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:342)
> at
> org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:320)
> at
> org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
> at
> org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106)
> at
> org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:604)
> at java.lang.Thread.run(Thread.java:636)
> In the above example, I was able to determine that this behavior was caused
> by a client sending a ClientHello that resumed an established session,
> immediately followed by a CloseNotify Alert. This sequence only sometimes
> triggers the infinite loop, so the problem appears to be timing related. I
> get the feeling that there are other sequences that may trigger this, but I
> don't have any other concrete examples at the moment.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
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]