SspiWrapper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / IdentityModel / System / IdentityModel / SspiWrapper.cs / 2 / SspiWrapper.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.IdentityModel 
{
    using System.Runtime.InteropServices; 
    using System.Diagnostics; 
    using System.ComponentModel;
    using System.Security.Permissions; 
    using System.Globalization;


    //From Schannel.h 
    internal enum SchProtocols
    { 
        Zero                = 0, 
        Ssl2Client = 0x00000008,
        Ssl2Server = 0x00000004, 
        Ssl2 = (Ssl2Client | Ssl2Server),
        Ssl3Client          = 0x00000020,
        Ssl3Server          = 0x00000010,
        Ssl3                = (Ssl3Client | Ssl3Server), 
        TlsClient           = 0x00000080,
        TlsServer           = 0x00000040, 
        Tls                 = (TlsClient | TlsServer), 
        Ssl3Tls             = (Ssl3 | Tls),
    }; 

    //From WinCrypt.h
    internal enum Alg
    { 
        Any             = 0,
        ClassSignture   = (1 << 13), 
        ClassEncrypt    = (3 << 13), 
        ClassHash       = (4 << 13),
        ClassKeyXch     = (5 << 13), 
        TypeRSA         = (2 << 9),
        TypeBlock       = (3 << 9),
        TypeStream      = (4 << 9),
        TypeDH          = (5 << 9), 

        NameDES         = 1, 
        NameRC2         = 2, 
        NameRC4         = 1,
        NameSkipJack    = 10, 

        // want to ensure MD5 is never used
        // NameMD5         = 3,
        NameSHA         = 4, 

        NameDH_Ephem    = 2, 
        Fortezza        = 4 
    }
 
    [StructLayout(LayoutKind.Sequential)]
    internal struct SecurityPackageInfo
    {
        // see SecPkgInfoW in  
        internal int Capabilities;
        internal short Version; 
        internal short RPCID; 
        internal int MaxToken;
        internal IntPtr Name; 
        internal IntPtr Comment;

        internal static readonly int Size = Marshal.SizeOf(typeof(SecurityPackageInfo));
        internal static readonly int NameOffest = (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name"); 
    }
 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct LifeSpan_Struct
    { 
        internal long start;
        internal long end;

        internal static readonly int Size = Marshal.SizeOf(typeof(LifeSpan_Struct)); 
    }
 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct NegotiationInfo
    { 
        // see SecPkgContext_NegotiationInfoW in 

        // [MarshalAs(UnmanagedType.LPStruct)] internal SecurityPackageInfo PackageInfo;
        internal IntPtr PackageInfo; 
        internal uint NegotiationState;
        internal static readonly int Size = Marshal.SizeOf(typeof(NegotiationInfo)); 
        internal static readonly int NegotiationStateOffset = (int) Marshal.OffsetOf(typeof(NegotiationInfo), "NegotiationState"); 
    }
 
    // Note: pack=0 since the first member (SessionKeyLength) is C's long (platform dependent).
    [StructLayout(LayoutKind.Sequential, Pack=0)]
    internal struct SecPkgContext_SessionKey
    { 
        //[MarshalAs(UnmanagedType.SysUInt)] internal uint SessionKeyLength;
        internal uint SessionKeyLength; 
        internal IntPtr Sessionkey; 
        internal static readonly int Size = Marshal.SizeOf(typeof(SecPkgContext_SessionKey));
        internal static readonly int SessionkeyOffset = (int)Marshal.OffsetOf(typeof(SecPkgContext_SessionKey), "Sessionkey"); 
    }

    internal class LifeSpan
    { 
        DateTime effectiveTimeUtc;
        DateTime expiryTimeUtc; 
 
        internal DateTime EffectiveTimeUtc
        { 
            get
            {
                return this.effectiveTimeUtc;
            } 
        }
 
        internal DateTime ExpiryTimeUtc 
        {
            get 
            {
                return this.expiryTimeUtc;
            }
        } 

        internal unsafe LifeSpan(byte[] buffer) 
        { 
            fixed(byte * pbuffer = & buffer[0])
            { 
                IntPtr ptr = new IntPtr(pbuffer);
                LifeSpan_Struct lifeSpan = (LifeSpan_Struct) Marshal.PtrToStructure(ptr, typeof(LifeSpan_Struct));
                // start and end times are expressed as local file times.
                // however dateTime.FromFileTime* expects the file time to be in UTC. 
                // so we need to add the difference to the DateTime
                this.effectiveTimeUtc = DateTime.FromFileTimeUtc(lifeSpan.start) + (DateTime.UtcNow - DateTime.Now); 
                this.expiryTimeUtc = DateTime.FromFileTimeUtc(lifeSpan.end) + (DateTime.UtcNow - DateTime.Now); 
            }
        } 
    }

    internal class SecurityPackageInfoClass
    { 
        internal int Capabilities = 0;
        internal short Version = 0; 
        internal short RPCID = 0; 
        internal int MaxToken = 0;
        internal string Name = null; 
        internal string Comment = null;

        internal SecurityPackageInfoClass(SafeHandle safeHandle, int index)
        { 
            if (safeHandle.IsInvalid)
            { 
                return; 
            }
            IntPtr unmanagedAddress = IntPtrHelper.Add(safeHandle.DangerousGetHandle(), SecurityPackageInfo.Size * index); 
            Capabilities = Marshal.ReadInt32(unmanagedAddress, (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "Capabilities"));
            Version = Marshal.ReadInt16(unmanagedAddress, (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "Version"));
            RPCID = Marshal.ReadInt16(unmanagedAddress, (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "RPCID"));
            MaxToken = Marshal.ReadInt32(unmanagedAddress, (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "MaxToken")); 

            IntPtr unmanagedString; 
            unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "Name")); 
            if (unmanagedString != IntPtr.Zero)
            { 
                Name = Marshal.PtrToStringUni(unmanagedString);
            }

            unmanagedString = Marshal.ReadIntPtr(unmanagedAddress, (int) Marshal.OffsetOf(typeof(SecurityPackageInfo), "Comment")); 
            if (unmanagedString != IntPtr.Zero)
            { 
 
                Comment = Marshal.PtrToStringUni(unmanagedString);
            } 
        }

    }
 

    // we keep it simple since we use this only to know if NTLM or 
    // Kerberos are used in the context of a Negotiate handshake 
    internal class NegotiationInfoClass
    { 
        internal const string NTLM = "NTLM";
        internal const string Kerberos = "Kerberos";
        internal string AuthenticationPackage;
 
        internal NegotiationInfoClass(SafeHandle safeHandle, int negotiationState)
        { 
            if (safeHandle.IsInvalid) 
            {
                return; 
            }
            IntPtr packageInfo = safeHandle.DangerousGetHandle();

            const int SECPKG_NEGOTIATION_COMPLETE           = 0; 
            const int SECPKG_NEGOTIATION_OPTIMISTIC         = 1;
            // const int SECPKG_NEGOTIATION_IN_PROGRESS     = 2; 
            // const int SECPKG_NEGOTIATION_DIRECT          = 3; 
            // const int SECPKG_NEGOTIATION_TRY_MULTICRED   = 4;
 
            if (negotiationState==SECPKG_NEGOTIATION_COMPLETE || negotiationState==SECPKG_NEGOTIATION_OPTIMISTIC)
            {
                IntPtr unmanagedString = Marshal.ReadIntPtr(packageInfo, SecurityPackageInfo.NameOffest);
                string name = null; 
                if (unmanagedString != IntPtr.Zero)
                { 
                    name = Marshal.PtrToStringUni(unmanagedString); 
                }
                // an optimization for future string comparisons 
                if (string.Compare(name, "Kerberos", StringComparison.OrdinalIgnoreCase)==0)
                {
                    AuthenticationPackage = Kerberos;
                } 
                else if (string.Compare(name, "NTLM", StringComparison.OrdinalIgnoreCase)==0)
                { 
                    AuthenticationPackage = NTLM; 
                }
                else 
                {
                    AuthenticationPackage = name;
                }
            } 
        }
    } 
 
    internal class SecuritySessionKeyClass
    { 
        byte [] sessionKey;

        internal SecuritySessionKeyClass(SafeHandle safeHandle, int sessionKeyLength)
        { 
            byte[] sessionKey = new byte[sessionKeyLength];
            Marshal.Copy(safeHandle.DangerousGetHandle(), sessionKey, 0, sessionKeyLength); 
            this.sessionKey = sessionKey; 
        }
 
        internal byte [] SessionKey
        {
            get { return this.sessionKey; }
        } 
    }
 
    [StructLayout(LayoutKind.Sequential)] 
    internal class StreamSizes
    { 
        public int header;
        public int trailer;
        public int maximumMessage;
        public int buffersCount; 
        public int blockSize;
 
        internal unsafe StreamSizes(byte[] memory) 
        {
            fixed(void * voidPtr = memory) 
            {
                IntPtr unmanagedAddress = new IntPtr(voidPtr);
                header = Marshal.ReadInt32(unmanagedAddress);
                trailer = Marshal.ReadInt32(unmanagedAddress, 4); 
                maximumMessage = Marshal.ReadInt32(unmanagedAddress, 8);
                buffersCount = Marshal.ReadInt32(unmanagedAddress, 12); 
                blockSize = Marshal.ReadInt32(unmanagedAddress, 16); 
            }
        } 
        public static readonly int SizeOf = Marshal.SizeOf(typeof(StreamSizes));
    }

    internal static class SspiWrapper 
    {
        static SecurityPackageInfoClass[] securityPackages; 
 
        public static SecurityPackageInfoClass[] SecurityPackages
        { 
            get
            {
                return securityPackages;
            } 
            set
            { 
                securityPackages = value; 
            }
        } 

        static SecurityPackageInfoClass[] EnumerateSecurityPackages()
        {
            if (SecurityPackages != null) 
            {
                return SecurityPackages; 
            } 

            int moduleCount = 0; 
            SafeFreeContextBuffer arrayBaseHandle = null;
            try
            {
                int errorCode = SafeFreeContextBuffer.EnumeratePackages(out moduleCount, out arrayBaseHandle); 
                if (errorCode != 0)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); 
                }
 
                SecurityPackageInfoClass[] securityPackages = new SecurityPackageInfoClass[moduleCount];
                for (int i = 0; i < moduleCount; i++)
                {
                    securityPackages[i] = new SecurityPackageInfoClass(arrayBaseHandle, i); 
                }
                SecurityPackages = securityPackages; 
            } 
            finally
            { 
                if (arrayBaseHandle != null)
                {
                    arrayBaseHandle.Close();
                } 
            }
 
            return SecurityPackages; 
        }
 
        public static SecurityPackageInfoClass GetVerifyPackageInfo(string packageName)
        {
            SecurityPackageInfoClass[] supportedSecurityPackages = EnumerateSecurityPackages();
            if (supportedSecurityPackages != null) 
            {
                for (int i = 0; i < supportedSecurityPackages.Length; i++) 
                { 
                    if (String.Compare(supportedSecurityPackages[i].Name, packageName, StringComparison.OrdinalIgnoreCase) == 0)
                    { 
                        return supportedSecurityPackages[i];
                    }
                }
            } 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SSPIPackageNotSupported, packageName)));
        } 
 
        public static SafeFreeCredentials AcquireDefaultCredential(
            string package, 
            CredentialUse intent,
            params string[] additionalPackages)
        {
            SafeFreeCredentials outCredential = null; 
            AuthIdentityEx authIdentity = new AuthIdentityEx(null, null, null, additionalPackages);
            int errorCode = SafeFreeCredentials.AcquireDefaultCredential(package, intent, ref authIdentity, out outCredential); 
            if (errorCode != 0) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); 
            }
            return outCredential;
        }
 
        public static SafeFreeCredentials AcquireCredentialsHandle(
            string package, 
            CredentialUse intent, 
            ref AuthIdentityEx authdata)
        { 
            SafeFreeCredentials credentialsHandle = null;
            int errorCode = SafeFreeCredentials.AcquireCredentialsHandle(package,
                intent,
                ref authdata, 
                out credentialsHandle
                ); 
            if (errorCode != 0) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); 
            }
            return credentialsHandle;
        }
 
        public static SafeFreeCredentials AcquireCredentialsHandle(
            string package, 
            CredentialUse intent, 
            SecureCredential scc)
        { 
            SafeFreeCredentials outCredential = null;
            int errorCode = SafeFreeCredentials.AcquireCredentialsHandle(
                package,
                intent, 
                ref scc,
                out outCredential 
                ); 
            if (errorCode != 0)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
            }
            return outCredential;
        } 

        internal static int InitializeSecurityContext( 
            SafeFreeCredentials credential, 
            ref SafeDeleteContext context,
            string targetName, 
            SspiContextFlags inFlags,
            Endianness datarep,
            SecurityBuffer inputBuffer,
            SecurityBuffer outputBuffer, 
            ref SspiContextFlags outFlags)
        { 
            return SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, inputBuffer, null, outputBuffer, ref outFlags); 
        }
 
        //internal static int InitializeSecurityContext(
        //    SafeFreeCredentials credential,
        //    ref SafeDeleteContext context,
        //    string targetName, 
        //    SspiContextFlags inFlags,
        //    Endianness datarep, 
        //    SecurityBuffer[] inputBuffers, 
        //    SecurityBuffer outputBuffer,
        //    ref SspiContextFlags outFlags) 
        //{
        //    return SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags);
        //}
 
        internal static int AcceptSecurityContext(
            SafeFreeCredentials credential, 
            ref SafeDeleteContext refContext, 
            SspiContextFlags inFlags,
            Endianness datarep, 
            SecurityBuffer inputBuffer,
            SecurityBuffer outputBuffer,
            ref SspiContextFlags outFlags)
        { 
            return SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, inputBuffer, null, outputBuffer, ref outFlags);
        } 
 
        //internal static int AcceptSecurityContext(
        //    SafeFreeCredentials credential, 
        //    ref SafeDeleteContext refContext,
        //    SspiContextFlags inFlags,
        //    Endianness datarep,
        //    SecurityBuffer[] inputBuffers, 
        //    SecurityBuffer outputBuffer,
        //    ref SspiContextFlags outFlags) 
        //{ 
        //    return SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags);
        //} 

        public static int QuerySecurityContextToken(
            SafeDeleteContext context,
            out SafeCloseHandle token) 
        {
            return context.GetSecurityContextToken(out token); 
        } 

        static unsafe int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute  attribute, byte[] buffer, Type handleType, out SafeHandle refHandle) 
        {
            refHandle = null;
            if (handleType != null)
            { 
                if (handleType == typeof(SafeFreeContextBuffer))
                { 
                    refHandle = SafeFreeContextBuffer.CreateEmptyHandle(); 
                }
                else if (handleType == typeof(SafeFreeCertContext)) 
                {
                    refHandle = new SafeFreeCertContext();
                }
                else 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("handleType", SR.GetString(SR.ValueMustBeOf2Types, typeof(SafeFreeContextBuffer).ToString(),  typeof(SafeFreeCertContext).ToString()))); 
                } 
            }
            fixed(byte * bufferPtr = buffer) 
            {
                return SafeFreeContextBuffer.QueryContextAttributes(phContext, attribute, bufferPtr, refHandle);
            }
        } 

        public static unsafe object QueryContextAttributes( 
            SafeDeleteContext securityContext, 
            ContextAttribute contextAttribute)
        { 
            int nativeBlockSize = IntPtr.Size;
            Type    handleType = null;

            switch (contextAttribute) 
            {
                case ContextAttribute.Flags: 
                    break; 
                case ContextAttribute.Sizes:
                    nativeBlockSize = SecSizes.SizeOf; 
                    break;
                case ContextAttribute.StreamSizes:
                    nativeBlockSize = StreamSizes.SizeOf;
                    break; 
                case ContextAttribute.Names:
                    handleType = typeof(SafeFreeContextBuffer); 
                    break; 
                case ContextAttribute.PackageInfo:
                    handleType = typeof(SafeFreeContextBuffer); 
                    break;
                case ContextAttribute.NegotiationInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    nativeBlockSize = Marshal.SizeOf(typeof(NegotiationInfo)); 
                    break;
                case ContextAttribute.RemoteCertificate: 
                    handleType = typeof(SafeFreeCertContext); 
                    break;
                case ContextAttribute.LocalCertificate: 
                    handleType = typeof(SafeFreeCertContext);
                    break;
                case ContextAttribute.ConnectionInfo:
                    nativeBlockSize = Marshal.SizeOf(typeof(SslConnectionInfo)); 
                    break;
                case ContextAttribute.Lifespan: 
                    nativeBlockSize = LifeSpan_Struct.Size; 
                    break;
                case ContextAttribute.SessionKey: 
                    handleType = typeof(SafeFreeContextBuffer);
                    nativeBlockSize = SecPkgContext_SessionKey.Size;
                    break;
                default: 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int)contextAttribute,
                    typeof(ContextAttribute))); 
            } 

            SafeHandle sspiHandle = null; 
            object attribute = null;
            try
            {
                byte[] nativeBuffer = new byte[nativeBlockSize]; 
                int errorCode = QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0) 
                { 
                    return null;
                } 

                switch (contextAttribute)
                {
                    case ContextAttribute.Flags: 
                        fixed(byte * pnativeBuffer = nativeBuffer)
                        { 
                            attribute = (object) Marshal.ReadInt32(new IntPtr(pnativeBuffer)); 
                        }
                        break; 
                    case ContextAttribute.Sizes:
                        attribute = new SecSizes(nativeBuffer);
                        break;
                    case ContextAttribute.StreamSizes: 
                        attribute = new StreamSizes(nativeBuffer);
                        break; 
                    case ContextAttribute.Names: 
                        attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                        break; 
                    case ContextAttribute.PackageInfo:
                        attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                        break;
                    case ContextAttribute.NegotiationInfo: 
                        unsafe
                        { 
                            fixed(void * ptr = nativeBuffer) 
                            {
                                attribute = new NegotiationInfoClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr), NegotiationInfo.NegotiationStateOffset)); 
                            }
                        }
                        break;
                    case ContextAttribute.LocalCertificate: 
                        goto case ContextAttribute.RemoteCertificate;
                    case ContextAttribute.RemoteCertificate: 
                        attribute = sspiHandle; 
                        sspiHandle = null;
                        break; 
                    case ContextAttribute.ConnectionInfo:
                        attribute = new SslConnectionInfo(nativeBuffer);
                        break;
                    case ContextAttribute.Lifespan: 
                        attribute = new LifeSpan(nativeBuffer);
                        break; 
                    case ContextAttribute.SessionKey: 
                        unsafe
                        { 
                            fixed(void * ptr = nativeBuffer)
                            {
                                attribute = new SecuritySessionKeyClass(sspiHandle, Marshal.ReadInt32(new IntPtr(ptr)));
                            } 
                        }
                        break; 
                    default: 
                        // will return null
                        break; 
                }
            }
            finally
            { 
                if (sspiHandle != null)
                { 
                    sspiHandle.Close(); 
                }
            } 
            return attribute;
        }

        public static void ImpersonateSecurityContext( 
            SafeDeleteContext context)
        { 
            int errorCode = SafeDeleteContext.ImpersonateSecurityContext(context); 
            if (errorCode != (int) SecurityStatus.OK)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
            }
        }
 
        public static unsafe int EncryptDecryptHelper(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool encrypt, bool isGssBlob)
        { 
            SecurityBufferDescriptor sdcInOut = new SecurityBufferDescriptor(input.Length); 
            SecurityBufferStruct[] unmanagedBuffer  = new SecurityBufferStruct[input.Length];
            byte[][] buffers = new byte[input.Length][]; 
            fixed(void * unmanagedBufferPtr = unmanagedBuffer)
            {
                sdcInOut.UnmanagedPointer = unmanagedBufferPtr;
                GCHandle[] pinnedBuffers = new GCHandle[input.Length]; 
                try
                { 
                    for (int i = 0; i < input.Length; ++i) 
                    {
                        SecurityBuffer iBuffer = input[i]; 
                        unmanagedBuffer[i].count = iBuffer.size;
                        unmanagedBuffer[i].type = iBuffer.type;
                        if (iBuffer.token == null || iBuffer.token.Length == 0)
                        { 
                            unmanagedBuffer[i].token = IntPtr.Zero;
                        } 
                        else 
                        {
                            pinnedBuffers[i] = GCHandle.Alloc(iBuffer.token, GCHandleType.Pinned); 
                            unmanagedBuffer[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(iBuffer.token, iBuffer.offset);
                            buffers[i] = iBuffer.token;
                        }
                    } 
                    int errorCode;
                    if (encrypt) 
                    { 
                        errorCode = SafeDeleteContext.EncryptMessage(context, sdcInOut, sequenceNumber);
                    } 
                    else
                    {
                        errorCode = SafeDeleteContext.DecryptMessage(context, sdcInOut, sequenceNumber);
                    } 
                    // Marshalling back returned sizes (do not marshal the "token" field)
                    for (int i = 0; i < input.Length; ++i) 
                    { 
                        SecurityBuffer iBuffer = input[i];
                        iBuffer.size = unmanagedBuffer[i].count; 
                        iBuffer.type = unmanagedBuffer[i].type;
                        if (iBuffer.size == 0)
                        {
                            iBuffer.offset = 0; 
                            iBuffer.token = null;
                        } 
                        else if (isGssBlob && !encrypt && iBuffer.type == BufferType.Data) 
                        {
                            iBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(iBuffer.size); 
                            Marshal.Copy(unmanagedBuffer[i].token, iBuffer.token, 0, iBuffer.size);
                        }
                        else checked
                            { 
                                // Find the buffer this is inside of.  Usually they all point inside buffer 0.
                                int j; 
                                for (j = 0; j < input.Length; j++) 
                                {
                                    if (buffers[j] == null) 
                                    {
                                        continue;
                                    }
 
                                    byte* bufferAddress = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers[j], 0);
                                    if ((byte*)unmanagedBuffer[i].token >= bufferAddress && 
                                        (byte*)unmanagedBuffer[i].token + iBuffer.size <= bufferAddress + buffers[j].Length) 
                                    {
                                        iBuffer.offset = (int)((byte*)unmanagedBuffer[i].token - bufferAddress); 
                                        iBuffer.token = buffers[j];
                                        break;
                                    }
                                } 

                                if (j >= input.Length) 
                                { 
                                    iBuffer.size = 0;
                                    iBuffer.offset = 0; 
                                    iBuffer.token = null;
                                }
                                if (!(iBuffer.offset >= 0 && iBuffer.offset <= (iBuffer.token == null ? 0 : iBuffer.token.Length)))
                                { 
                                    DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset));
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert1, iBuffer.offset))); 
 
                                }
                                if (!(iBuffer.size >= 0 && iBuffer.size <= (iBuffer.token == null ? 0 : iBuffer.token.Length - iBuffer.offset))) 
                                {
                                    DiagnosticUtility.DebugAssert(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size));
                                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiWrapperEncryptDecryptAssert2, iBuffer.size)));
                                } 
                            }
                    } 
                    return errorCode; 
                }
                finally 
                {
                    for (int i = 0; i < pinnedBuffers.Length; ++i)
                    {
                        if (pinnedBuffers[i].IsAllocated) 
                        {
                            pinnedBuffers[i].Free(); 
                        } 
                    }
                } 
            }
        }

        public static unsafe int EncryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber) 
        {
            return EncryptDecryptHelper(context, input, sequenceNumber, true, false); 
        } 

        public static unsafe int DecryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool isGssBlob) 
        {
            return EncryptDecryptHelper(context, input, sequenceNumber, false, isGssBlob);
        }
 
        //public static string ErrorDescription(int errorCode)
        //{ 
        //    if (errorCode == -1) 
        //    {
        //        return "An exception when invoking Win32 API"; 
        //    }
        //    switch ((SecurityStatus) errorCode)
        //    {
        //        case SecurityStatus.InvalidHandle: 
        //            return "Invalid handle";
        //        case SecurityStatus.InvalidToken: 
        //            return "Invalid token"; 
        //        case SecurityStatus.ContinueNeeded:
        //            return "Continue needed"; 
        //        case SecurityStatus.IncompleteMessage:
        //            return "Message incomplete";
        //        case SecurityStatus.WrongPrincipal:
        //            return "Wrong principal"; 
        //        case SecurityStatus.TargetUnknown:
        //            return "Target unknown"; 
        //        case SecurityStatus.PackageNotFound: 
        //            return "Package not found";
        //        case SecurityStatus.BufferNotEnough: 
        //            return "Buffer not enough";
        //        case SecurityStatus.MessageAltered:
        //            return "Message altered";
        //        case SecurityStatus.UntrustedRoot: 
        //            return "Untrusted root";
        //        default: 
        //            return "0x" + errorCode.ToString("x", NumberFormatInfo.InvariantInfo); 
        //    }
        //} 
    }

    //From Schannel.h
    [StructLayout(LayoutKind.Sequential)] 
    internal class SslConnectionInfo
    { 
        public readonly int           Protocol; 
        public readonly int           DataCipherAlg;
        public readonly int           DataKeySize; 
        public readonly int           DataHashAlg;
        public readonly int           DataHashKeySize;
        public readonly int           KeyExchangeAlg;
        public readonly int           KeyExchKeySize; 

        internal unsafe SslConnectionInfo(byte[] nativeBuffer) 
        { 
            fixed(void * voidPtr = nativeBuffer)
            { 
                IntPtr unmanagedAddress = new IntPtr(voidPtr);
                Protocol = Marshal.ReadInt32(unmanagedAddress);
                DataCipherAlg = Marshal.ReadInt32(unmanagedAddress, 4);
                DataKeySize = Marshal.ReadInt32(unmanagedAddress, 8); 
                DataHashAlg = Marshal.ReadInt32(unmanagedAddress, 12);
                DataHashKeySize = Marshal.ReadInt32(unmanagedAddress, 16); 
                KeyExchangeAlg = Marshal.ReadInt32(unmanagedAddress, 20); 
                KeyExchKeySize = Marshal.ReadInt32(unmanagedAddress, 24);
            } 
        }
    }

    [StructLayout(LayoutKind.Sequential)] 
    internal class SecSizes
    { 
        public int MaxToken; 
        public int MaxSignature;
        public int BlockSize; 
        public int SecurityTrailer;

        internal unsafe SecSizes(byte[] memory)
        { 
            fixed(void * voidPtr = memory)
            { 
                IntPtr unmanagedAddress = new IntPtr(voidPtr); 
                MaxToken = Marshal.ReadInt32(unmanagedAddress);
                MaxSignature = Marshal.ReadInt32(unmanagedAddress, 4); 
                BlockSize = Marshal.ReadInt32(unmanagedAddress, 8);
                SecurityTrailer = Marshal.ReadInt32(unmanagedAddress, 12);
            }
        } 
        public static readonly int SizeOf = Marshal.SizeOf(typeof(SecSizes));
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK