public void ContentServer_SmbServer_HashRetrivalTypeInvalid() { CheckApplicability(); contentInformationUtility.RetrieveContentData(); using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(testConfig.Timeout)) { smb2Client.OpenFile( testConfig.ContentServerComputerName, testConfig.SharedFolderName, testConfig.NameOfFileWithMultipleBlocks, testConfig.SecurityPackageType, testConfig.DomainName, testConfig.UserName, testConfig.UserPassword, AccessMask.GENERIC_READ); HASH_HEADER hashHeader; byte[] hashData; uint smb2Status = 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)0xFEFEFEFE, 0, uint.MaxValue, out hashHeader, out hashData); BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, smb2Status, "The content server should return error for invalid hash retrieval type"); BaseTestSite.CaptureRequirementIfAreEqual( Smb2Status.STATUS_INVALID_PARAMETER, smb2Status, RequirementCategory.InvalidParameter, RequirementCategory.InvalidParameterMessage); smb2Client.CloseFile(); } }
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); } }
public void ContentServer_SmbServer_OffsetInvalid() { CheckApplicability(); contentInformationUtility.RetrieveContentData(); using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(testConfig.Timeout)) { smb2Client.OpenFile( testConfig.ContentServerComputerName, testConfig.SharedFolderName, testConfig.NameOfFileWithMultipleBlocks, testConfig.SecurityPackageType, testConfig.DomainName, testConfig.UserName, testConfig.UserPassword, AccessMask.GENERIC_READ); HASH_HEADER hashHeader; byte[] hashData; uint smb2Status = 0; TestUtility.DoUntilSucceed( () => (smb2Status = 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, uint.MaxValue, uint.MaxValue, out hashHeader, out hashData)) != Smb2Status.STATUS_HASH_NOT_PRESENT, testConfig.Timeout, testConfig.RetryInterval); BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, smb2Status, "The content server should return error for invalid offset"); /// If the HashRetrievalType is SRV_HASH_RETRIEVE_FILE_BASED and Offset field of the SRV_READ_HASH request is equal to or beyond the end of the file /// represented by Open.LocalOpen, the server MUST fail the SRV_READ_HASH request with error code STATUS_END_OF_FILE. BaseTestSite.CaptureRequirementIfAreEqual( Smb2Status.STATUS_END_OF_FILE, smb2Status, RequirementCategory.EndOfFile, RequirementCategory.EndOfFileMessage); smb2Client.CloseFile(); } }