Signature Object
Inheritance: StreamObject
        /// <summary>
        /// Get the signature for single chunk.
        /// </summary>
        /// <param name="header">The data of file header.</param>
        /// <param name="dataFile">The data of data file.</param>
        /// <returns>An instance of SignatureObject.</returns>
        private SignatureObject GetSingleChunkSignature(byte[] header, byte[] dataFile)
        {
            SHA1 sha = new SHA1CryptoServiceProvider();

            byte[] headerSignature = sha.ComputeHash(header);
            sha.Dispose();
            byte[] singleSignature = null;

            if (SharedContext.Current.CellStorageVersionType.MinorVersion >= 2)
            {
                singleSignature = new byte[dataFile.Length];

                for (int i = 0; i < headerSignature.Length; i++)
                {
                    singleSignature[i] = (byte)(headerSignature[i] ^ dataFile[i]);
                }
            }
            else
            {
                List <byte> tmp = new List <byte>();
                tmp.AddRange(headerSignature);
                tmp.AddRange(dataFile);

                singleSignature = tmp.ToArray();
            }

            SignatureObject signature = new SignatureObject();

            signature.SignatureData = new BinaryItem(singleSignature);

            return(signature);
        }
        /// <summary>
        /// Get the signature for data file.
        /// </summary>
        /// <param name="array">The input data.</param>
        /// <returns>An instance of SignatureObject.</returns>
        private SignatureObject GetDataFileSignature(byte[] array)
        {
            SignatureObject signature = new SignatureObject();

            signature.SignatureData = new BinaryItem(array);

            return(signature);
        }
        /// <summary>
        /// Get signature with SHA1 algorithm.
        /// </summary>
        /// <param name="array">The input data.</param>
        /// <returns>An instance of SignatureObject.</returns>
        private SignatureObject GetSHA1Signature(byte[] array)
        {
            SHA1 sha = new SHA1CryptoServiceProvider();

            byte[] temp = sha.ComputeHash(array);
            sha.Dispose();

            SignatureObject signature = new SignatureObject();

            signature.SignatureData = new BinaryItem(temp);
            return(signature);
        }
Example #4
0
        /// <summary>
        /// This method is used to verify the signature object related requirements.
        /// </summary>
        /// <param name="instance">Specify the signature object instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public void VerifySignatureObject(SignatureObject instance, ITestSite site)
        {
            // If the instance is not null and there are no parsing errors, then the SignatureObject related adapter requirements can be directly captured.
            if (null == instance)
            {
                site.Assert.Fail("The instance of type SignatureObject is null due to parsing error or type casting error.");
            }

            // Verify the stream object header related requirements.
            this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site);

            this.ExpectSingleObject(instance.StreamObjectHeaderStart, site);
        }
        /// <summary>
        /// This method is used to verify the signature object related requirements.
        /// </summary>
        /// <param name="instance">Specify the signature object instance.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public void VerifySignatureObject(SignatureObject instance, ITestSite site)
        {
            // If the instance is not null and there are no parsing errors, then the SignatureObject related adapter requirements can be directly captured.
            if (null == instance)
            {
                site.Assert.Fail("The instance of type SignatureObject is null due to parsing error or type casting error.");
            }

            // Verify the stream object header related requirements.
            this.ExpectStreamObjectHeaderStart(instance.StreamObjectHeaderStart, instance.GetType(), site);

            this.ExpectSingleObject(instance.StreamObjectHeaderStart, site);
        }
Example #6
0
            /// <summary>
            /// This method is used to build intermediate node object from a byte array with a signature.
            /// </summary>
            /// <param name="array">Specify the byte array.</param>
            /// <param name="signature">Specify the signature.</param>
            /// <returns>Return the intermediate node object.</returns>
            public LeafNodeObject Build(byte[] array, SignatureObject signature)
            {
                LeafNodeObject nodeObject = new LeafNodeObject();

                nodeObject.DataSize          = new DataSizeObject();
                nodeObject.DataSize.DataSize = (ulong)array.Length;

                nodeObject.Signature = signature;
                nodeObject.ExGuid    = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());

                nodeObject.DataNodeObjectData         = new DataNodeObjectData(array, 0, array.Length);
                nodeObject.IntermediateNodeObjectList = null;

                // Now in the current implementation, one intermediate node only contain one single data object node.
                return(nodeObject);
            }
Example #7
0
        /// <summary>
        /// Get signature for the chunk.
        /// </summary>
        /// <param name="array">The data of the chunk.</param>
        /// <returns>The signature instance.</returns>
        private SignatureObject GetSignature(byte[] array)
        {
            if (this.FileContent.Length <= 250 * 1024 * 1024)
            {
                SHA1   sha  = new SHA1CryptoServiceProvider();
                byte[] temp = sha.ComputeHash(array);
                sha.Dispose();

                SignatureObject signature = new SignatureObject();
                signature.SignatureData = new BinaryItem(temp);
                return(signature);
            }
            else
            {
                throw new NotImplementedException("When the file size is larger than 250MB, the signature method is not implemented.");
            }
        }
Example #8
0
        /// <summary>
        /// This method is used to analyze the chunk for simple chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which is needed to be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(IntermediateNodeObject rootNode, ITestSite site)
        {
            if (rootNode.DataSize.DataSize <= 1024 * 1024)
            {
                // These would be something ignored for MOSS2010, when the file size is less than 1MB.
                // In this case the server will response data without signature, but to be consistent with the behavior,
                // The Simple chunk still will be used, but empty signature check will be ignored.
                return;
            }
            else if (rootNode.DataSize.DataSize <= 250 * 1024 * 1024)
            {
                foreach (LeafNodeObject interNode in rootNode.IntermediateNodeObjectList)
                {
                    SignatureObject expect    = this.GetSignature(interNode.DataNodeObjectData.ObjectData);
                    SignatureObject realValue = interNode.Signature;
                    if (!expect.Equals(interNode.Signature))
                    {
                        site.Assert.Fail("Expect the signature value {0}, but actual value is {1}", expect.ToString(), realValue.ToString());
                    }

                    site.Assert.IsTrue(interNode.DataSize.DataSize <= 1024 * 1024, "The size of each chunk should be equal or less than 1MB for simple chunk.");

                    site.Assert.AreEqual <ulong>(
                        (ulong)interNode.GetContent().Count,
                        interNode.DataSize.DataSize,
                        "Expect the data size value equal the number represented by the chunk.");

                    site.Assert.IsNotNull(
                        interNode.DataNodeObjectData,
                        "The Object References array of the Intermediate Node Object associated with this Data Node Object MUST have a single entry which MUST be the Object ID of the Data Node Object.");
                }

                site.Log.Add(LogEntryKind.Debug, "All the intermediate signature value matches.");

                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                {
                    MsfsshttpdCapture.VerifySimpleChunk(SharedContext.Current.Site);
                }
            }
            else
            {
                throw new NotImplementedException("When the file size is larger than 250MB, because the signature method is not implemented, the analysis method is also not implemented.");
            }
        }
Example #9
0
        /// <summary>
        /// Get a chunk with the input bytes.
        /// </summary>
        /// <param name="chunkStart">The start index of the chunk.</param>
        /// <param name="chunkEnd">The end index of the chunk.</param>
        /// <returns>An IntermediateNodeObject which contains a chunk.</returns>
        private IntermediateNodeObject GetChunk(uint chunkStart, uint chunkEnd)
        {
            if (chunkEnd <= chunkStart || (chunkEnd - chunkStart > this.maxChunkSize) || chunkStart > uint.MaxValue)
            {
                throw new ArgumentOutOfRangeException("chunkStart");
            }

            byte[] temp = AdapterHelper.GetBytes(this.FileContent, (int)chunkStart, (int)(chunkEnd - chunkStart));

            byte[] signatureBytes = null;
            using (RDCSignatureGenerator generator = new RDCSignatureGenerator())
            {
                signatureBytes = generator.ComputeHash(temp);
            }

            SignatureObject signature = new SignatureObject();

            signature.SignatureData = new BinaryItem(signatureBytes);

            return(new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(temp, signature));
        }
Example #10
0
        /// <summary>
        /// Override the equals method.
        /// </summary>
        /// <param name="obj">Specify the compared instance.</param>
        /// <returns>If equals return true, otherwise return false.</returns>
        public override bool Equals(object obj)
        {
            SignatureObject so = obj as SignatureObject;

            if (so == null)
            {
                return(false);
            }

            if (so.SignatureData != null && this.SignatureData != null)
            {
                return(so.SignatureData.Equals(this.SignatureData));
            }
            else if (so.SignatureData == null && this.SignatureData == null)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Get the signature for single chunk.
        /// </summary>
        /// <param name="header">The data of file header.</param>
        /// <param name="dataFile">The data of data file.</param>
        /// <returns>An instance of SignatureObject.</returns>
        private SignatureObject GetSingleChunkSignature(byte[] header, byte[] dataFile)
        {
            SHA1 sha = new SHA1CryptoServiceProvider();
            byte[] headerSignature = sha.ComputeHash(header);
            sha.Dispose();
            byte[] singleSignature = null;

            if (SharedContext.Current.CellStorageVersionType.MinorVersion >= 2)
            {
                singleSignature = new byte[dataFile.Length];

                for (int i = 0; i < headerSignature.Length; i++)
                {
                    singleSignature[i] = (byte)(headerSignature[i] ^ dataFile[i]);
                }
            }
            else
            {
                List<byte> tmp = new List<byte>();
                tmp.AddRange(headerSignature);
                tmp.AddRange(dataFile);

                singleSignature = tmp.ToArray(); 
            }

            SignatureObject signature = new SignatureObject();
            signature.SignatureData = new BinaryItem(singleSignature);

            return signature;
        }
        /// <summary>
        /// Get signature for the chunk.
        /// </summary>
        /// <param name="array">The data of the chunk.</param>
        /// <returns>The signature instance.</returns>
        private SignatureObject GetSignature(byte[] array)
        {
            if (this.FileContent.Length <= 250 * 1024 * 1024)
            {
                SHA1 sha = new SHA1CryptoServiceProvider();
                byte[] temp = sha.ComputeHash(array);
                sha.Dispose();

                SignatureObject signature = new SignatureObject();
                signature.SignatureData = new BinaryItem(temp);
                return signature;
            }
            else
            {
                throw new NotImplementedException("When the file size is larger than 250MB, the signature method is not implemented.");
            }
        }
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(IntermediateNodeObject rootNode, ITestSite site)
        {
            List <LeafNodeObject> cloneList = new List <LeafNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                LeafNodeObject nodeObject = cloneList.First();
                byte[]         content    = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header         = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int    headerLength   = header.Length;
                        int    compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            if (Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointFoundation2010" && Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointServer2010")
                            {
                                LeafNodeObject expectNode = new LeafNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                                if (!expectNode.Signature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                                }
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8213, SharedContext.Current.Site))
                                {
                                    bool isR8213Verified = false;
                                    if (compressedSize > 1024 * 1024 && nodeObject.IntermediateNodeObjectList.Count > 1)
                                    {
                                        isR8213Verified = true;
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8213Verified,
                                        "MS-FSSHTTPD",
                                        8213,
                                        @"[In Appendix A: Product Behavior] For implementation, if the number of .ZIP file bytes represented by a chunk is greater than 1 megabyte, a list of subchunks is generated. <4> Section 2.4.1:  For SharePoint Server 2010, if the number of .ZIP file bytes represented by a chunk is greater than 1 megabyte, a list of subchunks is generated.");
                                }

                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8207, SharedContext.Current.Site))
                                {
                                    bool isR8207Verified = false;
                                    if (compressedSize > 3 * 1024 * 1024 && nodeObject.IntermediateNodeObjectList.Count > 1)
                                    {
                                        isR8207Verified = true;
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8207Verified,
                                        "MS-FSSHTTPD",
                                        8207,
                                        @"[In Appendix A: Product Behavior] For implementation, if the number of .ZIP file bytes represented by a chunk is greater than 3 megabytes, a list of subchunks is generated. (Microsoft Office 2013/Microsoft SharePoint Foundation 2013/Microsoft SharePoint Server 2013/Microsoft SharePoint Workspace 2010/Microsft Office 2016/Microsft SharePoint Server 2016 follow this behavior.)");
                                }

                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8208, SharedContext.Current.Site) && Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8210, SharedContext.Current.Site))
                                {
                                    bool isR8208Verified = true;
                                    bool isR8210Verified = true;
                                    if (nodeObject.IntermediateNodeObjectList[nodeObject.IntermediateNodeObjectList.Count - 1].DataSize.DataSize > 1024 * 1024)
                                    {
                                        isR8208Verified = false;
                                    }

                                    for (int i = 0; i < nodeObject.IntermediateNodeObjectList.Count - 1; i++)
                                    {
                                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != 1024 * 1024)
                                        {
                                            isR8210Verified = false;
                                        }
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8208Verified,
                                        "MS-FSSHTTPD",
                                        8208,
                                        @"[In Appendix A: Product Behavior] The size of each subchunk is at most 1 megabyte. (Microsoft SharePoint Server 2010 follows this behavior.)");

                                    site.CaptureRequirementIfIsTrue(
                                        isR8210Verified,
                                        "MS-FSSHTTPD",
                                        8210,
                                        @"[In Appendix A: Product Behavior] All but the last subchunk MUST be 1 megabyte in size. (Microsfot SharePoint Server 2010 follows this behavior.)");
                                }

                                if (Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8209, SharedContext.Current.Site) && Common.IsRequirementEnabled("MS-FSSHTTP-FSSHTTPB", 8211, SharedContext.Current.Site))
                                {
                                    bool isR8209Verified = true;
                                    bool isR8211Verified = true;
                                    if (nodeObject.IntermediateNodeObjectList[nodeObject.IntermediateNodeObjectList.Count - 1].DataSize.DataSize > 3 * 1024 * 1024)
                                    {
                                        isR8209Verified = false;
                                    }

                                    for (int i = 0; i < nodeObject.IntermediateNodeObjectList.Count - 1; i++)
                                    {
                                        if (nodeObject.IntermediateNodeObjectList[i].DataSize.DataSize != 3 * 1024 * 1024)
                                        {
                                            isR8211Verified = false;
                                        }
                                    }

                                    site.CaptureRequirementIfIsTrue(
                                        isR8209Verified,
                                        "MS-FSSHTTPD",
                                        8209,
                                        @"[In Appendix A: Product Behavior] The size of each subchunk is at most 3 megabytes. (Microsoft Office 2013/Microsoft SharePoint Foundation 2013/Microsoft SharePoint Server 2013/Microsoft SharePoint Workspace 2010/Microsft Office 2016/Microsft SharePoint Server 2016 follow this behavior.)");

                                    site.CaptureRequirementIfIsTrue(
                                        isR8211Verified,
                                        "MS-FSSHTTPD",
                                        8211,
                                        @"[In Appendix A: Product Behavior] All but the last subchunk MUST be 3 megabyte in size. (Microsoft Office 2013/Microsoft SharePoint Foundation 2013/Microsoft SharePoint Server 2013/Microsoft SharePoint Workspace 2010/Microsft Office 2016/Microsft SharePoint Server 2016 follow this behavior.)");
                                }
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual <ulong>(
                                    (ulong)compressedSize,
                                    nodeObject.DataSize.DataSize,
                                    "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                if (Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointFoundation2010" && Common.GetConfigurationPropertyValue("SutVersion", SharedContext.Current.Site) != "SharePointServer2010")
                                {
                                    SignatureObject contentSignature = new SignatureObject();
                                    contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                    if (!contentSignature.Equals(nodeObject.Signature))
                                    {
                                        site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                    }
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }
        /// <summary>
        /// Get the signature for data file.
        /// </summary>
        /// <param name="array">The input data.</param>
        /// <returns>An instance of SignatureObject.</returns>
        private SignatureObject GetDataFileSignature(byte[] array)
        {
            SignatureObject signature = new SignatureObject();
            signature.SignatureData = new BinaryItem(array);

            return signature;
        }
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            List<IntermediateNodeObject> cloneList = new List<IntermediateNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                IntermediateNodeObject nodeObject = cloneList.First();
                byte[] content = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int headerLength = header.Length;
                        int compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            IntermediateNodeObject expectNode = new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                            if (!expectNode.Signature.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                // This situation could most happens for MOSS2010, we fake intermediate node instead of the root node when the zip file size is larger than 1M.
                                // In the current stage, this kind of signature algorithm is not mentioned in the open specification, so leave this verify blank.
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual<ulong>(
                                            (ulong)compressedSize,
                                            nodeObject.DataSize.DataSize,
                                            "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                SignatureObject contentSignature = new SignatureObject();
                                contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                if (!contentSignature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }
Example #16
0
        /// <summary>
        /// This method is used to analyze the chunk.
        /// </summary>
        /// <param name="rootNode">Specify the root node object which will be analyzed.</param>
        /// <param name="site">Specify the ITestSite instance.</param>
        public override void AnalyzeChunking(RootNodeObject rootNode, ITestSite site)
        {
            List <IntermediateNodeObject> cloneList = new List <IntermediateNodeObject>(rootNode.IntermediateNodeObjectList);

            while (cloneList.Count != 0)
            {
                IntermediateNodeObject nodeObject = cloneList.First();
                byte[] content = nodeObject.DataNodeObjectData.ObjectData;

                if (cloneList.Count == 1)
                {
                    if (content.Length > 1048576)
                    {
                        throw new NotImplementedException("If the final chunk is larger than 1MB, the signature method is not implemented.");
                    }

                    // Only final chunk left
                    SignatureObject expect = this.GetSHA1Signature(content);
                    if (!expect.Equals(nodeObject.Signature))
                    {
                        site.Assert.Fail("For the Zip file, final part chunk expect the signature {0}, actual signature {1}", expect.ToString(), nodeObject.Signature.ToString());
                    }

                    // Verify the less than 1MB final part related requirements
                    if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                    {
                        MsfsshttpdCapture.VerifySmallFinalChunk(SharedContext.Current.Site);
                    }
                }
                else
                {
                    if (ZipHeader.IsFileHeader(content, 0))
                    {
                        byte[] dataFileSignatureBytes;
                        byte[] header         = this.AnalyzeFileHeader(content, 0, out dataFileSignatureBytes);
                        int    headerLength   = header.Length;
                        int    compressedSize = (int)this.GetCompressedSize(dataFileSignatureBytes);

                        if (headerLength + compressedSize <= 4096)
                        {
                            IntermediateNodeObject expectNode = new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(content, this.GetSingleChunkSignature(header, dataFileSignatureBytes));
                            if (!expectNode.Signature.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file, when zip file is less than 4096, expect the signature {0}, actual signature {1}", expectNode.Signature.ToString(), nodeObject.Signature.ToString());
                            }

                            // Verify the zip file less than 4096 bytes
                            MsfsshttpdCapture.VerifyZipFileLessThan4096Bytes(SharedContext.Current.Site);
                        }
                        else
                        {
                            SignatureObject expectHeader = this.GetSHA1Signature(header);
                            if (!expectHeader.Equals(nodeObject.Signature))
                            {
                                site.Assert.Fail("For the Zip file header, expect the signature {0}, actual signature {1}", expectHeader.ToString(), nodeObject.Signature.ToString());
                            }

                            // Remove the header node
                            cloneList.RemoveAt(0);

                            // Then expect the next is file content node
                            nodeObject = cloneList.First();

                            // Here having something need to be distinguished between the MOSS2010 and MOSS2013
                            if (nodeObject.DataNodeObjectData == null && nodeObject.IntermediateNodeObjectList != null)
                            {
                                // This situation could most happens for MOSS2010, we fake intermediate node instead of the root node when the zip file size is larger than 1M.
                                // In the current stage, this kind of signature algorithm is not mentioned in the open specification, so leave this verify blank.
                            }
                            else if (nodeObject.DataNodeObjectData != null)
                            {
                                site.Assert.AreEqual <ulong>(
                                    (ulong)compressedSize,
                                    nodeObject.DataSize.DataSize,
                                    "The Data Size of the Intermediate Node Object MUST be the total number of bytes represented by the chunk.");

                                SignatureObject contentSignature = new SignatureObject();
                                contentSignature.SignatureData = new BinaryItem(dataFileSignatureBytes);
                                if (!contentSignature.Equals(nodeObject.Signature))
                                {
                                    site.Assert.Fail("For the Zip file content, expect the signature {0}, actual signature {1}", contentSignature.ToString(), nodeObject.Signature.ToString());
                                }

                                // Verify the zip file larger than 4096 bytes and less than 1MB.
                                if (SharedContext.Current.IsMsFsshttpRequirementsCaptured)
                                {
                                    MsfsshttpdCapture.VerifyZipFileHeaderAndContentSignature(SharedContext.Current.Site);
                                    MsfsshttpdCapture.VerifyIntermediateNodeForZipFileChunk(SharedContext.Current.Site);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The DataNodeObjectData and IntermediateNodeObjectList cannot be null at the same time.");
                            }
                        }
                    }
                }

                cloneList.RemoveAt(0);
            }
        }
        /// <summary>
        /// Get signature with SHA1 algorithm.
        /// </summary>
        /// <param name="array">The input data.</param>
        /// <returns>An instance of SignatureObject.</returns>
        private SignatureObject GetSHA1Signature(byte[] array)
        {
            SHA1 sha = new SHA1CryptoServiceProvider();
            byte[] temp = sha.ComputeHash(array);
            sha.Dispose();

            SignatureObject signature = new SignatureObject();
            signature.SignatureData = new BinaryItem(temp);
            return signature;
        }
        /// <summary>
        /// Get a chunk with the input bytes.
        /// </summary>
        /// <param name="chunkStart">The start index of the chunk.</param>
        /// <param name="chunkEnd">The end index of the chunk.</param>
        /// <returns>An IntermediateNodeObject which contains a chunk.</returns>
        private IntermediateNodeObject GetChunk(uint chunkStart, uint chunkEnd)
        {
            if (chunkEnd <= chunkStart || (chunkEnd - chunkStart > this.maxChunkSize) || chunkStart > uint.MaxValue)
            {
                throw new ArgumentOutOfRangeException("chunkStart");
            }

            byte[] temp = AdapterHelper.GetBytes(this.FileContent, (int)chunkStart, (int)(chunkEnd - chunkStart));

            byte[] signatureBytes = null;
            using (RDCSignatureGenerator generator = new RDCSignatureGenerator())
            {
                signatureBytes = generator.ComputeHash(temp);
            }

            SignatureObject signature = new SignatureObject();
            signature.SignatureData = new BinaryItem(signatureBytes);

            return new IntermediateNodeObject.IntermediateNodeObjectBuilder().Build(temp, signature);
        }
            /// <summary>
            /// This method is used to build intermediate node object from a byte array with a signature.
            /// </summary>
            /// <param name="array">Specify the byte array.</param>
            /// <param name="signature">Specify the signature.</param>
            /// <returns>Return the intermediate node object.</returns>
            public IntermediateNodeObject Build(byte[] array, SignatureObject signature)
            {
                IntermediateNodeObject nodeObject = new IntermediateNodeObject();
                nodeObject.DataSize = new DataSizeObject();
                nodeObject.DataSize.DataSize = (ulong)array.Length;

                nodeObject.Signature = signature;
                nodeObject.ExGuid = new ExGuid(SequenceNumberGenerator.GetCurrentSerialNumber(), Guid.NewGuid());

                nodeObject.DataNodeObjectData = new DataNodeObjectData(array, 0, array.Length);
                nodeObject.IntermediateNodeObjectList = null;

                // Now in the current implementation, one intermediate node only contain one single data object node.
                return nodeObject;
            }