public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            SecurityBuffer incomingSecurity = null;
            if (incomingBlob != null)
            {
                incomingSecurity = new SecurityBuffer(incomingBlob, BufferType.Token);
            }

            SecurityBuffer outgoingSecurity = new SecurityBuffer(null, BufferType.Token);
            this.remoteCertificate = null;
            int statusCode = 0;
            if (this.isServer == true)
            {
                statusCode = SspiWrapper.AcceptSecurityContext(
                    this.credentialsHandle,
                    ref this.securityContext,
                    ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero),
                    Endianness.Native,
                    incomingSecurity,
                    outgoingSecurity,
                    ref this.attributes
                    );

            }
            else
            {
                statusCode = SspiWrapper.InitializeSecurityContext(
                    this.credentialsHandle,
                    ref this.securityContext,
                    this.destination,
                    ClientStandardFlags,
                    Endianness.Native,
                    incomingSecurity,
                    outgoingSecurity,
                    ref this.attributes
                    );
            }

            if ((statusCode & unchecked((int)0x80000000)) != 0)
            {
                this.Dispose();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                // ensure that the key negotiated is strong enough
                if (SecurityUtils.ShouldValidateSslCipherStrength())
                {
                    SslConnectionInfo connectionInfo = (SslConnectionInfo)SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo);
                    if (connectionInfo == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.CannotObtainSslConnectionInfo)));
                    }
                    SecurityUtils.ValidateSslCipherStrength(connectionInfo.DataKeySize);
                }
                this.isCompleted = true;
            }
            else if (statusCode == (int)SecurityStatus.CredentialsNeeded)
            {
                // the server requires the client to supply creds
                // Currently we dont attempt to find the client cert to choose at runtime
                // so just re-call the function
                AcquireClientCredentials();
                if (this.ClientCertificate != null)
                {
                    this.wasClientCertificateSent = true;
                }
                return this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy);
            }
            else if (statusCode != (int)SecurityStatus.ContinueNeeded)
            {
                this.Dispose();
                if (statusCode == (int)SecurityStatus.InternalError)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.LsaAuthorityNotContacted)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
                }
            }
            return outgoingSecurity.token;
        }
 public static unsafe int EncryptDecryptHelper(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool encrypt, bool isGssBlob)
 {
     int num6;
     SecurityBufferStruct[] structArray2;
     SecurityBufferDescriptor inputOutput = new SecurityBufferDescriptor(input.Length);
     SecurityBufferStruct[] structArray = new SecurityBufferStruct[input.Length];
     byte[][] bufferArray = new byte[input.Length][];
     if (((structArray2 = structArray) == null) || (structArray2.Length == 0))
     {
         fixed (IntPtr* ptrRef = null)
         {
         }
     }
     inputOutput.UnmanagedPointer = (void*) ptrRef;
     GCHandle[] handleArray = new GCHandle[input.Length];
     try
     {
         int num2;
         for (int i = 0; i < input.Length; i++)
         {
             SecurityBuffer buffer = input[i];
             structArray[i].count = buffer.size;
             structArray[i].type = buffer.type;
             if ((buffer.token == null) || (buffer.token.Length == 0))
             {
                 structArray[i].token = IntPtr.Zero;
             }
             else
             {
                 handleArray[i] = GCHandle.Alloc(buffer.token, GCHandleType.Pinned);
                 structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer.token, buffer.offset);
                 bufferArray[i] = buffer.token;
             }
         }
         if (encrypt)
         {
             num2 = SafeDeleteContext.EncryptMessage(context, inputOutput, sequenceNumber);
         }
         else
         {
             num2 = SafeDeleteContext.DecryptMessage(context, inputOutput, sequenceNumber);
         }
         for (int j = 0; j < input.Length; j++)
         {
             SecurityBuffer buffer2 = input[j];
             buffer2.size = structArray[j].count;
             buffer2.type = structArray[j].type;
             if (buffer2.size == 0)
             {
                 buffer2.offset = 0;
                 buffer2.token = null;
                 continue;
             }
             if ((isGssBlob && !encrypt) && (buffer2.type == BufferType.Data))
             {
                 buffer2.token = DiagnosticUtility.Utility.AllocateByteArray(buffer2.size);
                 Marshal.Copy(structArray[j].token, buffer2.token, 0, buffer2.size);
                 continue;
             }
             int index = 0;
             while (index < input.Length)
             {
                 if (bufferArray[index] != null)
                 {
                     byte* numPtr = (byte*) Marshal.UnsafeAddrOfPinnedArrayElement(bufferArray[index], 0);
                     if ((((void*) structArray[j].token) >= numPtr) && ((((void*) structArray[j].token) + buffer2.size) <= (numPtr + bufferArray[index].Length)))
                     {
                         buffer2.offset = (int) ((long) ((((void*) structArray[j].token) - numPtr) / 1));
                         buffer2.token = bufferArray[index];
                         break;
                     }
                 }
                 index++;
             }
             if (index >= input.Length)
             {
                 buffer2.size = 0;
                 buffer2.offset = 0;
                 buffer2.token = null;
             }
             if ((buffer2.offset < 0) || (buffer2.offset > ((buffer2.token == null) ? 0 : buffer2.token.Length)))
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.IdentityModel.SR.GetString("SspiWrapperEncryptDecryptAssert1", new object[] { buffer2.offset })));
             }
             if ((buffer2.size < 0) || (buffer2.size > ((buffer2.token == null) ? 0 : (buffer2.token.Length - buffer2.offset))))
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.IdentityModel.SR.GetString("SspiWrapperEncryptDecryptAssert2", new object[] { buffer2.size })));
             }
         }
         num6 = num2;
     }
     finally
     {
         for (int k = 0; k < handleArray.Length; k++)
         {
             if (handleArray[k].IsAllocated)
             {
                 handleArray[k].Free();
             }
         }
     }
     return num6;
 }
        private void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, System.IdentityModel.SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool flag = false;

            System.IdentityModel.SafeDeleteContext context = null;
            try
            {
                if (credentialsHandle == null)
                {
                    if ((networkCredential == null) || (networkCredential == CredentialCache.DefaultNetworkCredentials))
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", System.IdentityModel.CredentialUse.Outbound, new string[0]);
                    }
                    else
                    {
                        AuthIdentityEx authdata = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain, new string[0]);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", System.IdentityModel.CredentialUse.Outbound, ref authdata);
                    }
                    flag = true;
                }
                SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    inFlags |= SspiContextFlags.InitIdentify;
                }
                SspiContextFlags zero = SspiContextFlags.Zero;
                System.IdentityModel.SecurityBuffer inputBuffer = null;
                if (channelBinding != null)
                {
                    inputBuffer = new System.IdentityModel.SecurityBuffer(channelBinding);
                }
                System.IdentityModel.SecurityBuffer outputBuffer = new System.IdentityModel.SecurityBuffer(0, System.IdentityModel.BufferType.Token);
                int error = SspiWrapper.InitializeSecurityContext(credentialsHandle, ref context, this.servicePrincipalName, inFlags, System.IdentityModel.Endianness.Native, inputBuffer, outputBuffer, ref zero);
                switch (error)
                {
                case 0:
                    break;

                case 0x90312:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error)));

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailInitializeSecurityContext"), new Win32Exception(error)));
                }
                this.apreq = outputBuffer.token;
                LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.Lifespan);
                this.effectiveTime  = span.EffectiveTimeUtc;
                this.expirationTime = span.ExpiryTimeUtc;
                SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
            }
            finally
            {
                if (context != null)
                {
                    context.Close();
                }
                if (flag && (credentialsHandle != null))
                {
                    credentialsHandle.Close();
                }
            }
        }
 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);
 }
 public static int DecryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool isGssBlob)
 {
     return EncryptDecryptHelper(context, input, sequenceNumber, false, isGssBlob);
 }
Exemplo n.º 6
0
        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 int EncryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber)
 {
     return EncryptDecryptHelper(context, input, sequenceNumber, true, false);
 }
 public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
 {
     this.ThrowIfDisposed();
     SecurityBuffer inputBuffer = null;
     if (incomingBlob != null)
     {
         inputBuffer = new SecurityBuffer(incomingBlob, System.IdentityModel.BufferType.Token);
     }
     SecurityBuffer outputBuffer = new SecurityBuffer(null, System.IdentityModel.BufferType.Token);
     this.remoteCertificate = null;
     int error = 0;
     if (this.isServer)
     {
         error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, ServerStandardFlags | (this.clientCertRequired ? SspiContextFlags.MutualAuth : SspiContextFlags.Zero), Endianness.Native, inputBuffer, outputBuffer, ref this.attributes);
     }
     else
     {
         error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.destination, ClientStandardFlags, Endianness.Native, inputBuffer, outputBuffer, ref this.attributes);
     }
     if ((error & -2147483648) != 0)
     {
         this.Dispose();
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
     }
     if (error == 0)
     {
         if (System.ServiceModel.Security.SecurityUtils.ShouldValidateSslCipherStrength())
         {
             SslConnectionInfo info = (SslConnectionInfo) SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.ConnectionInfo);
             if (info == null)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(System.ServiceModel.SR.GetString("CannotObtainSslConnectionInfo")));
             }
             System.ServiceModel.Security.SecurityUtils.ValidateSslCipherStrength(info.DataKeySize);
         }
         this.isCompleted = true;
     }
     else
     {
         if (error == 0x90320)
         {
             this.AcquireClientCredentials();
             if (this.ClientCertificate != null)
             {
                 this.wasClientCertificateSent = true;
             }
             return this.GetOutgoingBlob(incomingBlob, channelbinding, protectionPolicy);
         }
         if (error != 0x90312)
         {
             this.Dispose();
             if (error == -2146893052)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("LsaAuthorityNotContacted")));
             }
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
         }
     }
     return outputBuffer.token;
 }
        //-------------------------------------------------------------------
        internal static unsafe int AcceptSecurityContext(
            SafeFreeCredentials inCredentials,
            ref SafeDeleteContext refContext,
            SspiContextFlags inFlags,
            Endianness endianness,
            SecurityBuffer inSecBuffer,
            SecurityBuffer[] inSecBuffers,
            SecurityBuffer outSecBuffer,
            ref SspiContextFlags outFlags)
        {

            if (inCredentials == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials");
            }

            SecurityBufferDescriptor inSecurityBufferDescriptor = null;
            if (inSecBuffer != null)
            {
                inSecurityBufferDescriptor = new SecurityBufferDescriptor(1);
            }
            else if (inSecBuffers != null)
            {
                inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length);
            }
            SecurityBufferDescriptor outSecurityBufferDescriptor = new SecurityBufferDescriptor(1);

            // actually this is returned in outFlags
            bool isSspiAllocated = (inFlags & SspiContextFlags.AllocateMemory) != 0 ? true : false;

            int errorCode = -1;
            SSPIHandle contextHandle = new SSPIHandle();
            if (refContext != null)
            {
                contextHandle = refContext._handle;
            }

            // these are pinned user byte arrays passed along with SecurityBuffers
            GCHandle[] pinnedInBytes = null;
            GCHandle pinnedOutBytes = new GCHandle();
            // optional output buffer that may need to be freed
            SafeFreeContextBuffer outFreeContextBuffer = null;

            try
            {
                pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);

                SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count];
                fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
                {
                    if (inSecurityBufferDescriptor != null)
                    {
                        // Fix Descriptor pointer that points to unmanaged SecurityBuffers
                        inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr;
                        pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count];
                        SecurityBuffer securityBuffer;
                        for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index)
                        {
                            securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index];
                            if (securityBuffer != null)
                            {
                                // Copy the SecurityBuffer content into unmanaged place holder
                                inUnmanagedBuffer[index].count = securityBuffer.size;
                                inUnmanagedBuffer[index].type = securityBuffer.type;
                                // use the unmanaged token if it's not null; otherwise use the managed buffer
                                if (securityBuffer.unmanagedToken != null)
                                {
                                    inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle();
                                }
                                else if (securityBuffer.token == null || securityBuffer.token.Length == 0)
                                {
                                    inUnmanagedBuffer[index].token = IntPtr.Zero;
                                }
                                else
                                {
                                    pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned);
                                    inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
                                }
                            }
                        }
                    }
                    SecurityBufferStruct[] outUnmanagedBuffer = new SecurityBufferStruct[1];
                    fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer)
                    {
                        // Fix Descriptor pointer that points to unmanaged SecurityBuffers
                        outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr;
                        // Copy the SecurityBuffer content into unmanaged place holder
                        outUnmanagedBuffer[0].count = outSecBuffer.size;
                        outUnmanagedBuffer[0].type = outSecBuffer.type;
                        if (outSecBuffer.token == null || outSecBuffer.token.Length == 0)
                        {
                            outUnmanagedBuffer[0].token = IntPtr.Zero;
                        }
                        else
                        {
                            outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
                        }
                        if (isSspiAllocated)
                        {
                            outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle();
                        }

                        if (refContext == null || refContext.IsInvalid)
                        {
                            refContext = new SafeDeleteContext();
                        }
                        errorCode = MustRunAcceptSecurityContext(
                            inCredentials,
                            contextHandle.IsZero ? null : &contextHandle,
                            inSecurityBufferDescriptor,
                            inFlags,
                            endianness,
                            refContext,
                            outSecurityBufferDescriptor,
                            ref outFlags,
                            outFreeContextBuffer
                            );

                        // Get unmanaged buffer with index 0 as the only one passed into PInvoke
                        outSecBuffer.size = outUnmanagedBuffer[0].count;
                        outSecBuffer.type = outUnmanagedBuffer[0].type;
                        if (outSecBuffer.size > 0)
                        {
                            outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size);
                            Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size);
                        }
                        else
                        {
                            outSecBuffer.token = null;
                        }
                    }
                }
            }
            finally
            {
                if (pinnedInBytes != null)
                {
                    for (int index = 0; index < pinnedInBytes.Length; index++)
                    {
                        if (pinnedInBytes[index].IsAllocated)
                        {
                            pinnedInBytes[index].Free();
                        }
                    }
                }
                if (pinnedOutBytes.IsAllocated)
                {
                    pinnedOutBytes.Free();
                }
                if (outFreeContextBuffer != null)
                {
                    outFreeContextBuffer.Close();
                }
            }

            return errorCode;
        }
 internal void DecryptInPlace(byte[] encryptedContent, out int dataStartOffset, out int dataLen)
 {
     this.ThrowIfDisposed();
     dataStartOffset = this.StreamSizes.header;
     dataLen = 0;
     byte[] data = new byte[0];
     byte[] buffer2 = new byte[0];
     byte[] buffer3 = new byte[0];
     SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, System.IdentityModel.BufferType.Data), new SecurityBuffer(data, System.IdentityModel.BufferType.Empty), new SecurityBuffer(buffer2, System.IdentityModel.BufferType.Empty), new SecurityBuffer(buffer3, System.IdentityModel.BufferType.Empty) };
     int error = SspiWrapper.DecryptMessage(this.securityContext, input, 0, false);
     if (error != 0)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
     }
     for (int i = 0; i < input.Length; i++)
     {
         if (input[i].type == System.IdentityModel.BufferType.Data)
         {
             dataLen = input[i].size;
             return;
         }
     }
     this.OnBadData();
 }
 internal void EncryptInPlace(byte[] buffer, int bufferStartOffset, int dataLen, out int encryptedDataLen)
 {
     this.ThrowIfDisposed();
     encryptedDataLen = 0;
     if ((((bufferStartOffset + dataLen) + this.StreamSizes.header) + this.StreamSizes.trailer) > buffer.Length)
     {
         this.OnBadData();
     }
     byte[] data = new byte[0];
     int offset = (bufferStartOffset + this.StreamSizes.header) + dataLen;
     SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(buffer, bufferStartOffset, this.StreamSizes.header, System.IdentityModel.BufferType.Header), new SecurityBuffer(buffer, bufferStartOffset + this.StreamSizes.header, dataLen, System.IdentityModel.BufferType.Data), new SecurityBuffer(buffer, offset, this.StreamSizes.trailer, System.IdentityModel.BufferType.Trailer), new SecurityBuffer(data, System.IdentityModel.BufferType.Empty) };
     int error = SspiWrapper.EncryptMessage(this.securityContext, input, 0);
     if (error != 0)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
     }
     int size = 0;
     for (int i = 0; i < input.Length; i++)
     {
         if (input[i].type == System.IdentityModel.BufferType.Trailer)
         {
             size = input[i].size;
             encryptedDataLen = (this.StreamSizes.header + dataLen) + size;
             return;
         }
     }
     this.OnBadData();
 }
 public byte[] Decrypt(byte[] encryptedContent)
 {
     if (encryptedContent == null)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptedContent");
     }
     this.ThrowIfDisposed();
     SecurityBuffer[] input = new SecurityBuffer[] { new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Stream), new SecurityBuffer(0, BufferType.Data) };
     int error = SspiWrapper.DecryptMessage(this.securityContext, input, 0, true);
     if (error != 0)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
     }
     for (int i = 0; i < input.Length; i++)
     {
         if (input[i].type == BufferType.Data)
         {
             return input[i].token;
         }
     }
     this.OnBadData();
     return null;
 }
 public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
 {
     this.ThrowIfDisposed();
     int error = 0;
     SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
     if (this.doMutualAuth)
     {
         inFlags |= SspiContextFlags.MutualAuth;
     }
     if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
     {
         inFlags |= SspiContextFlags.Delegate;
     }
     else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification))
     {
         inFlags |= SspiContextFlags.InitIdentify;
     }
     else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous))
     {
         inFlags |= SspiContextFlags.InitAnonymous;
     }
     ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);
     if (this.isServer)
     {
         if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing")));
         }
         if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
         {
             inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
         }
         if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
         {
             inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
         }
     }
     List<SecurityBuffer> list = new List<SecurityBuffer>(2);
     if (incomingBlob != null)
     {
         list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
     }
     if (this.isServer)
     {
         if (helper.ShouldAddChannelBindingToASC())
         {
             list.Add(new SecurityBuffer(helper.ChannelBinding));
         }
     }
     else if (helper.ChannelBinding != null)
     {
         list.Add(new SecurityBuffer(helper.ChannelBinding));
     }
     SecurityBuffer[] inputBuffers = null;
     if (list.Count > 0)
     {
         inputBuffers = list.ToArray();
     }
     SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);
     if (!this.isServer)
     {
         error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
     }
     else
     {
         bool flag = this.securityContext == null;
         SspiContextFlags contextFlags = this.contextFlags;
         error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
         if ((error == -2146893048) && !flag)
         {
             this.contextFlags = contextFlags;
             this.CloseContext();
             error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
         }
     }
     if ((error & -2147483648) != 0)
     {
         if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint) error))) && SspiWrapper.IsNegotiateExPackagePresent())
         {
             if (this.MaxPromptAttempts >= 1)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials")));
             }
             IntPtr zero = IntPtr.Zero;
             uint num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi);
             if (num2 == 0)
             {
                 IntPtr ppNewAuthIdentity = IntPtr.Zero;
                 if (!this.allowNtlm)
                 {
                     UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity);
                 }
                 else
                 {
                     ppNewAuthIdentity = zero;
                 }
                 this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);
                 if (IntPtr.Zero != ppNewAuthIdentity)
                 {
                     UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                 }
                 this.CloseContext();
                 this.MaxPromptAttempts++;
                 return this.GetOutgoingBlob(null, channelbinding, protectionPolicy);
             }
             if (IntPtr.Zero != zero)
             {
                 UnsafeNativeMethods.SspiFreeAuthIdentity(zero);
             }
             this.CloseContext();
             this.isCompleted = true;
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int) num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials")));
         }
         this.CloseContext();
         this.isCompleted = true;
         if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022)))
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation")));
         }
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName })));
     }
     if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
     {
         if (this.isServer)
         {
             SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
         }
         else
         {
             SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
         }
     }
     if (error == 0)
     {
         this.isCompleted = true;
         if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding))
         {
             helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
         }
     }
     return outputBuffer.token;
 }
 public byte[] Encrypt(byte[] input)
 {
     if (input == null)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("input");
     }
     this.ThrowIfDisposed();
     SecurityBuffer[] bufferArray = new SecurityBuffer[3];
     byte[] data = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(this.SecuritySizes.SecurityTrailer);
     bufferArray[0] = new SecurityBuffer(data, 0, data.Length, BufferType.Token);
     byte[] dst = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(input.Length);
     Buffer.BlockCopy(input, 0, dst, 0, input.Length);
     bufferArray[1] = new SecurityBuffer(dst, 0, dst.Length, BufferType.Data);
     byte[] buffer3 = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray(this.SecuritySizes.BlockSize);
     bufferArray[2] = new SecurityBuffer(buffer3, 0, buffer3.Length, BufferType.Padding);
     int error = SspiWrapper.EncryptMessage(this.securityContext, bufferArray, 0);
     if (error != 0)
     {
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
     }
     int count = 0;
     int size = 0;
     for (int i = 0; i < bufferArray.Length; i++)
     {
         if (bufferArray[i].type == BufferType.Token)
         {
             count = bufferArray[i].size;
         }
         else if (bufferArray[i].type == BufferType.Padding)
         {
             size = bufferArray[i].size;
         }
     }
     byte[] buffer4 = System.ServiceModel.DiagnosticUtility.Utility.AllocateByteArray((count + dst.Length) + size);
     Buffer.BlockCopy(data, 0, buffer4, 0, count);
     Buffer.BlockCopy(dst, 0, buffer4, count, dst.Length);
     Buffer.BlockCopy(buffer3, 0, buffer4, count + dst.Length, size);
     return buffer4;
 }
        /// <summary>
        /// The decrypted data will start header bytes from the start of
        /// encryptedContent array.
        /// </summary>
        internal unsafe void DecryptInPlace(byte[] encryptedContent, out int dataStartOffset, out int dataLen)
        {
            ThrowIfDisposed();
            dataStartOffset = StreamSizes.header;
            dataLen = 0;

            byte[] emptyBuffer1 = new byte[0];
            byte[] emptyBuffer2 = new byte[0];
            byte[] emptyBuffer3 = new byte[0];

            SecurityBuffer[] securityBuffer = new SecurityBuffer[4];
            securityBuffer[0] = new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Data);
            securityBuffer[1] = new SecurityBuffer(emptyBuffer1, BufferType.Empty);
            securityBuffer[2] = new SecurityBuffer(emptyBuffer2, BufferType.Empty);
            securityBuffer[3] = new SecurityBuffer(emptyBuffer3, BufferType.Empty);

            int errorCode = SspiWrapper.DecryptMessage(this.securityContext, securityBuffer, 0, false);
            if (errorCode != 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
            }

            for (int i = 0; i < securityBuffer.Length; ++i)
            {
                if (securityBuffer[i].type == BufferType.Data)
                {
                    dataLen = securityBuffer[i].size;
                    return;
                }
            }

            OnBadData();
        }
 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);
 }
        /// <summary>
        /// Assumes that the data to encrypt is "header" bytes ahead of bufferStartOffset
        /// </summary>
        internal unsafe void EncryptInPlace(byte[] buffer, int bufferStartOffset, int dataLen, out int encryptedDataLen)
        {
            ThrowIfDisposed();
            encryptedDataLen = 0;
            if (bufferStartOffset + dataLen + StreamSizes.header + StreamSizes.trailer > buffer.Length)
            {
                OnBadData();
            }

            byte[] emptyBuffer = new byte[0];
            int trailerOffset = bufferStartOffset + StreamSizes.header + dataLen;

            SecurityBuffer[] securityBuffer = new SecurityBuffer[4];
            securityBuffer[0] = new SecurityBuffer(buffer, bufferStartOffset, StreamSizes.header, BufferType.Header);
            securityBuffer[1] = new SecurityBuffer(buffer, bufferStartOffset + StreamSizes.header, dataLen, BufferType.Data);
            securityBuffer[2] = new SecurityBuffer(buffer, trailerOffset, StreamSizes.trailer, BufferType.Trailer);
            securityBuffer[3] = new SecurityBuffer(emptyBuffer, BufferType.Empty);

            int errorCode = SspiWrapper.EncryptMessage(this.securityContext, securityBuffer, 0);
            if (errorCode != 0)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
            }

            int trailerSize = 0;
            for (int i = 0; i < securityBuffer.Length; ++i)
            {
                if (securityBuffer[i].type == BufferType.Trailer)
                {
                    trailerSize = securityBuffer[i].size;
                    encryptedDataLen = StreamSizes.header + dataLen + trailerSize;
                    return;
                }
            }

            OnBadData();
        }
 internal static unsafe int InitializeSecurityContext(SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, string targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref SspiContextFlags outFlags)
 {
     if (inCredentials == null)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials");
     }
     SecurityBufferDescriptor inputBuffer = null;
     if (inSecBuffer != null)
     {
         inputBuffer = new SecurityBufferDescriptor(1);
     }
     else if (inSecBuffers != null)
     {
         inputBuffer = new SecurityBufferDescriptor(inSecBuffers.Length);
     }
     SecurityBufferDescriptor outputBuffer = new SecurityBufferDescriptor(1);
     bool flag = (inFlags & SspiContextFlags.AllocateMemory) != SspiContextFlags.Zero;
     int num = -1;
     SSPIHandle handle = new SSPIHandle();
     if (refContext != null)
     {
         handle = refContext._handle;
     }
     GCHandle[] handleArray = null;
     GCHandle handle2 = new GCHandle();
     SafeFreeContextBuffer handleTemplate = null;
     try
     {
         handle2 = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);
         SecurityBufferStruct[] structArray = new SecurityBufferStruct[(inputBuffer == null) ? 1 : inputBuffer.Count];
         try
         {
             SecurityBufferStruct[] structArray3;
             if (((structArray3 = structArray) == null) || (structArray3.Length == 0))
             {
                 ptrRef = null;
                 goto Label_00A9;
             }
             fixed (IntPtr* ptrRef = structArray3)
             {
             Label_00A9:
                 if (inputBuffer != null)
                 {
                     inputBuffer.UnmanagedPointer = (void*) ptrRef;
                     handleArray = new GCHandle[inputBuffer.Count];
                     for (int i = 0; i < inputBuffer.Count; i++)
                     {
                         SecurityBuffer buffer2 = (inSecBuffer != null) ? inSecBuffer : inSecBuffers[i];
                         if (buffer2 != null)
                         {
                             structArray[i].count = buffer2.size;
                             structArray[i].type = buffer2.type;
                             if (buffer2.unmanagedToken != null)
                             {
                                 structArray[i].token = buffer2.unmanagedToken.DangerousGetHandle();
                             }
                             else if ((buffer2.token == null) || (buffer2.token.Length == 0))
                             {
                                 structArray[i].token = IntPtr.Zero;
                             }
                             else
                             {
                                 handleArray[i] = GCHandle.Alloc(buffer2.token, GCHandleType.Pinned);
                                 structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2.token, buffer2.offset);
                             }
                         }
                     }
                 }
                 SecurityBufferStruct[] structArray2 = new SecurityBufferStruct[1];
                 try
                 {
                     SecurityBufferStruct[] structArray4;
                     if (((structArray4 = structArray2) == null) || (structArray4.Length == 0))
                     {
                         ptrRef2 = null;
                         goto Label_01CF;
                     }
                     fixed (IntPtr* ptrRef2 = structArray4)
                     {
                     Label_01CF:
                         outputBuffer.UnmanagedPointer = (void*) ptrRef2;
                         structArray2[0].count = outSecBuffer.size;
                         structArray2[0].type = outSecBuffer.type;
                         if ((outSecBuffer.token == null) || (outSecBuffer.token.Length == 0))
                         {
                             structArray2[0].token = IntPtr.Zero;
                         }
                         else
                         {
                             structArray2[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
                         }
                         if (flag)
                         {
                             handleTemplate = SafeFreeContextBuffer.CreateEmptyHandle();
                         }
                         if ((refContext == null) || refContext.IsInvalid)
                         {
                             refContext = new SafeDeleteContext();
                         }
                         if ((targetName == null) || (targetName.Length == 0))
                         {
                             targetName = " ";
                         }
                         fixed (char* str = ((char*) targetName))
                         {
                             char* chPtr = str;
                             num = MustRunInitializeSecurityContext(inCredentials, handle.IsZero ? null : ((void*) &handle), (targetName == " ") ? null : ((byte*) chPtr), inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate);
                         }
                         outSecBuffer.size = structArray2[0].count;
                         outSecBuffer.type = structArray2[0].type;
                         if (outSecBuffer.size > 0)
                         {
                             outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size);
                             Marshal.Copy(structArray2[0].token, outSecBuffer.token, 0, outSecBuffer.size);
                             return num;
                         }
                         outSecBuffer.token = null;
                         return num;
                     }
                 }
                 finally
                 {
                     ptrRef2 = null;
                 }
                 return num;
             }
         }
         finally
         {
             ptrRef = null;
         }
     }
     finally
     {
         if (handleArray != null)
         {
             for (int j = 0; j < handleArray.Length; j++)
             {
                 if (handleArray[j].IsAllocated)
                 {
                     handleArray[j].Free();
                 }
             }
         }
         if (handle2.IsAllocated)
         {
             handle2.Free();
         }
         if (handleTemplate != null)
         {
             handleTemplate.Close();
         }
     }
     return num;
 }