Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal interface ISSPIInterface

int QueryContextChannelBinding(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, out SafeFreeContextBufferChannelBinding refHandle);
int QueryContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, Span<byte> buffer, Type? handleType, out SafeHandle? refHandle);
unsafe int QueryContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, IntPtr* refHandle);
int QuerySecurityContextToken(SafeDeleteContext phContext, out SecurityContextTokenHandle phToken);
int CompleteAuthToken(ref SafeDeleteSslContext? refContext, in InputSecurityBuffer inputBuffer);
int ApplyControlToken(ref SafeDeleteSslContext? refContext, in SecurityBuffer inputBuffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ public int QueryContextChannelBinding(SafeDeleteContext context, Interop.SspiCli
throw new NotSupportedException();
}

public unsafe int QueryContextAttributes(SafeDeleteContext context, Interop.SspiCli.ContextAttribute attribute, IntPtr* refHandle)
{
return SafeFreeContextBuffer.QueryContextAttributes(context, attribute, refHandle);
}

public unsafe int QueryContextAttributes(SafeDeleteContext context, Interop.SspiCli.ContextAttribute attribute, Span<byte> buffer, Type? handleType, out SafeHandle? refHandle)
{
refHandle = null;
Expand All @@ -115,10 +120,6 @@ public unsafe int QueryContextAttributes(SafeDeleteContext context, Interop.Sspi
{
refHandle = SafeFreeContextBuffer.CreateEmptyHandle();
}
else if (handleType == typeof(SafeFreeCertContext))
{
refHandle = new SafeFreeCertContext();
}
else
{
throw new ArgumentException(SR.Format(SR.SSPIInvalidHandleType, handleType.FullName), nameof(handleType));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ public unsafe int QueryContextChannelBinding(SafeDeleteContext phContext, Intero
return SafeFreeContextBufferChannelBinding.QueryContextChannelBinding(phContext, attribute, &bindings, refHandle);
}

public unsafe int QueryContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, IntPtr* refHandle)
{
return SafeFreeContextBuffer.QueryContextAttributes(phContext, attribute, refHandle);
}

public unsafe int QueryContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute attribute, Span<byte> buffer, Type? handleType, out SafeHandle? refHandle)
{
refHandle = null;
Expand Down
49 changes: 31 additions & 18 deletions src/libraries/Common/src/Interop/Windows/SspiCli/SSPIWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,29 +270,42 @@ public static bool QueryBlittableContextAttributes<T>(ISSPIInterface secModule,
}
}

private static bool QueryCertContextAttribute(ISSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute attribute, out SafeFreeCertContext? certContext)
private static unsafe bool QueryCertContextAttribute(ISSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute attribute, out SafeFreeCertContext? certContext)
{
Span<IntPtr> buffer = stackalloc IntPtr[1];
int errorCode = secModule.QueryContextAttributes(
securityContext,
attribute,
MemoryMarshal.AsBytes(buffer),
typeof(SafeFreeCertContext),
out SafeHandle? sspiHandle);
IntPtr handle = IntPtr.Zero;
certContext = null;

// certificate is not always present (e.g. on server when querying client certificate)
// but we still want to consider such case as a success.
bool success = errorCode == 0 || errorCode == (int)Interop.SECURITY_STATUS.NoCredentials;
try
{
int errorCode = secModule.QueryContextAttributes(
securityContext,
attribute,
&handle);

// certificate is not always present (e.g. on server when querying client certificate)
// but we still want to consider such case as a success.
bool success = errorCode == 0 || errorCode == (int)Interop.SECURITY_STATUS.NoCredentials;

if (!success)
if (errorCode == 0 && handle != IntPtr.Zero)
{
certContext = new SafeFreeCertContext();
certContext.Set(handle);
// Handle was successfully transferred to SafeHandle
handle = IntPtr.Zero;
}
if (!success)
{
if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, $"ERROR = {ErrorDescription(errorCode)}");
}
return success;
}
finally
{
sspiHandle?.Dispose();
sspiHandle = null;
if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(null, $"ERROR = {ErrorDescription(errorCode)}");
if (handle != IntPtr.Zero)
{
Interop.Crypt32.CertFreeCertificateContext(handle);
}
}

certContext = sspiHandle as SafeFreeCertContext;
return success;
}

public static bool QueryContextAttributes_SECPKG_ATTR_REMOTE_CERT_CONTEXT(ISSPIInterface secModule, SafeDeleteContext securityContext, out SafeFreeCertContext? certContext)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,23 @@ internal static SafeFreeContextBuffer CreateEmptyHandle()
return new SafeFreeContextBuffer_SECURITY();
}

public static unsafe int QueryContextAttributes(SafeDeleteContext phContext, Interop.SspiCli.ContextAttribute contextAttribute, IntPtr* handle)
{
bool mustRelease = false;
try
{
phContext.DangerousAddRef(ref mustRelease);
return Interop.SspiCli.QueryContextAttributesW(ref phContext._handle, contextAttribute, handle);
}
finally
{
if (mustRelease)
{
phContext.DangerousRelease();
}
}
}

//
// After PInvoke call the method will fix the refHandle.handle with the returned value.
// The caller is responsible for creating a correct SafeHandle template or null can be passed if no handle is returned.
Expand Down Expand Up @@ -98,7 +115,7 @@ public static unsafe int QueryContextAttributes(SafeDeleteContext phContext, Int
}
else
{
((SafeFreeCertContext)refHandle).Set(*(IntPtr*)buffer);
Debug.Assert(false);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,9 @@ internal static bool IsLocalCertificateUsed(SafeFreeCredentials? _credentialsHan
SafeFreeCertContext? localContext = null;
try
{
if (SSPIWrapper.QueryContextAttributes_SECPKG_ATTR_LOCAL_CERT_CONTEXT(GlobalSSPI.SSPISecureChannel, securityContext, out localContext) &&
localContext != null)
if (SSPIWrapper.QueryContextAttributes_SECPKG_ATTR_LOCAL_CERT_CONTEXT(GlobalSSPI.SSPISecureChannel, securityContext, out localContext))
{
return !localContext.IsInvalid;
return localContext != null ? !localContext.IsInvalid : false;
}
}
finally
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public static ProtocolToken AcceptSecurityContext(
}

ProtocolToken token = default;
token.RentBuffer = true;

int errorCode = SSPIWrapper.AcceptSecurityContext(
GlobalSSPI.SSPISecureChannel,
Expand Down Expand Up @@ -163,6 +164,7 @@ public static ProtocolToken InitializeSecurityContext(
}

ProtocolToken token = default;
token.RentBuffer = true;
int errorCode = SSPIWrapper.InitializeSecurityContext(
GlobalSSPI.SSPISecureChannel,
ref credentialsHandle,
Expand Down