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); }
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); }
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); }
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); }