Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Reducing chances of polluting SSL error queue #29351

Merged
merged 4 commits into from
May 1, 2018

Conversation

pjanotti
Copy link
Contributor

@pjanotti pjanotti commented Apr 26, 2018

This merges my sample change with some changes coded by @bartonjs.

If errors were being ignored the typical approach is for adding a managed wrapper that P/Invokes the native PAL and clear the error there, alternatively it could have been done on the native but per conversation, @bartonjs asked for consistency and to make it in managed.

In a few cases it is more economical (in terms of # of lines changed) to do everything on the code calling the PAL methods, e.g.: single call can clean up multiple methods. In other situations this is required to keep the current exceptions unchanged and still having something to report. Some errors related to OOM on the native PAL were being ignored and likely causing failures later, these now should throw with proper exception. A few changes to the native PAL were required either to return errors to managed or in a special case clean-up the errors that were ignored.

A wider refactoring regarding error handling for usage of OpenSsl is desirable in the future (perhaps when upgrading to newer version of OpenSsl). This change is tactical with the goal of being relatively low risk while reducing the risk of, self-inflicted, spurious SslStream errors during Write/Read.

@@ -382,6 +382,7 @@ private static bool VerifyCertChain(SafeX509StoreCtxHandle storeCtx, EasyRequest

// X509_verify_cert can return < 0 in the case of programmer error
Debug.Assert(sslResult == 0, "Unexpected error from X509_verify_cert: " + sslResult);
Interop.Crypto.ErrClearError();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only be necessary if the result wasn't 0. (No need to grab the lock when it isn't needed)

@bartonjs
Copy link
Member

What happened to the src/Native/Unix/System.Security.Cryptography.Native/pal_ecc_import_export.cpp and the src/System.Security.Cryptography.Algorithms/tests/DefaultECDiffieHellmanProvider.Unix.cs (and ECDSA tests) changes?

@pjanotti
Copy link
Contributor Author

@pjanotti
Copy link
Contributor Author

pjanotti commented Apr 26, 2018

@dotnet-bot test Outerloop Linux x64 Debug
@dotnet-bot test OSX x64 Debug

@bartonjs
Copy link
Member

The Interop.Crypto in the test projects isn't the same Interop.Crypto, so you still need the fixes there.

And it looks like Interop.Crypto.EcKeyCreateByKeyParameters doesn't clear the error queue before throwing a PNSE. (And... apparently... neglects to throw at all if rc was 0; though the caller would catch it as an invalid key handle and throw)

@bartonjs
Copy link
Member

The Interop.Crypto in the test projects isn't the same Interop.Crypto, so you still need the fixes there.

Though, applying logic: if all we care about is SslStream-correctness, the crypto algorithms tests aren't really a risk for that. If the tests mess themselves up, I guess that's their own problem.

@pjanotti
Copy link
Contributor Author

Thanks for pointing the location that I missed.

@@ -242,6 +246,10 @@ internal static bool DoSslHandshake(SafeSslHandle context, byte[] recvBuf, int r

internal static int Encrypt(SafeSslHandle context, ReadOnlyMemory<byte> input, ref byte[] output, out Ssl.SslErrorCode errorCode)
{
#if DEBUG
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this when I separated a larger PR into smaller clean ups for SSL. I will add something to capture the whole error queue but perhaps not on this PR.

@pjanotti
Copy link
Contributor Author

@dotnet-bot test this

// If it ever happens, ensure the error queue gets cleared.
// And since it didn't write the data, reporting an exception is good too.
throw CreateOpenSslCryptographicException();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Presumably we're asserting because it's never possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is more on the paranoid side but at least for one of the encode delegates called via this method the OpenSsl docs states the following: "This may be fixed in future so code should not assume that i2d_X509() will always succeed." - granted that it is in the context of not fully initialized struct.

@bartonjs what is your take here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on the goals. We've never seen the assert fire, so this is probabilisticly dead code.

Under weird not-supported multi-threading modes, though, maybe one of the values being sent to Encode is capable of failing; and that would then cause an error to show up in SslStream.

If we're going for "perfect" then this is warranted. If we're going for "probabilistic" then it isn't.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's go for "asymptotically perfect" ...

@@ -171,7 +187,8 @@ internal static RSAParameters ExportRsaParameters(SafeRsaHandle key, bool includ
out IntPtr iqmp);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SetRsaParameters")]
internal static extern void SetRsaParameters(
[return: MarshalAs(UnmanagedType.Bool)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this MarshalAs necessary? Isn't this the default marshaling for a bool?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fair I actually don't know I just followed the pattern from other declarations... I will check this during the day.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not required, but with the exception of 2 "CryptoNative_*" all extern bool have the MarshalAs - unless there is a cost associated to it I would say to keep it for consistency.

@@ -49,7 +49,8 @@ internal static partial class Ssl
private static extern IntPtr SslGetVersion(SafeSslHandle ssl);

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_SslSetTlsExtHostName")]
internal static extern int SslSetTlsExtHostName(SafeSslHandle ssl, string host);
[return: MarshalAs(UnmanagedType.Bool)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question for all of these.

@pjanotti
Copy link
Contributor Author

@dotnet-bot test Outerloop Linux x64 Debug Build
@dotnet-bot test Outerloop Linux x64 Release Build

@pjanotti
Copy link
Contributor Author

pjanotti commented May 1, 2018

Failure in Outerloop Linux x64 Debug (SLES.12.Amd64.Open-x64) was unrelated: https://mc.dot.net/#/user/pjanotti/pr~2Fjenkins~2Fdotnet~2Fcorefx~2Fmaster~2F/test~2Ffunctional~2Fcli~2F/3911d5ff2777d9acc68901aa5372b3b1707aa466/workItem/System.Net.NameResolution.Functional.Tests

Doing another round, just to get more runs with the changes:
@dotnet-bot test Outerloop Linux x64 Debug Build
@dotnet-bot test Outerloop Linux x64 Release Build

@pjanotti
Copy link
Contributor Author

pjanotti commented May 1, 2018

One more round just for extra precaution:
@dotnet-bot test Outerloop Linux x64 Debug Build
@dotnet-bot test Outerloop Linux x64 Release Build

@pjanotti pjanotti merged commit f95b511 into dotnet:master May 1, 2018
pjanotti pushed a commit to pjanotti/corefx that referenced this pull request May 1, 2018
* 1st pass to reduce chances of polluting SSL error queue

* Remove extra line added by mistake

* PR feedback: remove 1 unneeded ErrClearError

* PR feedback (1 missed clean up) + Assert that was missed from earlier PR
pjanotti pushed a commit that referenced this pull request May 2, 2018
* Reducing chances of polluting SSL error queue (#29351)
tmds added a commit to tmds/corefx that referenced this pull request May 30, 2018
stephentoub pushed a commit that referenced this pull request Jun 5, 2018
* Skip certificates we can't read when populating machine store.

This is a regression in 2.1.0 (#29351).

Fixes https://github.com/dotnet/corefx/issues/29942.

* Add test

* Assert chmod returns 0

* Skip test on OSX

* Add valid content to the unreadable cert file
stephentoub pushed a commit to stephentoub/corefx that referenced this pull request Jun 5, 2018
…t#29973)

* Skip certificates we can't read when populating machine store.

This is a regression in 2.1.0 (dotnet#29351).

Fixes https://github.com/dotnet/corefx/issues/29942.

* Add test

* Assert chmod returns 0

* Skip test on OSX

* Add valid content to the unreadable cert file
filipnavara pushed a commit to filipnavara/corefx that referenced this pull request Jun 25, 2018
…t#29973)

* Skip certificates we can't read when populating machine store.

This is a regression in 2.1.0 (dotnet#29351).

Fixes https://github.com/dotnet/corefx/issues/29942.

* Add test

* Assert chmod returns 0

* Skip test on OSX

* Add valid content to the unreadable cert file
marek-safar pushed a commit to mono/corefx that referenced this pull request Jun 25, 2018
…t#29973)

* Skip certificates we can't read when populating machine store.

This is a regression in 2.1.0 (dotnet#29351).

Fixes https://github.com/dotnet/corefx/issues/29942.

* Add test

* Assert chmod returns 0

* Skip test on OSX

* Add valid content to the unreadable cert file
stephentoub added a commit that referenced this pull request Jun 26, 2018
… (#30155)

* Skip certificates we can't read when populating machine store.

This is a regression in 2.1.0 (#29351).

Fixes https://github.com/dotnet/corefx/issues/29942.

* Add test

* Assert chmod returns 0

* Skip test on OSX

* Add valid content to the unreadable cert file
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* 1st pass to reduce chances of polluting SSL error queue

* Remove extra line added by mistake

* PR feedback: remove 1 unneeded ErrClearError

* PR feedback (1 missed clean up) + Assert that was missed from earlier PR


Commit migrated from dotnet/corefx@f95b511
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…t/corefx#29973)

* Skip certificates we can't read when populating machine store.

This is a regression in 2.1.0 (dotnet/corefx#29351).

Fixes https://github.com/dotnet/corefx/issues/29942.

* Add test

* Assert chmod returns 0

* Skip test on OSX

* Add valid content to the unreadable cert file


Commit migrated from dotnet/corefx@ca9e224
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants