public static unsafe int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute contextAttribute, byte* buffer, SafeHandle refHandle)
 {
     int num = -2146893055;
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         phContext.DangerousAddRef(ref success);
     }
     catch (Exception exception)
     {
         if (success)
         {
             phContext.DangerousRelease();
             success = false;
         }
         if (!(exception is ObjectDisposedException))
         {
             throw;
         }
     }
     finally
     {
         if (success)
         {
             num = QueryContextAttributesW(ref phContext._handle, contextAttribute, (void*) buffer);
             phContext.DangerousRelease();
         }
         if ((num == 0) && (refHandle != null))
         {
             if (refHandle is SafeFreeContextBuffer)
             {
                 if (contextAttribute == ContextAttribute.SessionKey)
                 {
                     IntPtr ptr = Marshal.ReadIntPtr(new IntPtr((void*) buffer), SecPkgContext_SessionKey.SessionkeyOffset);
                     ((SafeFreeContextBuffer) refHandle).Set(ptr);
                 }
                 else
                 {
                     ((SafeFreeContextBuffer) refHandle).Set(*((IntPtr*) buffer));
                 }
             }
             else
             {
                 ((SafeFreeCertContext) refHandle).Set(*((IntPtr*) buffer));
             }
         }
         if ((num != 0) && (refHandle != null))
         {
             refHandle.SetHandleAsInvalid();
         }
     }
     return num;
 }
 internal void CloseContext()
 {
     this.ThrowIfDisposed();
     try
     {
         if (this.securityContext != null)
         {
             this.securityContext.Close();
         }
     }
     finally
     {
         this.securityContext = null;
     }
 }
 private TlsSspiNegotiation(string destination, bool isServer, SchProtocols protocolFlags, X509Certificate2 serverCertificate, X509Certificate2 clientCertificate, bool clientCertRequired)
 {
     this.syncObject = new object();
     SspiWrapper.GetVerifyPackageInfo("Microsoft Unified Security Protocol Provider");
     this.destination = destination;
     this.isServer = isServer;
     this.protocolFlags = protocolFlags;
     this.serverCertificate = serverCertificate;
     this.clientCertificate = clientCertificate;
     this.clientCertRequired = clientCertRequired;
     this.securityContext = null;
     if (isServer)
     {
         this.ValidateServerCertificate();
     }
     else
     {
         this.ValidateClientCertificate();
     }
     if (this.isServer)
     {
         try
         {
             this.AcquireServerCredentials();
         }
         catch (Win32Exception exception)
         {
             if (exception.NativeErrorCode != -2146893043)
             {
                 throw;
             }
             if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
             {
                 System.ServiceModel.DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information);
             }
             Thread.Sleep(0);
             this.AcquireServerCredentials();
         }
     }
     else
     {
         this.AcquireDummyCredentials();
     }
 }
 private WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth, bool interactiveLogonEnabled, bool ntlmEnabled)
 {
     this.syncObject = new object();
     this.interactiveNegoLogonEnabled = true;
     this.saveClientCredentialsOnSspiUi = true;
     this.tokenSize = SspiWrapper.GetVerifyPackageInfo(package).MaxToken;
     this.isServer = isServer;
     this.servicePrincipalName = servicePrincipalName;
     this.securityContext = null;
     if (isServer)
     {
         this.impersonationLevel = TokenImpersonationLevel.Delegation;
         this.doMutualAuth = false;
     }
     else
     {
         this.impersonationLevel = impersonationLevel;
         this.doMutualAuth = doMutualAuth;
         this.interactiveNegoLogonEnabled = interactiveLogonEnabled;
         this.clientPackageName = package;
         this.allowNtlm = ntlmEnabled;
     }
     this.credentialsHandle = credentialsHandle;
 }
 public static int EncryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
 {
     int num = -2146893055;
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         context.DangerousAddRef(ref success);
     }
     catch (Exception exception)
     {
         if (success)
         {
             context.DangerousRelease();
             success = false;
         }
         if (!(exception is ObjectDisposedException))
         {
             throw;
         }
     }
     finally
     {
         if (success)
         {
             num = EncryptMessage(ref context._handle, 0, inputOutput, sequenceNumber);
             context.DangerousRelease();
         }
     }
     return num;
 }
        private void Dispose(bool disposing)
        {
            lock (this.syncObject)
            {
                if (this.disposed == false)
                {
                    this.disposed = true;
                    if (disposing)
                    {
                        if (this.securityContext != null)
                        {
                            this.securityContext.Close();
                            this.securityContext = null;
                        }
                        if (this.credentialsHandle != null)
                        {
                            this.credentialsHandle.Close();
                            this.credentialsHandle = null;
                        }
                    }

                    // set to null any references that aren't finalizable
                    this.connectionInfo = null;
                    this.destination = null;
                    this.streamSizes = null;
                }
            }
        }
        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();
                }
            }
        }
 private static unsafe int MustRunInitializeSecurityContext(SafeFreeCredentials inCredentials, void* inContextPtr, byte* targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBufferDescriptor inputBuffer, SafeDeleteContext outContext, SecurityBufferDescriptor outputBuffer, ref SspiContextFlags attributes, SafeFreeContextBuffer handleTemplate)
 {
     int num = -1;
     bool success = false;
     bool flag2 = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         inCredentials.DangerousAddRef(ref success);
         outContext.DangerousAddRef(ref flag2);
     }
     catch (Exception exception)
     {
         if (success)
         {
             inCredentials.DangerousRelease();
             success = false;
         }
         if (flag2)
         {
             outContext.DangerousRelease();
             flag2 = false;
         }
         if (!(exception is ObjectDisposedException))
         {
             throw;
         }
     }
     finally
     {
         if (!success)
         {
             inCredentials = null;
         }
         else if (success && flag2)
         {
             long num2;
             num = InitializeSecurityContextW(ref inCredentials._handle, inContextPtr, targetName, inFlags, 0, endianness, inputBuffer, 0, ref outContext._handle, outputBuffer, ref attributes, out num2);
             if ((outContext._EffectiveCredential != inCredentials) && ((num & 0x80000000L) == 0L))
             {
                 if (outContext._EffectiveCredential != null)
                 {
                     outContext._EffectiveCredential.DangerousRelease();
                 }
                 outContext._EffectiveCredential = inCredentials;
             }
             else
             {
                 inCredentials.DangerousRelease();
             }
             outContext.DangerousRelease();
             if (handleTemplate != null)
             {
                 handleTemplate.Set(outputBuffer.UnmanagedPointer.token);
                 if (handleTemplate.IsInvalid)
                 {
                     handleTemplate.SetHandleAsInvalid();
                 }
             }
         }
         if ((inContextPtr == null) && ((num & 0x80000000L) != 0L))
         {
             outContext._handle.SetToInvalid();
         }
     }
     return num;
 }
        public static unsafe object QueryContextAttributes(SafeDeleteContext securityContext, ContextAttribute contextAttribute)
        {
            int size = IntPtr.Size;
            Type handleType = null;
            switch (contextAttribute)
            {
                case ContextAttribute.Sizes:
                    size = SecSizes.SizeOf;
                    break;

                case ContextAttribute.Names:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case ContextAttribute.Lifespan:
                    size = LifeSpan_Struct.Size;
                    break;

                case ContextAttribute.StreamSizes:
                    size = StreamSizes.SizeOf;
                    break;

                case ContextAttribute.SessionKey:
                    handleType = typeof(SafeFreeContextBuffer);
                    size = SecPkgContext_SessionKey.Size;
                    break;

                case ContextAttribute.PackageInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    break;

                case ContextAttribute.NegotiationInfo:
                    handleType = typeof(SafeFreeContextBuffer);
                    size = Marshal.SizeOf(typeof(NegotiationInfo));
                    break;

                case ContextAttribute.Flags:
                    break;

                case ContextAttribute.RemoteCertificate:
                    handleType = typeof(SafeFreeCertContext);
                    break;

                case ContextAttribute.LocalCertificate:
                    handleType = typeof(SafeFreeCertContext);
                    break;

                case ContextAttribute.ConnectionInfo:
                    size = Marshal.SizeOf(typeof(SslConnectionInfo));
                    break;

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidEnumArgumentException("contextAttribute", (int) contextAttribute, typeof(ContextAttribute)));
            }
            SafeHandle refHandle = null;
            object obj2 = null;
            try
            {
                byte[] buffer = new byte[size];
                int error = QueryContextAttributes(securityContext, contextAttribute, buffer, handleType, out refHandle);
                if (error != 0)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                }
                switch (contextAttribute)
                {
                    case ContextAttribute.Sizes:
                        break;

                    case ContextAttribute.Names:
                        return Marshal.PtrToStringUni(refHandle.DangerousGetHandle());

                    case ContextAttribute.Lifespan:
                        return new LifeSpan(buffer);

                    case ContextAttribute.DceInfo:
                    case (ContextAttribute.StreamSizes | ContextAttribute.Names):
                    case ContextAttribute.Authority:
                    case (ContextAttribute.Authority | ContextAttribute.Names):
                    case ((ContextAttribute) 8):
                    case (ContextAttribute.PackageInfo | ContextAttribute.Names):
                    case (ContextAttribute.NegotiationInfo | ContextAttribute.Names):
                        return obj2;

                    case ContextAttribute.StreamSizes:
                        return new StreamSizes(buffer);

                    case ContextAttribute.SessionKey:
                        try
                        {
                            byte[] buffer4;
                            if (((buffer4 = buffer) == null) || (buffer4.Length == 0))
                            {
                                fixed (IntPtr* ptrRef2 = null)
                                {
                                }
                            }
                            obj2 = new SecuritySessionKeyClass(refHandle, Marshal.ReadInt32(new IntPtr((void*) ptrRef2)));
                        }
                        finally
                        {
                            ptrRef2 = null;
                        }
                        return obj2;

                    case ContextAttribute.PackageInfo:
                        return new SecurityPackageInfoClass(refHandle, 0);

                    case ContextAttribute.NegotiationInfo:
                        try
                        {
                            byte[] buffer3;
                            if (((buffer3 = buffer) == null) || (buffer3.Length == 0))
                            {
                                fixed (IntPtr* ptrRef = null)
                                {
                                }
                            }
                            return new NegotiationInfoClass(refHandle, Marshal.ReadInt32(new IntPtr((void*) ptrRef), NegotiationInfo.NegotiationStateOffset));
                        }
                        finally
                        {
                            ptrRef = null;
                        }
                        goto Label_026A;

                    case ContextAttribute.Flags:
                        try
                        {
                            fixed (byte* numRef = buffer)
                            {
                                return Marshal.ReadInt32(new IntPtr((void*) numRef));
                            }
                        }
                        finally
                        {
                            numRef = null;
                        }
                        break;

                    case ContextAttribute.RemoteCertificate:
                    case ContextAttribute.LocalCertificate:
                        goto Label_026A;

                    case ContextAttribute.ConnectionInfo:
                        return new SslConnectionInfo(buffer);

                    default:
                        return obj2;
                }
                return new SecSizes(buffer);
            Label_026A:
                obj2 = refHandle;
                refHandle = null;
                return obj2;
            }
            finally
            {
                if (refHandle != null)
                {
                    refHandle.Close();
                }
            }
            return obj2;
        }
 public static void ImpersonateSecurityContext(SafeDeleteContext context)
 {
     int error = SafeDeleteContext.ImpersonateSecurityContext(context);
     if (error != 0)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
     }
 }
 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);
 }
Exemplo n.º 12
0
 public static unsafe int EncryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber)
 {
     return(EncryptDecryptHelper(context, input, sequenceNumber, true, false));
 }
Exemplo n.º 13
0
 public static unsafe int DecryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber, bool isGssBlob)
 {
     return(EncryptDecryptHelper(context, input, sequenceNumber, false, isGssBlob));
 }
Exemplo n.º 14
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();
                        }
                    }
                }
            }
        }
Exemplo n.º 15
0
        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)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
                }

                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);
        }
Exemplo n.º 16
0
 public static int QuerySecurityContextToken(
     SafeDeleteContext context,
     out SafeCloseHandle token)
 {
     return(context.GetSecurityContextToken(out token));
 }
Exemplo n.º 17
0
        public static int EncryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
        {
            int status = (int)SecurityStatus.InvalidHandle;
            bool b = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                context.DangerousAddRef(ref b);
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                if (b)
                {
                    context.DangerousRelease();
                    b = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally
            {
                if (b)
                {
                    // PreSharp Bug: Call 'Marshal.GetLastWin32Error' or 'Marshal.GetHRForLastWin32Error' before any other interop call. 
#pragma warning suppress 56523 // The API does not set Win32 Last Error. It returns a error code.
                    status = EncryptMessage(ref context._handle, 0, inputOutput, sequenceNumber);
                    context.DangerousRelease();
                }
            }
            return status;
        }
 public static int ImpersonateSecurityContext(SafeDeleteContext context)
 {
     int num = -2146893055;
     bool success = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         context.DangerousAddRef(ref success);
     }
     catch (Exception exception)
     {
         if (success)
         {
             context.DangerousRelease();
             success = false;
         }
         if (!(exception is ObjectDisposedException))
         {
             throw;
         }
     }
     finally
     {
         if (success)
         {
             num = ImpersonateSecurityContext(ref context._handle);
             context.DangerousRelease();
         }
     }
     return num;
 }
Exemplo n.º 19
0
        public unsafe static int DecryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
        {
            int status = (int)SecurityStatus.InvalidHandle;
            bool b = false;
            uint qop = 0;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                context.DangerousAddRef(ref b);
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                if (b)
                {
                    context.DangerousRelease();
                    b = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally
            {

                if (b)
                {
#pragma warning suppress 56523 // we don't take any action on the win32 error message.
                    status = DecryptMessage(ref context._handle, inputOutput, sequenceNumber, &qop);
                    context.DangerousRelease();
                }
            }

            const uint SECQOP_WRAP_NO_ENCRYPT = 0x80000001;
            if (status == 0 && qop == SECQOP_WRAP_NO_ENCRYPT)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SspiPayloadNotEncrypted)));
            }

            return status;
        }
 private void Dispose(bool disposing)
 {
     lock (this.syncObject)
     {
         if (!this.disposed)
         {
             this.disposed = true;
             if (disposing)
             {
                 if (this.securityContext != null)
                 {
                     this.securityContext.Close();
                     this.securityContext = null;
                 }
                 if (this.credentialsHandle != null)
                 {
                     this.credentialsHandle.Close();
                     this.credentialsHandle = null;
                 }
             }
             this.connectionInfo = null;
             this.destination = null;
             this.streamSizes = null;
         }
     }
 }
 public static int EncryptMessage(SafeDeleteContext context, SecurityBuffer[] input, uint sequenceNumber)
 {
     return EncryptDecryptHelper(context, input, sequenceNumber, true, false);
 }
 public static int QuerySecurityContextToken(SafeDeleteContext context, out SafeCloseHandle token)
 {
     return context.GetSecurityContextToken(out token);
 }
 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);
 }
 private static unsafe int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute attribute, byte[] buffer, Type handleType, out SafeHandle refHandle)
 {
     refHandle = null;
     if (handleType != null)
     {
         if (handleType != typeof(SafeFreeContextBuffer))
         {
             if (handleType != typeof(SafeFreeCertContext))
             {
                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("handleType", System.IdentityModel.SR.GetString("ValueMustBeOf2Types", new object[] { typeof(SafeFreeContextBuffer).ToString(), typeof(SafeFreeCertContext).ToString() })));
             }
             refHandle = new SafeFreeCertContext();
         }
         else
         {
             refHandle = SafeFreeContextBuffer.CreateEmptyHandle();
         }
     }
     fixed (byte* numRef = buffer)
     {
         return SafeFreeContextBuffer.QueryContextAttributes(phContext, attribute, numRef, refHandle);
     }
 }
 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;
 }
 public static int QuerySpecifiedTarget(SafeDeleteContext securityContext, out string specifiedTarget)
 {
     int num2;
     int size = IntPtr.Size;
     Type handleType = typeof(SafeFreeContextBuffer);
     SafeHandle refHandle = null;
     specifiedTarget = null;
     try
     {
         byte[] buffer = new byte[size];
         num2 = QueryContextAttributes(securityContext, ContextAttribute.SpecifiedTarget, buffer, handleType, out refHandle);
         if (num2 != 0)
         {
             return num2;
         }
         specifiedTarget = Marshal.PtrToStringUni(refHandle.DangerousGetHandle());
     }
     finally
     {
         if (refHandle != null)
         {
             refHandle.Close();
         }
     }
     return num2;
 }
        public void CheckServiceBinding(SafeDeleteContext securityContext, string defaultServiceBinding)
        {
            if (this._policyEnforcement != System.Security.Authentication.ExtendedProtection.PolicyEnforcement.Never)
            {
                string specifiedTarget = null;
                int num = SspiWrapper.QuerySpecifiedTarget(securityContext, out specifiedTarget);
                if (num == 0)
                {
                    switch (this._policyEnforcement)
                    {
                        case System.Security.Authentication.ExtendedProtection.PolicyEnforcement.WhenSupported:
                            if (specifiedTarget != null)
                            {
                                break;
                            }
                            return;

                        case System.Security.Authentication.ExtendedProtection.PolicyEnforcement.Always:
                            if (string.IsNullOrEmpty(specifiedTarget))
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationServiceBindingNotMatched", new object[] { string.Empty })));
                            }
                            break;
                    }
                    if ((this._serviceNameCollection == null) || (this._serviceNameCollection.Count < 1))
                    {
                        if (defaultServiceBinding == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationServiceBindingNotMatched", new object[] { string.Empty })));
                        }
                        if (string.Compare(defaultServiceBinding, specifiedTarget, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            return;
                        }
                        if (string.IsNullOrEmpty(specifiedTarget))
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationServiceBindingNotMatched", new object[] { string.Empty })));
                        }
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationServiceBindingNotMatched", new object[] { specifiedTarget })));
                    }
                    foreach (string str2 in this._serviceNameCollection)
                    {
                        if ((str2 != null) && (string.Compare(str2, specifiedTarget, StringComparison.OrdinalIgnoreCase) == 0))
                        {
                            return;
                        }
                    }
                    if (string.IsNullOrEmpty(specifiedTarget))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationServiceBindingNotMatched", new object[] { string.Empty })));
                    }
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationServiceBindingNotMatched", new object[] { specifiedTarget })));
                }
                if ((num != -2146893053) && (num != -2146893054))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationNoServiceBinding")));
                }
                if (this._policyEnforcement == System.Security.Authentication.ExtendedProtection.PolicyEnforcement.Always)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationNoServiceBinding")));
                }
                if (this._policyEnforcement != System.Security.Authentication.ExtendedProtection.PolicyEnforcement.WhenSupported)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("InvalidServiceBindingInSspiNegotiationNoServiceBinding")));
                }
            }
        }
 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;
 }
Exemplo n.º 30
0
        //
        // After PInvoke call the method will fix the refHandle.handle with the returned value.
        // The caller is responsible for creating a correct SafeHandle template or null can be passed if no handle is returned.
        //
        // This method is run as non-interruptible.
        //
        public static unsafe int QueryContextAttributes(SafeDeleteContext phContext, ContextAttribute contextAttribute, byte* buffer, SafeHandle refHandle)
        {
            int status = (int)SecurityStatus.InvalidHandle;
            bool b = false;

            // We don't want to be interrupted by thread abort exceptions or unexpected out-of-memory errors failing to jit
            // one of the following methods. So run within a CER non-interruptible block.
            RuntimeHelpers.PrepareConstrainedRegions();

            try
            {
                phContext.DangerousAddRef(ref b);
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                if (b)
                {
                    phContext.DangerousRelease();
                    b = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally
            {
                if (b)
                {
                    // PreSharp Bug: Call 'Marshal.GetLastWin32Error' or 'Marshal.GetHRForLastWin32Error' before any other interop call. 
#pragma warning suppress 56523 // The API does not set Win32 Last Error. The API returns a error code.
                    status = SafeFreeContextBuffer.QueryContextAttributesW(ref phContext._handle, contextAttribute, buffer);
                    phContext.DangerousRelease();
                }
                if (status == 0 && refHandle != null)
                {
                    if (refHandle is SafeFreeContextBuffer)
                    {
                        if (contextAttribute == ContextAttribute.SessionKey)
                        {
                            IntPtr keyPtr = Marshal.ReadIntPtr(new IntPtr(buffer), SecPkgContext_SessionKey.SessionkeyOffset);
                            ((SafeFreeContextBuffer)refHandle).Set(keyPtr);
                        }
                        else
                        {
                            ((SafeFreeContextBuffer)refHandle).Set(*(IntPtr*)buffer);
                        }
                    }
                    else
                    {
                        ((SafeFreeCertContext)refHandle).Set(*(IntPtr*)buffer);
                    }
                }

                if (status != 0 && refHandle != null)
                {
                    refHandle.SetHandleAsInvalid();
                }
            }
            return status;
        }
Exemplo n.º 31
0
        //-------------------------------------------------------------------
        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;
        }
Exemplo n.º 32
0
        // After PINvoke call the method will fix the handleTemplate.handle with the returned value.
        // The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned.
        // This method is run as non-interruptible.
        static unsafe int MustRunAcceptSecurityContext(
            SafeFreeCredentials inCredentials,
            void* inContextPtr,
            SecurityBufferDescriptor inputBuffer,
            SspiContextFlags inFlags,
            Endianness endianness,
            SafeDeleteContext outContext,
            SecurityBufferDescriptor outputBuffer,
            ref SspiContextFlags outFlags,
            SafeFreeContextBuffer handleTemplate)
        {
            int errorCode = -1;
            bool b1 = false;
            bool b2 = false;

            // Run the body of this method as a non-interruptible block.
            RuntimeHelpers.PrepareConstrainedRegions();

            try
            {
                inCredentials.DangerousAddRef(ref b1);
                outContext.DangerousAddRef(ref b2);
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                if (b1)
                {
                    inCredentials.DangerousRelease();
                    b1 = false;
                }
                if (b2)
                {
                    outContext.DangerousRelease();
                    b2 = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally
            {
                long timeStamp;
                if (!b1)
                {
                    // caller should retry
                    inCredentials = null;
                }
                else if (b1 && b2)
                {

                    SSPIHandle credentialHandle = inCredentials._handle;
                    // PreSharp Bug: Call 'Marshal.GetLastWin32Error' or 'Marshal.GetHRForLastWin32Error' before any other interop call. 
#pragma warning suppress 56523 // This API does not set Win32 Last Error.
                    errorCode = AcceptSecurityContext(
                        ref credentialHandle,
                        inContextPtr,
                        inputBuffer,
                        inFlags,
                        endianness,
                        ref outContext._handle,
                        outputBuffer,
                        ref outFlags,
                        out timeStamp
                        );

                    //
                    // When a credential handle is first associated with the context we keep credential
                    // ref count bumped up to ensure ordered finalization.
                    // If the credential handle has been changed we de-ref the old one and associate the
                    //  context with the new cred handle but only if the call was successful.
                    if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0)
                    {
                        // Disassociate the previous credential handle
                        if (outContext._EffectiveCredential != null)
                            outContext._EffectiveCredential.DangerousRelease();
                        outContext._EffectiveCredential = inCredentials;
                    }
                    else
                    {
                        inCredentials.DangerousRelease();
                    }

                    outContext.DangerousRelease();

                    // The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer.
                    if (handleTemplate != null)
                    {
                        handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes
                        if (handleTemplate.IsInvalid)
                        {
                            handleTemplate.SetHandleAsInvalid();
                        }
                    }
                    if (inContextPtr == null && (errorCode & 0x80000000) != 0)
                    {
                        // an error on the first call, need to set the out handle to invalid value
                        outContext._handle.SetToInvalid();
                    }
                }
            }
            return errorCode;
        }
        private TlsSspiNegotiation(
            string destination,
            bool isServer,
            SchProtocols protocolFlags,
            X509Certificate2 serverCertificate,
            X509Certificate2 clientCertificate,
            bool clientCertRequired)
        {
            SspiWrapper.GetVerifyPackageInfo(SecurityPackage);
            this.destination = destination;
            this.isServer = isServer;
            this.protocolFlags = protocolFlags;
            this.serverCertificate = serverCertificate;
            this.clientCertificate = clientCertificate;
            this.clientCertRequired = clientCertRequired;
            this.securityContext = null;
            if (isServer)
            {
                ValidateServerCertificate();
            }
            else
            {
                ValidateClientCertificate();
            }
            if (this.isServer)
            {
                // This retry is to address intermittent failure when accessing private key (MB56153)
                try
                {
                    AcquireServerCredentials();
                }
                catch (Win32Exception ex)
                {
                    if (ex.NativeErrorCode != (int)SecurityStatus.UnknownCredential)
                    {
                        throw;
                    }

                    DiagnosticUtility.TraceHandledException(ex, TraceEventType.Information);

                    // Yield
                    Thread.Sleep(0);
                    AcquireServerCredentials();
                }
            }
            else
            {
                // delay client credentials presenting till they are asked for
                AcquireDummyCredentials();
            }
        }
 public static unsafe int DecryptMessage(SafeDeleteContext context, SecurityBufferDescriptor inputOutput, uint sequenceNumber)
 {
     int num = -2146893055;
     bool success = false;
     uint qualityOfProtection = 0;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         context.DangerousAddRef(ref success);
     }
     catch (Exception exception)
     {
         if (success)
         {
             context.DangerousRelease();
             success = false;
         }
         if (!(exception is ObjectDisposedException))
         {
             throw;
         }
     }
     finally
     {
         if (success)
         {
             num = DecryptMessage(ref context._handle, inputOutput, sequenceNumber, &qualityOfProtection);
             context.DangerousRelease();
         }
     }
     if ((num == 0) && (qualityOfProtection == 0x80000001))
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.IdentityModel.SR.GetString("SspiPayloadNotEncrypted")));
     }
     return num;
 }