internal static int Decrypt(SafeSslHandle context, Span <byte> buffer, out Ssl.SslErrorCode errorCode)
        {
#if DEBUG
            ulong assertNoError = Crypto.ErrPeekError();
            Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error.");
#endif
            BioWrite(context.InputBio !, buffer);

            int retVal = Ssl.SslRead(context, ref MemoryMarshal.GetReference(buffer), buffer.Length, out errorCode);
            if (retVal > 0)
            {
                return(retVal);
            }

            switch (errorCode)
            {
            // indicate end-of-file
            case Ssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                break;

            case Ssl.SslErrorCode.SSL_ERROR_WANT_READ:
                // update error code to renegotiate if renegotiate is pending, otherwise make it SSL_ERROR_WANT_READ
                errorCode = Ssl.IsSslRenegotiatePending(context) ?
                            Ssl.SslErrorCode.SSL_ERROR_RENEGOTIATE :
                            Ssl.SslErrorCode.SSL_ERROR_WANT_READ;
                break;

            default:
                throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), GetSslError(retVal, errorCode));
            }

            return(0);
        }
示例#2
0
        internal static int Decrypt(SafeSslHandle context, byte[] outBuffer, int offset, int count, out Ssl.SslErrorCode errorCode)
        {
#if DEBUG
            ulong assertNoError = Crypto.ErrPeekError();
            Debug.Assert(assertNoError == 0, "OpenSsl error queue is not empty, run: 'openssl errstr " + assertNoError.ToString("X") + "' for original error.");
#endif
            errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;

            int       retVal     = BioWrite(context.InputBio, outBuffer, offset, count);
            Exception innerError = null;

            lock (context)
            {
                if (retVal == count)
                {
                    unsafe
                    {
                        fixed(byte *fixedBuffer = outBuffer)
                        {
                            retVal = Ssl.SslRead(context, fixedBuffer + offset, outBuffer.Length);
                        }
                    }

                    if (retVal > 0)
                    {
                        count = retVal;
                    }
                }

                if (retVal != count)
                {
                    errorCode = GetSslError(context, retVal, out innerError);
                }
            }

            if (retVal != count)
            {
                retVal = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case Ssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                    break;

                case Ssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    // update error code to renegotiate if renegotiate is pending, otherwise make it SSL_ERROR_WANT_READ
                    errorCode = Ssl.IsSslRenegotiatePending(context) ?
                                Ssl.SslErrorCode.SSL_ERROR_RENEGOTIATE :
                                Ssl.SslErrorCode.SSL_ERROR_WANT_READ;
                    break;

                default:
                    throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), innerError);
                }
            }

            return(retVal);
        }
示例#3
0
        internal static int Decrypt(SafeSslHandle context, byte[] outBuffer, int offset, int count, out Ssl.SslErrorCode errorCode)
        {
            errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE;

            int retVal = BioWrite(context.InputBio, outBuffer, offset, count);

            if (retVal == count)
            {
                unsafe
                {
                    fixed(byte *fixedBuffer = outBuffer)
                    {
                        retVal = Ssl.SslRead(context, fixedBuffer + offset, outBuffer.Length);
                    }
                }

                if (retVal > 0)
                {
                    count = retVal;
                }
            }

            if (retVal != count)
            {
                Exception innerError;
                errorCode = GetSslError(context, retVal, out innerError);
                retVal    = 0;

                switch (errorCode)
                {
                // indicate end-of-file
                case Ssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                    break;

                case Ssl.SslErrorCode.SSL_ERROR_WANT_READ:
                    // update error code to renegotiate if renegotiate is pending, otherwise make it SSL_ERROR_WANT_READ
                    errorCode = Ssl.IsSslRenegotiatePending(context) ?
                                Ssl.SslErrorCode.SSL_ERROR_RENEGOTIATE :
                                Ssl.SslErrorCode.SSL_ERROR_WANT_READ;
                    break;

                default:
                    throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), innerError);
                }
            }

            return(retVal);
        }
示例#4
0
        internal static int Decrypt(SafeSslHandle context, Span <byte> buffer, out Ssl.SslErrorCode errorCode)
        {
            BioWrite(context.InputBio !, buffer);

            int retVal = Ssl.SslRead(context, ref MemoryMarshal.GetReference(buffer), buffer.Length, out errorCode);

            if (retVal > 0)
            {
                return(retVal);
            }

            switch (errorCode)
            {
            // indicate end-of-file
            case Ssl.SslErrorCode.SSL_ERROR_ZERO_RETURN:
                break;

            case Ssl.SslErrorCode.SSL_ERROR_WANT_READ:
                // update error code to renegotiate if renegotiate is pending, otherwise make it SSL_ERROR_WANT_READ
                errorCode = Ssl.IsSslRenegotiatePending(context)
                        ? Ssl.SslErrorCode.SSL_ERROR_RENEGOTIATE
                        : Ssl.SslErrorCode.SSL_ERROR_WANT_READ;
                break;

            case Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP:
                // This happens in TLS 1.3 when server requests post-handshake authentication
                // but no certificate is provided by client. We can process it the same way as
                // renegotiation on older TLS versions
                errorCode = Ssl.SslErrorCode.SSL_ERROR_RENEGOTIATE;
                break;

            default:
                throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), GetSslError(retVal, errorCode));
            }

            return(0);
        }