Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilip Navara <navara@emclient.com>2022-06-30 15:19:42 +0300
committerGitHub <noreply@github.com>2022-06-30 15:19:42 +0300
commitac9e1f968050fa5f83a81a62c69e3eb0185975f8 (patch)
tree50a1f5d0d574ec2ab7e01c02f842f6a701e740b5 /src/libraries/System.Net.Security/tests/UnitTests
parent667812e459b135c14486431e4c7f27e770b987fc (diff)
Improve interoperability of NTLM encryption/decryption and authentication (#71373)
* Implement NTLM quirk in NegotiateStreamPal.Encrypt/Decrypt NegotiateStream on non-encrypted connections with NTLM sends the messages in a special `<signature token><plain text message>` format. That's not something that gss_wrap/gss_unwrap would produce. It can be produced through gss_get_mic/gss_verify_mic calls though so let's do that. * Remove MakeSignature/VerifySignature from SspiCli interop The method names were misleading since they wrapped the EncryptMessage and DecryptMessage native APIs and not the MakeSignature/VerifySignature APIs that also exist. * Remove unused sequenceNumber parameters in NegotiateStreamPal.Encrypt/Decrypt The SSPI / GSSAPI providers keep track of the sequence numbers themselves. * Replace NTAuthentication.MakeSignature/VerifySignature with Wrap/Unwrap This maps directly to the semantics of gss_wrap/gss_unwrap methods that are used in many specifications. It replaces the misleading name which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic. It also fixes the declaration to actually decode the buffers both on Windows and Unix. In NTLM the content of the message is sealed and needs to be decoded. Note that previously on Unix the VerifySignature API didn't decode the content. On Windows it did decode the content inside a buffer that was passed as ReadOnlySpan<byte> but it didn't communicate back the offset of the decoded data. The SMTP GSSAPI authentication code was thus reading incorrect data. In case the underlying authentication was Kerberos the data were not encrypted and they were located at the beginning of the buffer so it was not an issue. In case the underlying authentication was NTLM it was looking at the NTLM signature token which luckily happens to always start with the bytes 01 00 00 00. That exactly matched the expected value by accident. * Fix processing of last SMTP GSSAPI token The last token in the GSSAPI SASL authentication mechanism is a bit mask that specifies the supported security protections offered by the server and the maximum token size. The client is supposed to choose one of the protections and reply back. Relax the check to actually support servers that offer anything but "no protection". As long as the server also offers no protection we can choose it. * Update unit test to use the new Wrap/Unwrap APIs * Reset NTLM keys after successful Negotiate authentication Updated the managed NTLM implementation and the fake servers to implement the specification quirk: MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First Signed Message specifies that the RC4 sealing keys are reset back to the initial state for the first message. Since the managed implementation doesn't expose encryption yet it didn't affect any observable behavior. Likewise the fake servers didn't need this code path yet. * Add GSSAPI authentication test to the loopback SMTP server * Workaround for https://github.com/gssapi/gss-ntlmssp/issues/77 * Expose the confidentiality flag from the native gss_wrap/unwrap APIs * Allow default credentials for NTLM server-side on Linux/macOS
Diffstat (limited to 'src/libraries/System.Net.Security/tests/UnitTests')
-rw-r--r--src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs14
1 files changed, 5 insertions, 9 deletions
diff --git a/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs b/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs
index 34c816b867b..da1e4d23e6d 100644
--- a/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs
+++ b/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs
@@ -34,24 +34,20 @@ namespace System.Net.Security.Tests
// Test MakeSignature on client side and decoding it on server side
byte[]? output = null;
- int len = ntAuth.MakeSignature(s_Hello, ref output);
+ int len = ntAuth.Wrap(s_Hello, ref output, true);
Assert.NotNull(output);
Assert.Equal(16 + s_Hello.Length, len);
// Unseal the content and check it
byte[] temp = new byte[s_Hello.Length];
- fakeNtlmServer.Unseal(output.AsSpan(16), temp);
+ fakeNtlmServer.Unwrap(output, temp);
Assert.Equal(s_Hello, temp);
- // Check the signature
- fakeNtlmServer.VerifyMIC(temp, output.AsSpan(0, 16), sequenceNumber: 0);
// Test creating signature on server side and decoding it with VerifySignature on client side
byte[] serverSignedMessage = new byte[16 + s_Hello.Length];
- fakeNtlmServer.Seal(s_Hello, serverSignedMessage.AsSpan(16, s_Hello.Length));
- fakeNtlmServer.GetMIC(s_Hello, serverSignedMessage.AsSpan(0, 16), sequenceNumber: 0);
- len = ntAuth.VerifySignature(serverSignedMessage);
+ fakeNtlmServer.Wrap(s_Hello, serverSignedMessage);
+ len = ntAuth.Unwrap(serverSignedMessage, out int newOffset, out _);
Assert.Equal(s_Hello.Length, len);
- // NOTE: VerifySignature doesn't return the content on Windows
- // Assert.Equal(s_Hello, serverSignedMessage.AsSpan(0, len).ToArray());
+ Assert.Equal(s_Hello, serverSignedMessage.AsSpan(newOffset, len).ToArray());
}
private void DoNtlmExchange(FakeNtlmServer fakeNtlmServer, NTAuthentication ntAuth)