/// <summary>
        /// Updates the SSL stack to use updated certificates.
        /// </summary>
        /// <param name="cert">The personal certificate to update.</param>
        /// <param name="ca">The certificate authority certificate to update.</param>
        public void UpdateCertificates(X509Certificate cert, X509Certificate[] ca)
        {
            if (_sslContext == -1)
            {
                throw new InvalidOperationException();
            }

            SslNative.UpdateCertificates(_sslContext, cert, ca);
        }
        protected override void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                _disposed = true;

                if (_socket.m_Handle != -1)
                {
                    SslNative.SecureCloseSocket(_socket);
                    _socket.m_Handle = -1;
                }

                if (_sslContext != -1)
                {
                    SslNative.ExitSecureContext(_sslContext);
                    _sslContext = -1;
                }
            }
        }
        internal void Authenticate(bool isServer, string targetHost, X509Certificate certificate, X509Certificate[] ca, SslVerification verify, params SslProtocols[] sslProtocols)
        {
            SslProtocols vers = (SslProtocols)0;

            if (-1 != _sslContext)
            {
                throw new InvalidOperationException();
            }

            for (int i = sslProtocols.Length - 1; i >= 0; i--)
            {
                vers |= sslProtocols[i];
            }

            _isServer = isServer;

            try
            {
                if (isServer)
                {
                    _sslContext = SslNative.SecureServerInit((int)vers, (int)verify, certificate, ca);
                    SslNative.SecureAccept(_sslContext, _socket);
                }
                else
                {
                    _sslContext = SslNative.SecureClientInit((int)vers, (int)verify, certificate, ca);
                    SslNative.SecureConnect(_sslContext, targetHost, _socket);
                }
            }
            catch
            {
                if (_sslContext != -1)
                {
                    SslNative.ExitSecureContext(_sslContext);
                    _sslContext = -1;
                }

                throw;
            }
        }
        /// <summary>
        /// Write the specified number of bytes to the underlying stream using the specified buffer and offset.
        /// </summary>
        /// <param name="buffer">An array that supplies the bytes written to the stream.</param>
        /// <param name="offset">he zero-based location in buffer at which to begin reading bytes to be written to the stream.</param>
        /// <param name="size">The number of bytes to read from buffer.</param>
        public override void Write(byte[] buffer, int offset, int size)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException();
            }

            if (_disposed)
            {
                throw new ObjectDisposedException();
            }

            if (offset < 0 || offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (size < 0 || size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException();
            }

            SslNative.SecureWrite(_socket, buffer, offset, size, _socket.SendTimeout);
        }
        /// <summary>
        /// Reads data from this stream and stores it in the specified array.
        /// </summary>
        /// <param name="buffer">An array that receives the bytes read from this stream.</param>
        /// <param name="offset">An integer that contains the zero-based location in buffer at which to begin storing the data read from this stream.</param>
        /// <param name="size">The maximum number of bytes to read from this stream.</param>
        /// <returns></returns>
        public override int Read(byte[] buffer, int offset, int size)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException();
            }

            if (_disposed)
            {
                throw new ObjectDisposedException();
            }

            if (offset < 0 || offset > buffer.Length)
            {
                throw new ArgumentOutOfRangeException();
            }

            if (size < 0 || size > buffer.Length - offset)
            {
                throw new ArgumentOutOfRangeException();
            }

            return(SslNative.SecureRead(_socket, buffer, offset, size, _socket.ReceiveTimeout));
        }