@msdn=http://search.microsoft.com/search/results.aspx?qu=$$$ @pinvoke=http://pinvoke.net/$$$.htm Summary: TODO - a short description !!!!C# Signature: [DllImport("secur32.dll", SetLastError=true)] static extern int InitializeSecurityContext(ref SECURITY_HANDLE phCredential,//PCredHandle IntPtr phContext, //PCtxtHandle string pszTargetName, int fContextReq, int Reserved1, int TargetDataRep, IntPtr pInput, //PSecBufferDesc SecBufferDesc int Reserved2, out SECURITY_HANDLE phNewContext, //PCtxtHandle out SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc out uint pfContextAttr, //managed ulong == 64 bits!!! out SECURITY_INTEGER ptsExpiry); //PTimeStamp !!!!VB Signature: <DllImport("secur32", CharSet:=CharSet.Auto, SetLastError:=True)> _ Private Shared Function InitializeSecurityContext(ByRef phCredential As SECURITY_HANDLE, _ ByVal phContext As IntPtr, _ ByVal pszTargetName As String, _ ByVal fContextReq As Integer, _ ByVal Reserved1 As Integer, _ ByVal TargetDataRep As Integer, _ ByVal pInput As IntPtr, _ ByVal Reserved2 As Integer, _ ByRef phNewContext As SECURITY_HANDLE, _ ByRef pOutput As SecBufferDesc, _ ByRef pfContextAttr As UInteger, _ ByRef ptsExpiry As SECURITY_INTEGER) As Integer End Function !!!!User-Defined Types: None. !!!!Notes: Check out complete program below.... Contributed by http://dotnetjunkies.com/weblog/dotnetruminator !!!!Tips & Tricks: Please add some! !!!!Sample Code: #region Using directives using System; using System.Text; #endregion using System.Collections; using System.Security.Principal; using System.Diagnostics; using System.Runtime.InteropServices; using System.Net.Sockets; using TestMe; using HANDLE = System.IntPtr; public enum SecBufferType { SECBUFFER_VERSION = 0, SECBUFFER_EMPTY = 0, SECBUFFER_DATA = 1, SECBUFFER_TOKEN = 2 } [StructLayout(LayoutKind.Sequential)] public struct SecHandle //=PCtxtHandle { IntPtr dwLower; // ULONG_PTR translates to IntPtr not to uint IntPtr dwUpper; // this is crucial for 64-Bit Platforms } [StructLayout(LayoutKind.Sequential)] public struct SecBuffer : IDisposable { public int cbBuffer; public int BufferType; public IntPtr pvBuffer; public SecBuffer(int bufferSize) { cbBuffer = bufferSize; BufferType = (int)SecBufferType.SECBUFFER_TOKEN; pvBuffer = Marshal.AllocHGlobal(bufferSize); } public SecBuffer(byte[] secBufferBytes) { cbBuffer = secBufferBytes.Length; BufferType = (int)SecBufferType.SECBUFFER_TOKEN; pvBuffer = Marshal.AllocHGlobal(cbBuffer); Marshal.Copy(secBufferBytes,0,pvBuffer,cbBuffer); } public SecBuffer(byte[] secBufferBytes,SecBufferType bufferType) { cbBuffer = secBufferBytes.Length; BufferType = (int)bufferType; pvBuffer = Marshal.AllocHGlobal(cbBuffer); Marshal.Copy(secBufferBytes,0,pvBuffer,cbBuffer); } public void Dispose() { if(pvBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pvBuffer); pvBuffer = IntPtr.Zero; } } } public struct MultipleSecBufferHelper { public byte[] Buffer; public SecBufferType BufferType; public MultipleSecBufferHelper(byte[] buffer,SecBufferType bufferType) { if(buffer == null || buffer.Length == 0) { throw new ArgumentException("buffer cannot be null or 0 length"); } Buffer = buffer; BufferType = bufferType; } }; [StructLayout(LayoutKind.Sequential)] public struct SecBufferDesc : IDisposable { public int ulVersion; public int cBuffers; public IntPtr pBuffers; //Point to SecBuffer public SecBufferDesc(int bufferSize) { ulVersion = (int)SecBufferType.SECBUFFER_VERSION; cBuffers = 1; SecBuffer ThisSecBuffer = new SecBuffer(bufferSize); pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer)); Marshal.StructureToPtr(ThisSecBuffer,pBuffers,false); } public SecBufferDesc(byte[] secBufferBytes) { ulVersion = (int)SecBufferType.SECBUFFER_VERSION; cBuffers = 1; SecBuffer ThisSecBuffer = new SecBuffer(secBufferBytes); pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(ThisSecBuffer)); Marshal.StructureToPtr(ThisSecBuffer,pBuffers,false); } public SecBufferDesc(MultipleSecBufferHelper[] secBufferBytesArray) { if(secBufferBytesArray == null || secBufferBytesArray.Length == 0) { throw new ArgumentException("secBufferBytesArray cannot be null or 0 length"); } ulVersion = (int)SecBufferType.SECBUFFER_VERSION; cBuffers = secBufferBytesArray.Length; //Allocate memory for SecBuffer Array.... pBuffers = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecBuffer)) * cBuffers); for(int Index = 0;Index < secBufferBytesArray.Length;Index++) { //Super hack: Now allocate memory for the individual SecBuffers //and just copy the bit values to the SecBuffer array!!! SecBuffer ThisSecBuffer = new SecBuffer(secBufferBytesArray[Index].Buffer,secBufferBytesArray[Index].BufferType); //We will write out bits in the following order: //int cbBuffer; //int BufferType; //pvBuffer; //Note that we won't be releasing the memory allocated by ThisSecBuffer until we //are disposed... int CurrentOffset = Index*Marshal.SizeOf(typeof(SecBuffer)); Marshal.WriteInt32(pBuffers,CurrentOffset,ThisSecBuffer.cbBuffer); Marshal.WriteInt32(pBuffers,CurrentOffset + Marshal.SizeOf(ThisSecBuffer.cbBuffer),ThisSecBuffer.BufferType); Marshal.WriteIntPtr(pBuffers,CurrentOffset + Marshal.SizeOf(ThisSecBuffer.cbBuffer)+Marshal.SizeOf(ThisSecBuffer.BufferType),ThisSecBuffer.pvBuffer); } } public void Dispose() { if(pBuffers != IntPtr.Zero) { if(cBuffers == 1) { SecBuffer ThisSecBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers,typeof(SecBuffer)); ThisSecBuffer.Dispose(); } else { for(int Index = 0;Index < cBuffers;Index++) { //The bits were written out the following order: //int cbBuffer; //int BufferType; //pvBuffer; //What we need to do here is to grab a hold of the pvBuffer allocate by the individual //SecBuffer and release it... int CurrentOffset = Index*Marshal.SizeOf(typeof(SecBuffer)); IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers,CurrentOffset + Marshal.SizeOf(typeof(int))+Marshal.SizeOf(typeof(int))); Marshal.FreeHGlobal(SecBufferpvBuffer); } } Marshal.FreeHGlobal(pBuffers); pBuffers = IntPtr.Zero; } } public byte[] GetSecBufferByteArray() { byte[] Buffer = null; if(pBuffers == IntPtr.Zero) { throw new InvalidOperationException("Object has already been disposed!!!"); } if(cBuffers == 1) { SecBuffer ThisSecBuffer = (SecBuffer)Marshal.PtrToStructure(pBuffers,typeof(SecBuffer)); if(ThisSecBuffer.cbBuffer > 0) { Buffer = new byte[ThisSecBuffer.cbBuffer]; Marshal.Copy(ThisSecBuffer.pvBuffer,Buffer,0,ThisSecBuffer.cbBuffer); } } else { int BytesToAllocate = 0; for(int Index = 0;Index < cBuffers;Index++) { //The bits were written out the following order: //int cbBuffer; //int BufferType; //pvBuffer; //What we need to do here calculate the total number of bytes we need to copy... int CurrentOffset = Index*Marshal.SizeOf(typeof(SecBuffer)); BytesToAllocate += Marshal.ReadInt32(pBuffers,CurrentOffset); } Buffer = new byte[BytesToAllocate]; for(int Index = 0,BufferIndex = 0;Index < cBuffers;Index++) { //The bits were written out the following order: //int cbBuffer; //int BufferType; //pvBuffer; //Now iterate over the individual buffers and put them together into a //byte array... int CurrentOffset = Index*Marshal.SizeOf(typeof(SecBuffer)); int BytesToCopy = Marshal.ReadInt32(pBuffers,CurrentOffset); IntPtr SecBufferpvBuffer = Marshal.ReadIntPtr(pBuffers,CurrentOffset + Marshal.SizeOf(typeof(int))+Marshal.SizeOf(typeof(int))); Marshal.Copy(SecBufferpvBuffer,Buffer,BufferIndex,BytesToCopy); BufferIndex += BytesToCopy; } } return(Buffer); } /*public SecBuffer GetSecBuffer() { if(pBuffers == IntPtr.Zero) { throw new InvalidOperationException("Object has already been disposed!!!"); } return((SecBuffer)Marshal.PtrToStructure(pBuffers,typeof(SecBuffer))); }*/ } [StructLayout(LayoutKind.Sequential)] public struct SECURITY_INTEGER { public uint LowPart; public int HighPart; public SECURITY_INTEGER(int dummy) { LowPart = 0; HighPart = 0; } }; [StructLayout(LayoutKind.Sequential)] public struct SECURITY_HANDLE { public IntPtr LowPart; public IntPtr HighPart; public SECURITY_HANDLE(int dummy) { LowPart = HighPart = IntPtr.Zero; } }; [StructLayout(LayoutKind.Sequential)] public struct SecPkgContext_Sizes { public uint cbMaxToken; public uint cbMaxSignature; public uint cbBlockSize; public uint cbSecurityTrailer; }; namespace SSPITest { public class SSPIHelper { public const int TOKEN_QUERY = 0x00008; public const int SEC_E_OK = 0; public const int SEC_I_CONTINUE_NEEDED = 0x90312; const int SECPKG_CRED_OUTBOUND = 2; const int SECURITY_NATIVE_DREP = 0x10; const int SECPKG_CRED_INBOUND = 1; const int MAX_TOKEN_SIZE = 12288; //For AcquireCredentialsHandle in 3er Parameter "fCredentialUse" SECURITY_HANDLE _hInboundCred = new SECURITY_HANDLE(0); public SECURITY_HANDLE _hServerContext = new SECURITY_HANDLE(0); SECURITY_HANDLE _hOutboundCred = new SECURITY_HANDLE(0); public SECURITY_HANDLE _hClientContext = new SECURITY_HANDLE(0); public const int ISC_REQ_DELEGATE = 0x00000001; public const int ISC_REQ_MUTUAL_AUTH = 0x00000002; public const int ISC_REQ_REPLAY_DETECT = 0x00000004; public const int ISC_REQ_SEQUENCE_DETECT = 0x00000008; public const int ISC_REQ_CONFIDENTIALITY = 0x00000010; public const int ISC_REQ_USE_SESSION_KEY = 0x00000020; public const int ISC_REQ_PROMPT_FOR_CREDS = 0x00000040; public const int ISC_REQ_USE_SUPPLIED_CREDS = 0x00000080; public const int ISC_REQ_ALLOCATE_MEMORY = 0x00000100; public const int ISC_REQ_USE_DCE_STYLE = 0x00000200; public const int ISC_REQ_DATAGRAM = 0x00000400; public const int ISC_REQ_CONNECTION = 0x00000800; public const int ISC_REQ_CALL_LEVEL = 0x00001000; public const int ISC_REQ_FRAGMENT_SUPPLIED = 0x00002000; public const int ISC_REQ_EXTENDED_ERROR = 0x00004000; public const int ISC_REQ_STREAM = 0x00008000; public const int ISC_REQ_INTEGRITY = 0x00010000; public const int ISC_REQ_IDENTIFY = 0x00020000; public const int ISC_REQ_NULL_SESSION = 0x00040000; public const int ISC_REQ_MANUAL_CRED_VALIDATION = 0x00080000; public const int ISC_REQ_RESERVED1 = 0x00100000; public const int ISC_REQ_FRAGMENT_TO_FIT = 0x00200000; public const int SECPKG_ATTR_SIZES = 0; public const int STANDARD_CONTEXT_ATTRIBUTES = ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONNECTION; bool _bGotClientCredentials = false; bool _bGotServerCredentials = false; bool _bGotServerContext = false; [DllImport("secur32", CharSet = CharSet.Auto)] static extern int AcquireCredentialsHandle( string pszPrincipal, //SEC_CHAR* string pszPackage, //SEC_CHAR* //"Kerberos","NTLM","Negotiative" int fCredentialUse, IntPtr PAuthenticationID,//_LUID AuthenticationID,//pvLogonID, //PLUID IntPtr pAuthData,//PVOID int pGetKeyFn, //SEC_GET_KEY_FN IntPtr pvGetKeyArgument, //PVOID ref SECURITY_HANDLE phCredential, //SecHandle //PCtxtHandle ref ref SECURITY_INTEGER ptsExpiry); //PTimeStamp //TimeStamp ref [DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)] static extern int InitializeSecurityContext(ref SECURITY_HANDLE phCredential,//PCredHandle IntPtr phContext, //PCtxtHandle string pszTargetName, int fContextReq, int Reserved1, int TargetDataRep, IntPtr pInput, //PSecBufferDesc SecBufferDesc int Reserved2, out SECURITY_HANDLE phNewContext, //PCtxtHandle out SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc out uint pfContextAttr, //managed ulong == 64 bits!!! out SECURITY_INTEGER ptsExpiry); //PTimeStamp [DllImport("secur32", CharSet = CharSet.Auto, SetLastError = true)] static extern int InitializeSecurityContext(ref SECURITY_HANDLE phCredential,//PCredHandle ref SECURITY_HANDLE phContext, //PCtxtHandle string pszTargetName, int fContextReq, int Reserved1, int TargetDataRep, ref SecBufferDesc SecBufferDesc, //PSecBufferDesc SecBufferDesc int Reserved2, out SECURITY_HANDLE phNewContext, //PCtxtHandle out SecBufferDesc pOutput, //PSecBufferDesc SecBufferDesc out uint pfContextAttr, //managed ulong == 64 bits!!! out SECURITY_INTEGER ptsExpiry); //PTimeStamp [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] static extern int AcceptSecurityContext(ref SECURITY_HANDLE phCredential, IntPtr phContext, ref SecBufferDesc pInput, uint fContextReq, uint TargetDataRep, out SECURITY_HANDLE phNewContext, out SecBufferDesc pOutput, out uint pfContextAttr, //managed ulong == 64 bits!!! out SECURITY_INTEGER ptsTimeStamp); [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] static extern int AcceptSecurityContext(ref SECURITY_HANDLE phCredential, ref SECURITY_HANDLE phContext, ref SecBufferDesc pInput, uint fContextReq, uint TargetDataRep, out SECURITY_HANDLE phNewContext, out SecBufferDesc pOutput, out uint pfContextAttr, //managed ulong == 64 bits!!! out SECURITY_INTEGER ptsTimeStamp); [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] public static extern int ImpersonateSecurityContext(ref SECURITY_HANDLE phContext); [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] public static extern int QueryContextAttributes(ref SECURITY_HANDLE phContext, uint ulAttribute, out SecPkgContext_Sizes pContextAttributes); [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] public static extern int EncryptMessage(ref SECURITY_HANDLE phContext, uint fQOP, //managed ulong == 64 bits!!! ref SecBufferDesc pMessage, uint MessageSeqNo); //managed ulong == 64 bits!!! [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] public static extern int DecryptMessage(ref SECURITY_HANDLE phContext, ref SecBufferDesc pMessage, uint MessageSeqNo, out uint pfQOP); [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] public static extern int MakeSignature(ref SECURITY_HANDLE phContext, // Context to use uint fQOP, // Quality of Protection ref SecBufferDesc pMessage, // Message to sign uint MessageSeqNo); // Message Sequence Num. [DllImport("secur32.Dll", CharSet = CharSet.Auto, SetLastError = false)] public static extern int VerifySignature(ref SECURITY_HANDLE phContext, // Context to use ref SecBufferDesc pMessage, // Message to sign uint MessageSeqNo, // Message Sequence Num. out uint pfQOP); // Quality of Protection string _sAccountName = WindowsIdentity.GetCurrent().Name; public SSPIHelper() { } public SSPIHelper(string sRemotePrincipal) { _sAccountName = sRemotePrincipal; } public void InitializeClient(out byte[] clientToken,byte[] serverToken, out bool bContinueProcessing) { clientToken = null; bContinueProcessing = true; SECURITY_INTEGER ClientLifeTime = new SECURITY_INTEGER(0); if(!_bGotClientCredentials) { if(AcquireCredentialsHandle(_sAccountName,"Kerberos",SECPKG_CRED_OUTBOUND, IntPtr.Zero,IntPtr.Zero,0,IntPtr.Zero, ref _hOutboundCred,ref ClientLifeTime) != SEC_E_OK) { throw new Exception("Couldn't acquire client credentials"); } _bGotClientCredentials = true; } int ss = -1; SecBufferDesc ClientToken = new SecBufferDesc(MAX_TOKEN_SIZE); try { uint ContextAttributes = 0; if(serverToken == null) { ss = InitializeSecurityContext(ref _hOutboundCred, IntPtr.Zero, _sAccountName,// null string pszTargetName, STANDARD_CONTEXT_ATTRIBUTES, 0,//int Reserved1, SECURITY_NATIVE_DREP,//int TargetDataRep IntPtr.Zero, //Always zero first time around... 0, //int Reserved2, out _hClientContext, //pHandle CtxtHandle = SecHandle out ClientToken,//ref SecBufferDesc pOutput, //PSecBufferDesc out ContextAttributes,//ref int pfContextAttr, out ClientLifeTime); //ref IntPtr ptsExpiry ); //PTimeStamp } else { SecBufferDesc ServerToken = new SecBufferDesc(serverToken); try { ss = InitializeSecurityContext(ref _hOutboundCred, ref _hClientContext, _sAccountName,// null string pszTargetName, STANDARD_CONTEXT_ATTRIBUTES, 0,//int Reserved1, SECURITY_NATIVE_DREP,//int TargetDataRep ref ServerToken, //Always zero first time around... 0, //int Reserved2, out _hClientContext, //pHandle CtxtHandle = SecHandle out ClientToken,//ref SecBufferDesc pOutput, //PSecBufferDesc out ContextAttributes,//ref int pfContextAttr, out ClientLifeTime); //ref IntPtr ptsExpiry ); //PTimeStamp } finally { ServerToken.Dispose(); } } if(ss != SEC_E_OK && ss != SEC_I_CONTINUE_NEEDED) { throw new Exception("InitializeSecurityContext() failed!!!"); } clientToken = ClientToken.GetSecBufferByteArray(); } finally { ClientToken.Dispose(); } bContinueProcessing = ss != SEC_E_OK; } public void InitializeServer(byte[] clientToken,out byte[] serverToken, out bool bContinueProcessing) { serverToken = null; bContinueProcessing = true; SECURITY_INTEGER NewLifeTime = new SECURITY_INTEGER(0); if(!_bGotServerCredentials) { if(AcquireCredentialsHandle(_sAccountName,"Kerberos",SECPKG_CRED_INBOUND, IntPtr.Zero,IntPtr.Zero,0,IntPtr.Zero, ref _hInboundCred,ref NewLifeTime) != SEC_E_OK) { throw new Exception("Couldn't acquire server credentials handle!!!"); } _bGotServerCredentials = true; } SecBufferDesc ServerToken = new SecBufferDesc(MAX_TOKEN_SIZE); SecBufferDesc ClientToken = new SecBufferDesc(clientToken); try { int ss = -1; uint uNewContextAttr = 0; if(!_bGotServerContext) { ss = AcceptSecurityContext(ref _hInboundCred, // [in] handle to the credentials IntPtr.Zero, // [in/out] handle of partially formed context. Always NULL the first time through ref ClientToken, // [in] pointer to the input buffers STANDARD_CONTEXT_ATTRIBUTES, // [in] required context attributes SECURITY_NATIVE_DREP, // [in] data representation on the target out _hServerContext, // [in/out] receives the new context handle out ServerToken, // [in/out] pointer to the output buffers out uNewContextAttr, // [out] receives the context attributes out NewLifeTime); // [out] receives the life span of the security context } else { ss = AcceptSecurityContext(ref _hInboundCred, // [in] handle to the credentials ref _hServerContext, // [in/out] handle of partially formed context. Always NULL the first time through ref ClientToken, // [in] pointer to the input buffers STANDARD_CONTEXT_ATTRIBUTES, // [in] required context attributes SECURITY_NATIVE_DREP, // [in] data representation on the target out _hServerContext, // [in/out] receives the new context handle out ServerToken, // [in/out] pointer to the output buffers out uNewContextAttr, // [out] receives the context attributes out NewLifeTime); // [out] receives the life span of the security context } if(ss != SEC_E_OK && ss != SEC_I_CONTINUE_NEEDED) { throw new Exception("AcceptSecurityContext() failed!!!"); } if(!_bGotServerContext) { _bGotServerContext = true; } serverToken = ServerToken.GetSecBufferByteArray(); bContinueProcessing = ss != SEC_E_OK; } finally { ClientToken.Dispose(); ServerToken.Dispose(); } } public void EncryptMessage(byte[] message,bool bUseClientContext,out byte[] encryptedBuffer) { encryptedBuffer = null; SECURITY_HANDLE EncryptionContext = _hServerContext; if(bUseClientContext) { EncryptionContext = _hClientContext; } SecPkgContext_Sizes ContextSizes = new SecPkgContext_Sizes(); if(QueryContextAttributes(ref EncryptionContext,SECPKG_ATTR_SIZES,out ContextSizes) != SEC_E_OK) { throw new Exception("QueryContextAttribute() failed!!!"); } MultipleSecBufferHelper[] ThisSecHelper = new MultipleSecBufferHelper[2]; ThisSecHelper[0] = new MultipleSecBufferHelper(message,SecBufferType.SECBUFFER_DATA); ThisSecHelper[1] = new MultipleSecBufferHelper(new byte[ContextSizes.cbSecurityTrailer],SecBufferType.SECBUFFER_TOKEN); SecBufferDesc DescBuffer = new SecBufferDesc(ThisSecHelper); try { if(EncryptMessage(ref EncryptionContext,0,ref DescBuffer,0) != SEC_E_OK) { throw new Exception("EncryptMessage() failed!!!"); } encryptedBuffer = DescBuffer.GetSecBufferByteArray(); } finally { DescBuffer.Dispose(); } } public void DecryptMessage(int messageLength,byte[] encryptedBuffer,bool bUseClientContext, out byte[] decryptedBuffer) { decryptedBuffer = null; SECURITY_HANDLE DecryptionContext = _hServerContext; if(bUseClientContext) { DecryptionContext = _hClientContext; } byte[] EncryptedMessage = new byte[messageLength]; Array.Copy(encryptedBuffer,0,EncryptedMessage,0,messageLength); int SecurityTrailerLength = encryptedBuffer.Length - messageLength; byte[] SecurityTrailer = new byte[SecurityTrailerLength]; Array.Copy(encryptedBuffer,messageLength,SecurityTrailer,0,SecurityTrailerLength); MultipleSecBufferHelper[] ThisSecHelper = new MultipleSecBufferHelper[2]; ThisSecHelper[0] = new MultipleSecBufferHelper(EncryptedMessage,SecBufferType.SECBUFFER_DATA); ThisSecHelper[1] = new MultipleSecBufferHelper(SecurityTrailer,SecBufferType.SECBUFFER_TOKEN); SecBufferDesc DescBuffer = new SecBufferDesc(ThisSecHelper); try { uint EncryptionQuality = 0; if(DecryptMessage(ref DecryptionContext,ref DescBuffer,0,out EncryptionQuality) != SEC_E_OK) { throw new Exception("DecryptMessage() failed!!!"); } decryptedBuffer = new byte[messageLength]; Array.Copy(DescBuffer.GetSecBufferByteArray(),0,decryptedBuffer,0,messageLength); } finally { DescBuffer.Dispose(); } } public void SignMessage(byte[] message,bool bUseClientContext,out byte[] signedBuffer, ref SECURITY_HANDLE hServerContext) { signedBuffer = null; SECURITY_HANDLE EncryptionContext = _hServerContext; if(bUseClientContext) { EncryptionContext = _hClientContext; } SecPkgContext_Sizes ContextSizes = new SecPkgContext_Sizes(); if(QueryContextAttributes(ref EncryptionContext,SECPKG_ATTR_SIZES,out ContextSizes) != SEC_E_OK) { throw new Exception("QueryContextAttribute() failed!!!"); } MultipleSecBufferHelper[] ThisSecHelper = new MultipleSecBufferHelper[2]; ThisSecHelper[0] = new MultipleSecBufferHelper(message,SecBufferType.SECBUFFER_DATA); ThisSecHelper[1] = new MultipleSecBufferHelper(new byte[ContextSizes.cbMaxSignature],SecBufferType.SECBUFFER_TOKEN); SecBufferDesc DescBuffer = new SecBufferDesc(ThisSecHelper); try { if(MakeSignature(ref EncryptionContext,0,ref DescBuffer,0) != SEC_E_OK) { throw new Exception("MakeSignature() failed!!!"); } //SSPIHelper.SignAndVerify(ref _hClientContext,ref hServerContext,ref DescBuffer); uint EncryptionQuality = 0; VerifySignature(ref this._hServerContext,ref DescBuffer,0,out EncryptionQuality); signedBuffer = DescBuffer.GetSecBufferByteArray(); } finally { DescBuffer.Dispose(); } } public void VerifyMessage(int messageLength,byte[] signedBuffer,bool bUseClientContext, out byte[] verifiedBuffer) { verifiedBuffer = null; SECURITY_HANDLE DecryptionContext = _hServerContext; if(bUseClientContext) { DecryptionContext = _hClientContext; } byte[] SignedMessage = new byte[messageLength]; Array.Copy(signedBuffer,0,SignedMessage,0,messageLength); int SignatureLength = signedBuffer.Length - messageLength; byte[] Signature = new byte[SignatureLength]; Array.Copy(signedBuffer,messageLength,Signature,0,SignatureLength); MultipleSecBufferHelper[] ThisSecHelper = new MultipleSecBufferHelper[2]; ThisSecHelper[0] = new MultipleSecBufferHelper(SignedMessage,SecBufferType.SECBUFFER_DATA); ThisSecHelper[1] = new MultipleSecBufferHelper(Signature,SecBufferType.SECBUFFER_TOKEN); SecBufferDesc DescBuffer = new SecBufferDesc(ThisSecHelper); try { uint EncryptionQuality = 0; int Return = VerifySignature(ref DecryptionContext,ref DescBuffer,0,out EncryptionQuality); if(Return != SEC_E_OK) { throw new Exception("VerifySignature() failed!!!"); } verifiedBuffer = new byte[messageLength]; Array.Copy(DescBuffer.GetSecBufferByteArray(),0,verifiedBuffer,0,messageLength); } finally { DescBuffer.Dispose(); } } } class TestMe { static void Main(string[] args) { try { SSPIHelper MyHelper = new SSPIHelper(); SSPIHelper MyServerHelper = new SSPIHelper(); byte[] ClientToken = null; byte[] ServerToken = null; bool bContinueClient = true, bContinueServer = true; while(bContinueClient || bContinueServer) { MyHelper.InitializeClient(out ClientToken,ServerToken,out bContinueClient); MyServerHelper.InitializeServer(ClientToken,out ServerToken,out bContinueServer); } byte[] Message = System.Text.Encoding.ASCII.GetBytes("hi there"); byte[] EncryptedBuffer = null; MyHelper.EncryptMessage(Message,true,out EncryptedBuffer); byte[] DecryptedBuffer; MyServerHelper.DecryptMessage(Message.Length,EncryptedBuffer,false,out DecryptedBuffer); Console.WriteLine(System.Text.Encoding.ASCII.GetString(DecryptedBuffer)); } catch(Exception Ex) { Console.WriteLine(Marshal.GetLastWin32Error()); } } } } !!!!Alternative Managed API: Whidbey makes it trivial to Kerberize your application using NegotiateStream. Check the Beta documentation for details... Documentation: InitializeSecurityContext@msdn on MSDN
Edit secur32.Initializ...
You do not have permission to change this page. If you feel this is in error, please send feedback with the contact link on the main page.