Esempio n. 1
0
        /// <summary>
        /// Calls VerifySignature SSPI API function to ensure that given signature 
        /// is correct.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Established security context handle.</param>
        /// <param name="contentBuffer">Content to check the signature for.</param>
        /// <param name="signature">Stream containing the signature.</param>
        public static void VerifySignature(SspiApi.SecHandle phContext, 
            byte[] contentBuffer, byte[] signature)
        {
            SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative();
            SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[2];

            using (GCHandleKeeper pinnedSignature = new GCHandleKeeper(signature, GCHandleType.Pinned))
            {
                // the first contains the signature
                secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN;
                secBuffers[0].cbBuffer = signature.Length;
                secBuffers[0].pvBuffer = pinnedSignature.GCHandle.AddrOfPinnedObject();

                using (GCHandleKeeper pinnedContentBuffer = new GCHandleKeeper(contentBuffer, GCHandleType.Pinned))
                {
                    // and pin it for signing
                    secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA;
                    secBuffers[1].cbBuffer = contentBuffer.Length;
                    secBuffers[1].pvBuffer = pinnedContentBuffer.GCHandle.AddrOfPinnedObject();

                    using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned))
                    {
                        // setup descriptor
                        secDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                        secDesc.cBuffers = 2;
                        secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject();

                        int result = 0;
                        int pfQOP = 0;
                        if (_isNT)
                            result = VerifySignature_NT(phContext, ref secDesc, 0, ref pfQOP);
                        else
                            result = VerifySignature__(phContext, ref secDesc, 0, ref pfQOP);
                        if (result != SspiApi.SEC_E_OK)
                            throw GenuineExceptions.Get_Windows_SspiError(result);
                    }	// pin sec buffers
                }	// pin the content buffer
            }	// pin the signature buffer
        }
Esempio n. 2
0
        /// <summary>
        /// Calls MakeSignature SSPI API function and saves obtained signature to 
        /// outputSignature parameter.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Established security context handle.</param>
        /// <param name="contentBuffer">Content to make signature for.</param>
        /// <param name="outputSignature">Output stream to write signature to.</param>
        /// <param name="secPkgContext_Sizes">Security context size constants.</param>
        public static void MakeSignature(SspiApi.SecHandle phContext, 
            byte[] contentBuffer, BinaryWriter outputSignature, ref SecPkgContext_Sizes secPkgContext_Sizes)
        {
            SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative();
            SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[2];

            byte[] signBuffer = new byte[secPkgContext_Sizes.cbMaxSignature];
            using (GCHandleKeeper pinnedSignBuffer = new GCHandleKeeper(signBuffer, GCHandleType.Pinned))
            {
                // the first is for getting a sign
                secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN;
                secBuffers[0].cbBuffer = secPkgContext_Sizes.cbMaxSignature;
                secBuffers[0].pvBuffer = pinnedSignBuffer.GCHandle.AddrOfPinnedObject();

                // pin contentBuffer
                secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA;
                secBuffers[1].cbBuffer = (int) contentBuffer.Length;
                using (GCHandleKeeper pinnedContentBuffer = new GCHandleKeeper(contentBuffer, GCHandleType.Pinned))
                {
                    secBuffers[1].pvBuffer = pinnedContentBuffer.GCHandle.AddrOfPinnedObject();

                    // setup descriptor
                    secDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                    secDesc.cBuffers = 2;
                    using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned))
                    {
                        secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject();

                        int result = 0;
                        if (_isNT)
                            result = MakeSignature_NT(phContext, 0, ref secDesc, 0);
                        else
                            result = MakeSignature__(phContext, 0, ref secDesc, 0);
                        if (result != SspiApi.SEC_E_OK)
                            throw GenuineExceptions.Get_Windows_SspiError(result);

                        outputSignature.Write(signBuffer, 0, secBuffers[0].cbBuffer);
                    }	// pin sec buffers
                }	// pin the content buffer
            }	// pin the signature buffer
        }
Esempio n. 3
0
        /// <summary>
        /// Calls InitializeSecurityContext SSPI API function.
        /// Throws an exception if the call fails.
        /// receivedData parameter must be null for the first call.
        /// </summary>
        /// <param name="credHandle">Credential handle.</param>
        /// <param name="inputPhContext">Source security context.</param>
        /// <param name="outputPhContext">Created security context.</param>
        /// <param name="targetName">Target name.</param>
        /// <param name="requiredFeatures">Requested features.</param>
        /// <param name="ptsExpiry">Expiry.</param>
        /// <param name="receivedData">Input data.</param>
        /// <param name="outputStream">Output data.</param>
        /// <returns>True if security context has been succesfully built up.</returns>
        public static bool InitializeSecurityContext(SspiApi.SecHandle credHandle, 
            SspiApi.SecHandle inputPhContext, SspiApi.SecHandle outputPhContext, string targetName,
            SspiFeatureFlags requiredFeatures, ref Int64 ptsExpiry,
            Stream receivedData, Stream outputStream)
        {
            bool finalResult = false;

            // get the size of the received chunk
            int inputContentSize = 0;
            if (receivedData != null)
            {
                BinaryReader binaryReader = new BinaryReader(receivedData);
                inputContentSize = binaryReader.ReadInt32();
            }

            SspiApi.SecBufferDescNative secInputDesc = new SspiApi.SecBufferDescNative();
            SspiApi.SecBuffer secInputBuf = new SspiApi.SecBuffer();
            SspiApi.SecBufferDescNative secOutputDesc = new SspiApi.SecBufferDescNative();
            SspiApi.SecBuffer secOutputBuf = new SspiApi.SecBuffer();
            IntPtr inputDescBuffer = IntPtr.Zero;
            IntPtr outputDescBuffer = IntPtr.Zero;

            #if TRIAL
            #else
            try
            {
            #endif
                inputDescBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SspiApi.SecBufferDescNative)));
                outputDescBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SspiApi.SecBufferDescNative)));

                // setup input buffer
                secInputDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                secInputDesc.cBuffers = 1;
                secInputDesc.pBuffers = inputDescBuffer;

                secInputBuf.BufferType = SspiApi.SECBUFFER_TOKEN;
                secInputBuf.cbBuffer = inputContentSize;
                if (inputContentSize > 0)
                {
                    secInputBuf.pvBuffer = Marshal.AllocHGlobal(inputContentSize);

                    // read from the stream
                    byte[] content = new byte[inputContentSize];
                    GenuineUtility.ReadDataFromStream(receivedData, content, 0, inputContentSize);
                    Marshal.Copy(content, 0, secInputBuf.pvBuffer, inputContentSize);
                }
                else
                    secInputBuf.pvBuffer = IntPtr.Zero;

                Marshal.StructureToPtr(secInputBuf, inputDescBuffer, false);

                // setup output buffer
                secOutputDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                secOutputDesc.cBuffers = 1;
                secOutputDesc.pBuffers = outputDescBuffer;

                secOutputBuf.BufferType = SspiApi.SECBUFFER_TOKEN;
                secOutputBuf.cbBuffer = 0;
                secOutputBuf.pvBuffer = IntPtr.Zero;
                Marshal.StructureToPtr(secOutputBuf, outputDescBuffer, false);

                int fContextReq = SspiApi.ISC_REQ_REPLAY_DETECT | SspiApi.ISC_REQ_CONNECTION | SspiApi.ISC_REQ_ALLOCATE_MEMORY;
                if ((requiredFeatures & SspiFeatureFlags.Encryption) != 0)
                    fContextReq |= SspiApi.ISC_REQ_CONFIDENTIALITY;
                if ((requiredFeatures & SspiFeatureFlags.Signing) != 0)
                    fContextReq |= SspiApi.ISC_REQ_INTEGRITY;
                if ((requiredFeatures & SspiFeatureFlags.Delegation) != 0)
                    fContextReq |= SspiApi.ISC_REQ_MUTUAL_AUTH | SspiApi.ISC_REQ_DELEGATE;

                int fContextAttr = 0;

                // initialize context
                int result = 0;

                if (_isNT)
                    result = SspiApi.InitializeSecurityContext_NT(credHandle,
                        inputPhContext, targetName, fContextReq, 0,
                        SspiApi.SECURITY_NATIVE_DREP, ref secInputDesc, 0, outputPhContext,
                        ref secOutputDesc, ref fContextAttr, ref ptsExpiry);
                else
                    result = SspiApi.InitializeSecurityContext__(credHandle,
                        inputPhContext, targetName, fContextReq, 0,
                        SspiApi.SECURITY_NATIVE_DREP, ref secInputDesc, 0, outputPhContext,
                        ref secOutputDesc, ref fContextAttr, ref ptsExpiry);

            #if DEBUG
            //				GenuineLoggingServices.BinaryLogWriter.Log(LogMessageCategory.Notification, null, "SspiApi.InitializeSecurityContext",
            //					null, "SSPI InitializeSecurityContext function returned {0:X}.", result);
            #endif

                // analyze the result
                if (result == SspiApi.SEC_E_OK)
                    finalResult = true;
                else if (result == SspiApi.SEC_I_CONTINUE_NEEDED)
                    finalResult = false;
                else
                    throw GenuineExceptions.Get_Windows_SspiError(result);

                // bring out feature checking into security session built event
                if (finalResult)
                {
                    // check whether all the requested features will be available
                    if ((requiredFeatures & SspiFeatureFlags.Encryption) != 0 &&
                        (fContextAttr & SspiApi.ISC_REQ_CONFIDENTIALITY) == 0)
                        throw GenuineExceptions.Get_Windows_SspiDidNotProvideRequestedFeature("SspiFeatureFlags.Encryption");

                    if ((requiredFeatures & SspiFeatureFlags.Signing) != 0 &&
                        (fContextAttr & SspiApi.ISC_REQ_INTEGRITY) == 0)
                        throw GenuineExceptions.Get_Windows_SspiDidNotProvideRequestedFeature("SspiFeatureFlags.Signing");

                    if ((requiredFeatures & SspiFeatureFlags.Delegation) != 0 &&
                        (fContextAttr & SspiApi.ISC_REQ_DELEGATE) == 0)
                        throw GenuineExceptions.Get_Windows_SspiDidNotProvideRequestedFeature("SspiFeatureFlags.Delegation");
                }

                // copy received data from the buffer
                Marshal.PtrToStructure(outputDescBuffer, secOutputBuf);
                if (secOutputBuf.cbBuffer > 0)
                {
                    // allocate memory chunk and write content
                    byte[] content = new byte[secOutputBuf.cbBuffer];
                    Marshal.Copy(secOutputBuf.pvBuffer, content, 0, secOutputBuf.cbBuffer);

                    // write it to the stream
                    BinaryWriter binaryWriter = new BinaryWriter(outputStream);
                    binaryWriter.Write((int) secOutputBuf.cbBuffer);
                    binaryWriter.Write(content);
                }
            #if TRIAL
            #else
            }
            finally
            {
                // release allocated resources
                if (secInputBuf.pvBuffer != IntPtr.Zero)
                    Marshal.FreeHGlobal(secInputBuf.pvBuffer);
                if (secOutputBuf.pvBuffer != IntPtr.Zero)
                    SspiApi.FreeContextBuffer(secOutputBuf.pvBuffer);

                if (inputDescBuffer != IntPtr.Zero)
                    Marshal.FreeHGlobal(inputDescBuffer);

                if (outputDescBuffer != IntPtr.Zero)
                    Marshal.FreeHGlobal(outputDescBuffer);
            }
            #endif
            return finalResult;
        }
Esempio n. 4
0
        /// <summary>
        /// Calls EncryptMessage SSPI API function.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Established security context handle.</param>
        /// <param name="sourceContent">Source data.</param>
        /// <param name="outputContent">Writer to write encrypted data to.</param>
        /// <param name="secPkgContext_Sizes">Current package's sizes.</param>
        public static void EncryptMessage(SspiApi.SecHandle phContext, 
            Stream sourceContent, BinaryWriter outputContent,
            ref SecPkgContext_Sizes secPkgContext_Sizes)
        {
            SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative();
            // for token, data and padding
            SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[3];

            byte[] signature = new byte[secPkgContext_Sizes.cbSecurityTrailer];
            byte[] message = new byte[(int) sourceContent.Length];
            byte[] padding = new byte[secPkgContext_Sizes.cbBlockSize];

            GenuineUtility.ReadDataFromStream(sourceContent, message, 0, message.Length);

            using (GCHandleKeeper pinnedSignature = new GCHandleKeeper(signature, GCHandleType.Pinned))
            {
                // the first is for signature
                secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN;
                secBuffers[0].cbBuffer = signature.Length;
                secBuffers[0].pvBuffer = pinnedSignature.GCHandle.AddrOfPinnedObject();

                using (GCHandleKeeper pinnedMessage = new GCHandleKeeper(message, GCHandleType.Pinned))
                {
                    // the second contains data
                    secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA;
                    secBuffers[1].cbBuffer = message.Length;
                    secBuffers[1].pvBuffer = pinnedMessage.GCHandle.AddrOfPinnedObject();

                    using (GCHandleKeeper pinnedPadding = new GCHandleKeeper(padding, GCHandleType.Pinned))
                    {
                        // the third is for padding
                        secBuffers[2].BufferType = SspiApi.SECBUFFER_PADDING;
                        secBuffers[2].cbBuffer = padding.Length;
                        secBuffers[2].pvBuffer = pinnedPadding.GCHandle.AddrOfPinnedObject();

                        // setup descriptor
                        secDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                        secDesc.cBuffers = 3;
                        using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned))
                        {
                            secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject();

                            // make the call
                            int result = 0;
                            if (_isNT)
                                result = EncryptMessage_NT(phContext, 0, ref secDesc, 0);
                            else
                                result = EncryptMessage__(phContext, 0, ref secDesc, 0);
                            if (result != SspiApi.SEC_E_OK)
                                throw GenuineExceptions.Get_Windows_SspiError(result);

                        }
                    }

                }
            }

            // write sizes
            outputContent.Write( (int) secBuffers[0].cbBuffer );
            outputContent.Write( (int) secBuffers[1].cbBuffer );
            outputContent.Write( (int) secBuffers[2].cbBuffer );

            // and content
            outputContent.Write( signature, 0, secBuffers[0].cbBuffer );
            outputContent.Write( message, 0, secBuffers[1].cbBuffer );
            outputContent.Write( padding, 0, secBuffers[2].cbBuffer );
        }
Esempio n. 5
0
        /// <summary>
        /// Calls DecryptMessage SSPI API function.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="phContext">Established security context handle.</param>
        /// <param name="sourceContent">Stream containing encrypted data.</param>
        /// <returns>Stream containing decrypted data.</returns>
        public static Stream DecryptMessage(SspiApi.SecHandle phContext, 
            BinaryReader sourceContent)
        {
            SspiApi.SecBufferDescNative secDesc = new SspiApi.SecBufferDescNative();
            // for token, data and padding
            SspiApi.SecBufferNative[] secBuffers = new SspiApi.SecBufferNative[3];

            // read sizes
            int signatureSize = sourceContent.ReadInt32();
            int messageSize = sourceContent.ReadInt32();
            int paddingSize = sourceContent.ReadInt32();

            // allocate buffers
            byte[] signature = new byte[signatureSize];
            byte[] message = new byte[messageSize];
            byte[] padding = new byte[paddingSize];

            // read content
            GenuineUtility.ReadDataFromStream(sourceContent.BaseStream, signature, 0, signatureSize);
            GenuineUtility.ReadDataFromStream(sourceContent.BaseStream, message, 0, messageSize);
            GenuineUtility.ReadDataFromStream(sourceContent.BaseStream, padding, 0, paddingSize);

            using (GCHandleKeeper pinnedSignature = new GCHandleKeeper(signature, GCHandleType.Pinned))
            {
                // the first is for signature
                secBuffers[0].BufferType = SspiApi.SECBUFFER_TOKEN;
                secBuffers[0].cbBuffer = signatureSize;
                secBuffers[0].pvBuffer = pinnedSignature.GCHandle.AddrOfPinnedObject();

                using (GCHandleKeeper pinnedMessage = new GCHandleKeeper(message, GCHandleType.Pinned))
                {
                    // the second contains data
                    secBuffers[1].BufferType = SspiApi.SECBUFFER_DATA;
                    secBuffers[1].cbBuffer = messageSize;
                    secBuffers[1].pvBuffer = pinnedMessage.GCHandle.AddrOfPinnedObject();

                    using (GCHandleKeeper pinnedPadding = new GCHandleKeeper(padding, GCHandleType.Pinned))
                    {
                        // the third is for padding
                        secBuffers[2].BufferType = SspiApi.SECBUFFER_PADDING;
                        secBuffers[2].cbBuffer = paddingSize;
                        secBuffers[2].pvBuffer = pinnedPadding.GCHandle.AddrOfPinnedObject();

                        // setup descriptor
                        secDesc.ulVersion = SspiApi.SECBUFFER_VERSION;
                        secDesc.cBuffers = 3;
                        using (GCHandleKeeper pinnedSecBuffers = new GCHandleKeeper(secBuffers, GCHandleType.Pinned))
                        {
                            secDesc.pBuffers = pinnedSecBuffers.GCHandle.AddrOfPinnedObject();

                            // make the call
                            int result = 0;
                            int pfQOP = 0;
                            if (_isNT)
                                result = DecryptMessage_NT(phContext, ref secDesc, 0, ref pfQOP);
                            else
                                result = DecryptMessage__(phContext, ref secDesc, 0, ref pfQOP);
                            if (result != SspiApi.SEC_E_OK)
                                throw GenuineExceptions.Get_Windows_SspiError(result);
                        }
                    }

                }
            }

            // return the result
            return new MemoryStream(message, 0, secBuffers[1].cbBuffer, false, true);
        }
Esempio n. 6
0
        /// <summary>
        /// Calls AcquireCredentialsHandle SSPI API function.
        /// Throws an exception if the call fails.
        /// </summary>
        /// <param name="authIdentity">User credential.</param>
        /// <param name="packageName">Package name.</param>
        /// <param name="fCredentialUse">Exchange direction.</param>
        /// <param name="credHandle">Where to store credential handle.</param>
        /// <param name="ptsExpiry">Lifetime span.</param>
        public static void AcquireCredentialsHandle(NetworkCredential authIdentity, 
            string packageName, int fCredentialUse, SspiApi.SecHandle credHandle,
            ref Int64 ptsExpiry)
        {
            SspiApi.SEC_WINNT_AUTH_IDENTITY sspiAuthIdentity = new SspiApi.SEC_WINNT_AUTH_IDENTITY();

            #if TRIAL
            #else
            try
            {
            #endif
                // prepare identity structure
                if (authIdentity != null)
                {
                    sspiAuthIdentity.Domain = Marshal.StringToCoTaskMemAuto(authIdentity.Domain);
                    sspiAuthIdentity.User = Marshal.StringToCoTaskMemAuto(authIdentity.UserName);
                    sspiAuthIdentity.Password = Marshal.StringToCoTaskMemAuto(authIdentity.Password);

                    sspiAuthIdentity.DomainLength = authIdentity.Domain.Length;
                    sspiAuthIdentity.UserLength = authIdentity.UserName.Length;
                    sspiAuthIdentity.PasswordLength = authIdentity.Password.Length;

                    sspiAuthIdentity.Flags = Marshal.SystemDefaultCharSize == 2 ? SspiApi.SEC_WINNT_AUTH_IDENTITY_UNICODE : SspiApi.SEC_WINNT_AUTH_IDENTITY_ANSI;
                }

                int result = 0;

                // make the call
                if (authIdentity != null)
                {
                    if (_isNT)
                        result = SspiApi.AcquireCredentialsHandleIdentity_NT(IntPtr.Zero,
                            packageName, fCredentialUse, IntPtr.Zero, ref sspiAuthIdentity,
                            IntPtr.Zero, IntPtr.Zero, credHandle, ref ptsExpiry);
                    else
                        result = SspiApi.AcquireCredentialsHandleIdentity__(IntPtr.Zero,
                            packageName, fCredentialUse, IntPtr.Zero, ref sspiAuthIdentity,
                            IntPtr.Zero, IntPtr.Zero, credHandle, ref ptsExpiry);
                }
                else
                {
                    if (_isNT)
                        result = SspiApi.AcquireCredentialsHandleIdentityNull_NT(IntPtr.Zero,
                            packageName, fCredentialUse, IntPtr.Zero, IntPtr.Zero,
                            IntPtr.Zero, IntPtr.Zero, credHandle, ref ptsExpiry);
                    else
                        result = SspiApi.AcquireCredentialsHandleIdentityNull__(IntPtr.Zero,
                            packageName, fCredentialUse, IntPtr.Zero, IntPtr.Zero,
                            IntPtr.Zero, IntPtr.Zero, credHandle, ref ptsExpiry);
                }

                if (result != SspiApi.SEC_E_OK)
                    throw GenuineExceptions.Get_Windows_SspiError(result);
            #if TRIAL
            #else
            }
            finally
            {
                // release allocated memory
                if (sspiAuthIdentity.Domain != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(sspiAuthIdentity.Domain);
                if (sspiAuthIdentity.User != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(sspiAuthIdentity.User);
                if (sspiAuthIdentity.Password != IntPtr.Zero)
                    Marshal.FreeCoTaskMem(sspiAuthIdentity.Password);
            }
            #endif
        }