[ 
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]

Reply via email to