Hello,

I have a question about what happens when the first SSL handshake on a
SSL connection tries to gather data from a socket that would block
(e.g. there is no data tobe read yet).

I am using the SSL3 implementation on a Linux platform.

So, in Do1stHandshake(), the next handshake function is callled
repeatedly even when the rv is SECWouldBlock.  In the case of the
client side of the SSL connection, the handshake function pointer is
first set to BeginClientHandshake().  The BeginClientHandshake function
sets it to GatherRecord1stHandshake() and calls ssl3_SendClientHello.

So, it seems that GatherRecord1stHandshake gets called to gather the
server_hello handshake message when it is received.  In the case of
SSL3, GatherRecord1stHandshake calls ssl3_GatherCompleteHandshake,
which in turn calls ssl3_GatherData.  ssl3_GatherData calls
ssl_DefRecv, which returns the number of bytes it read from the lower
FD layer.

Now, ssl3_GatherData interprets a negative number of bytes read as a
failure and returns SECFailure.  ssl3_GatherCompleteHandshake simply
returns the SECFailure to ssl_GatherRecord1stHandshake.  If
ssl_GatherRecord1stHandshake receives back rv <= 0, it checks if rv ==
SECWouldBlock.  However, the rv was set to SECFailure from
ssl3_GatherData, so ssl_GatherRecord1stHandshake returns SECFailure.

Do1stHandshake receives that and also returns with failure.  Even
though it is supposed to keep trying in the case of a would-block
socket, it just receives SECFailure from the handshake function and
returns with the same.

Now, I went deeper and found the NSPR function called to receive data
from the socket for the Unix platform - _MD_recv in unix.c.  The
_MD_recv function calls recv (or read) and if it receives back a
negative number of bytes, it maps the OS error received to a NSPR error
code.  From what I understand, if the socket would block, the system
call sets the errno to EAGAIN / EWOULDBLOCK.  The _MD_recv function
maps this errno to PR_WOULD_BLOCK_ERROR in NSPR and calls PR_SetError()
with it.

To me it seems that ssl3_GatherData should check the NSPR error code if
it receives a negative number of bytes read.  If PR_GetError() returns
PR_WOULD_BLOCK, ssl3_GatherData should return SECWouldBlock, but it
returns SECFailure instead, causing everything below it on the stack to
propagate the SECFailure return value back to Do1stHandshake().

Am I going wrong somewhere or is this a bug?  Somebody who knows more
about the code maybe can tell me :)

Regards,
Peter

_______________________________________________
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to