private static Ssl.SslErrorCode GetSslError(SafeSslHandle context, int result, out Exception?innerError) { ErrorInfo lastErrno = Sys.GetLastErrorInfo(); // cache it before we make more P/Invoke calls, just in case we need it Ssl.SslErrorCode retVal = Ssl.SslGetError(context, result); switch (retVal) { case Ssl.SslErrorCode.SSL_ERROR_SYSCALL: // Some I/O error occurred innerError = Crypto.ErrPeekError() != 0 ? Crypto.CreateOpenSslCryptographicException() : // crypto error queue not empty result == 0 ? new EndOfStreamException() : // end of file that violates protocol result == -1 && lastErrno.Error != Error.SUCCESS ? new IOException(lastErrno.GetErrorMessage(), lastErrno.RawErrno) : // underlying I/O error null; // no additional info available break; case Ssl.SslErrorCode.SSL_ERROR_SSL: // OpenSSL failure occurred. The error queue contains more details, when building the exception the queue will be cleared. innerError = Interop.Crypto.CreateOpenSslCryptographicException(); break; default: // No additional info available. innerError = null; break; } return(retVal); }