Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,11 @@ internal static extern Status GetUser(
ref GssBuffer token);

[DllImport(Interop.Libraries.NetSecurityNative, EntryPoint="NetSecurityNative_Wrap")]
private static extern Status Wrap(
private static extern unsafe Status Wrap(
out Status minorStatus,
SafeGssContextHandle? contextHandle,
bool isEncrypt,
byte[] inputBytes,
int offset,
byte* inputBytes,
int count,
ref GssBuffer outBuffer);

Expand All @@ -145,20 +144,17 @@ private static extern Status Unwrap(
int count,
ref GssBuffer outBuffer);

internal static Status WrapBuffer(
internal static unsafe Status WrapBuffer(
out Status minorStatus,
SafeGssContextHandle? contextHandle,
bool isEncrypt,
byte[] inputBytes,
int offset,
int count,
ReadOnlySpan<byte> inputBytes,
ref GssBuffer outBuffer)
{
Debug.Assert(inputBytes != null, "inputBytes must be valid value");
Debug.Assert(offset >= 0 && offset <= inputBytes.Length, "offset must be valid");
Debug.Assert(count >= 0 && count <= (inputBytes.Length - offset), "count must be valid");

return Wrap(out minorStatus, contextHandle, isEncrypt, inputBytes, offset, count, ref outBuffer);
fixed (byte* inputBytesPtr = inputBytes)
{
return Wrap(out minorStatus, contextHandle, isEncrypt, inputBytesPtr, inputBytes.Length, ref outBuffer);
}
}

internal static Status UnwrapBuffer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,13 @@ internal static string QueryContextAuthenticationPackage(SafeDeleteContext secur
private static byte[] GssWrap(
SafeGssContextHandle? context,
bool encrypt,
byte[] buffer,
int offset,
int count)
ReadOnlySpan<byte> buffer)
{
Debug.Assert((buffer != null) && (buffer.Length > 0), "Invalid input buffer passed to Encrypt");
Debug.Assert((offset >= 0) && (offset < buffer.Length), "Invalid input offset passed to Encrypt");
Debug.Assert((count >= 0) && (count <= (buffer.Length - offset)), "Invalid input count passed to Encrypt");

Interop.NetSecurityNative.GssBuffer encryptedBuffer = default(Interop.NetSecurityNative.GssBuffer);
Interop.NetSecurityNative.GssBuffer encryptedBuffer = default;
try
{
Interop.NetSecurityNative.Status minorStatus;
Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.WrapBuffer(out minorStatus, context, encrypt, buffer, offset, count, ref encryptedBuffer);
Interop.NetSecurityNative.Status status = Interop.NetSecurityNative.WrapBuffer(out minorStatus, context, encrypt, buffer, ref encryptedBuffer);
if (status != Interop.NetSecurityNative.Status.GSS_S_COMPLETE)
{
throw new Interop.NetSecurityNative.GssApiException(status, minorStatus);
Expand Down Expand Up @@ -555,16 +549,14 @@ internal static SecurityStatusPal CompleteAuthToken(

internal static int Encrypt(
SafeDeleteContext securityContext,
byte[] buffer,
int offset,
int count,
ReadOnlySpan<byte> buffer,
bool isConfidential,
bool isNtlm,
ref byte[]? output,
[NotNull] ref byte[]? output,
uint sequenceNumber)
{
SafeDeleteNegoContext gssContext = (SafeDeleteNegoContext) securityContext;
byte[] tempOutput = GssWrap(gssContext.GssContext, isConfidential, buffer, offset, count);
byte[] tempOutput = GssWrap(gssContext.GssContext, isConfidential, buffer);

// Create space for prefixing with the length
const int prefixLength = 4;
Expand Down Expand Up @@ -628,7 +620,7 @@ internal static int VerifySignature(SafeDeleteContext securityContext, byte[] bu
internal static int MakeSignature(SafeDeleteContext securityContext, byte[] buffer, int offset, int count, [AllowNull] ref byte[] output)
{
SafeDeleteNegoContext gssContext = (SafeDeleteNegoContext)securityContext;
byte[] tempOutput = GssWrap(gssContext.GssContext, false, buffer, offset, count);
byte[] tempOutput = GssWrap(gssContext.GssContext, false, new ReadOnlySpan<byte>(buffer, offset, count));
// Create space for prefixing with the length
const int prefixLength = 4;
output = new byte[tempOutput.Length + prefixLength];
Expand Down
13 changes: 11 additions & 2 deletions src/libraries/Common/src/System/Threading/Tasks/TaskToApm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#nullable enable
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace System.Threading.Tasks
{
Expand Down Expand Up @@ -43,7 +44,7 @@ public static void End(IAsyncResult asyncResult)
return;
}

throw new ArgumentNullException(nameof(asyncResult));
ThrowArgumentException(asyncResult);
}

/// <summary>Processes an IAsyncResult returned by Begin.</summary>
Expand All @@ -55,9 +56,17 @@ public static TResult End<TResult>(IAsyncResult asyncResult)
return task.GetAwaiter().GetResult();
}

throw new ArgumentNullException(nameof(asyncResult));
ThrowArgumentException(asyncResult);
return default!; // unreachable
}

/// <summary>Throws an argument exception for the invalid <paramref name="asyncResult"/>.</summary>
[DoesNotReturn]
private static void ThrowArgumentException(IAsyncResult asyncResult) =>
throw (asyncResult is null ?
new ArgumentNullException(nameof(asyncResult)) :
new ArgumentException(null, nameof(asyncResult)));

/// <summary>Provides a simple IAsyncResult that wraps a Task.</summary>
/// <remarks>
/// We could use the Task as the IAsyncResult if the Task's AsyncState is the same as the object state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public VirtualNetworkStream(VirtualNetwork network, bool isServer)
_isServer = isServer;
}

public int DelayMilliseconds { get; set; }

public bool Disposed { get; private set; }

public override bool CanRead => true;
Expand Down Expand Up @@ -87,6 +89,11 @@ public override async Task<int> ReadAsync(byte[] buffer, int offset, int count,
await _readStreamLock.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
if (DelayMilliseconds > 0)
{
await Task.Delay(DelayMilliseconds, cancellationToken);
}

if (_readStream == null || (_readStream.Position >= _readStream.Length))
{
_readStream = new MemoryStream(await _network.ReadFrameAsync(_isServer, cancellationToken).ConfigureAwait(false));
Expand All @@ -105,22 +112,16 @@ public override void Write(byte[] buffer, int offset, int count)
_network.WriteFrame(_isServer, buffer.AsSpan(offset, count).ToArray());
}

public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (cancellationToken.IsCancellationRequested)
{
return Task.FromCanceled<int>(cancellationToken);
}
cancellationToken.ThrowIfCancellationRequested();

try
if (DelayMilliseconds > 0)
{
Write(buffer, offset, count);
return Task.CompletedTask;
}
catch (Exception exc)
{
return Task.FromException(exc);
await Task.Delay(DelayMilliseconds, cancellationToken);
}

Write(buffer, offset, count);
}

public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,22 +417,20 @@ uint32_t NetSecurityNative_Wrap(uint32_t* minorStatus,
GssCtxId* contextHandle,
int32_t isEncrypt,
uint8_t* inputBytes,
int32_t offset,
int32_t count,
PAL_GssBuffer* outBuffer)
{
assert(minorStatus != NULL);
assert(contextHandle != NULL);
assert(isEncrypt == 1 || isEncrypt == 0);
assert(inputBytes != NULL);
assert(offset >= 0);
assert(count >= 0);
assert(outBuffer != NULL);
// count refers to the length of the input message. That is, number of bytes of inputBytes
// starting at offset that need to be wrapped.
// that need to be wrapped.

int confState;
GssBuffer inputMessageBuffer = {.length = (size_t)count, .value = inputBytes + offset};
GssBuffer inputMessageBuffer = {.length = (size_t)count, .value = inputBytes};
GssBuffer gssBuffer;
uint32_t majorStatus =
gss_wrap(minorStatus, contextHandle, isEncrypt, GSS_C_QOP_DEFAULT, &inputMessageBuffer, &confState, &gssBuffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ PALEXPORT uint32_t NetSecurityNative_Wrap(uint32_t* minorStatus,
GssCtxId* contextHandle,
int32_t isEncrypt,
uint8_t* inputBytes,
int32_t offset,
int32_t count,
PAL_GssBuffer* outBuffer);

Expand Down
4 changes: 4 additions & 0 deletions src/libraries/System.Net.Security/ref/System.Net.Security.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,13 @@ public override void EndWrite(System.IAsyncResult asyncResult) { }
public override void Flush() { }
public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
public override int Read(byte[] buffer, int offset, int count) { throw null; }
public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<int> ReadAsync(System.Memory<byte> buffer, System.Threading.CancellationToken cancellationToken = default) { throw null; }
public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
public override void SetLength(long value) { }
public override void Write(byte[] buffer, int offset, int count) { }
public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory<byte> buffer, System.Threading.CancellationToken cancellationToken = default) { throw null; }
}
public enum ProtectionLevel
{
Expand Down
21 changes: 7 additions & 14 deletions src/libraries/System.Net.Security/src/System.Net.Security.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,32 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Net\CertificateValidationPal.cs" />
<Compile Include="System\Net\FixedSizeReader.cs" />
<Compile Include="System\Net\HelperAsyncResults.cs" />
<Compile Include="System\Net\Logging\NetEventSource.cs" />
<Compile Include="System\Net\SslStreamContext.cs" />
<Compile Include="System\Net\Security\AuthenticatedStream.cs" />
<Compile Include="System\Security\Authentication\AuthenticationException.cs" />
<Compile Include="System\Net\Security\CipherSuitesPolicy.cs" />
<Compile Include="System\Net\Security\NetEventSource.Security.cs" />
<Compile Include="System\Net\Security\ReadWriteAdapter.cs" />
<Compile Include="System\Net\Security\ProtectionLevel.cs" />
<Compile Include="System\Net\Security\SniHelper.cs" />
<Compile Include="System\Net\Security\SslApplicationProtocol.cs" />
<Compile Include="System\Net\Security\SslAuthenticationOptions.cs" />
<Compile Include="System\Net\Security\SslClientAuthenticationOptions.cs" />
<Compile Include="System\Net\Security\SslServerAuthenticationOptions.cs" />
<Compile Include="System\Net\Security\SslStream.Implementation.Adapters.cs" />
<Compile Include="System\Net\SslStreamContext.cs" />
<Compile Include="System\Net\Security\AuthenticatedStream.cs" />
<Compile Include="System\Net\Security\CipherSuitesPolicy.cs" />
<Compile Include="System\Net\Security\NetEventSource.Security.cs" />
<Compile Include="System\Net\Security\SecureChannel.cs" />
<Compile Include="System\Net\Security\SslSessionsCache.cs" />
<Compile Include="System\Net\Security\SslStream.cs" />
<Compile Include="System\Net\Security\SslStream.Implementation.cs" />
<Compile Include="System\Net\Security\ProtectionLevel.cs" />
<Compile Include="System\Net\Security\SslConnectionInfo.cs" />
<Compile Include="System\Net\Security\StreamSizes.cs" />
<Compile Include="System\Net\Security\TlsAlertType.cs" />
<Compile Include="System\Net\Security\TlsAlertMessage.cs" />
<Compile Include="System\Net\Security\TlsFrameHelper.cs" />
<Compile Include="System\Security\Authentication\AuthenticationException.cs" />
<!-- NegotiateStream -->
<Compile Include="System\Net\BufferAsyncResult.cs" />
<Compile Include="System\Net\NTAuthentication.cs" />
<Compile Include="System\Net\StreamFramer.cs" />
<Compile Include="System\Net\Security\NegotiateStream.cs" />
<Compile Include="System\Net\Security\NegoState.cs" />
<Compile Include="System\Net\Security\InternalNegotiateStream.cs" />
<Compile Include="System\Security\Authentication\ExtendedProtection\ExtendedProtectionPolicy.cs" />
<Compile Include="System\Security\Authentication\ExtendedProtection\PolicyEnforcement.cs" />
<Compile Include="System\Security\Authentication\ExtendedProtection\ProtectionScenario.cs" />
Expand All @@ -65,8 +60,6 @@
</Compile>
<Compile Include="$(CommonPath)System\Net\ExceptionCheck.cs"
Link="Common\System\Net\ExceptionCheck.cs" />
<Compile Include="$(CommonPath)System\Net\LazyAsyncResult.cs"
Link="Common\System\Net\LazyAsyncResult.cs" />
<Compile Include="$(CommonPath)System\Net\SecurityProtocol.cs"
Link="Common\System\Net\SecurityProtocol.cs" />
<Compile Include="$(CommonPath)System\Net\UriScheme.cs"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Net.Security;
using System.Security.Authentication.ExtendedProtection;

Expand Down Expand Up @@ -114,13 +115,11 @@ private static void InitializeCallback(object state)
context.ThisPtr.Initialize(context.IsServer, context.Package, context.Credential, context.Spn, context.RequestedContextFlags, context.ChannelBinding);
}

internal int Encrypt(byte[] buffer, int offset, int count, ref byte[]? output, uint sequenceNumber)
internal int Encrypt(ReadOnlySpan<byte> buffer, [NotNull] ref byte[]? output, uint sequenceNumber)
{
return NegotiateStreamPal.Encrypt(
_securityContext!,
buffer,
offset,
count,
IsConfidentialityFlag,
IsNTLM,
ref output,
Expand Down
Loading