/// <summary>
        /// Queries for context properties
        /// </summary>
        private SSPINative.SecPkgContext_Sizes GetContextSizes()
        {
            // check object state
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            // query context properties
            SSPINative.SecPkgContext_Sizes contextSizes = new SSPINative.SecPkgContext_Sizes();
            GCHandle gcSizes = GCHandle.Alloc(contextSizes, GCHandleType.Pinned);

            int error = SSPINative.QueryContextAttributes(
                ref _contextHandle,
                SSPINative.SECPKG_ATTR_SIZES,
                gcSizes.AddrOfPinnedObject());

            gcSizes.Free();

            if (error < 0)
            {
                throw new SSPIException(error, "Could not query security context information");
            }

            return(contextSizes);
        }
示例#2
0
        public SecurityPackage(string name)
        {
            // parameters validation
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            // query package information
            IntPtr pkgInfo;
            int    error = SSPINative.QuerySecurityPackageInfo(name, out pkgInfo);

            if (error < 0)
            {
                throw new SSPIException(error, "Could not query security package information");
            }

            try
            {
                // initialize package object
                Init(pkgInfo);
            }
            finally
            {
                SSPINative.FreeContextBuffer(pkgInfo);
            }
        }
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_contextHandle != 0)
                {
                    SSPINative.DeleteSecurityContext(ref _contextHandle);
                    _contextHandle = 0;
                }

                _disposed = true;
            }
        }
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_credHandle != 0)
                {
                    SSPINative.FreeCredentialsHandle(ref _credHandle);
                    _credHandle = 0;
                }

                _disposed = true;
            }
        }
        /// <summary>
        /// Reverts impersonation of a security context
        /// </summary>
        public void RevertContext()
        {
            // check object state
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            // revert impersonation
            int error = SSPINative.RevertSecurityContext(ref _contextHandle);

            if (error < 0)
            {
                throw new SSPIException(error, "Could not revert security context impersonation");
            }
        }
示例#6
0
        /// <summary>
        /// Verifies the signature of a message
        /// </summary>
        public void VerifySignature(SecurityContext context, byte[] message, byte[] signature)
        {
            // parameters validation
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (signature == null)
            {
                throw new ArgumentNullException("signature");
            }

            // prepare buffers
            SecurityBuffers inputBuffers = new SecurityBuffers(2);

            inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, message);
            inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, signature);

            // verify signature
            Int64 contextHandle = context.Handle;
            int   error         = SSPINative.VerifySignature(
                ref contextHandle,
                inputBuffers,
                0,
                0);

            if (error < 0)
            {
                switch (error)
                {
                case SSPINative.SEC_E_MESSAGE_ALTERED:
                    throw new SSPIException(error, "The message or signature supplied for verification has been altered");

                case SSPINative.SEC_E_OUT_OF_SEQUENCE:
                    throw new SSPIException(error, "The message supplied for verification is out of sequence");

                default:
                    throw new SSPIException(error, "Could not verify message signature");
                }
                ;
            }
        }
示例#7
0
        /// <summary>
        /// Decrypts message
        /// </summary>
        public byte[] DecryptMessage(SecurityContext context, byte[] encBuffer)
        {
            // parameters validation
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (encBuffer == null)
            {
                throw new ArgumentNullException("encMessage");
            }

            // parse encrypted buffer
            byte[] encrypted;
            byte[] trailer;
            ParseEncryptedBuffer(encBuffer, out encrypted, out trailer);

            // prepare buffers
            SecurityBuffers inputBuffers = new SecurityBuffers(2);

            inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, encrypted);
            inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, trailer);

            // encrypt message
            Int64 contextHandle = context.Handle;
            int   error         = SSPINative.DecryptMessage(
                ref contextHandle,
                inputBuffers,
                0,
                0);

            if (error < 0)
            {
                throw new SSPIException(error, "Could not decrypt message");
            }

            // get decrypted message
            byte[] message = inputBuffers.GetBuffer(0);
            inputBuffers.Dispose();

            return(message);
        }
        /// <summary>
        /// Returns security context access token
        /// </summary>
        private WindowsIdentity GetContextIdentity()
        {
            // check object state
            if (_disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }

            // query context token
            IntPtr accessToken = IntPtr.Zero;
            int    error       = SSPINative.QuerySecurityContextToken(
                ref _contextHandle,
                out accessToken);

            if (error < 0)
            {
                throw new SSPIException(error, "Could not determine security context identity");
            }

            return(new WindowsIdentity(accessToken));
        }
示例#9
0
        /// <summary>
        /// Encrypts message
        /// </summary>
        public byte[] EncryptMessage(SecurityContext context, byte[] message)
        {
            // parameters validation
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            // prepare buffers
            SecurityBuffers inputBuffers = new SecurityBuffers(2);

            inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, message);
            inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, context.SecurityTrailer);

            // encrypt message
            Int64 contextHandle = context.Handle;
            int   error         = SSPINative.EncryptMessage(
                ref contextHandle,
                0,
                inputBuffers,
                0);

            if (error < 0)
            {
                throw new SSPIException(error, "Could not encrypt message");
            }

            // get encrypted data and trailer
            byte[] encrypted = inputBuffers.GetBuffer(0);
            byte[] trailer   = inputBuffers.GetBuffer(1);
            inputBuffers.Dispose();

            // create encrypted buffer
            return(CreateEncryptedBuffer(encrypted, trailer));
        }
示例#10
0
        /// <summary>
        /// Creates the signature of a message
        /// </summary>
        public byte[] CreateSignature(SecurityContext context, byte[] message)
        {
            // parameters validation
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            // prepare buffers
            SecurityBuffers inputBuffers = new SecurityBuffers(2);

            inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_DATA, message);
            inputBuffers.SetBuffer(1, (int)SSPINative.SECBUFFER_TOKEN, context.MaxSignature);

            // create signature
            Int64 contextHandle = context.Handle;
            int   error         = SSPINative.MakeSignature(
                ref contextHandle,
                0,
                inputBuffers,
                0);

            if (error < 0)
            {
                throw new SSPIException(error, "Could not create signature");
            }

            // get signature
            byte[] signature = inputBuffers.GetBuffer(1);
            inputBuffers.Dispose();

            return(signature);
        }
示例#11
0
        /// <summary>
        /// Acquires security credentials for a current security principal
        /// </summary>
        public SecurityCredentials AcquireSecurityCredentials(
            SecurityCredentialsType credType,
            IDictionary authData)
        {
            // prepare context usage
            uint credUsage = 0;

            if ((credType & SecurityCredentialsType.InBound) != 0)
            {
                credUsage |= SSPINative.SECPKG_CRED_INBOUND;
            }
            if ((credType & SecurityCredentialsType.OutBound) != 0)
            {
                credUsage |= SSPINative.SECPKG_CRED_OUTBOUND;
            }

            // prepare identity information
            SSPINative.SecWinNTAuthIdentity authIdentity = new SSPINative.SecWinNTAuthIdentity();
            if (authData != null)
            {
                string userName = (string)authData["user"];
                if (userName != null)
                {
                    authIdentity.User       = userName;
                    authIdentity.UserLength = userName.Length;
                }
                string domain = (string)authData["domain"];
                if (domain != null)
                {
                    authIdentity.Domain       = domain;
                    authIdentity.DomainLength = domain.Length;
                }
                string password = (string)authData["password"];
                if (password != null)
                {
                    authIdentity.Password       = password;
                    authIdentity.PasswordLength = password.Length;
                }
            }

            // acquire credentials
            Int64 credHandle;
            Int64 credExpiry;

            int error = SSPINative.AcquireCredentialsHandle(
                null,
                _secPackage.Name,
                credUsage,
                IntPtr.Zero,
                authIdentity,
                IntPtr.Zero,
                IntPtr.Zero,
                out credHandle,
                out credExpiry);

            if (error < 0)
            {
                throw new SSPIException(Marshal.GetLastWin32Error(), "Could not acquire credentials handle");
            }

            // create credentials object
            return(new SecurityCredentials(_secPackage, credHandle, credExpiry, credType));
        }
示例#12
0
        /// <summary>
        /// Updates security context, proceeds input token and generates output token
        /// </summary>
        public void UpdateSecurityContext(
            SecurityContext context,
            SecurityContextAttributes contextAttributes,
            byte[] inputToken,
            out byte[] outputToken)
        {
            // parameters validation
            if (context == null)
            {
                throw new ArgumentNullException("credentials");
            }
            if (inputToken == null)
            {
                throw new ArgumentNullException("inputToken");
            }

            // prepare requirements for context
            uint contextReq = GetContextRequirements(context.Type == SecurityContextType.Server, contextAttributes);

            // prepare buffers
            SecurityBuffers inputBuffers = new SecurityBuffers(1);

            inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_TOKEN, inputToken);

            SecurityBuffers outputBuffers = new SecurityBuffers(1);

            outputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_TOKEN, _secPackage.MaxToken);

            // update context
            Int64 credHandle    = context.credentials.Handle;
            Int64 contextHandle = context.Handle;
            uint  contextAttribs;
            int   error;

            if (context.Type == SecurityContextType.Client)
            {
                error = SSPINative.InitializeSecurityContext(
                    ref credHandle,
                    ref contextHandle,
                    null,
                    contextReq,
                    0,
                    SSPINative.SECURITY_NETWORK_DREP,
                    inputBuffers,
                    0,
                    IntPtr.Zero,
                    outputBuffers,
                    out contextAttribs,
                    IntPtr.Zero);
            }
            else
            {
                error = SSPINative.AcceptSecurityContext(
                    ref credHandle,
                    ref contextHandle,
                    inputBuffers,
                    contextReq,
                    SSPINative.SECURITY_NETWORK_DREP,
                    IntPtr.Zero,
                    outputBuffers,
                    out contextAttribs,
                    IntPtr.Zero);
            }

            inputBuffers.Dispose();

            // check context state
            bool continueNeeded = false;
            bool completeNeeded = false;

            switch (error)
            {
            case Win32.ERROR_SUCCESS:
                break;

            case SSPINative.SEC_I_CONTINUE_NEEDED:
                continueNeeded = true;
                break;

            case SSPINative.SEC_I_COMPLETE_NEEDED:
                completeNeeded = true;
                break;

            case SSPINative.SEC_I_COMPLETE_AND_CONTINUE:
                continueNeeded = true;
                completeNeeded = true;
                break;

            default:
                throw new SSPIException(error, "Could not update security context");
            }

            if (completeNeeded)
            {
                // complete context
                error = SSPINative.CompleteAuthToken(ref contextHandle, outputBuffers);
                if (error < 0)
                {
                    throw new SSPIException(error, "Could not complete security context");
                }
            }

            // get output token
            outputToken = outputBuffers.GetBuffer(0);
            outputBuffers.Dispose();

            // update context object state
            if (!continueNeeded)
            {
                context.SetCompleted();
            }
        }
示例#13
0
        /// <summary>
        /// Creates security context, proceeds client token and generates server token
        /// </summary>
        public SecurityContext AcceptSecurityContext(
            SecurityCredentials credentials,
            SecurityContextAttributes contextAttributes,
            byte[] inputToken,
            out byte[] outputToken)
        {
            // parameters validation
            if (credentials == null)
            {
                throw new ArgumentNullException("credentials");
            }
            if (inputToken == null)
            {
                throw new ArgumentNullException("inputToken");
            }

            // prepare requirements for context
            uint contextReq = GetContextRequirements(true, contextAttributes);

            // prepare buffers
            SecurityBuffers inputBuffers = new SecurityBuffers(1);

            inputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_TOKEN, inputToken);

            SecurityBuffers outputBuffers = new SecurityBuffers(1);

            outputBuffers.SetBuffer(0, (int)SSPINative.SECBUFFER_TOKEN, _secPackage.MaxToken);

            // create context
            Int64 credHandle = credentials.Handle;
            Int64 newContextHandle;
            Int64 contextExpiry;
            uint  contextAttribs;

            int error = SSPINative.AcceptSecurityContext(
                ref credHandle,
                IntPtr.Zero,
                inputBuffers,
                contextReq,
                SSPINative.SECURITY_NETWORK_DREP,
                out newContextHandle,
                outputBuffers,
                out contextAttribs,
                out contextExpiry);

            inputBuffers.Dispose();

            // check context state
            bool continueNeeded = false;
            bool completeNeeded = false;

            switch (error)
            {
            case Win32.ERROR_SUCCESS:
                break;

            case SSPINative.SEC_I_CONTINUE_NEEDED:
                continueNeeded = true;
                break;

            case SSPINative.SEC_I_COMPLETE_NEEDED:
                completeNeeded = true;
                break;

            case SSPINative.SEC_I_COMPLETE_AND_CONTINUE:
                continueNeeded = true;
                completeNeeded = true;
                break;

            default:
                throw new SSPIException(error, "Could not accept security context");
            }

            if (completeNeeded)
            {
                // complete context
                error = SSPINative.CompleteAuthToken(ref newContextHandle, outputBuffers);
                if (error < 0)
                {
                    throw new SSPIException(error, "Could not complete security context");
                }
            }

            // get output token
            outputToken = outputBuffers.GetBuffer(0);
            outputBuffers.Dispose();

            // create context object
            SecurityContextState contextState = (continueNeeded ? SecurityContextState.ContinueNeeded : SecurityContextState.Completed);

            return(new SecurityContext(credentials, newContextHandle, contextExpiry, SecurityContextType.Server, contextState));
        }