All Retrieval Protocol messages are prefixed by a message header.Messages can be one of two types: request-type or response-type. Request-type messages initiate a communication session between two peers. Response-type messages are sent only on response to a Request-type one (see Protocol Details section for more details).A request-type message can be delivered only as an HTTP request. A response-type message can be delivered only as an HTTP response to an incoming HTTP request.The layout of the message header is as follows.
        /// <summary>
        /// Create a MsgBlk response.
        /// </summary>
        /// <param name="segmentId">The segmentId.</param>
        /// <param name="block">The block.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <param name="isLastBLKAvail">If it is true, the block is the last available block.</param>
        /// <returns>The MsgBlk response.</returns>
        public PccrrBLKResponsePacket CreateMsgBlkResponse(
            byte[] segmentId,
            byte[] block,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues,
            bool isLastBLKAvail)
        {
            if (segmentId == null)
            {
                segmentId = new byte[0];
            }

            if (block == null)
            {
                block = new byte[0];
            }

            PccrrBLKResponsePacket packet = new PccrrBLKResponsePacket();

            MSG_BLK msgBlkResp = new MSG_BLK();

            byte[] zeroPad   = new byte[0] {
            };
            byte[] zeroPad_2 = new byte[0] {
            };
            byte[] zeroPad_3 = new byte[0] {
            };
            byte[] iVBlock   = new byte[0] {
            };
            msgBlkResp.ZeroPad3        = zeroPad_3;
            msgBlkResp.ZeroPad2        = zeroPad_2;
            msgBlkResp.ZeroPad         = zeroPad;
            msgBlkResp.VrfBlock        = null;
            msgBlkResp.SizeOfVrfBlock  = 0;
            msgBlkResp.SizeOfSegmentId = (uint)segmentId.Length;
            msgBlkResp.SizeOfIVBlock   = (uint)iVBlock.Length;
            msgBlkResp.SizeOfBlock     = (uint)block.Length;
            msgBlkResp.SegmentId       = segmentId;
            msgBlkResp.IVBlock         = iVBlock;
            msgBlkResp.Block           = block;
            msgBlkResp.BlockIndex      = 0;

            if (!isLastBLKAvail)
            {
                msgBlkResp.NextBlockIndex = 1;
            }
            else
            {
                msgBlkResp.NextBlockIndex = 0;
            }

            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            });

            packet.MsgBLK        = msgBlkResp;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Create a MsgGetSegList request.
        /// </summary>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="requestID">Request ID.</param>
        /// <param name="segmentIDs">Array of segment IDs.</param>
        /// <param name="extensibleBlob">Extensible blob.</param>
        /// <returns>MsgGetSegList request.</returns>
        public PccrrGetSegListRequestPacket CreateMsgGetSegListRequest(
            CryptoAlgoId_Values cryptoAlgoIdValues,
            Guid requestID,
            byte[][] segmentIDs,
            byte[] extensibleBlob)
        {
            var packet = new PccrrGetSegListRequestPacket();

            var msgGetSegList = new MSG_GETSEGLIST();

            msgGetSegList.RequestID         = requestID;
            msgGetSegList.CountOfSegmentIDs = (uint)segmentIDs.Length;
            msgGetSegList.SegmentIDs        = new SegmentIDStructure[segmentIDs.Length];
            for (int i = 0; i < segmentIDs.Length; i++)
            {
                msgGetSegList.SegmentIDs[i] = new SegmentIDStructure(segmentIDs[i]);
            }
            ///[MS-PCCRR]Section 2.2.4.4 SizeOfExtensibleBlob: Size, in bytes, of the ExtensibleBlob field. Implementations MAY support extensible blobs in MSG_GETSEGLIST
            ///message.Implementations that do not support extensible blobs in MSG_GETSEGLIST messages MUST set SizeOfExtensibleBlob to zero and omit the ExtensibleBlob field.
            msgGetSegList.SizeOfExtensibleBlob = (uint)extensibleBlob.Length;
            msgGetSegList.ExtensibleBlob       = extensibleBlob;

            packet.MsgGetSegList = msgGetSegList;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, MsgType_Values.MSG_GETSEGLIST, new ProtoVersion {
                MajorVersion = 2, MinorVersion = 0
            });

            messageHeader.MsgSize += (uint)TypeMarshal.GetBlockMemorySize(msgGetSegList);
            packet.MessageHeader   = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Create a MsgGetBlks request.
        /// </summary>
        /// <param name="segmentId">The segmentId.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <returns>MsgGetBlks request.</returns>
        public PccrrGETBLKSRequestPacket CreateMsgGetBlksRequest(
            byte[] segmentId,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues)
        {
            if (segmentId == null)
            {
                segmentId = new byte[0];
            }

            PccrrGETBLKSRequestPacket packet = new PccrrGETBLKSRequestPacket();

            MSG_GETBLKS msgGetBlksReq = new MSG_GETBLKS();

            msgGetBlksReq.DataForVrfBlock = null;
            byte[] zeroPad = new byte[0] {
            };
            BLOCK_RANGE[] reqBlockRanges = new BLOCK_RANGE[1];
            reqBlockRanges[0].Index             = 0;
            reqBlockRanges[0].Count             = 1;
            msgGetBlksReq.ReqBlockRanges        = reqBlockRanges;
            msgGetBlksReq.ReqBlockRangeCount    = (uint)reqBlockRanges.Length;
            msgGetBlksReq.ZeroPad               = zeroPad;
            msgGetBlksReq.SizeOfSegmentID       = (uint)segmentId.Length;
            msgGetBlksReq.SizeOfDataForVrfBlock = 0;
            msgGetBlksReq.SegmentID             = segmentId;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            });

            packet.MsgGetBLKS    = msgGetBlksReq;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Create MessageHeader.
        /// </summary>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoIdValues.</param>
        /// <param name="msgTypeValues">The msgTypeValues.</param>
        /// <param name="protoVer">The protoVer.</param>
        /// <returns>The MESSAGE_HEADER struct.</returns>
        public static MESSAGE_HEADER CreateMessageHeader(CryptoAlgoId_Values cryptoAlgoIdValues, MsgType_Values msgTypeValues, ProtoVersion protoVer)
        {
            MESSAGE_HEADER messageHeader = new MESSAGE_HEADER();
            messageHeader.CryptoAlgoId = cryptoAlgoIdValues;
            messageHeader.MsgType = msgTypeValues;
            messageHeader.MsgSize = 16;
            messageHeader.ProtVer = protoVer;

            return messageHeader;
        }
Exemple #5
0
        /// <summary>
        /// Decode message header.
        /// </summary>
        /// <param name="data">Data to be decoded.</param>
        /// <param name="index">Started index.</param>
        /// <returns>The MESSAGE_HEADER struct.</returns>
        private MESSAGE_HEADER DecodeMessageHeader(byte[] data, ref int index)
        {
            MESSAGE_HEADER ret = new MESSAGE_HEADER();

            ret.ProtVer.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
            ret.ProtVer.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);
            ret.MsgType      = (MsgType_Values)MarshalHelper.GetUInt32(data, ref index, false);
            ret.MsgSize      = MarshalHelper.GetUInt32(data, ref index, false);
            ret.CryptoAlgoId = (CryptoAlgoId_Values)MarshalHelper.GetUInt32(data, ref index, false);
            return(ret);
        }
Exemple #6
0
        /// <summary>
        /// Create MessageHeader.
        /// </summary>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoIdValues.</param>
        /// <param name="msgTypeValues">The msgTypeValues.</param>
        /// <param name="protoVer">The protoVer.</param>
        /// <returns>The MESSAGE_HEADER struct.</returns>
        public static MESSAGE_HEADER CreateMessageHeader(CryptoAlgoId_Values cryptoAlgoIdValues, MsgType_Values msgTypeValues, ProtoVersion protoVer)
        {
            MESSAGE_HEADER messageHeader = new MESSAGE_HEADER();

            messageHeader.CryptoAlgoId = cryptoAlgoIdValues;
            messageHeader.MsgType      = msgTypeValues;
            messageHeader.MsgSize      = 16;
            messageHeader.ProtVer      = protoVer;

            return(messageHeader);
        }
        /// <summary>
        /// Decode pack.
        /// </summary>
        /// <param name="rawdata">The rawdata.</param>
        /// <returns>The PccrrPacket.</returns>
        public override PccrrPacket Decode(byte[] rawdata)
        {
            if (rawdata == null)
            {
                throw new ArgumentNullException("rawdata");
            }

            if (rawdata.Length == 0)
            {
                throw new ArgumentException("The raw data should not be empty.");
            }

            PccrrNegoResponsePacket packet = new PccrrNegoResponsePacket();

            int messageLength = 0;

            messageLength = rawdata.Length;

            if (messageLength > 0)
            {
                int index = 0;

                byte[] data = rawdata;

                RESPONSE_MESSAGE ret = new RESPONSE_MESSAGE();
                ret.TRANSPORTRESPONSEHEADER.Size = MarshalHelper.GetUInt32(data, ref index, false);

                MESSAGE_HEADER ret1 = new MESSAGE_HEADER();
                ret1.ProtVer.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret1.ProtVer.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret1.MsgType      = (MsgType_Values)MarshalHelper.GetUInt32(data, ref index, false);
                ret1.MsgSize      = MarshalHelper.GetUInt32(data, ref index, false);
                ret1.CryptoAlgoId = (CryptoAlgoId_Values)MarshalHelper.GetUInt32(data, ref index, false);

                MSG_NEGO_RESP ret2 = new MSG_NEGO_RESP();
                ret2.MinSupporteProtocolVersion.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret2.MinSupporteProtocolVersion.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret2.MaxSupporteProtocolVersion.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret2.MaxSupporteProtocolVersion.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);

                packet.TransportResponseHeader = ret.TRANSPORTRESPONSEHEADER;
                packet.MsgNegoResp             = ret2;
                packet.MessageHeader           = ret1;
            }

            return(packet);
        }
        /// <summary>
        /// Create a MsgNego response.
        /// </summary>
        /// <param name="minSupportedProtocolVer">The minSupportedProtocolVersion.</param>
        /// <param name="maxSupportedProtocolVer">The maxSupportedProtocolVersion.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <returns>The MsgNego response.</returns>
        public PccrrNegoResponsePacket CreateMsgNegoResponse(
            ProtoVersion minSupportedProtocolVer,
            ProtoVersion maxSupportedProtocolVer,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues)
        {
            PccrrNegoResponsePacket packet = new PccrrNegoResponsePacket();

            MSG_NEGO_RESP msgNegoResp = new MSG_NEGO_RESP();

            msgNegoResp.MaxSupporteProtocolVersion = maxSupportedProtocolVer;
            msgNegoResp.MinSupporteProtocolVersion = minSupportedProtocolVer;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            });

            packet.MsgNegoResp   = msgNegoResp;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Create a MsgSegList response.
        /// </summary>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="requestID">Request ID.</param>
        /// <param name="segmentRanges">Segment ranges.</param>
        /// <returns>The MsgSegList response.</returns>
        public PccrrSegListResponsePacket CreateSegListResponse(
            CryptoAlgoId_Values cryptoAlgoIdValues,
            Guid requestID,
            BLOCK_RANGE[] segmentRanges)
        {
            var packet = new PccrrSegListResponsePacket();

            var msgSegList = new MSG_SEGLIST();

            msgSegList.RequestID         = requestID;
            msgSegList.SegmentRangeCount = (uint)segmentRanges.Length;
            msgSegList.SegmentRanges     = segmentRanges;

            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, MsgType_Values.MSG_SEGLIST, new ProtoVersion {
                MajorVersion = 2, MinorVersion = 0
            });

            packet.MsgSegList    = msgSegList;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Create a MsgBlkList response.
        /// </summary>
        /// <param name="segmentId">The segmentId.</param>
        /// <param name="blockRanges">The blockRanges.</param>
        /// <param name="nextBlockIndex">The nextBlockIndex.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <returns>The MsgBlkList response.</returns>
        public PccrrBLKLISTResponsePacket CreateMsgBlkListResponse(
            byte[] segmentId,
            BLOCK_RANGE[] blockRanges,
            uint nextBlockIndex,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues)
        {
            if (segmentId == null)
            {
                segmentId = new byte[0];
            }

            if (blockRanges == null)
            {
                blockRanges = new BLOCK_RANGE[0];
            }

            PccrrBLKLISTResponsePacket packet = new PccrrBLKLISTResponsePacket();

            MSG_BLKLIST msgBlkListResp = new MSG_BLKLIST();

            byte[] zeroPad = new byte[0] {
            };
            msgBlkListResp.ZeroPad         = zeroPad;
            msgBlkListResp.SizeOfSegmentId = (uint)segmentId.Length;
            msgBlkListResp.SegmentId       = segmentId;
            msgBlkListResp.BlockRanges     = blockRanges;
            msgBlkListResp.BlockRangeCount = (uint)blockRanges.Length;
            msgBlkListResp.NextBlockIndex  = nextBlockIndex;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            });

            packet.MsgBLKLIST    = msgBlkListResp;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Create a MsgGetBlkList request.
        /// </summary>
        /// <param name="segmentId">The segmentId.</param>
        /// <param name="blockRanges">The needed BlockRanges.</param>
        /// <param name="cryptoAlgoIdValues">The cryptoAlgoId.</param>
        /// <param name="msgTypeValues">The msgType.</param>
        /// <returns>MsgGetBlkList request.</returns>
        public PccrrGETBLKLISTRequestPacket CreateMsgGetBlkListRequest(
            byte[] segmentId,
            BLOCK_RANGE[] blockRanges,
            CryptoAlgoId_Values cryptoAlgoIdValues,
            MsgType_Values msgTypeValues)
        {
            if (segmentId == null)
            {
                segmentId = new byte[0];
            }

            if (blockRanges == null)
            {
                blockRanges = new BLOCK_RANGE[0];
            }

            PccrrGETBLKLISTRequestPacket packet = new PccrrGETBLKLISTRequestPacket();

            MSG_GETBLKLIST msgGetBlkListReq = new MSG_GETBLKLIST();

            byte[] zeroPad = new byte[0] {
            };
            msgGetBlkListReq.SegmentID              = segmentId;
            msgGetBlkListReq.SizeOfSegmentID        = (uint)segmentId.Length;
            msgGetBlkListReq.NeededBlockRanges      = blockRanges;
            msgGetBlkListReq.NeededBlocksRangeCount = (uint)blockRanges.Length;
            msgGetBlkListReq.ZeroPad = zeroPad;
            MESSAGE_HEADER messageHeader = PccrrUtitlity.CreateMessageHeader(cryptoAlgoIdValues, msgTypeValues, new ProtoVersion {
                MajorVersion = 1, MinorVersion = 0
            });

            packet.MsgGetBLKLIST = msgGetBlkListReq;
            packet.MessageHeader = messageHeader;

            return(packet);
        }
        /// <summary>
        /// Send message MSG_NEGO_RESP.
        /// </summary>
        /// <param name="isSupportVersion">If it is true, it is support version, if it is false, it is not support version.</param>
        /// <param name="isWellFormed">If it is true, it is well formed, if it is false, it is not well formed.</param>
        public void SendMsgNegoResp(bool isSupportVersion, bool isWellFormed)
        {
            PccrrNegoResponsePacket pccrrNegoResponsePacket;
            if (!isSupportVersion && isWellFormed)
            {
                pccrrNegoResponsePacket = this.pccrrStackSer.CreateMsgNegoResponse(this.minErrorSupV, this.maxErrorSupV, CryptoAlgoId_Values.AES_128, MsgType_Values.MSG_NEGO_RESP, this.protoErrorVer);
            }
            else if (isSupportVersion && isWellFormed)
            {
                pccrrNegoResponsePacket = this.pccrrStackSer.CreateMsgNegoResponse(this.minSupV, this.maxSupV, CryptoAlgoId_Values.AES_128, MsgType_Values.MSG_NEGO_RESP, this.protoVer);
            }
            else
            {
                pccrrNegoResponsePacket = this.pccrrStackSer.CreateMsgNegoResponse(this.minErrorSupV, this.maxErrorSupV, CryptoAlgoId_Values.AES_128, MsgType_Values.MSG_NEGO_RESP, this.protoErrorVer);
                MSG_NEGO_RESP msgNegoResp = new MSG_NEGO_RESP();
                MESSAGE_HEADER messageHeader = new MESSAGE_HEADER();
                messageHeader = pccrrNegoResponsePacket.MessageHeader;
                msgNegoResp.MinSupporteProtocolVersion.MajorVersion = 0;
                msgNegoResp.MinSupporteProtocolVersion.MinorVersion = 0;
                messageHeader.ProtVer.MajorVersion = 1;
                messageHeader.ProtVer.MinorVersion = 0;
                msgNegoResp.MaxSupporteProtocolVersion.MajorVersion = 0;
                msgNegoResp.MaxSupporteProtocolVersion.MinorVersion = 0;

                pccrrNegoResponsePacket.MsgNegoResp = msgNegoResp;
                pccrrNegoResponsePacket.MessageHeader = messageHeader;
            }

            this.pccrrStackSer.SendPacket(pccrrNegoResponsePacket);
        }
        /// <summary>
        /// Decode pack.
        /// </summary>
        /// <param name="rawdata">The rawdata.</param>
        /// <returns>The PccrrPacket.</returns>
        public override PccrrPacket Decode(byte[] rawdata)
        {
            if (rawdata == null)
            {
                throw new ArgumentNullException("rawdata");
            }

            if (rawdata.Length == 0)
            {
                throw new ArgumentException("The raw data should not be empty.");
            }

            PccrrNegoResponsePacket packet = new PccrrNegoResponsePacket();

            int messageLength = 0;

            messageLength = rawdata.Length;

            if (messageLength > 0)
            {
                int index = 0;

                byte[] data = rawdata;

                RESPONSE_MESSAGE ret = new RESPONSE_MESSAGE();
                ret.TRANSPORTRESPONSEHEADER.Size = MarshalHelper.GetUInt32(data, ref index, false);

                MESSAGE_HEADER ret1 = new MESSAGE_HEADER();
                ret1.ProtVer.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret1.ProtVer.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret1.MsgType = (MsgType_Values)MarshalHelper.GetUInt32(data, ref index, false);
                ret1.MsgSize = MarshalHelper.GetUInt32(data, ref index, false);
                ret1.CryptoAlgoId = (CryptoAlgoId_Values)MarshalHelper.GetUInt32(data, ref index, false);

                MSG_NEGO_RESP ret2 = new MSG_NEGO_RESP();
                ret2.MinSupporteProtocolVersion.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret2.MinSupporteProtocolVersion.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret2.MaxSupporteProtocolVersion.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
                ret2.MaxSupporteProtocolVersion.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);

                packet.TransportResponseHeader = ret.TRANSPORTRESPONSEHEADER;
                packet.MsgNegoResp = ret2;
                packet.MessageHeader = ret1;
            }

            return packet;
        }
 /// <summary>
 /// Decode message header.
 /// </summary>
 /// <param name="data">Data to be decoded.</param>
 /// <param name="index">Started index.</param>
 /// <returns>The MESSAGE_HEADER struct.</returns>
 private MESSAGE_HEADER DecodeMessageHeader(byte[] data, ref int index)
 {
     MESSAGE_HEADER ret = new MESSAGE_HEADER();
     ret.ProtVer.MinorVersion = MarshalHelper.GetUInt16(data, ref index, false);
     ret.ProtVer.MajorVersion = MarshalHelper.GetUInt16(data, ref index, false);
     ret.MsgType = (MsgType_Values)MarshalHelper.GetUInt32(data, ref index, false);
     ret.MsgSize = MarshalHelper.GetUInt32(data, ref index, false);
     ret.CryptoAlgoId = (CryptoAlgoId_Values)MarshalHelper.GetUInt32(data, ref index, false);
     return ret;
 }
        /// <summary>
        /// Capture MESSAGE_HEADER structure releated requirements.
        /// </summary>
        /// <param name="messageHeader">Message header object</param>
        /// <param name="uiPayload">The length of http content body.</param>
        public static void CaptureMessageHeaderRequirements(MESSAGE_HEADER messageHeader, int uiPayload)
        {
            // The protocol version of the server-peer, which is configured in ptfconfig file.
            ushort uiMajor = ushort.Parse(
                site.Properties.Get(
                "PCCRR.Protocol.MSG_NEGO_REQ.MinSupportedProtocolVersion.MajorVer"));
            ushort uiMinor = ushort.Parse(
                site.Properties.Get(
                "PCCRR.Protocol.MSG_NEGO_REQ.MinSupportedProtocolVersion.MinorVer"));

            ProtoVersion protVer = messageHeader.ProtVer;

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R47");

            // Verify MS-PCCRR requirement: MS-PCCRR_R47
            // If the following types are verified, means those fields are the layout of message header.
            bool isVerifyR47 = messageHeader.GetType() == typeof(MESSAGE_HEADER) &&
                messageHeader.ProtVer.GetType() == typeof(ProtoVersion) &&
                messageHeader.MsgType.GetType() == typeof(MsgType_Values) &&
                messageHeader.MsgSize.GetType() == typeof(uint) &&
                messageHeader.CryptoAlgoId.GetType() == typeof(CryptoAlgoId_Values);

            site.CaptureRequirementIfIsTrue(
                isVerifyR47,
                47,
                @"[In MESSAGE_HEADER]The layout of the message header is as follows
                [ProtVer,MsgType,MsgSize,CryptoAlgoId].");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R48");

            bool isVerifyR48 = messageHeader.ProtVer.GetType() == typeof(ProtoVersion) &&
                messageHeader.ProtVer.MajorVersion.GetType() == typeof(ushort) &&
                messageHeader.ProtVer.MinorVersion.GetType() == typeof(ushort);

            // Verify MS-PCCRR requirement: MS-PCCRR_R48
            site.CaptureRequirementIfIsTrue(
                isVerifyR48,
                48,
                @"[MESSAGE_HEADER]ProtVer (4 bytes):  Protocol version number, formed by concatenating the
                protocol major version number and protocol minor version number, encoded as follows (where MSB
                is Most Significant Byte and LSB is Least Significant Byte): 1st Byte (Addr: X) is Minor version
                MSB;2nd Byte (Addr: X+1) is Minor version LSB;3rd Byte (Addr: X+2) is Major version MSB;4th Byte
                (Addr: X+3) is Major version LSB.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R49");

            // Verify MS-PCCRR requirement: MS-PCCRR_R49
            // The protVer field will be set in HttpTransport_Receive method when receive a response message
            // Verify its low byte
            site.CaptureRequirementIfAreEqual<ushort>(
                uiMajor,
                protVer.MajorVersion,
                49,
                @"[In MESSAGE_HEADER][ProtVer (4 bytes)]The major version number is encoded in the least
                significant word of the protocol version's DWORD.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R50");

            // Verify MS-PCCRR requirement: MS-PCCRR_R50
            // Verify its high byte
            site.CaptureRequirementIfAreEqual<ushort>(
                uiMinor,
                protVer.MinorVersion,
                50,
                @"[In MESSAGE_HEADER][ProtVer (4 bytes)]The minor version number is encoded in the most significant
                word of the protocol version's DWORD.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R51");

            // Verify MS-PCCRR requirement: MS-PCCRR_R51
            // This is a bug, Major  version number is 2 bytes.
            bool isVerifyR51 = uiMajor >= 0x0000 && uiMajor <= 0xFFFF;

            site.CaptureRequirementIfIsTrue(
                isVerifyR51,
                51,
                @"[In MESSAGE_HEADER][ProtVer (4 bytes)]Major  version number can express the version range of
                0x00000000 to 0xFFFFFFFF.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R5100");

            // Verify MS-PCCRR requirement: MS-PCCRR_R5100
            // This is a bug, Minor version number is 2 bytes.
            bool isVerifyR5100 = uiMinor >= 0x0000 && uiMinor <= 0xFFFF;

            site.CaptureRequirementIfIsTrue(
                isVerifyR5100,
                5100,
                @"[In MESSAGE_HEADER][ProtVer (4 bytes)]Minor version number can express the version range of
                0x00000000 to 0xFFFFFFFF.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R52");

            // Verify MS-PCCRR requirement: MS-PCCRR_R52
            bool isVerifyR52 = ((uint)protVer.MajorVersion & 0x0000FFFF) == 0x00000001 &&
                ((uint)protVer.MinorVersion & 0xFFFF0000) == 0x00000000;

            site.CaptureRequirementIfIsTrue(
                isVerifyR52,
                52,
                @"[In MESSAGE_HEADER][ProtVer (4 bytes)]Currently, the protocol[MS-PCCRR] version number MUST be
                set to {major=1 (0x0001), minor=0 (0x0000)}.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R54");

            // Verify MS-PCCRR requirement: MS-PCCRR_R54
            bool isVerifyR54 = messageHeader.MsgType == MsgType_Values.MSG_NEGO_REQ ||
                messageHeader.MsgType == MsgType_Values.MSG_NEGO_RESP ||
                messageHeader.MsgType == MsgType_Values.MSG_GETBLKLIST ||
                messageHeader.MsgType == MsgType_Values.MSG_GETBLKS ||
                messageHeader.MsgType == MsgType_Values.MSG_BLKLIST ||
                messageHeader.MsgType == MsgType_Values.MSG_BLK;

            site.CaptureRequirementIfIsTrue(
                isVerifyR54,
                54,
                @"[In MESSAGE_HEADER][MsgType (4 bytes)]MUST be set to one of the following values
                [MSG_NEGO_REQ 0x00000000,MSG_NEGO_RESP 0x00000001,MSG_GETBLKLIST 0x00000002,MSG_GETBLKS 0x00000003,
                MSG_BLKLIST0x00000004,MSG_BLK 0x00000005].");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R318");

            // Verify MS-PCCRR requirement: MS-PCCRR_R318
            bool isVerifyR318 = messageHeader.CryptoAlgoId == CryptoAlgoId_Values.V1 ||
                messageHeader.CryptoAlgoId == CryptoAlgoId_Values.AES_128 ||
                messageHeader.CryptoAlgoId == CryptoAlgoId_Values.AES_192 ||
                messageHeader.CryptoAlgoId == CryptoAlgoId_Values.AES_256;

            site.CaptureRequirementIfIsTrue(
                isVerifyR318,
                318,
                @"[In Appendix A: Product Behavior]<3> Section 2.2.3: Windows supports: no encryption, AES_128,
                    AES_ 192, and AES_256.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R64");

            // Verify MS-PCCRR requirement: MS-PCCRR_R64
            site.CaptureRequirementIfAreEqual<uint>(
                (uint)uiPayload,
                 messageHeader.MsgSize,
                64,
                @"[In MESSAGE_HEADER]MsgSize (4 bytes):  Protocol message total size including MESSAGE_HEADER,
                but not including the Transport Header.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R65");

            // Verify MS-PCCRR requirement: MS-PCCRR_R65
            bool isVerifyR65 = messageHeader.MsgSize >= 16 && messageHeader.MsgSize <= 98304;

            site.CaptureRequirementIfIsTrue(
                isVerifyR65,
                65,
                @"[In MESSAGE_HEADER][MsgSize (4 bytes)]The valid range of the total message size MUST be from
                16 bytes to 98,304 bytes (or 96 KB).");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R66");

            // Verify MS-PCCRR requirement: MS-PCCRR_R66
            site.CaptureRequirementIfAreEqual<int>(
                4,
                sizeof(CryptoAlgoId_Values),
                66,
                @"[In MESSAGE_HEADER]CryptoAlgoId (4 bytes):  Encryption algorithm used by the server-role peer
                to encrypt data.");

            //
            // Add the debug information
            //
            site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R317");

            if (messageHeader.MsgType == MsgType_Values.MSG_GETBLKS)
            {
                bool isVerifyR317 = messageHeader.CryptoAlgoId == CryptoAlgoId_Values.AES_128;

                // Verify MS-PCCRR requirement: MS-PCCRR_R317
                site.CaptureRequirementIfIsTrue(
                    isVerifyR317,
                    317,
                    @"[In Appendix A: Product Behavior]<3> Section 2.2.3: Windows uses AES_128 as the default encryption
                    algorithm.");

                // Verify MS-PCCRR requirement: MS-PCCRR_R19
                bool isFourBytesAlign = messageHeader.MsgSize % 4 == 0;
                CaptureFieldAlignRequirements(isFourBytesAlign);
            }
        }