Example #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
        }
Example #2
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 );
        }
Example #3
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
        }
Example #4
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);
        }