示例#1
0
 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);
     }
 }
示例#2
0
        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);
        }
示例#3
0
        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);
        }