internal static bool DoSslHandshake(SafeSslHandle context, byte[] recvBuf, int recvOffset, int recvCount, out byte[] sendBuf, out int sendCount) { sendBuf = null; sendCount = 0; if ((recvBuf != null) && (recvCount > 0)) { if (BioWrite(context.InputBio, recvBuf, recvOffset, recvCount) <= 0) { // Make sure we clear out the error that is stored in the queue throw Crypto.CreateOpenSslCryptographicException(); } } int retVal = Ssl.SslDoHandshake(context); if (retVal != 1) { Exception innerError; Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { throw new SslException(SR.Format(SR.net_ssl_handshake_failed_error, error), innerError); } } sendCount = Crypto.BioCtrlPending(context.OutputBio); if (sendCount > 0) { sendBuf = new byte[sendCount]; try { sendCount = BioRead(context.OutputBio, sendBuf, sendCount); } finally { if (sendCount <= 0) { // Make sure we clear out the error that is stored in the queue Crypto.ErrGetError(); sendBuf = null; sendCount = 0; } } } bool stateOk = Ssl.IsSslStateOK(context); if (stateOk) { context.MarkHandshakeCompleted(); } return(stateOk); }
internal static bool DoSslHandshake(SafeSslHandle context, byte[] recvBuf, int recvOffset, int recvCount, out byte[] sendBuf, out int sendCount) { sendBuf = null; sendCount = 0; if ((recvBuf != null) && (recvCount > 0)) { BioWrite(context.InputBio, recvBuf, recvOffset, recvCount); } Ssl.SslErrorCode error; int retVal = Ssl.SslDoHandshake(context); if (retVal != 1) { error = GetSslError(context, retVal); if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { throw CreateSslException(context, SR.net_ssl_handshake_failed_error, retVal); } } sendCount = Crypto.BioCtrlPending(context.OutputBio); if (sendCount > 0) { sendBuf = new byte[sendCount]; try { sendCount = BioRead(context.OutputBio, sendBuf, sendCount); } finally { if (sendCount <= 0) { sendBuf = null; sendCount = 0; } } } bool stateOk = Ssl.IsSslStateOK(context); if (stateOk) { context.MarkHandshakeCompleted(); } return(stateOk); }
internal static bool DoSslHandshake(SafeSslHandle context, ReadOnlySpan <byte> input, out byte[]?sendBuf, out int sendCount) { sendBuf = null; sendCount = 0; Exception?handshakeException = null; if (input.Length > 0) { if (Ssl.BioWrite(context.InputBio !, ref MemoryMarshal.GetReference(input), input.Length) != input.Length) { // Make sure we clear out the error that is stored in the queue throw Crypto.CreateOpenSslCryptographicException(); } } int retVal = Ssl.SslDoHandshake(context); if (retVal != 1) { Exception? innerError; Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { // Handshake failed, but even if the handshake does not need to read, there may be an Alert going out. // To handle that we will fall-through the block below to pull it out, and we will fail after. handshakeException = new SslException(SR.Format(SR.net_ssl_handshake_failed_error, error), innerError); Crypto.ErrClearError(); } } sendCount = Crypto.BioCtrlPending(context.OutputBio !); if (sendCount > 0) { sendBuf = new byte[sendCount]; try { sendCount = BioRead(context.OutputBio !, sendBuf, sendCount); } catch (Exception) when(handshakeException != null) { // If we already have handshake exception, ignore any exception from BioRead(). } finally { if (sendCount <= 0) { // Make sure we clear out the error that is stored in the queue Crypto.ErrClearError(); sendBuf = null; sendCount = 0; } } } if (handshakeException != null) { throw handshakeException; } bool stateOk = Ssl.IsSslStateOK(context); if (stateOk) { context.MarkHandshakeCompleted(); } return(stateOk); }