/// <summary>
        /// Get the pccrtp response with http header "peerdist".
        /// </summary>
        /// <param name="serverAddress"> The content server address.</param>
        /// <param name="port"> The port that the content server is listening.</param>
        /// <param name="uri"> The path of the file to request.</param>
        /// <returns>Only true can be returned that specifies the pccrtp response with
        /// http header "peerdist" is received.</returns>
        /// <exception cref="Exception">No http response with "peerdist" header is received,</exception>
        private bool GetPccrtpResponse(string serverAddress, int port, string uri)
        {
            PccrtpRequest  pccrtpRequest      = this.pccrtpStackClient.CreatePccrtpRequest(serverAddress, port, uri);
            PccrtpResponse pccrtpResponseTemp = this.pccrtpStackClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                int.Parse(Site.Properties["PCCRTP.Protocol.TimeOut"]) * 1000);
            int timesOfSendingPccrtpMsg = 1;

            while (!pccrtpResponseTemp.HttpResponse.ContentEncoding.Equals("peerdist"))
            {
                if (timesOfSendingPccrtpMsg >= 3)
                {
                    throw new InvalidOperationException(string.Format(
                                                            "Send {0} times Pccrtp request message, no http response with \"peerdist\" header is received.",
                                                            timesOfSendingPccrtpMsg));
                }

                pccrtpResponseTemp = this.pccrtpStackClient.SendHttpRequest(
                    Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                    pccrtpRequest,
                    int.Parse(Site.Properties["PCCRTP.Protocol.TimeOut"]) * 1000);
                timesOfSendingPccrtpMsg++;
            }

            this.pccrtpResponse = pccrtpResponseTemp;
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Receive a PCCRTP request message from the HTTP/1.1 client (SUT) when testing client endpoint.
        /// </summary>
        /// <returns>Return the PCCRTP request message received.</returns>
        public PccrtpRequest ReceivePccrtpRequestMessage()
        {
            TimeSpan timeOut = TimeSpan.FromSeconds(double.Parse(Site.Properties["PCCRTP.Protocol.TimeOut"]));

            this.pccrtpRequest = this.pccrtpServerStack.ReceivePccrtpRequest(timeOut);
            this.pccrtpRequest.DecodeHttpHeader(this.pccrtpRequest.HttpRequest);
            PccrtpBothRoleCapture.VerifyTransport(this.pccrtpRequest.HttpRequest.ProtocolVersion.ToString());
            PccrtpBothRoleCapture.VerifyPccrtpCommonHeader(this.pccrtpRequest.HttpHeader);
            this.VerifyPccrtpRequestRequirements();

            return(this.pccrtpRequest);
        }
Exemplo n.º 3
0
        public void ContentServer_PccrtpServer_ContentInformationVersionIncompatible()
        {
            CheckApplicability();

            PccrtpClient  pccrtpClient  = new PccrtpClient();
            PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                testConfig.ContentServerComputerName,
                testConfig.ContentServerHTTPListenPort,
                testConfig.NameOfFileWithMultipleBlocks,
                BranchCacheVersion.V2);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Send PCCRTP request to trigger hash generation");

            PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                (int)testConfig.Timeout.TotalMilliseconds);

            var contentBeforeHashGeneration = pccrtpResponse.PayloadData;

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Wait until the hash is generated on content server");

            TestUtility.DoUntilSucceed(() => sutControlAdapter.IsHTTPHashExisted(testConfig.ContentServerComputerFQDNOrNetBiosName), testConfig.Timeout, testConfig.RetryInterval);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Modify to an incompatible version");

            pccrtpRequest.HttpHeader[PccrtpConsts.XP2PPeerDistExHttpHeader] = "MinContentInformation=900.0, MaxContentInformation=999.0";

            pccrtpResponse = pccrtpClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                (int)testConfig.Timeout.TotalMilliseconds);

            var contentAfterHashGeneration = pccrtpResponse.PayloadData;

            BaseTestSite.Assert.AreNotEqual(
                "peerdist",
                pccrtpResponse.HttpResponse.ContentEncoding,
                "The content server should return file content when content information version is incompatible");

            BaseTestSite.Assert.IsTrue(
                contentAfterHashGeneration.SequenceEqual(contentBeforeHashGeneration),
                "The content server should return file content when content information version is incompatible");
        }
        /// <summary>
        /// Get the segment IDs computed using content information that is got from the content server.
        /// </summary>
        /// <param name="serverAddress"> The content server address.</param>
        /// <param name="port"> The port that the content server is listening.</param>
        /// <param name="path"> The path of the file to request.</param>
        /// <returns> Returns content info if success.</returns>
        public string[] GetSegmentIds(string serverAddress, int port, string path)
        {
            PccrtpRequest  pccrtpRequest       = this.pccrtpStackClient.CreatePccrtpRequest(serverAddress, port, path);
            PccrtpResponse pccrtpStackResponse = this.pccrtpStackClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                int.Parse(Site.Properties["PCCRR.Protocol.timeout"]) * 1000);
            List <byte[]> segmentIDs = (List <byte[]>) this.pccrtpStackClient.GetSegmentId(pccrtpStackResponse);

            List <string> segmentIdStr = new List <string>();

            foreach (byte[] segmentId in segmentIDs)
            {
                segmentIdStr.Add(ToHexString(segmentId));
            }

            return(segmentIdStr.ToArray());
        }
Exemplo n.º 5
0
        public void ContentServer_PccrtpServer_MissingDataRequestFalse()
        {
            CheckApplicability();

            PccrtpClient  pccrtpClient  = new PccrtpClient();
            PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                testConfig.ContentServerComputerName,
                testConfig.ContentServerHTTPListenPort,
                testConfig.NameOfFileWithMultipleBlocks);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Send PCCRTP request to trigger hash generation");

            PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                (int)testConfig.Timeout.TotalMilliseconds);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Wait until the hash is generated on content server");

            TestUtility.DoUntilSucceed(() => sutControlAdapter.IsHTTPHashExisted(testConfig.ContentServerComputerFQDNOrNetBiosName), testConfig.Timeout, testConfig.RetryInterval);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Modify to an incompatible version");

            pccrtpRequest.HttpHeader[PccrtpConsts.XP2PPeerDistHttpHeader] = "Version=1.0, MissingDataRequest=false";

            pccrtpResponse = pccrtpClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                (int)testConfig.Timeout.TotalMilliseconds);

            BaseTestSite.Assert.AreEqual(
                "peerdist",
                pccrtpResponse.HttpResponse.ContentEncoding,
                "The content server should return content information when MissingDataRequest is false");
        }
        /// <summary>
        /// Send a PCCRTP request message and receive a PCCRTP response message.
        /// </summary>
        /// <param name="httpVersion">Indicates the HTTP version type used.</param>
        /// <param name="isRequestPartialContent">Indicates it is requesting partical content or not.</param>
        /// <param name="uri">Indicates the URI on the SUT requested by the client.</param>
        /// <returns>Return the PCCRTP response message received.</returns>
        public PccrtpResponse SendPccrtpRequestMessage(
            HttpVersionType httpVersion,
            bool isRequestPartialContent,
            string uri)
        {
            PccrtpRequest  pccrtpRequest  = new PccrtpRequest();
            PccrtpResponse pccrtpResponse = new PccrtpResponse();
            string         serverAddress  = this.GetProperty("Environment.ContentServer.MachineName");
            int            port           = int.Parse(this.GetProperty("Environment.ContentServer.HTTP.Port"));
            int            timeOut        = (int)TimeSpan.FromSeconds(
                double.Parse(this.GetProperty("PCCRTP.Protocol.TimeOut"))).TotalMilliseconds;
            int rangeFrom = int.Parse(this.GetProperty("PCCRTP.Protocol.RangeFrom"));
            int rangeTo   = int.Parse(this.GetProperty("PCCRTP.Protocol.RangeTo"));

            if (isRequestPartialContent)
            {
                pccrtpRequest  = this.pccrtpClientStack.CreatePccrtpRequest(serverAddress, port, uri);
                pccrtpResponse = this.pccrtpClientStack.SendHttpRequest(
                    httpVersion,
                    pccrtpRequest,
                    timeOut,
                    rangeFrom,
                    rangeTo);
            }
            else
            {
                pccrtpRequest  = this.pccrtpClientStack.CreatePccrtpRequest(serverAddress, port, uri);
                pccrtpResponse = this.pccrtpClientStack.SendHttpRequest(httpVersion, pccrtpRequest, timeOut);
            }

            if (pccrtpResponse.HttpResponse.ContentEncoding.Equals("peerdist"))
            {
                PccrtpBothRoleCapture.VerifyTransport(pccrtpResponse.HttpResponse.ProtocolVersion.ToString());
                PccrtpBothRoleCapture.VerifyPccrtpCommonHeader(pccrtpResponse.HttpHeader);
                this.VerifyPccrtpResponse(pccrtpResponse);
                this.VerifyContentInfomationStructure(pccrtpResponse);
            }

            return(pccrtpResponse);
        }
Exemplo n.º 7
0
        public void ContentServer_PccrtpServer_ContentEncodingNotHavePeerDist()
        {
            CheckApplicability();

            PccrtpClient  pccrtpClient  = new PccrtpClient();
            PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                testConfig.ContentServerComputerName,
                testConfig.ContentServerHTTPListenPort,
                testConfig.NameOfFileWithMultipleBlocks);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Send PCCRTP request to trigger hash generation");

            PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest(
                Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                pccrtpRequest,
                (int)testConfig.Timeout.TotalMilliseconds);

            var contentBeforeHashGeneration = pccrtpResponse.PayloadData;

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Wait until the hash is generated on content server");

            TestUtility.DoUntilSucceed(() => sutControlAdapter.IsHTTPHashExisted(testConfig.ContentServerComputerFQDNOrNetBiosName), testConfig.Timeout, testConfig.RetryInterval);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Send HTTP request again without peerdist Accept-Encoding");

            var contentAfterHashGeneration = TestUtility.DownloadHTTPFile(testConfig.ContentServerComputerName, testConfig.NameOfFileWithMultipleBlocks);

            BaseTestSite.Assert.IsTrue(
                contentAfterHashGeneration.SequenceEqual(contentBeforeHashGeneration),
                "The content server should return file content when peerdist is not included in Accept-Encoding");
        }
        public byte[] RetrieveContentData(string filename)
        {
            switch (testConfig.ContentTransport)
            {
            case ContentInformationTransport.PCCRTP:

                PccrtpClient  pccrtpClient  = new PccrtpClient();
                PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                    testConfig.ContentServerComputerName,
                    testConfig.ContentServerHTTPListenPort,
                    filename);

                PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest(
                    Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                    pccrtpRequest,
                    (int)testConfig.Timeout.TotalMilliseconds);

                testSite.Assert.AreNotEqual(
                    "peerdist",
                    pccrtpResponse.HttpResponse.ContentEncoding,
                    "The content server should not have content information ready yet");

                return(pccrtpResponse.PayloadData);

            case ContentInformationTransport.SMB2:

                using (BranchCacheSmb2ClientTransport smb2Client = new BranchCacheSmb2ClientTransport(testConfig.Timeout, testSite, testConfig.SupportBranchCacheV1, testConfig.SupportBranchCacheV2))
                {
                    smb2Client.OpenFile(
                        testConfig.ContentServerComputerName,
                        testConfig.SharedFolderName,
                        filename,
                        testConfig.SecurityPackageType,
                        testConfig.DomainName,
                        testConfig.UserName,
                        testConfig.UserPassword,
                        AccessMask.GENERIC_READ);

                    HASH_HEADER hashHeader;
                    byte[]      hashData = null;

                    uint status = 0;

                    if (testConfig.SupportBranchCacheV1)
                    {
                        status = smb2Client.ReadHash(
                            SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                            SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1,
                            SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED,
                            0,
                            uint.MaxValue,
                            out hashHeader,
                            out hashData);

                        testSite.Assert.AreNotEqual(
                            Smb2Status.STATUS_SUCCESS,
                            status,
                            "The content server should not have content information ready yet");

                        testSite.CaptureRequirementIfAreEqual(
                            Smb2Status.STATUS_HASH_NOT_PRESENT,
                            status,
                            RequirementCategory.HashNotPresent,
                            RequirementCategory.HashNotPresentMessage);
                    }

                    if (testConfig.SupportBranchCacheV2)
                    {
                        status = smb2Client.ReadHash(
                            SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                            SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_2,
                            SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_FILE_BASED,
                            0,
                            uint.MaxValue,
                            out hashHeader,
                            out hashData);

                        testSite.Assert.AreNotEqual(
                            Smb2Status.STATUS_SUCCESS,
                            status,
                            "The content server should not have content information ready yet");

                        testSite.CaptureRequirementIfAreEqual(
                            Smb2Status.STATUS_HASH_NOT_PRESENT,
                            status,
                            RequirementCategory.HashNotPresent,
                            RequirementCategory.HashNotPresentMessage);
                    }

                    return(smb2Client.ReadAllBytes());
                }

            default:
                throw new NotImplementedException();
            }
        }
        public byte[] RetrieveContentInformation(BranchCacheVersion version, string filename)
        {
            switch (testConfig.ContentTransport)
            {
            case ContentInformationTransport.PCCRTP:

                TestUtility.DoUntilSucceed(() => sutControlAdapter.IsHTTPHashExisted(testConfig.ContentServerComputerName), testConfig.Timeout, testConfig.RetryInterval);

                PccrtpClient  pccrtpClient  = new PccrtpClient();
                PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                    testConfig.ContentServerComputerName,
                    testConfig.ContentServerHTTPListenPort,
                    filename,
                    version);

                var pccrtpResponse = pccrtpClient.SendHttpRequest(
                    Microsoft.Protocols.TestTools.StackSdk.BranchCache.Pccrtp.HttpVersionType.HttpVersion11,
                    pccrtpRequest,
                    (int)testConfig.Timeout.TotalMilliseconds);

                testSite.Assert.AreEqual(
                    "peerdist",
                    pccrtpResponse.HttpResponse.ContentEncoding,
                    "The content server should return peerdist encoded content information");

                return(pccrtpResponse.PayloadData);

            case ContentInformationTransport.SMB2:

                using (BranchCacheSmb2ClientTransport smb2Client = new BranchCacheSmb2ClientTransport(testConfig.Timeout, testSite, testConfig.SupportBranchCacheV1, testConfig.SupportBranchCacheV2))
                {
                    smb2Client.OpenFile(
                        testConfig.ContentServerComputerName,
                        testConfig.SharedFolderName,
                        filename,
                        testConfig.SecurityPackageType,
                        testConfig.DomainName,
                        testConfig.UserName,
                        testConfig.UserPassword,
                        AccessMask.GENERIC_READ);

                    HASH_HEADER hashHeader;
                    byte[]      hashData = null;

                    TestUtility.DoUntilSucceed(
                        () => smb2Client.ReadHash(
                            SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                            version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1 : SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_2,
                            version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED : SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_FILE_BASED,
                            0,
                            uint.MaxValue,
                            out hashHeader,
                            out hashData) == Smb2Status.STATUS_SUCCESS,
                        testConfig.Timeout,
                        testConfig.RetryInterval);

                    testSite.Assert.AreNotEqual(
                        0,
                        hashData.Length,
                        "The content server should return content information in READ_HASH_RESPONSE");

                    return(hashData);
                }

            default:
                throw new NotImplementedException();
            }
        }
Exemplo n.º 10
0
        private void executeButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (!CheckInput())
                {
                    return;
                }

                logger.Clear();

                #region Read settings from UI

                var version       = (BranchCacheVersion)branchCacheVersionComboBox.SelectedItem;
                var operationMode = (OperationMode)operationModeComboBox.SelectedItem;
                var transport     = (ContentInformationTransport)transportComboBox.SelectedItem;

                var serverSecret = serverSecretTextBox.Text;
                var filePath     = filePathTextBox.Text;

                var           hashAlgoValue = (dwHashAlgo_Values)hashAlgorithmComboBox.SelectedItem;
                HashAlgorithm hashAlgorithm;
                HMAC          hmacAlgorithm;
                int           hashBlockSize;

                string server        = null;
                string file          = null;
                string sharedFolder  = null;
                Match  filePathMatch = null;
                switch (transport)
                {
                case ContentInformationTransport.PCCRTP:
                    filePathMatch = Regex.Match(filePath, httpFilePathPattern);
                    server        = filePathMatch.Groups["Server"].Value;
                    file          = filePathMatch.Groups["FileName"].Value;
                    break;

                case ContentInformationTransport.SMB2:
                    filePathMatch = Regex.Match(filePath, smb2FilePathPattern);
                    server        = filePathMatch.Groups["Server"].Value;
                    sharedFolder  = filePathMatch.Groups["SharedFolder"].Value;
                    file          = filePathMatch.Groups["FileName"].Value;
                    break;

                default:
                    throw new NotImplementedException();
                }


                SecurityPackageType securityPackageType = (SecurityPackageType)smb2AuthenticationComboBox.SelectedItem;

                string domainName   = domainNameTextBox.Text;
                string userName     = userNameTextBox.Text;
                string userPassword = userPasswordTextBox.Text;

                #endregion

                var timeout = TimeSpan.FromSeconds(60);

                byte[] content;
                byte[] contentInformation;

                Content_Information_Data_Structure    contentInformationStructure   = new Content_Information_Data_Structure();
                Content_Information_Data_Structure_V2 contentInformationStructureV2 = new Content_Information_Data_Structure_V2();

                #region Read content and content information

                if (operationMode == OperationMode.RemoteHashVerification)
                {
                    switch (transport)
                    {
                    case ContentInformationTransport.PCCRTP:
                        PccrtpClient  pccrtpClient  = new PccrtpClient();
                        PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                            server,
                            80,
                            file,
                            version);
                        PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest(
                            HttpVersionType.HttpVersion11,
                            pccrtpRequest,
                            (int)timeout.TotalMilliseconds);

                        if (pccrtpResponse.HttpResponse.ContentEncoding == "peerdist")
                        {
                            contentInformation = pccrtpResponse.PayloadData;

                            content = Utility.DownloadHTTPFile(server, file);
                        }
                        else
                        {
                            content = pccrtpResponse.PayloadData;

                            Thread.Sleep(5000);     // Wait for hash generation

                            pccrtpResponse = pccrtpClient.SendHttpRequest(
                                HttpVersionType.HttpVersion11,
                                pccrtpRequest,
                                (int)timeout.TotalMilliseconds);

                            contentInformation = pccrtpResponse.PayloadData;
                        }

                        break;

                    case ContentInformationTransport.SMB2:
                        using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(timeout))
                        {
                            smb2Client.OpenFile(
                                server,
                                sharedFolder,
                                file,
                                securityPackageType,
                                domainName,
                                userName,
                                userPassword,
                                AccessMask.GENERIC_READ);

                            content = smb2Client.ReadAllBytes();

                            Thread.Sleep(5000);     // Wait for hash generation

                            HASH_HEADER hashHeader;
                            smb2Client.ReadHash(
                                SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                                version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1 : SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_2,
                                version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED : SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_FILE_BASED,
                                0,
                                uint.MaxValue,
                                out hashHeader,
                                out contentInformation);
                        }

                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    switch (version)
                    {
                    case BranchCacheVersion.V1:
                        contentInformationStructure = PccrcUtility.ParseContentInformation(contentInformation);
                        break;

                    case BranchCacheVersion.V2:
                        contentInformationStructureV2 = PccrcUtility.ParseContentInformationV2(contentInformation);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    content = File.ReadAllBytes(filePath);
                }

                #endregion

                #region Calculate hash and execute verification

                switch (version)
                {
                case BranchCacheVersion.V1:

                    if (operationMode == OperationMode.RemoteHashVerification)
                    {
                        PccrcUtility.GetHashAlgorithm(contentInformationStructure.dwHashAlgo, out hashAlgorithm, out hmacAlgorithm, out hashBlockSize);
                    }
                    else
                    {
                        PccrcUtility.GetHashAlgorithm(hashAlgoValue, out hashAlgorithm, out hmacAlgorithm, out hashBlockSize);
                    }
                    hmacAlgorithm.Key = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(serverSecret));

                    logger.LogInfo(
                        "Ks = Hash(ServerSecret): {0}",
                        Utility.ToHexString(hmacAlgorithm.Key));

                    logger.NewLine();

                    int blockTotalCount = content.Length / BLOCKBYTECOUNT;
                    if (content.Length > BLOCKBYTECOUNT * blockTotalCount)
                    {
                        blockTotalCount = blockTotalCount + 1;
                    }

                    int segmentCount = blockTotalCount / SEGMENTBLOCKCOUNT;
                    if (blockTotalCount > SEGMENTBLOCKCOUNT * segmentCount)
                    {
                        segmentCount = segmentCount + 1;
                    }

                    for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++)
                    {
                        logger.LogInfo("Segment{0}", segmentIndex);
                        logger.NewLine();
                        logger.Indent();

                        List <byte> blockHashList = new List <byte>();

                        List <byte> tempList = new List <byte>();

                        int blockCount = (segmentIndex == segmentCount - 1) ? (blockTotalCount % SEGMENTBLOCKCOUNT) : (SEGMENTBLOCKCOUNT);

                        for (int blockIndex = 0; blockIndex < blockCount; blockIndex++)
                        {
                            logger.LogInfo(
                                "Block{0} Offset {1} Length {2}",
                                blockIndex,
                                BLOCKBYTECOUNT * SEGMENTBLOCKCOUNT * segmentIndex + BLOCKBYTECOUNT * blockIndex,
                                BLOCKBYTECOUNT);
                            logger.NewLine();
                            logger.Indent();

                            var block = content.Skip(BLOCKBYTECOUNT * SEGMENTBLOCKCOUNT * segmentIndex + BLOCKBYTECOUNT * blockIndex).Take(BLOCKBYTECOUNT).ToArray();

                            byte[] blockHash = hashAlgorithm.ComputeHash(block);

                            logger.LogInfo("BlockHash{0} = Hash(Block): {1}", blockIndex, Utility.ToHexString(blockHash));

                            if (operationMode == OperationMode.RemoteHashVerification &&
                                !blockHash.SequenceEqual(contentInformationStructure.blocks[segmentIndex].BlockHashes.Skip(blockIndex * hashBlockSize).Take(hashBlockSize)))
                            {
                                logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.blocks[segmentIndex].BlockHashes.Skip(blockIndex * hashBlockSize).Take(hashBlockSize).ToArray()));
                            }

                            blockHashList.AddRange(blockHash);

                            logger.Unindent();
                            logger.NewLine();
                        }

                        byte[] hod = hashAlgorithm.ComputeHash(blockHashList.ToArray());

                        logger.LogInfo(
                            "HoD = Hash(BlockHash0 + BlockHash1 + ... + BlockHashN): {0}",
                            Utility.ToHexString(hod));

                        if (operationMode == OperationMode.RemoteHashVerification &&
                            !hod.SequenceEqual(contentInformationStructure.segments[segmentIndex].SegmentHashOfData))
                        {
                            logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.segments[segmentIndex].SegmentHashOfData));
                        }

                        logger.NewLine();

                        byte[] kp = hmacAlgorithm.ComputeHash(hod);

                        logger.LogInfo(
                            "Kp = HMAC(Ks, HoD): {0}",
                            Utility.ToHexString(kp));

                        if (operationMode == OperationMode.RemoteHashVerification &&
                            !kp.SequenceEqual(contentInformationStructure.segments[segmentIndex].SegmentSecret))
                        {
                            logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.segments[segmentIndex].SegmentSecret));
                        }

                        logger.NewLine();

                        tempList.AddRange(hod);
                        tempList.AddRange(Encoding.Unicode.GetBytes(HOHODK_APPEND_STRING));

                        byte[] hoHoDK = hashAlgorithm.ComputeHash(tempList.ToArray());

                        logger.LogInfo(
                            "hoHoDK = HMAC(HoD + \"MS_P2P_CACHING\"): {0}",
                            Utility.ToHexString(hoHoDK));

                        logger.NewLine();

                        logger.Unindent();
                    }
                    break;

                case BranchCacheVersion.V2:

                    PccrcUtility.GetHashAlgorithm(dwHashAlgoV2_Values.TRUNCATED_SHA512, out hashAlgorithm, out hmacAlgorithm);
                    hmacAlgorithm.Key = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(serverSecret)).Take(32).ToArray();

                    logger.LogInfo(
                        "Ks = Hash(ServerSecret): {0}",
                        Utility.ToHexString(hmacAlgorithm.Key));

                    logger.NewLine();

                    int segmentLength = BLOCKBYTECOUNT;
                    int chunkCount    = 1;

                    if (operationMode == OperationMode.RemoteHashVerification)
                    {
                        chunkCount = contentInformationStructureV2.chunks.Length;
                    }

                    int segmentOffset = 0;
                    for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++)
                    {
                        logger.LogInfo("Chunk{0}", chunkIndex);
                        logger.NewLine();
                        logger.Indent();

                        segmentCount = content.Length / segmentLength;
                        if (content.Length > segmentCount * segmentLength)
                        {
                            segmentCount++;
                        }

                        if (operationMode == OperationMode.RemoteHashVerification)
                        {
                            segmentCount = contentInformationStructureV2.chunks[chunkIndex].chunkData.Length;
                        }

                        for (int segmentIndex = 0; segmentIndex < segmentCount; ++segmentIndex)
                        {
                            logger.LogInfo(
                                "Segment{0} Offset {1} Length {2}",
                                segmentIndex,
                                segmentOffset,
                                BLOCKBYTECOUNT);
                            logger.NewLine();
                            logger.Indent();

                            if (operationMode == OperationMode.RemoteHashVerification)
                            {
                                segmentLength = (int)contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].cbSegment;
                            }

                            List <byte> tempList = new List <byte>();

                            var segment = content.Skip(segmentOffset).Take(segmentLength).ToArray();

                            segmentOffset += segmentLength;

                            //TRANCATED_SHA_512
                            byte[] hod = hashAlgorithm.ComputeHash(segment).Take(32).ToArray();

                            logger.LogInfo(
                                "HoD = Hash(Segment): {0}",
                                Utility.ToHexString(hod));

                            if (operationMode == OperationMode.RemoteHashVerification &&
                                !hod.SequenceEqual(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentHashOfData))
                            {
                                logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentHashOfData));
                            }

                            logger.NewLine();

                            byte[] kp = hmacAlgorithm.ComputeHash(hod).Take(32).ToArray();

                            logger.LogInfo(
                                "Kp = HMAC(Ks, HoD): {0}",
                                Utility.ToHexString(kp));

                            if (operationMode == OperationMode.RemoteHashVerification &&
                                !kp.SequenceEqual(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentSecret))
                            {
                                logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentSecret));
                            }

                            logger.NewLine();

                            tempList.AddRange(hod);
                            tempList.AddRange(Encoding.Unicode.GetBytes(HOHODK_APPEND_STRING));

                            byte[] hoHoDK = hashAlgorithm.ComputeHash(tempList.ToArray());

                            logger.LogInfo(
                                "hoHoDK = HMAC(HoD + \"MS_P2P_CACHING\"): {0}",
                                Utility.ToHexString(hoHoDK));

                            logger.NewLine();

                            logger.Unindent();
                        }
                    }

                    break;

                default:
                    throw new NotImplementedException();
                }

                if (operationMode == OperationMode.RemoteHashVerification)
                {
                    if (logger.HasError)
                    {
                        Utility.ShowMessageBox("Hash verification error found!", MessageBoxIcon.Error);
                    }
                    else
                    {
                        Utility.ShowMessageBox("Hash verification passed!", MessageBoxIcon.Information);
                    }
                }

                #endregion
            }
            catch (Exception ex)
            {
                Utility.ShowMessageBox(ex.Message + "\r\n\r\n" + ex.StackTrace, MessageBoxIcon.Error);
            }
        }