int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref SafeSspiAuthDataHandle authdata, out SafeFreeCredentials outCredential);
int AcquireCredentialsHandle(string moduleName, Interop.SspiCli.CredentialUse usage, ref Interop.SspiCli.SCHANNEL_CRED authdata, out SafeFreeCredentials outCredential);
int AcquireDefaultCredential(string moduleName, Interop.SspiCli.CredentialUse usage, out SafeFreeCredentials outCredential);
- int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, ReadOnlySpan<SecurityBuffer> inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags);
- int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ReadOnlySpan<SecurityBuffer> inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags);
+ int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags);
+ int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags);
int EncryptMessage(SafeDeleteContext context, ref Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber);
int DecryptMessage(SafeDeleteContext context, ref Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber);
int MakeSignature(SafeDeleteContext context, ref Interop.SspiCli.SecBufferDesc inputOutput, uint sequenceNumber);
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
}
- public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, ReadOnlySpan<SecurityBuffer> inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
+ public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
{
return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags);
}
- public int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ReadOnlySpan<SecurityBuffer> inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
+ public int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
{
return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags);
}
return SafeFreeCredentials.AcquireCredentialsHandle(moduleName, usage, ref authdata, out outCredential);
}
- public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, ReadOnlySpan<SecurityBuffer> inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
+ public int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteSslContext context, InputSecurityBuffers inputBuffers, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
{
return SafeDeleteContext.AcceptSecurityContext(ref credential, ref context, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags);
}
- public int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, ReadOnlySpan<SecurityBuffer> inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
+ public int InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness endianness, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
{
return SafeDeleteContext.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, endianness, inputBuffers, ref outputBuffer, ref outFlags);
}
return outCredential;
}
- internal static int InitializeSecurityContext(ISSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, ReadOnlySpan<SecurityBuffer> inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
+ internal static int InitializeSecurityContext(ISSPIInterface secModule, ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
{
if (NetEventSource.IsEnabled) NetEventSource.Log.InitializeSecurityContext(credential, context, targetName, inFlags);
int errorCode = secModule.InitializeSecurityContext(ref credential, ref context, targetName, inFlags, datarep, inputBuffers, ref outputBuffer, ref outFlags);
- if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffers(nameof(InitializeSecurityContext), inputBuffers.Length, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode);
+ if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffers(nameof(InitializeSecurityContext), inputBuffers.Count, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode);
return errorCode;
}
- internal static int AcceptSecurityContext(ISSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteSslContext context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, ReadOnlySpan<SecurityBuffer> inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
+ internal static int AcceptSecurityContext(ISSPIInterface secModule, SafeFreeCredentials credential, ref SafeDeleteSslContext context, Interop.SspiCli.ContextFlags inFlags, Interop.SspiCli.Endianness datarep, InputSecurityBuffers inputBuffers, ref SecurityBuffer outputBuffer, ref Interop.SspiCli.ContextFlags outFlags)
{
if (NetEventSource.IsEnabled) NetEventSource.Log.AcceptSecurityContext(credential, context, inFlags);
int errorCode = secModule.AcceptSecurityContext(credential, ref context, inputBuffers, inFlags, datarep, ref outputBuffer, ref outFlags);
- if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), inputBuffers.Length, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode);
+ if (NetEventSource.IsEnabled) NetEventSource.Log.SecurityContextInputBuffers(nameof(AcceptSecurityContext), inputBuffers.Count, outputBuffer.size, (Interop.SECURITY_STATUS)errorCode);
return errorCode;
}
string targetName,
Interop.SspiCli.ContextFlags inFlags,
Interop.SspiCli.Endianness endianness,
- ReadOnlySpan<SecurityBuffer> inSecBuffers,
+ InputSecurityBuffers inSecBuffers,
ref SecurityBuffer outSecBuffer,
ref Interop.SspiCli.ContextFlags outFlags)
{
throw new ArgumentNullException(nameof(inCredentials));
}
- Interop.SspiCli.SecBufferDesc inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Length);
+ Debug.Assert(inSecBuffers.Count <= 3);
+ Interop.SspiCli.SecBufferDesc inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Count);
Interop.SspiCli.SecBufferDesc outSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(1);
// Actually, this is returned in outFlags.
SafeFreeContextBuffer outFreeContextBuffer = null;
try
{
- Span<Interop.SspiCli.SecBuffer> inUnmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[inSecurityBufferDescriptor.cBuffers];
- inUnmanagedBuffer.Clear();
+ Span<Interop.SspiCli.SecBuffer> inUnmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[3];
fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
- fixed (void* pinnedToken0 = inSecBuffers.Length > 0 ? inSecBuffers[0].token : null)
- fixed (void* pinnedToken1 = inSecBuffers.Length > 1 ? inSecBuffers[1].token : null)
- fixed (void* pinnedToken2 = inSecBuffers.Length > 2 ? inSecBuffers[2].token : null) // pin all buffers, even if null or not used, to avoid needing to allocate GCHandles
+ fixed (void* pinnedToken0 = inSecBuffers._item0.Token)
+ fixed (void* pinnedToken1 = inSecBuffers._item1.Token)
+ fixed (void* pinnedToken2 = inSecBuffers._item2.Token)
{
- Debug.Assert(inSecBuffers.Length <= 3);
-
// Fix Descriptor pointer that points to unmanaged SecurityBuffers.
inSecurityBufferDescriptor.pBuffers = inUnmanagedBufferPtr;
- for (int index = 0; index < inSecurityBufferDescriptor.cBuffers; ++index)
+ // Updated pvBuffer with pinned address. UnmanagedToken takes precedence.
+ if (inSecBuffers.Count > 2)
{
- ref readonly SecurityBuffer securityBuffer = ref inSecBuffers[index];
+ inUnmanagedBuffer[2].BufferType = inSecBuffers._item2.Type;
+ inUnmanagedBuffer[2].cbBuffer = inSecBuffers._item2.Token.Length;
+ inUnmanagedBuffer[2].pvBuffer = inSecBuffers._item2.UnmanagedToken != null ?
+ (IntPtr)inSecBuffers._item2.UnmanagedToken.DangerousGetHandle() :
+ (IntPtr)pinnedToken2;
+ }
- // Copy the SecurityBuffer content into unmanaged place holder.
- inUnmanagedBuffer[index].cbBuffer = securityBuffer.size;
- inUnmanagedBuffer[index].BufferType = securityBuffer.type;
-
- // Use the unmanaged token if it's not null; otherwise use the managed buffer.
- inUnmanagedBuffer[index].pvBuffer =
- securityBuffer.unmanagedToken != null ? securityBuffer.unmanagedToken.DangerousGetHandle() :
- securityBuffer.token == null || securityBuffer.token.Length == 0 ? IntPtr.Zero :
- Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
-#if TRACE_VERBOSE
- if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"SecBuffer: cbBuffer:{securityBuffer.size} BufferType:{securityBuffer.type}");
-#endif
+ if (inSecBuffers.Count > 1)
+ {
+ inUnmanagedBuffer[1].BufferType = inSecBuffers._item1.Type;
+ inUnmanagedBuffer[1].cbBuffer = inSecBuffers._item1.Token.Length;
+ inUnmanagedBuffer[1].pvBuffer = inSecBuffers._item1.UnmanagedToken != null ?
+ (IntPtr)inSecBuffers._item1.UnmanagedToken.DangerousGetHandle() :
+ (IntPtr)pinnedToken1;
+ }
+
+ if (inSecBuffers.Count > 0)
+ {
+ inUnmanagedBuffer[0].BufferType = inSecBuffers._item0.Type;
+ inUnmanagedBuffer[0].cbBuffer = inSecBuffers._item0.Token.Length;
+ inUnmanagedBuffer[0].pvBuffer = inSecBuffers._item0.UnmanagedToken != null ?
+ (IntPtr)inSecBuffers._item0.UnmanagedToken.DangerousGetHandle() :
+ (IntPtr)pinnedToken0;
}
fixed (byte* pinnedOutBytes = outSecBuffer.token)
ref SafeDeleteSslContext refContext,
Interop.SspiCli.ContextFlags inFlags,
Interop.SspiCli.Endianness endianness,
- ReadOnlySpan<SecurityBuffer> inSecBuffers,
+ InputSecurityBuffers inSecBuffers,
ref SecurityBuffer outSecBuffer,
ref Interop.SspiCli.ContextFlags outFlags)
{
throw new ArgumentNullException(nameof(inCredentials));
}
- Interop.SspiCli.SecBufferDesc inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Length);
+ Debug.Assert(inSecBuffers.Count <= 3);
+ Interop.SspiCli.SecBufferDesc inSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(inSecBuffers.Count);
Interop.SspiCli.SecBufferDesc outSecurityBufferDescriptor = new Interop.SspiCli.SecBufferDesc(count: 2);
// Actually, this is returned in outFlags.
outUnmanagedBuffer[1].pvBuffer = IntPtr.Zero;
try
{
- Span<Interop.SspiCli.SecBuffer> inUnmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[inSecurityBufferDescriptor.cBuffers];
- inUnmanagedBuffer.Clear();
+ // Allocate always maximum to allow better code optimization.
+ Span<Interop.SspiCli.SecBuffer> inUnmanagedBuffer = stackalloc Interop.SspiCli.SecBuffer[3];
fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer)
- fixed (void* pinnedToken0 = inSecBuffers.Length > 0 ? inSecBuffers[0].token : null)
- fixed (void* pinnedToken1 = inSecBuffers.Length > 1 ? inSecBuffers[1].token : null)
- fixed (void* pinnedToken2 = inSecBuffers.Length > 2 ? inSecBuffers[2].token : null) // pin all buffers, even if null or not used, to avoid needing to allocate GCHandles
+ fixed (void* pinnedToken0 = inSecBuffers._item0.Token)
+ fixed (void* pinnedToken1 = inSecBuffers._item1.Token)
+ fixed (void* pinnedToken2 = inSecBuffers._item2.Token)
{
- Debug.Assert(inSecBuffers.Length <= 3);
-
- // Fix Descriptor pointer that points to unmanaged SecurityBuffers.
inSecurityBufferDescriptor.pBuffers = inUnmanagedBufferPtr;
- for (int index = 0; index < inSecurityBufferDescriptor.cBuffers; ++index)
+ // Updated pvBuffer with pinned address. UnmanagedToken takes precedence.
+ if (inSecBuffers.Count > 2)
{
- ref readonly SecurityBuffer securityBuffer = ref inSecBuffers[index];
+ inUnmanagedBuffer[2].BufferType = inSecBuffers._item2.Type;
+ inUnmanagedBuffer[2].cbBuffer = inSecBuffers._item2.Token.Length;
+ inUnmanagedBuffer[2].pvBuffer = inSecBuffers._item2.UnmanagedToken != null ?
+ (IntPtr)inSecBuffers._item2.UnmanagedToken.DangerousGetHandle() :
+ (IntPtr)pinnedToken2;
+ }
- // Copy the SecurityBuffer content into unmanaged place holder.
- inUnmanagedBuffer[index].cbBuffer = securityBuffer.size;
- inUnmanagedBuffer[index].BufferType = securityBuffer.type;
-
- // Use the unmanaged token if it's not null; otherwise use the managed buffer.
- inUnmanagedBuffer[index].pvBuffer =
- securityBuffer.unmanagedToken != null ? securityBuffer.unmanagedToken.DangerousGetHandle() :
- securityBuffer.token == null || securityBuffer.token.Length == 0 ? IntPtr.Zero :
- Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
-#if TRACE_VERBOSE
- if (NetEventSource.IsEnabled) NetEventSource.Info(null, $"SecBuffer: cbBuffer:{securityBuffer.size} BufferType:{securityBuffer.type}");
-#endif
+ if (inSecBuffers.Count > 1)
+ {
+ inUnmanagedBuffer[1].BufferType = inSecBuffers._item1.Type;
+ inUnmanagedBuffer[1].cbBuffer = inSecBuffers._item1.Token.Length;
+ inUnmanagedBuffer[1].pvBuffer = inSecBuffers._item1.UnmanagedToken != null ?
+ (IntPtr)inSecBuffers._item1.UnmanagedToken.DangerousGetHandle() :
+ (IntPtr)pinnedToken1;
+ }
+
+ if (inSecBuffers.Count > 0)
+ {
+ inUnmanagedBuffer[0].BufferType = inSecBuffers._item0.Type;
+ inUnmanagedBuffer[0].cbBuffer = inSecBuffers._item0.Token.Length;
+ inUnmanagedBuffer[0].pvBuffer = inSecBuffers._item0.UnmanagedToken != null ?
+ (IntPtr)inSecBuffers._item0.UnmanagedToken.DangerousGetHandle() :
+ (IntPtr)pinnedToken0;
}
fixed (byte* pinnedOutBytes = outSecBuffer.token)
ref byte[] resultBlob,
ref ContextFlagsPal contextFlags)
{
-#if NETSTANDARD2_0
- Span<SecurityBuffer> inSecurityBufferSpan = new SecurityBuffer[2];
-#else
- TwoSecurityBuffers twoSecurityBuffers = default;
- Span<SecurityBuffer> inSecurityBufferSpan = MemoryMarshal.CreateSpan(ref twoSecurityBuffers._item0, 2);
-#endif
- int inSecurityBufferSpanLength = 0;
- if (incomingBlob != null && channelBinding != null)
+ InputSecurityBuffers inputBuffers = default;
+ if (incomingBlob != null)
{
- inSecurityBufferSpan[0] = new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN);
- inSecurityBufferSpan[1] = new SecurityBuffer(channelBinding);
- inSecurityBufferSpanLength = 2;
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN));
}
- else if (incomingBlob != null)
- {
- inSecurityBufferSpan[0] = new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN);
- inSecurityBufferSpanLength = 1;
- }
- else if (channelBinding != null)
+
+ if (channelBinding != null)
{
- inSecurityBufferSpan[0] = new SecurityBuffer(channelBinding);
- inSecurityBufferSpanLength = 1;
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(channelBinding));
}
- inSecurityBufferSpan = inSecurityBufferSpan.Slice(0, inSecurityBufferSpanLength);
var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN);
spn,
ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags),
Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP,
- inSecurityBufferSpan,
+ inputBuffers,
ref outSecurityBuffer,
ref outContextFlags);
securityContext = sslContext;
ref byte[] resultBlob,
ref ContextFlagsPal contextFlags)
{
-#if NETSTANDARD2_0
- Span<SecurityBuffer> inSecurityBufferSpan = new SecurityBuffer[2];
-#else
- TwoSecurityBuffers twoSecurityBuffers = default;
- Span<SecurityBuffer> inSecurityBufferSpan = MemoryMarshal.CreateSpan(ref twoSecurityBuffers._item0, 2);
-#endif
-
- int inSecurityBufferSpanLength = 0;
- if (incomingBlob != null && channelBinding != null)
+ InputSecurityBuffers inputBuffers = default;
+ if (incomingBlob != null)
{
- inSecurityBufferSpan[0] = new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN);
- inSecurityBufferSpan[1] = new SecurityBuffer(channelBinding);
- inSecurityBufferSpanLength = 2;
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN));
}
- else if (incomingBlob != null)
- {
- inSecurityBufferSpan[0] = new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN);
- inSecurityBufferSpanLength = 1;
- }
- else if (channelBinding != null)
+
+ if (channelBinding != null)
{
- inSecurityBufferSpan[0] = new SecurityBuffer(channelBinding);
- inSecurityBufferSpanLength = 1;
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(channelBinding));
}
- inSecurityBufferSpan = inSecurityBufferSpan.Slice(0, inSecurityBufferSpanLength);
var outSecurityBuffer = new SecurityBuffer(resultBlob, SecurityBufferType.SECBUFFER_TOKEN);
ref sslContext,
ContextFlagsAdapterPal.GetInteropFromContextFlagsPal(requestedContextFlags),
Interop.SspiCli.Endianness.SECURITY_NETWORK_DREP,
- inSecurityBufferSpan,
+ inputBuffers,
ref outSecurityBuffer,
ref outContextFlags);
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Authentication.ExtendedProtection;
private SecurityBuffer _item2;
}
+ [StructLayout(LayoutKind.Sequential)]
+ internal ref struct InputSecurityBuffers
+ {
+ internal int Count;
+ internal InputSecurityBuffer _item0;
+ internal InputSecurityBuffer _item1;
+ internal InputSecurityBuffer _item2;
+
+ internal void SetNextBuffer(InputSecurityBuffer buffer)
+ {
+ Debug.Assert(Count >= 0 && Count < 3);
+ if (Count == 0)
+ {
+ _item0 = buffer;
+ }
+ else if (Count == 1)
+ {
+ _item1 = buffer;
+ }
+ else
+ {
+ _item2 = buffer;
+ }
+
+ Count++;
+ }
+ }
+
+ [StructLayout(LayoutKind.Auto)]
+ internal readonly ref struct InputSecurityBuffer
+ {
+ public readonly SecurityBufferType Type;
+ public readonly ReadOnlySpan<byte> Token;
+ public readonly SafeHandle UnmanagedToken;
+
+ public InputSecurityBuffer(ReadOnlySpan<byte> data, SecurityBufferType tokentype)
+ {
+ Token = data;
+ Type = tokentype;
+ UnmanagedToken = null;
+ }
+
+ public InputSecurityBuffer(ChannelBinding binding)
+ {
+ Type = SecurityBufferType.SECBUFFER_CHANNEL_BINDINGS;
+ Token = default;
+ UnmanagedToken = binding;
+ }
+ }
+
[StructLayout(LayoutKind.Auto)]
internal struct SecurityBuffer
{
SecurityStatusPal status = default;
bool cachedCreds = false;
byte[] thumbPrint = null;
+ ReadOnlySpan<byte> inputBuffer = new ReadOnlySpan<byte>(input, offset, count);
//
// Looping through ASC or ISC with potentially cached credential that could have been
if (_refreshCredentialNeeded)
{
cachedCreds = _sslAuthenticationOptions.IsServer
- ? AcquireServerCredentials(ref thumbPrint, new ReadOnlySpan<byte>(input, offset, count))
+ ? AcquireServerCredentials(ref thumbPrint, inputBuffer)
: AcquireClientCredentials(ref thumbPrint);
}
status = SslStreamPal.AcceptSecurityContext(
ref _credentialsHandle,
ref _securityContext,
- input, offset, count,
+ inputBuffer,
ref result,
_sslAuthenticationOptions);
}
ref _credentialsHandle,
ref _securityContext,
_sslAuthenticationOptions.TargetHost,
- input, offset, count,
+ inputBuffer,
ref result,
_sslAuthenticationOptions);
}
public static SecurityStatusPal AcceptSecurityContext(
ref SafeFreeCredentials credential,
ref SafeDeleteSslContext context,
- byte[] inputBuffer, int offset, int count,
+ ReadOnlySpan<byte> inputBuffer,
ref byte[] outputBuffer,
SslAuthenticationOptions sslAuthenticationOptions)
{
- return HandshakeInternal(credential, ref context, new ReadOnlySpan<byte>(inputBuffer, offset, count), ref outputBuffer, sslAuthenticationOptions);
+ return HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions);
}
public static SecurityStatusPal InitializeSecurityContext(
ref SafeFreeCredentials credential,
ref SafeDeleteSslContext context,
string targetName,
- byte[] inputBuffer, int offset, int count,
+ ReadOnlySpan<byte> inputBuffer,
ref byte[] outputBuffer,
SslAuthenticationOptions sslAuthenticationOptions)
{
- return HandshakeInternal(credential, ref context, new ReadOnlySpan<byte>(inputBuffer, offset, count), ref outputBuffer, sslAuthenticationOptions);
+ return HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions);
}
public static SafeFreeCredentials AcquireCredentialsHandle(
}
public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context,
- byte[] inputBuffer, int offset, int count, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
+ ReadOnlySpan<byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
{
- return HandshakeInternal(credential, ref context, new ReadOnlySpan<byte>(inputBuffer, offset, count), ref outputBuffer, sslAuthenticationOptions);
+ return HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions);
}
public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credential, ref SafeDeleteSslContext context, string targetName,
- byte[] inputBuffer, int offset, int count, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
+ ReadOnlySpan<byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
{
- return HandshakeInternal(credential, ref context, new ReadOnlySpan<byte>(inputBuffer, offset, count), ref outputBuffer, sslAuthenticationOptions);
+ return HandshakeInternal(credential, ref context, inputBuffer, ref outputBuffer, sslAuthenticationOptions);
}
public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate,
return Interop.Sec_Application_Protocols.ToByteArray(protocols);
}
- public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteSslContext context, byte[] inputBuffer, int offset, int count, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
+ public static SecurityStatusPal AcceptSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteSslContext context, ReadOnlySpan<byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
{
Interop.SspiCli.ContextFlags unusedAttributes = default;
- ArraySegment<byte> input = inputBuffer != null ? new ArraySegment<byte>(inputBuffer, offset, count) : default;
- ThreeSecurityBuffers threeSecurityBuffers = default;
- SecurityBuffer? incomingSecurity = input.Array != null ?
- new SecurityBuffer(input.Array, input.Offset, input.Count, SecurityBufferType.SECBUFFER_TOKEN) :
- (SecurityBuffer?)null;
- Span<SecurityBuffer> inputBuffers = MemoryMarshal.CreateSpan(ref threeSecurityBuffers._item0, 3);
- GetIncomingSecurityBuffers(sslAuthenticationOptions, in incomingSecurity, ref inputBuffers);
+ InputSecurityBuffers inputBuffers = default;
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(inputBuffer, SecurityBufferType.SECBUFFER_TOKEN));
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(default, SecurityBufferType.SECBUFFER_EMPTY));
+
+ if (sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0)
+ {
+ byte[] alpnBytes = ConvertAlpnProtocolListToByteArray(sslAuthenticationOptions.ApplicationProtocols);
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(new ReadOnlySpan<byte>(alpnBytes), SecurityBufferType.SECBUFFER_APPLICATION_PROTOCOLS));
+ }
var resultBuffer = new SecurityBuffer(outputBuffer, SecurityBufferType.SECBUFFER_TOKEN);
return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode);
}
- public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteSslContext context, string targetName, byte[] inputBuffer, int offset, int count, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
+ public static SecurityStatusPal InitializeSecurityContext(ref SafeFreeCredentials credentialsHandle, ref SafeDeleteSslContext context, string targetName, ReadOnlySpan<byte> inputBuffer, ref byte[] outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
{
Interop.SspiCli.ContextFlags unusedAttributes = default;
- ArraySegment<byte> input = inputBuffer != null ? new ArraySegment<byte>(inputBuffer, offset, count) : default;
- ThreeSecurityBuffers threeSecurityBuffers = default;
- SecurityBuffer? incomingSecurity = input.Array != null ?
- new SecurityBuffer(input.Array, input.Offset, input.Count, SecurityBufferType.SECBUFFER_TOKEN) :
- (SecurityBuffer?)null;
- Span<SecurityBuffer> inputBuffers = MemoryMarshal.CreateSpan(ref threeSecurityBuffers._item0, 3);
- GetIncomingSecurityBuffers(sslAuthenticationOptions, in incomingSecurity, ref inputBuffers);
+ InputSecurityBuffers inputBuffers = default;
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(inputBuffer, SecurityBufferType.SECBUFFER_TOKEN));
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(default, SecurityBufferType.SECBUFFER_EMPTY));
+ if (sslAuthenticationOptions.ApplicationProtocols != null && sslAuthenticationOptions.ApplicationProtocols.Count != 0)
+ {
+ byte[] alpnBytes = ConvertAlpnProtocolListToByteArray(sslAuthenticationOptions.ApplicationProtocols);
+ inputBuffers.SetNextBuffer(new InputSecurityBuffer(new ReadOnlySpan<byte>(alpnBytes), SecurityBufferType.SECBUFFER_APPLICATION_PROTOCOLS));
+ }
var resultBuffer = new SecurityBuffer(outputBuffer, SecurityBufferType.SECBUFFER_TOKEN);
return SecurityStatusAdapterPal.GetSecurityStatusPalFromNativeInt(errorCode);
}
- private static void GetIncomingSecurityBuffers(SslAuthenticationOptions options, in SecurityBuffer? incomingSecurity, ref Span<SecurityBuffer> incomingSecurityBuffers)
- {
- SecurityBuffer? alpnBuffer = null;
-
- if (options.ApplicationProtocols != null && options.ApplicationProtocols.Count != 0)
- {
- byte[] alpnBytes = ConvertAlpnProtocolListToByteArray(options.ApplicationProtocols);
- alpnBuffer = new SecurityBuffer(alpnBytes, 0, alpnBytes.Length, SecurityBufferType.SECBUFFER_APPLICATION_PROTOCOLS);
- }
-
- if (incomingSecurity != null)
- {
- if (alpnBuffer != null)
- {
- Debug.Assert(incomingSecurityBuffers.Length >= 3);
- incomingSecurityBuffers[0] = incomingSecurity.GetValueOrDefault();
- incomingSecurityBuffers[1] = new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY);
- incomingSecurityBuffers[2] = alpnBuffer.GetValueOrDefault();
- incomingSecurityBuffers = incomingSecurityBuffers.Slice(0, 3);
- }
- else
- {
- Debug.Assert(incomingSecurityBuffers.Length >= 2);
- incomingSecurityBuffers[0] = incomingSecurity.GetValueOrDefault();
- incomingSecurityBuffers[1] = new SecurityBuffer(null, 0, 0, SecurityBufferType.SECBUFFER_EMPTY);
- incomingSecurityBuffers = incomingSecurityBuffers.Slice(0, 2);
- }
- }
- else if (alpnBuffer != null)
- {
- incomingSecurityBuffers[0] = alpnBuffer.GetValueOrDefault();
- incomingSecurityBuffers = incomingSecurityBuffers.Slice(0, 1);
- }
- else
- {
- incomingSecurityBuffers = default;
- }
- }
-
public static SafeFreeCredentials AcquireCredentialsHandle(X509Certificate certificate, SslProtocols protocols, EncryptionPolicy policy, bool isServer)
{
int protocolFlags = GetProtocolFlagsFromSslProtocols(protocols, isServer);