/// <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); }
/// <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); }
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()); }
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); }
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(); } }
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); } }