<html><head></head><body><div style="font-family: Verdana;font-size: 12.0px;"><div>
<div>Hello All,</div>
<div> </div>
<div>I experience the same problem as other people described in the past. Despite reading all the postings on the topic I am still not sure if there is a usable workaround to make spontaneous message exchange between server an client work:</div>
<div> </div>
<div>- both client and server exchange spontaneous application messages.<br/>
- both client and server use non-blocking sockets. SSL_read() and SSL_write() are serviced by one message pump thread.<br/>
- server initiates renegotiation with SSL_renegotiate()<br/>
- both client and server continue exchanging messages and renegotiation completes implicitly within the calls of SSL_read() and SSL_write()</div>
<div>--> sometimes (depending on timing) communication fails in client SSL_write() with 'unexpected record' because an application message is received instead of the expected renegotiation message.</div>
<div>So far, so good (bad)</div>
<div> </div>
<div>My question is if suppressing SSL_write() when SSL_renegotiate_pending() returns true would reliably avoid the problem:<br/>
<br/>
Her the pseudo-code:</div>
<div>server<br/>
-------</div>
<div>while(1) {<br/>
select()<br/>
if needToRenegotiate() {<br/>
SSL_renegotiate()<br/>
}</div>
<div> SSL_read() // always read<br/>
if hasDataToSend() && !SSL_renegotiate_pending() {<br/>
SSL_write()<br/>
} <br/>
handleWantSomethingReturnCodes()<br/>
}</div>
<div><br/>
client<br/>
------</div>
<div>while(1) {<br/>
select()<br/>
SSL_read() // always read<br/>
if hasDataToSend() && !SSL_renegotiate_pending() {<br/>
SSL_write()<br/>
} <br/>
handleWantSomethingReturnCodes()<br/>
}</div>
<div><br/>
Since I implemented this trick the error has never happened anymore, however, I wonder if the problem is really solved ot it just happens far less frequently in race conditions, e.g. when messages arrive between the check on SSL_renegotiate_pending() and SSL_write()</div>
<div>My interpretation of the logic in s3_pkt.c is that it's ok to receive application data between clientHello and serverHello in client or between helloRequest and clientHello in server. But this is just a guess.</div>
<div>Can somebody with good knowledge of the whole OpenSSL state-machine logic give an authoritative opinion?<br/>
<br/>
case SSL3_RT_APPLICATION_DATA:<br/>
/*<br/>
* At this point, we were expecting handshake data, but have<br/>
* application data. If the library was running inside ssl3_read()<br/>
* (i.e. in_read_app_data is set) and it makes sense to read<br/>
* application data at this point (session renegotiation not yet<br/>
* started), we will indulge it.<br/>
*/<br/>
if (s->s3->in_read_app_data &&<br/>
(s->s3->total_renegotiations != 0) &&<br/>
(((s->state & SSL_ST_CONNECT) &&<br/>
(s->state >= SSL3_ST_CW_CLNT_HELLO_A) &&<br/>
(s->state <= SSL3_ST_CR_SRVR_HELLO_A)<br/>
) || ((s->state & SSL_ST_ACCEPT) &&<br/>
(s->state <= SSL3_ST_SW_HELLO_REQ_A) &&<br/>
(s->state >= SSL3_ST_SR_CLNT_HELLO_A)<br/>
)<br/>
)) {<br/>
s->s3->in_read_app_data = 2;<br/>
return (-1);<br/>
} else {<br/>
al = SSL_AD_UNEXPECTED_MESSAGE;<br/>
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);<br/>
goto f_err;<br/>
}</div>
<div> </div>
<div>Many Thanks</div>
<div>Fabrizio</div>
</div></div></body></html>