From 33cf59b999159596cb4a811d336eace1a834c442 Mon Sep 17 00:00:00 2001 From: wfurt Date: Mon, 24 Jan 2022 20:32:05 -0800 Subject: [PATCH 1/5] make sure failed SSL does not imapct other sessions --- .../Interop.OpenSsl.cs | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index d403daac342ad..c7eeb1d8a9978 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -372,6 +372,10 @@ internal static SecurityStatusPal SslRenegotiate(SafeSslHandle sslContext, out b internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, ReadOnlySpan input, out byte[]? sendBuf, out int sendCount) { +#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 sendBuf = null; sendCount = 0; Exception? handshakeException = null; @@ -385,25 +389,31 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, } } - int retVal = Ssl.SslDoHandshake(context); - if (retVal != 1) + Exception? innerError = null; + try { - Exception? innerError; - Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); - - if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) + int retVal = Ssl.SslDoHandshake(context); + if (retVal != 1) { - return SecurityStatusPalErrorCode.CredentialsNeeded; - } + 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(); + if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) + { + return SecurityStatusPalErrorCode.CredentialsNeeded; + } + + 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); + } } } + finally + { + Crypto.ErrClearError(); + } sendCount = Crypto.BioCtrlPending(context.OutputBio!); if (sendCount > 0) From 10fe5bcf2b9272d09c7b3f384be216f7705ec814 Mon Sep 17 00:00:00 2001 From: wfurt Date: Mon, 24 Jan 2022 20:44:11 -0800 Subject: [PATCH 2/5] move innerError --- .../Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index c7eeb1d8a9978..13757b820d85a 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -389,12 +389,12 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, } } - Exception? innerError = null; try { int retVal = Ssl.SslDoHandshake(context); if (retVal != 1) { + Exception? innerError = null; Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) From 78a17cdc90718199a3afe05624ca24c8967d0781 Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 3 Feb 2022 10:34:11 -0800 Subject: [PATCH 3/5] feedback from review --- .../Interop.OpenSsl.cs | 16 +++++++--------- .../Interop.Ssl.cs | 2 +- .../pal_ssl.c | 14 ++++++++++++-- .../pal_ssl.h | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 13757b820d85a..2c3f9fe61df9e 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -372,10 +372,6 @@ internal static SecurityStatusPal SslRenegotiate(SafeSslHandle sslContext, out b internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, ReadOnlySpan input, out byte[]? sendBuf, out int sendCount) { -#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 sendBuf = null; sendCount = 0; Exception? handshakeException = null; @@ -391,12 +387,9 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, try { - int retVal = Ssl.SslDoHandshake(context); + int retVal = Ssl.SslDoHandshake(context, out Ssl.SslErrorCode error); if (retVal != 1) { - Exception? innerError = null; - Ssl.SslErrorCode error = GetSslError(context, retVal, out innerError); - if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) { return SecurityStatusPalErrorCode.CredentialsNeeded; @@ -404,6 +397,8 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { + GetSslError(context, retVal, error, Sys.GetLastErrorInfo(), out Exception? innerError ); + // 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); @@ -663,8 +658,11 @@ private static void BioWrite(SafeBioHandle bio, ReadOnlySpan buffer) 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 + return GetSslError(context, result, Ssl.SslGetError(context, result), lastErrno, out innerError); + } - Ssl.SslErrorCode retVal = Ssl.SslGetError(context, result); + private static Ssl.SslErrorCode GetSslError(SafeSslHandle context, int result, Ssl.SslErrorCode retVal, ErrorInfo lastErrno, out Exception? innerError) + { switch (retVal) { case Ssl.SslErrorCode.SSL_ERROR_SYSCALL: diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs index 379ab7586ed38..038df71264ee8 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs @@ -97,7 +97,7 @@ internal static partial class Ssl internal static partial void SslSetBio(SafeSslHandle ssl, SafeBioHandle rbio, SafeBioHandle wbio); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslDoHandshake", SetLastError = true)] - internal static partial int SslDoHandshake(SafeSslHandle ssl); + internal static partial int SslDoHandshake(SafeSslHandle ssl, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_IsSslStateOK")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index b49ca41b1895d..deacf2b2f9d6e 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -412,10 +412,20 @@ void CryptoNative_SslSetBio(SSL* ssl, BIO* rbio, BIO* wbio) SSL_set_bio(ssl, rbio, wbio); } -int32_t CryptoNative_SslDoHandshake(SSL* ssl) +int32_t CryptoNative_SslDoHandshake(SSL* ssl, int32_t* error) { ERR_clear_error(); - return SSL_do_handshake(ssl); + int32_t result = SSL_do_handshake(ssl); + if (result == 1) + { + *error = SSL_ERROR_NONE; + } + else + { + *error = CryptoNative_SslGetError(ssl, result); + } + + return result; } int32_t CryptoNative_IsSslStateOK(SSL* ssl) diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index faf96988b1b50..6fcae533aa88b 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -259,7 +259,7 @@ Shims the SSL_do_handshake method. and by the specifications of the TLS/SSL protocol; <0 if the handshake was not successful because of a fatal error. */ -PALEXPORT int32_t CryptoNative_SslDoHandshake(SSL* ssl); +PALEXPORT int32_t CryptoNative_SslDoHandshake(SSL* ssl, int32_t* error); /* Gets a value indicating whether the SSL_state is SSL_ST_OK. From 4ea0f2be493cda2b83475bc93d0557db182fd467 Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 3 Feb 2022 10:36:43 -0800 Subject: [PATCH 4/5] remove try --- .../Interop.OpenSsl.cs | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 2c3f9fe61df9e..b06ce6ad87198 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -385,30 +385,23 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, } } - try + int retVal = Ssl.SslDoHandshake(context, out Ssl.SslErrorCode error); + if (retVal != 1) { - int retVal = Ssl.SslDoHandshake(context, out Ssl.SslErrorCode error); - if (retVal != 1) + if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) { - if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) - { - return SecurityStatusPalErrorCode.CredentialsNeeded; - } + return SecurityStatusPalErrorCode.CredentialsNeeded; + } - if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) - { - GetSslError(context, retVal, error, Sys.GetLastErrorInfo(), out Exception? innerError ); + if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) + { + GetSslError(context, retVal, error, Sys.GetLastErrorInfo(), out Exception? innerError ); - // 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); - } + // 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); } } - finally - { - Crypto.ErrClearError(); - } sendCount = Crypto.BioCtrlPending(context.OutputBio!); if (sendCount > 0) From b8fb508a5f4ecd7ee56800a84c57eca9c1d446ea Mon Sep 17 00:00:00 2001 From: wfurt Date: Thu, 3 Feb 2022 15:00:15 -0800 Subject: [PATCH 5/5] feedback from review --- .../Interop.OpenSsl.cs | 49 ++++++------------- .../Interop.Ssl.cs | 6 +-- .../pal_ssl.c | 36 +++++++++++--- .../pal_ssl.h | 6 +-- 4 files changed, 52 insertions(+), 45 deletions(-) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index b06ce6ad87198..180bf5ac83e5e 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -359,13 +359,12 @@ internal static SafeSslHandle AllocateSslHandle(SafeFreeSslCredentials credentia internal static SecurityStatusPal SslRenegotiate(SafeSslHandle sslContext, out byte[]? outputBuffer) { - int ret = Interop.Ssl.SslRenegotiate(sslContext); + int ret = Interop.Ssl.SslRenegotiate(sslContext, out Ssl.SslErrorCode errorCode); outputBuffer = Array.Empty(); if (ret != 1) { - GetSslError(sslContext, ret, out Exception? exception); - return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, exception); + return new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError, GetSslError(ret, errorCode)); } return new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } @@ -385,21 +384,21 @@ internal static SecurityStatusPalErrorCode DoSslHandshake(SafeSslHandle context, } } - int retVal = Ssl.SslDoHandshake(context, out Ssl.SslErrorCode error); + int retVal = Ssl.SslDoHandshake(context, out Ssl.SslErrorCode errorCode); if (retVal != 1) { - if (error == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) + if (errorCode == Ssl.SslErrorCode.SSL_ERROR_WANT_X509_LOOKUP) { return SecurityStatusPalErrorCode.CredentialsNeeded; } - if ((retVal != -1) || (error != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) + if ((retVal != -1) || (errorCode != Ssl.SslErrorCode.SSL_ERROR_WANT_READ)) { - GetSslError(context, retVal, error, Sys.GetLastErrorInfo(), out Exception? innerError ); + Exception? innerError = GetSslError(retVal, errorCode); // 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); + handshakeException = new SslException(SR.Format(SR.net_ssl_handshake_failed_error, errorCode), innerError); } } @@ -448,17 +447,7 @@ internal static int Encrypt(SafeSslHandle context, ReadOnlySpan input, ref ulong assertNoError = Crypto.ErrPeekError(); Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error."); #endif - errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE; - - int retVal; - Exception? innerError = null; - - retVal = Ssl.SslWrite(context, ref MemoryMarshal.GetReference(input), input.Length); - - if (retVal != input.Length) - { - errorCode = GetSslError(context, retVal, out innerError); - } + int retVal = Ssl.SslWrite(context, ref MemoryMarshal.GetReference(input), input.Length, out errorCode); if (retVal != input.Length) { @@ -472,7 +461,7 @@ internal static int Encrypt(SafeSslHandle context, ReadOnlySpan input, ref break; default: - throw new SslException(SR.Format(SR.net_ssl_encrypt_failed, errorCode), innerError); + throw new SslException(SR.Format(SR.net_ssl_encrypt_failed, errorCode), GetSslError(retVal, errorCode)); } } else @@ -502,17 +491,14 @@ internal static int Decrypt(SafeSslHandle context, Span buffer, out Ssl.Ss ulong assertNoError = Crypto.ErrPeekError(); Debug.Assert(assertNoError == 0, $"OpenSsl error queue is not empty, run: 'openssl errstr {assertNoError:X}' for original error."); #endif - errorCode = Ssl.SslErrorCode.SSL_ERROR_NONE; - BioWrite(context.InputBio!, buffer); - int retVal = Ssl.SslRead(context, ref MemoryMarshal.GetReference(buffer), buffer.Length); + int retVal = Ssl.SslRead(context, ref MemoryMarshal.GetReference(buffer), buffer.Length, out errorCode); if (retVal > 0) { return retVal; } - errorCode = GetSslError(context, retVal, out Exception? innerError); switch (errorCode) { // indicate end-of-file @@ -527,7 +513,7 @@ internal static int Decrypt(SafeSslHandle context, Span buffer, out Ssl.Ss break; default: - throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), innerError); + throw new SslException(SR.Format(SR.net_ssl_decrypt_failed, errorCode), GetSslError(retVal, errorCode)); } return 0; @@ -648,17 +634,13 @@ private static void BioWrite(SafeBioHandle bio, ReadOnlySpan buffer) } } - 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 - return GetSslError(context, result, Ssl.SslGetError(context, result), lastErrno, out innerError); - } - - private static Ssl.SslErrorCode GetSslError(SafeSslHandle context, int result, Ssl.SslErrorCode retVal, ErrorInfo lastErrno, out Exception? innerError) + private static Exception? GetSslError(int result, Ssl.SslErrorCode retVal) { + Exception? innerError; switch (retVal) { case Ssl.SslErrorCode.SSL_ERROR_SYSCALL: + ErrorInfo lastErrno = Sys.GetLastErrorInfo(); // Some I/O error occurred innerError = Crypto.ErrPeekError() != 0 ? Crypto.CreateOpenSslCryptographicException() : // crypto error queue not empty @@ -677,7 +659,8 @@ private static Ssl.SslErrorCode GetSslError(SafeSslHandle context, int result, S innerError = null; break; } - return retVal; + + return innerError; } private static void SetSslCertificate(SafeSslContextHandle contextPtr, SafeX509Handle certPtr, SafeEvpPKeyHandle keyPtr) diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs index 038df71264ee8..6ccb1307886f7 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs @@ -75,13 +75,13 @@ internal static partial class Ssl } [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslWrite", SetLastError = true)] - internal static partial int SslWrite(SafeSslHandle ssl, ref byte buf, int num); + internal static partial int SslWrite(SafeSslHandle ssl, ref byte buf, int num, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslRead", SetLastError = true)] - internal static partial int SslRead(SafeSslHandle ssl, ref byte buf, int num); + internal static partial int SslRead(SafeSslHandle ssl, ref byte buf, int num, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslRenegotiate")] - internal static partial int SslRenegotiate(SafeSslHandle ssl); + internal static partial int SslRenegotiate(SafeSslHandle ssl, out SslErrorCode error); [GeneratedDllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_IsSslRenegotiatePending")] [return: MarshalAs(UnmanagedType.Bool)] diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c index deacf2b2f9d6e..bd4cce49d6225 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.c @@ -358,14 +358,34 @@ int32_t CryptoNative_SslSessionReused(SSL* ssl) return SSL_session_reused(ssl) == 1; } -int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num) +int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num, int32_t* error) { - return SSL_write(ssl, buf, num); + int32_t result = SSL_write(ssl, buf, num); + if (result > 0) + { + *error = SSL_ERROR_NONE; + } + else + { + *error = CryptoNative_SslGetError(ssl, result); + } + + return result; } -int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num) +int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num, int32_t* error) { - return SSL_read(ssl, buf, num); + int32_t result = SSL_read(ssl, buf, num); + if (result > 0) + { + *error = SSL_ERROR_NONE; + } + else + { + *error = CryptoNative_SslGetError(ssl, result); + } + + return result; } static int verify_callback(int preverify_ok, X509_STORE_CTX* store) @@ -376,7 +396,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX* store) return 1; } -int32_t CryptoNative_SslRenegotiate(SSL* ssl) +int32_t CryptoNative_SslRenegotiate(SSL* ssl, int32_t* error) { // The openssl context is destroyed so we can't use ticket or session resumption. SSL_set_options(ssl, SSL_OP_NO_TICKET | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); @@ -387,11 +407,15 @@ int32_t CryptoNative_SslRenegotiate(SSL* ssl) SSL_set_verify(ssl, SSL_VERIFY_PEER, verify_callback); int ret = SSL_renegotiate(ssl); if(ret != 1) + { + *error = CryptoNative_SslGetError(ssl, ret); return ret; + } - return SSL_do_handshake(ssl); + return CryptoNative_SslDoHandshake(ssl, error); } + *error = SSL_ERROR_NONE; return 0; } diff --git a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h index 6fcae533aa88b..bdbfed127af99 100644 --- a/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/native/libs/System.Security.Cryptography.Native/pal_ssl.h @@ -211,7 +211,7 @@ Shims the SSL_write method. Returns the positive number of bytes written when successful, 0 or a negative number when an error is encountered. */ -PALEXPORT int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num); +PALEXPORT int32_t CryptoNative_SslWrite(SSL* ssl, const void* buf, int32_t num, int32_t* error); /* Shims the SSL_read method. @@ -219,14 +219,14 @@ Shims the SSL_read method. Returns the positive number of bytes read when successful, 0 or a negative number when an error is encountered. */ -PALEXPORT int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num); +PALEXPORT int32_t CryptoNative_SslRead(SSL* ssl, void* buf, int32_t num, int32_t* error); /* Shims the SSL_renegotiate method. Returns 1 when renegotiation started; 0 on error. */ -PALEXPORT int32_t CryptoNative_SslRenegotiate(SSL* ssl); +PALEXPORT int32_t CryptoNative_SslRenegotiate(SSL* ssl, int32_t* error); /* Shims the SSL_renegotiate_pending method.