1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //-----------------------------------------------------------------------------
5 namespace System.IdentityModel
7 using System.Runtime.InteropServices;
8 using System.Diagnostics;
9 using System.ComponentModel;
10 using System.Security.Permissions;
11 using System.Globalization;
12 using System.Security.Authentication.ExtendedProtection;
14 using System.Runtime.CompilerServices;
18 internal enum SchProtocols
21 PctClient = 0x00000002,
22 PctServer = 0x00000001,
23 Pct = (PctClient | PctServer),
24 Ssl2Client = 0x00000008,
25 Ssl2Server = 0x00000004,
26 Ssl2 = (Ssl2Client | Ssl2Server),
27 Ssl3Client = 0x00000020,
28 Ssl3Server = 0x00000010,
29 Ssl3 = (Ssl3Client | Ssl3Server),
30 TlsClient = 0x00000080,
31 TlsServer = 0x00000040,
32 Tls = (TlsClient | TlsServer),
33 Ssl3Tls = (Ssl3 | Tls),
34 Tls11Client = 0x00000200,
35 Tls11Server = 0x00000100,
36 Tls11 = (Tls11Client | Tls11Server),
37 Tls12Client = 0x00000800,
38 Tls12Server = 0x00000400,
39 Tls12 = (Tls12Client | Tls12Server),
40 UniClient = unchecked((int)0x80000000),
41 UniServer = 0x40000000,
42 Unified = (UniClient | UniServer),
43 ClientMask = (PctClient | Ssl2Client | Ssl3Client | TlsClient | Tls11Client | Tls12Client | UniClient),
44 ServerMask = (PctServer | Ssl2Server | Ssl3Server | TlsServer | Tls11Server | Tls12Server | UniServer)
51 ClassSignture = (1 << 13),
52 ClassEncrypt = (3 << 13),
53 ClassHash = (4 << 13),
54 ClassKeyXch = (5 << 13),
57 TypeStream = (4 << 9),
65 // want to ensure MD5 is never used
73 [StructLayout(LayoutKind.Sequential)]
74 internal struct SecurityPackageInfo
76 // see SecPkgInfoW in <sspi.h>
77 internal int Capabilities;
78 internal short Version;
80 internal int MaxToken;
82 internal IntPtr Comment;
84 internal static readonly int Size = Marshal.SizeOf(typeof(SecurityPackageInfo));
85 internal static readonly int NameOffest = (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name");
88 [StructLayout(LayoutKind.Sequential)]
89 internal struct LifeSpan_Struct
94 internal static readonly int Size = Marshal.SizeOf(typeof(LifeSpan_Struct));
97 [StructLayout(LayoutKind.Sequential)]
98 internal struct NegotiationInfo
100 // see SecPkgContext_NegotiationInfoW in <sspi.h>
102 // [MarshalAs(UnmanagedType.LPStruct)] internal SecurityPackageInfo PackageInfo;
103 internal IntPtr PackageInfo;
104 internal uint NegotiationState;
105 internal static readonly int Size = Marshal.SizeOf(typeof(NegotiationInfo));
106 internal static readonly int NegotiationStateOffset = (int)Marshal.OffsetOf(typeof(NegotiationInfo), "NegotiationState");
109 // Note: pack=0 since the first member (SessionKeyLength) is C's long (platform dependent).
110 [StructLayout(LayoutKind.Sequential, Pack = 0)]
111 internal struct SecPkgContext_SessionKey
113 //[MarshalAs(UnmanagedType.SysUInt)] internal uint SessionKeyLength;
114 internal uint SessionKeyLength;
115 internal IntPtr Sessionkey;
116 internal static readonly int Size = Marshal.SizeOf(typeof(SecPkgContext_SessionKey));
117 internal static readonly int SessionkeyOffset = (int)Marshal.OffsetOf(typeof(SecPkgContext_SessionKey), "Sessionkey");
120 internal class LifeSpan
122 DateTime effectiveTimeUtc;
123 DateTime expiryTimeUtc;
125 internal DateTime EffectiveTimeUtc
129 return this.effectiveTimeUtc;
133 internal DateTime ExpiryTimeUtc
137 return this.expiryTimeUtc;
141 internal unsafe LifeSpan(byte[] buffer)
143 fixed (byte* pbuffer = &buffer[0])
145 IntPtr ptr = new IntPtr(pbuffer);
146 LifeSpan_Struct lifeSpan = (LifeSpan_Struct)Marshal.PtrToStructure(ptr, typeof(LifeSpan_Struct));
147 // start and end times are expressed as local file times.
148 // however dateTime.FromFileTime* expects the file time to be in UTC.
149 // so we need to add the difference to the DateTime
150 this.effectiveTimeUtc = DateTime.FromFileTimeUtc(lifeSpan.start) + (DateTime.UtcNow - DateTime.Now);
151 this.expiryTimeUtc = DateTime.FromFileTimeUtc(lifeSpan.end) + (DateTime.UtcNow - DateTime.Now);
156 internal class SecurityPackageInfoClass
158 internal int Capabilities = 0;
159 internal short Version = 0;
160 internal short RPCID = 0;
161 internal int MaxToken = 0;
162 internal string Name = null;
163 internal string Comment = null;
165 internal SecurityPackageInfoClass(SafeHandle safeHandle, int index)
167 if (safeHandle.IsInvalid)
171 IntPtr unmanagedAddress = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index);
172 Capabilities = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Capabilities"));
173 Version = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Version"));
174 RPCID = Marshal.ReadInt16(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "RPCID"));
175 MaxToken = Marshal.ReadInt32(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "MaxToken"));
177 IntPtr unmanagedString;
178 unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name"));
179 if (unmanagedString != IntPtr.Zero)
181 Name = Marshal.PtrToStringUni(unmanagedString);
184 unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int)Marshal.OffsetOf(typeof(SecurityPackageInfo), "Comment"));
185 if (unmanagedString != IntPtr.Zero)
188 Comment = Marshal.PtrToStringUni(unmanagedString);
195 // we keep it simple since we use this only to know if NTLM or
196 // Kerberos are used in the context of a Negotiate handshake
197 internal class NegotiationInfoClass
199 internal const string NTLM = "NTLM";
200 internal const string Kerberos = "Kerberos";
201 internal string AuthenticationPackage;
203 internal NegotiationInfoClass(SafeHandle safeHandle, int negotiationState)
205 if (safeHandle.IsInvalid)
209 IntPtr packageInfo = safeHandle.DangerousGetHandle();
211 const int SECPKG_NEGOTIATION_COMPLETE = 0;
212 const int SECPKG_NEGOTIATION_OPTIMISTIC = 1;
213 // const int SECPKG_NEGOTIATION_IN_PROGRESS = 2;
214 // const int SECPKG_NEGOTIATION_DIRECT = 3;
215 // const int SECPKG_NEGOTIATION_TRY_MULTICRED = 4;
217 if (negotiationState == SECPKG_NEGOTIATION_COMPLETE || negotiationState == SECPKG_NEGOTIATION_OPTIMISTIC)
219 IntPtr unmanagedString = Marshal.ReadIntPtr(packageInfo, SecurityPackageInfo.NameOffest);
221 if (unmanagedString != IntPtr.Zero)
223 name = Marshal.PtrToStringUni(unmanagedString);
225 // an optimization for future string comparisons
226 if (string.Compare(name, "Kerberos", StringComparison.OrdinalIgnoreCase) == 0)
228 AuthenticationPackage = Kerberos;
230 else if (string.Compare(name, "NTLM", StringComparison.OrdinalIgnoreCase) == 0)
232 AuthenticationPackage = NTLM;
236 AuthenticationPackage = name;
242 internal class SecuritySessionKeyClass
246 internal SecuritySessionKeyClass(SafeHandle safeHandle, int sessionKeyLength)
248 byte[] sessionKey = new byte[sessionKeyLength];
249 Marshal.Copy(safeHandle.DangerousGetHandle(), sessionKey, 0, sessionKeyLength);
250 this.sessionKey = sessionKey;
253 internal byte[] SessionKey
255 get { return this.sessionKey; }
259 [StructLayout(LayoutKind.Sequential)]
260 internal class StreamSizes
264 public int maximumMessage;
265 public int buffersCount;
266 public int blockSize;
268 internal unsafe StreamSizes(byte[] memory)
270 fixed (void* voidPtr = memory)
272 IntPtr unmanagedAddress = new IntPtr(voidPtr);
273 header = Marshal.ReadInt32(unmanagedAddress);
274 trailer = Marshal.ReadInt32(unmanagedAddress, 4);
275 maximumMessage = Marshal.ReadInt32(unmanagedAddress, 8);
276 buffersCount = Marshal.ReadInt32(unmanagedAddress, 12);
277 blockSize = Marshal.ReadInt32(unmanagedAddress, 16);
280 public static readonly int SizeOf = Marshal.SizeOf(typeof(StreamSizes));
283 internal static class SspiWrapper
285 const int SECPKG_FLAG_NEGOTIABLE2 = 0x00200000;
287 static SecurityPackageInfoClass[] securityPackages;
289 public static SecurityPackageInfoClass[] SecurityPackages
293 return securityPackages;
297 securityPackages = value;
301 static SecurityPackageInfoClass[] EnumerateSecurityPackages()
303 if (SecurityPackages != null)
305 return SecurityPackages;
309 SafeFreeContextBuffer arrayBaseHandle = null;
312 int errorCode = SafeFreeContextBuffer.EnumeratePackages(out moduleCount, out arrayBaseHandle);
315 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
318 SecurityPackageInfoClass[] securityPackages = new SecurityPackageInfoClass[moduleCount];
319 for (int i = 0; i < moduleCount; i++)
321 securityPackages[i] = new SecurityPackageInfoClass(arrayBaseHandle, i);
323 SecurityPackages = securityPackages;
327 if (arrayBaseHandle != null)
329 arrayBaseHandle.Close();
333 return SecurityPackages;
336 public static SecurityPackageInfoClass GetVerifyPackageInfo(string packageName)
338 SecurityPackageInfoClass[] supportedSecurityPackages = EnumerateSecurityPackages();
339 if (supportedSecurityPackages != null)
341 for (int i = 0; i < supportedSecurityPackages.Length; i++)
343 if (String.Compare(supportedSecurityPackages[i].Name, packageName, StringComparison.OrdinalIgnoreCase) == 0)
345 return supportedSecurityPackages[i];
350 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SSPIPackageNotSupported, packageName)));
353 public static bool IsNegotiateExPackagePresent()
355 SecurityPackageInfoClass[] supportedSecurityPackages = EnumerateSecurityPackages();
357 if (supportedSecurityPackages != null)
359 int nego2FlagIntValue = (int)SECPKG_FLAG_NEGOTIABLE2;
361 for (int i = 0; i < supportedSecurityPackages.Length; i++)
363 // if the package is a nego2 package
364 if ((supportedSecurityPackages[i].Capabilities & nego2FlagIntValue) != 0)
374 public static SafeFreeCredentials AcquireDefaultCredential(
376 CredentialUse intent,
377 params string[] additionalPackages)
379 SafeFreeCredentials outCredential = null;
380 AuthIdentityEx authIdentity = new AuthIdentityEx(null, null, null, additionalPackages);
381 int errorCode = SafeFreeCredentials.AcquireDefaultCredential(package, intent, ref authIdentity, out outCredential);
384 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
386 return outCredential;
389 public static SafeFreeCredentials AcquireCredentialsHandle(
391 CredentialUse intent,
392 ref AuthIdentityEx authdata)
394 SafeFreeCredentials credentialsHandle = null;
395 int errorCode = SafeFreeCredentials.AcquireCredentialsHandle(package,
398 out credentialsHandle
402 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
404 return credentialsHandle;
407 public static SafeFreeCredentials AcquireCredentialsHandle(
409 CredentialUse intent,
410 SecureCredential scc)
412 SafeFreeCredentials outCredential = null;
413 int errorCode = SafeFreeCredentials.AcquireCredentialsHandle(
421 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
423 return outCredential;
426 public static SafeFreeCredentials AcquireCredentialsHandle(
428 CredentialUse intent,
429 ref IntPtr ppAuthIdentity)
431 SafeFreeCredentials outCredential = null;
432 int errorCode = SafeFreeCredentials.AcquireCredentialsHandle(
440 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
442 return outCredential;
445 internal static int InitializeSecurityContext(
446 SafeFreeCredentials credential,
447 ref SafeDeleteContext context,
449 SspiContextFlags inFlags,
451 SecurityBuffer inputBuffer,
452 SecurityBuffer outputBuffer,
453 ref SspiContextFlags outFlags)
455 return SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, inputBuffer, null, outputBuffer, ref outFlags);
458 internal static int InitializeSecurityContext(
459 SafeFreeCredentials credential,
460 ref SafeDeleteContext context,
462 SspiContextFlags inFlags,
464 SecurityBuffer[] inputBuffers,
465 SecurityBuffer outputBuffer,
466 ref SspiContextFlags outFlags)
468 return SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags);
471 internal static int AcceptSecurityContext(
472 SafeFreeCredentials credential,
473 ref SafeDeleteContext refContext,
474 SspiContextFlags inFlags,
476 SecurityBuffer inputBuffer,
477 SecurityBuffer outputBuffer,
478 ref SspiContextFlags outFlags)
480 return SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, inputBuffer, null, outputBuffer, ref outFlags);
483 internal static int AcceptSecurityContext(
484 SafeFreeCredentials credential,
485 ref SafeDeleteContext refContext,
486 SspiContextFlags inFlags,
488 SecurityBuffer[] inputBuffers,
489 SecurityBuffer outputBuffer,
490 ref SspiContextFlags outFlags)
492 return SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags);
495 public static int QuerySecurityContextToken(
496 SafeDeleteContext context,
497 out SafeCloseHandle token)
499 return context.GetSecurityContextToken(out token);
502 static unsafe int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute attribute, byte[] buffer, Type handleType, out SafeHandle refHandle)
505 if (handleType != null)
507 if (handleType == typeof(SafeFreeContextBuffer))
509 refHandle = SafeFreeContextBuffer.CreateEmptyHandle();
511 else if (handleType == typeof(SafeFreeCertContext))
513 refHandle = new SafeFreeCertContext();
517 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("handleType", SR.GetString(SR.ValueMustBeOf2Types, typeof(SafeFreeContextBuffer).ToString(), typeof(SafeFreeCertContext).ToString())));
520 fixed (byte* bufferPtr = buffer)
522 return SafeFreeContextBuffer.QueryContextAttributes(phContext, attribute, bufferPtr, refHandle);
526 public static unsafe object QueryContextAttributes(
527 SafeDeleteContext securityContext,
528 ContextAttribute contextAttribute)
530 int nativeBlockSize = IntPtr.Size;
531 Type handleType = null;
533 switch (contextAttribute)
535 case ContextAttribute.Flags:
537 case ContextAttribute.Sizes:
538 nativeBlockSize = SecSizes.SizeOf;
540 case ContextAttribute.StreamSizes:
541 nativeBlockSize = StreamSizes.SizeOf;
543 case ContextAttribute.Names:
544 handleType = typeof(SafeFreeContextBuffer);
546 case ContextAttribute.PackageInfo:
547 handleType = typeof(SafeFreeContextBuffer);
549 case ContextAttribute.NegotiationInfo:
550 handleType = typeof(SafeFreeContextBuffer);
551 nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo));
553 case ContextAttribute.RemoteCertificate:
554 handleType = typeof(SafeFreeCertContext);
556 case ContextAttribute.LocalCertificate:
557 handleType = typeof(SafeFreeCertContext);
559 case ContextAttribute.ConnectionInfo:
560 nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo));
562 case ContextAttribute.Lifespan:
563 nativeBlockSize = LifeSpan_Struct.Size;
565 case ContextAttribute.SessionKey:
566 handleType = typeof(SafeFreeContextBuffer);
567 nativeBlockSize = SecPkgContext_SessionKey.Size;
570 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int)contextAttribute,
571 typeof(ContextAttribute)));
574 SafeHandle sspiHandle = null;
575 object attribute = null;
578 byte[] nativeBuffer = new byte[nativeBlockSize];
579 int errorCode = QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
582 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
585 switch (contextAttribute)
587 case ContextAttribute.Flags:
588 fixed (byte* pnativeBuffer = nativeBuffer)
590 attribute = (object)Marshal.ReadInt32(new IntPtr(pnativeBuffer));
593 case ContextAttribute.Sizes:
594 attribute = new SecSizes(nativeBuffer);
596 case ContextAttribute.StreamSizes:
597 attribute = new StreamSizes(nativeBuffer);
599 case ContextAttribute.Names:
600 attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
602 case ContextAttribute.PackageInfo:
603 attribute = new SecurityPackageInfoClass(sspiHandle, 0);
605 case ContextAttribute.NegotiationInfo:
608 fixed (void* ptr = nativeBuffer)
610 attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffset));
614 case ContextAttribute.LocalCertificate:
615 goto case ContextAttribute.RemoteCertificate;
616 case ContextAttribute.RemoteCertificate:
617 attribute = sspiHandle;
620 case ContextAttribute.ConnectionInfo:
621 attribute = new SslConnectionInfo(nativeBuffer);
623 case ContextAttribute.Lifespan:
624 attribute = new LifeSpan(nativeBuffer);
626 case ContextAttribute.SessionKey:
629 fixed (void* ptr = nativeBuffer)
631 attribute = new SecuritySessionKeyClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr)));
642 if (sspiHandle != null)
651 /// Queries the security context for the target name (SPN for kerb)
653 /// <param name="securityContext">security context to query</param>
654 /// <param name="specifiedTarget">output parameter for the name</param>
655 /// <returns>the status code returned from querying the context</returns>
656 public static unsafe int QuerySpecifiedTarget(SafeDeleteContext securityContext, out string specifiedTarget)
658 int nativeBlockSize = IntPtr.Size;
659 Type handleType = typeof(SafeFreeContextBuffer);
660 SafeHandle sspiHandle = null;
663 specifiedTarget = null;
666 byte[] nativeBuffer = new byte[nativeBlockSize];
667 errorCode = QueryContextAttributes(securityContext, ContextAttribute.SpecifiedTarget, nativeBuffer, handleType, out sspiHandle);
668 if (errorCode != (int)SecurityStatus.OK)
673 specifiedTarget = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle()) as string;
677 if (sspiHandle != null)
685 public static void ImpersonateSecurityContext(
686 SafeDeleteContext context)
688 int errorCode = SafeDeleteContext.ImpersonateSecurityContext(context);
689 if (errorCode != (int)SecurityStatus.OK)
691 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
695 public static unsafe int EncryptDecryptHelper(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool encrypt, bool isGssBlob)
697 SecurityBufferDescriptor sdcInOut = new SecurityBufferDescriptor(input.Length);
698 SecurityBufferStruct[] unmanagedBuffer = new SecurityBufferStruct[input.Length];
699 byte[][] buffers = new byte[input.Length][];
700 fixed (void* unmanagedBufferPtr = unmanagedBuffer)
702 sdcInOut.UnmanagedPointer = unmanagedBufferPtr;
703 GCHandle[] pinnedBuffers = new GCHandle[input.Length];
706 for (int i = 0; i < input.Length; ++i)
708 SecurityBuffer iBuffer = input[i];
709 unmanagedBuffer[i].count = iBuffer.size;
710 unmanagedBuffer[i].type = iBuffer.type;
711 if (iBuffer.token == null || iBuffer.token.Length == 0)
713 unmanagedBuffer[i].token = IntPtr.Zero;
717 pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned);
718 unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset);
719 buffers[i] = iBuffer.token;
725 errorCode = SafeDeleteContext.EncryptMessage(context, sdcInOut, sequenceNumber);
729 errorCode = SafeDeleteContext.DecryptMessage(context, sdcInOut, sequenceNumber);
731 // Marshalling back returned sizes (do not marshal the "token" field)
732 for (int i = 0; i < input.Length; ++i)
734 SecurityBuffer iBuffer = input[i];
735 iBuffer.size = unmanagedBuffer[i].count;
736 iBuffer.type = unmanagedBuffer[i].type;
737 if (iBuffer.size == 0)
740 iBuffer.token = null;
742 else if (isGssBlob && !encrypt && iBuffer.type == BufferType.Data)
744 iBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(iBuffer.size);
745 Marshal.Copy(unmanagedBuffer[i].token, iBuffer.token, 0, iBuffer.size);
749 // Find the buffer this is inside of. Usually they all point inside buffer 0.
751 for (j = 0; j < input.Length; j++)
753 if (buffers[j] == null)
758 byte* bufferAddress = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0);
759 if ((byte*)unmanagedBuffer[i].token >= bufferAddress &&
760 (byte*)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length)
762 iBuffer.offset = (int)((byte*)unmanagedBuffer[i].token - bufferAddress);
763 iBuffer.token = buffers[j];
768 if (j >= input.Length)
772 iBuffer.token = null;
774 if (!(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length)))
776 DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset));
777 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset)));
780 if (!(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset)))
782 DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size));
783 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size)));
791 for (int i = 0; i < pinnedBuffers.Length; ++i)
793 if (pinnedBuffers[i].IsAllocated)
795 pinnedBuffers[i].Free();
802 public static unsafe int EncryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber)
804 return EncryptDecryptHelper(context, input, sequenceNumber, true, false);
807 public static unsafe int DecryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool isGssBlob)
809 return EncryptDecryptHelper(context, input, sequenceNumber, false, isGssBlob);
812 public static unsafe uint SspiPromptForCredential(string targetName, string packageName, out IntPtr ppAuthIdentity, ref bool saveCredentials)
814 CREDUI_INFO credui_Info = new CREDUI_INFO();
815 credui_Info.cbSize = Marshal.SizeOf(typeof(CREDUI_INFO));
817 credui_Info.pszCaptionText = SR.GetString(SR.SspiLoginPromptHeaderMessage); // Login
818 credui_Info.pszMessageText = "";
819 uint retCode = uint.MaxValue;
820 retCode = NativeMethods.SspiPromptForCredentials(targetName, ref credui_Info, 0, packageName, IntPtr.Zero, out ppAuthIdentity, ref saveCredentials, 0);
824 public static unsafe bool IsSspiPromptingNeeded(uint ErrorOrNtStatus)
826 return NativeMethods.SspiIsPromptingNeeded(ErrorOrNtStatus);
829 //public static string ErrorDescription(int errorCode)
831 // if (errorCode == -1)
833 // return "An exception when invoking Win32 API";
835 // switch ((SecurityStatus) errorCode)
837 // case SecurityStatus.InvalidHandle:
838 // return "Invalid handle";
839 // case SecurityStatus.InvalidToken:
840 // return "Invalid token";
841 // case SecurityStatus.ContinueNeeded:
842 // return "Continue needed";
843 // case SecurityStatus.IncompleteMessage:
844 // return "Message incomplete";
845 // case SecurityStatus.WrongPrincipal:
846 // return "Wrong principal";
847 // case SecurityStatus.TargetUnknown:
848 // return "Target unknown";
849 // case SecurityStatus.PackageNotFound:
850 // return "Package not found";
851 // case SecurityStatus.BufferNotEnough:
852 // return "Buffer not enough";
853 // case SecurityStatus.MessageAltered:
854 // return "Message altered";
855 // case SecurityStatus.UntrustedRoot:
856 // return "Untrusted root";
858 // return "0x" + errorCode.ToString("x", NumberFormatInfo.InvariantInfo);
864 [StructLayout(LayoutKind.Sequential)]
865 internal class SslConnectionInfo
867 public readonly int Protocol;
868 public readonly int DataCipherAlg;
869 public readonly int DataKeySize;
870 public readonly int DataHashAlg;
871 public readonly int DataHashKeySize;
872 public readonly int KeyExchangeAlg;
873 public readonly int KeyExchKeySize;
875 internal unsafe SslConnectionInfo(byte[] nativeBuffer)
877 fixed (void* voidPtr = nativeBuffer)
879 IntPtr unmanagedAddress = new IntPtr(voidPtr);
880 Protocol = Marshal.ReadInt32(unmanagedAddress);
881 DataCipherAlg = Marshal.ReadInt32(unmanagedAddress, 4);
882 DataKeySize = Marshal.ReadInt32(unmanagedAddress, 8);
883 DataHashAlg = Marshal.ReadInt32(unmanagedAddress, 12);
884 DataHashKeySize = Marshal.ReadInt32(unmanagedAddress, 16);
885 KeyExchangeAlg = Marshal.ReadInt32(unmanagedAddress, 20);
886 KeyExchKeySize = Marshal.ReadInt32(unmanagedAddress, 24);
891 [StructLayout(LayoutKind.Sequential)]
892 internal class SecSizes
895 public int MaxSignature;
896 public int BlockSize;
897 public int SecurityTrailer;
899 internal unsafe SecSizes(byte[] memory)
901 fixed (void* voidPtr = memory)
903 IntPtr unmanagedAddress = new IntPtr(voidPtr);
904 MaxToken = Marshal.ReadInt32(unmanagedAddress);
905 MaxSignature = Marshal.ReadInt32(unmanagedAddress, 4);
906 BlockSize = Marshal.ReadInt32(unmanagedAddress, 8);
907 SecurityTrailer = Marshal.ReadInt32(unmanagedAddress, 12);
910 public static readonly int SizeOf = Marshal.SizeOf(typeof(SecSizes));
913 [StructLayout(LayoutKind.Sequential)]
914 internal struct Bindings
916 // see SecPkgContext_Bindings in <sspi.h>
917 internal int BindingsLength;
918 internal IntPtr pBindings;