private void QueryBufferSizes(out SecurityPackageContextSizes sizes)
        {
            var contextAddRefSuccess = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                var result = NativeMethods.QueryContextAttributes(ref _handle, QueryContextAttributes.Sizes, out sizes);

                DangerousRelease();

                if (result != NativeMethods.SEC_E_OK)
                {
                    throw Win32Exception.Create(result, "Unable to get the query context attribute sizes.");
                }
            }
        }
        public void DecryptMessage(int messageLength, byte[] encryptedBytes, out byte[] decryptedBytes)
        {
            decryptedBytes = null;

            var encryptedMessage = new byte[messageLength];

            Array.Copy(encryptedBytes, 0, encryptedMessage, 0, messageLength);

            var securityTrailerLength = encryptedBytes.Length - messageLength;
            var securityTrailer       = new byte[securityTrailerLength];

            Array.Copy(encryptedBytes, messageLength, securityTrailer, 0, securityTrailerLength);

            var buffers = new[]
            {
                new SecurityBuffer(encryptedBytes, SecurityBufferType.Data),
                new SecurityBuffer(securityTrailer, SecurityBufferType.Stream)
            };

            var descriptor           = new SecurityBufferDescriptor(buffers);
            var contextAddRefSuccess = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                try
                {
                    uint quality;
                    var  result = NativeMethods.DecryptMessage(ref _handle, ref descriptor, 0, out quality);
                    if (result != NativeMethods.SEC_E_OK)
                    {
                        throw Win32Exception.Create(result, "Unable to decrypt message.");
                    }

                    decryptedBytes = descriptor.ToByteArray();
                }
                finally
                {
                    descriptor.Free();
                }
            }
        }
        public void MakeSignature(byte[] inBytes, out byte[] outBytes)
        {
            outBytes = null;

            var contextAddRefSuccess = false;

            SecurityPackageContextSizes sizes;

            QueryBufferSizes(out sizes);

            var buffers = new[]
            {
                new SecurityBuffer(new byte[sizes.SecurityTrailer], SecurityBufferType.Token),
                new SecurityBuffer(inBytes, SecurityBufferType.Data),
                new SecurityBuffer(new byte[sizes.BlockSize], SecurityBufferType.Padding)
            };

            var descriptor = new SecurityBufferDescriptor(buffers);

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                try
                {
                    var result = NativeMethods.MakeSignature(ref _handle, MakeSignatureQualityOfProtection.None, ref descriptor, 0);

                    DangerousRelease();

                    if (result != NativeMethods.SEC_E_OK)
                    {
                        throw Win32Exception.Create(result, "Unable to encrypt message.");
                    }

                    outBytes = descriptor.ToByteArray();
                }
                finally
                {
                    descriptor.Free();
                }
            }
        }
예제 #4
0
        public void Acquire()
        {
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
            }
            finally
            {
                long timestamp;
                var  result = NativeMethods.AcquireCredentialsHandle(null, PackageInfo.Name, CredentialUse, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero, ref _handle, out timestamp);
                if (result != NativeMethods.SEC_E_OK)
                {
                    SetHandleAsInvalid();
                    throw Win32Exception.Create(result, "Unable to acquire credential.");
                }

                Expiry = timestamp.ToDateTime();
            }
        }
        private void QueryContextString(QueryContextAttributes attribute, out string names)
        {
            if (attribute != QueryContextAttributes.Names && attribute != QueryContextAttributes.Authority)
            {
                throw new InvalidOperationException("Only names and authorities are strings");
            }

            var contextAddRefSuccess = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                var ptr    = new IntPtr();
                var result = NativeMethods.QueryContextAttributes(ref _handle, attribute, out ptr);

                DangerousRelease();

                if (result != NativeMethods.SEC_E_OK)
                {
                    throw Win32Exception.Create(result, "Unable to get the query context attribute names.");
                }

                names = Marshal.PtrToStringAuto(ptr);
            }
        }
예제 #6
0
        public static IList <SecurityPackageInfo> Enumerate()
        {
            var ptr = new IntPtr();

            try
            {
                var count  = 0;
                var status = NativeMethods.EnumerateSecurityPackages(ref count, ref ptr);
                if (status != 0)
                {
                    throw Win32Exception.Create(status, "Failed to get enumerate packages.");
                }
                return(ptr.ToEnumerable <SecurityPackageInfo>(count).ToArray());
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    NativeMethods.FreeContextBuffer(ptr);
                }
            }
        }
예제 #7
0
        public static SecurityPackageInfo Query(string name)
        {
            var ptr = IntPtr.Zero;

            try
            {
                var status = NativeMethods.QuerySecurityPackageInfo(name, out ptr);
                if (status != 0)
                {
                    throw Win32Exception.Create(status, "Failed to get package \"" + name + "\".");
                }
                var secPkgInfo = ptr.ToStructure <SecurityPackageInfo>();
                return(secPkgInfo);
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    NativeMethods.FreeContextBuffer(ptr);
                }
            }
        }
예제 #8
0
        public string GetPrincipalName()
        {
            var success = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref success);

                var buffer = new IntPtr();
                try
                {
                    var status = NativeMethods.QueryCredentialsAttributes(ref _handle, QueryCredentialsAttribute.Names, out buffer);
                    if (status != 0)
                    {
                        throw Win32Exception.Create(status, "Failed to query principal name");
                    }

                    return(buffer == IntPtr.Zero ? string.Empty : Marshal.PtrToStringUni(buffer));
                }
                finally
                {
                    if (buffer != IntPtr.Zero)
                    {
                        NativeMethods.FreeContextBuffer(buffer);
                    }
                }
            }
            finally
            {
                if (success)
                {
                    DangerousRelease();
                }
            }
        }
        public void AcceptToken(byte[] inBytes, out byte[] outBytes)
        {
            outBytes = null;

            var outputBuffer = new SecurityBufferDescriptor((int)_credential.PackageInfo.MaxTokenSize);

            var credentialAddRefSuccess = false;
            var contextAddRefSuccess    = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                _credential.DangerousAddRef(ref credentialAddRefSuccess);
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (credentialAddRefSuccess)
                {
                    _credential.DangerousRelease();
                    credentialAddRefSuccess = false;
                }
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                try
                {
                    var flags       = SspiContextFlags.MutualAuth;
                    var clientToken = new SecurityBufferDescriptor(inBytes);

                    uint result;
                    long timestamp;
                    var  credentialHandle = _credential.Handle;
                    if (_handle.IsZero)
                    {
                        result = NativeMethods.AcceptSecurityContext(
                            ref credentialHandle,
                            IntPtr.Zero,
                            ref clientToken,
                            flags,
                            DataRepresentation.Network,
                            ref _handle,
                            ref outputBuffer,
                            out flags,
                            out timestamp);
                    }
                    else
                    {
                        try
                        {
                            result = NativeMethods.AcceptSecurityContext(
                                ref credentialHandle,
                                ref _handle,
                                ref clientToken,
                                flags,
                                DataRepresentation.Network,
                                ref _handle,
                                ref outputBuffer,
                                out flags,
                                out timestamp);
                        }
                        finally
                        {
                            clientToken.Free();
                        }
                    }

                    _credential.DangerousRelease();
                    DangerousRelease();

                    if (result != NativeMethods.SEC_E_OK && result != NativeMethods.SEC_I_CONTINUE_NEEDED)
                    {
                        throw Win32Exception.Create(result, "Unable to initialize security context.");
                    }

                    outBytes      = outputBuffer.ToByteArray();
                    IsInitialized = result == NativeMethods.SEC_E_OK;
                }
                finally
                {
                    outputBuffer.Free();
                }
            }
        }
        public void Initialize(string servicePrincipalName, byte[] inBytes, out byte[] outBytes)
        {
            outBytes = null;

            var outputBuffer = new SecurityBufferDescriptor((int)_credential.PackageInfo.MaxTokenSize);

            var credentialAddRefSuccess = false;
            var contextAddRefSuccess    = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                _credential.DangerousAddRef(ref credentialAddRefSuccess);
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (credentialAddRefSuccess)
                {
                    _credential.DangerousRelease();
                    credentialAddRefSuccess = false;
                }
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                try
                {
                    uint result;
                    long timestamp;
                    var  credentialHandle = _credential.Handle;
                    if (inBytes == null || inBytes.Length == 0)
                    {
                        result = NativeMethods.InitializeSecurityContext(
                            ref credentialHandle,
                            IntPtr.Zero,
                            servicePrincipalName,
                            _requestedContextFlags,
                            0,
                            DataRepresentation.Network,
                            IntPtr.Zero,
                            0,
                            ref _handle,
                            ref outputBuffer,
                            out _receivedContextFlags,
                            out timestamp);
                    }
                    else
                    {
                        var serverToken = new SecurityBufferDescriptor(inBytes);

                        try
                        {
                            result = NativeMethods.InitializeSecurityContext(
                                ref credentialHandle,
                                ref _handle,
                                servicePrincipalName,
                                _requestedContextFlags,
                                0,
                                DataRepresentation.Network,
                                ref serverToken,
                                0,
                                ref _handle,
                                ref outputBuffer,
                                out _receivedContextFlags,
                                out timestamp);
                        }
                        finally
                        {
                            serverToken.Free();
                        }
                    }

                    _credential.DangerousRelease();
                    DangerousRelease();

                    if (result != NativeMethods.SEC_E_OK && result != NativeMethods.SEC_I_CONTINUE_NEEDED)
                    {
                        throw Win32Exception.Create(result, "Unable to initialize security context.");
                    }

                    outBytes      = outputBuffer.ToByteArray();
                    IsInitialized = result == NativeMethods.SEC_E_OK;
                }
                finally
                {
                    outputBuffer.Free();
                }
            }
        }
        public void VerifySignature(byte[] inBytes, out byte[] outBytes)
        {
            bool contextAddRefSuccess = false;

            SecurityPackageContextSizes sizes;

            QueryBufferSizes(out sizes);

            var buffers = new[]
            {
                new SecurityBuffer(new byte[sizes.SecurityTrailer], SecurityBufferType.Token),
                new SecurityBuffer(inBytes, SecurityBufferType.Data),
                new SecurityBuffer(new byte[sizes.BlockSize], SecurityBufferType.Padding)
            };

            var descriptor = new SecurityBufferDescriptor(buffers);

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                DangerousAddRef(ref contextAddRefSuccess);
            }
            catch (Exception ex)
            {
                if (contextAddRefSuccess)
                {
                    DangerousRelease();
                    contextAddRefSuccess = false;
                }

                if (!(ex is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                try
                {
                    var status = NativeMethods.VerifySignature(ref _handle, ref descriptor, 0, MakeSignatureQualityOfProtection.None);

                    DangerousRelease();

                    switch ((long)status)
                    {
                    case NativeMethods.SEC_E_OK:
                        outBytes = descriptor.ToByteArray();
                        break;

                    case NativeMethods.SEC_E_OUT_OF_SEQUENCE:
                    case NativeMethods.SEC_E_MESSAGE_ALTERED:
                        outBytes = null;
                        break;

                    default:
                        throw Win32Exception.Create(status, "Unable to encrypt message.");
                    }
                }
                finally
                {
                    descriptor.Free();
                }
            }
        }