private static void BioWrite(SafeBioHandle bio, ReadOnlySpan<byte> buffer) { int bytes = Ssl.BioWrite(bio, ref MemoryMarshal.GetReference(buffer), buffer.Length); if (bytes != buffer.Length) { throw CreateSslException(SR.net_ssl_write_bio_failed_error); } }
private static int BioWrite(SafeBioHandle bio, byte[] buffer, int offset, int count) { Debug.Assert(buffer != null); Debug.Assert(offset >= 0); Debug.Assert(count >= 0); Debug.Assert(buffer.Length >= offset + count); int bytes; unsafe { fixed(byte *bufPtr = buffer) { bytes = Ssl.BioWrite(bio, bufPtr + offset, count); } } if (bytes != count) { throw CreateSslException(SR.net_ssl_write_bio_failed_error); } return(bytes); }
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); }