/// <summary> /// Decode MSG_GETBLKS message. /// </summary> /// <param name="data">Data to be decoded.</param> /// <param name="index">Started index.</param> /// <returns>The MSG_GETBLKS struct.</returns> private MSG_GETBLKS DecodeMSG_GETBLKS(byte[] data, ref int index) { MSG_GETBLKS ret = new MSG_GETBLKS(); ret.SizeOfSegmentID = MarshalHelper.GetUInt32(data, ref index, false); ret.SegmentID = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID); ret.ZeroPad = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID % 4); if (ret.ZeroPad == null) { ret.ZeroPad = new byte[0]; } ret.ReqBlockRangeCount = MarshalHelper.GetUInt32(data, ref index, false); ret.ReqBlockRanges = new BLOCK_RANGE[ret.ReqBlockRangeCount]; for (int i = 0; i < ret.ReqBlockRangeCount; i++) { ret.ReqBlockRanges[i].Index = MarshalHelper.GetUInt32(data, ref index, false); ret.ReqBlockRanges[i].Count = MarshalHelper.GetUInt32(data, ref index, false); } ret.SizeOfDataForVrfBlock = MarshalHelper.GetUInt32(data, ref index, false); ret.DataForVrfBlock = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfDataForVrfBlock); if (ret.DataForVrfBlock == null) { ret.DataForVrfBlock = new byte[0]; } return(ret); }
/// <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> /// Decode request message. /// </summary> /// <param name="rawdata">The raw data.</param> /// <param name="uri">The request uri.</param> /// <param name="method">The request method.</param> /// <returns>The PccrrPacket.</returns> public PccrrPacket DecodeRequestMessage(byte[] rawdata, Uri uri, HttpMethod method) { if (rawdata == null) { throw new ArgumentNullException("rawdata"); } if (rawdata.Length == 0) { throw new ArgumentException("The rawdata should not be empty."); } int messageLength = 0; messageLength = rawdata.Length; PccrrPacket packet = null; if (messageLength > 0) { int index = 0; REQUEST_MESSAGE ret = new REQUEST_MESSAGE(); ret.MESSAGEHEADER = this.DecodeMessageHeader(rawdata, ref index); switch (ret.MESSAGEHEADER.MsgType) { case MsgType_Values.MSG_NEGO_REQ: PccrrNegoRequestPacket pccrrNegoRequestPacket = new PccrrNegoRequestPacket(); MSG_NEGO_REQ msgNEGOREQ = this.DecodeMSG_NEGO_REQ(rawdata, ref index); pccrrNegoRequestPacket.MsgNegoReq = msgNEGOREQ; pccrrNegoRequestPacket.MessageHeader = ret.MESSAGEHEADER; pccrrNegoRequestPacket.Method = method; pccrrNegoRequestPacket.Uri = uri; packet = pccrrNegoRequestPacket; break; case MsgType_Values.MSG_GETBLKLIST: PccrrGETBLKLISTRequestPacket pccrrGETBLKLISTRequestPacket = new PccrrGETBLKLISTRequestPacket(); MSG_GETBLKLIST msgGETBLKLIST = this.DecodeMSG_GETBLKLIST(rawdata, ref index); pccrrGETBLKLISTRequestPacket.MsgGetBLKLIST = msgGETBLKLIST; pccrrGETBLKLISTRequestPacket.MessageHeader = ret.MESSAGEHEADER; pccrrGETBLKLISTRequestPacket.Method = method; pccrrGETBLKLISTRequestPacket.Uri = uri; packet = pccrrGETBLKLISTRequestPacket; break; case MsgType_Values.MSG_GETBLKS: PccrrGETBLKSRequestPacket pccrrGETBLKSRequestPacket = new PccrrGETBLKSRequestPacket(); MSG_GETBLKS msgGETBLKS = this.DecodeMSG_GETBLKS(rawdata, ref index); pccrrGETBLKSRequestPacket.MsgGetBLKS = msgGETBLKS; pccrrGETBLKSRequestPacket.MessageHeader = ret.MESSAGEHEADER; pccrrGETBLKSRequestPacket.Method = method; pccrrGETBLKSRequestPacket.Uri = uri; packet = pccrrGETBLKSRequestPacket; break; case MsgType_Values.MSG_GETSEGLIST: PccrrGetSegListRequestPacket pccrrGetSegListRequestPacket = new PccrrGetSegListRequestPacket(); pccrrGetSegListRequestPacket.MsgGetSegList = TypeMarshal.ToStruct <MSG_GETSEGLIST>(rawdata, ref index); pccrrGetSegListRequestPacket.MessageHeader = ret.MESSAGEHEADER; pccrrGetSegListRequestPacket.Method = method; pccrrGetSegListRequestPacket.Uri = uri; packet = pccrrGetSegListRequestPacket; break; } } return(packet); }
/// <summary> /// Decode MSG_GETBLKS message. /// </summary> /// <param name="data">Data to be decoded.</param> /// <param name="index">Started index.</param> /// <returns>The MSG_GETBLKS struct.</returns> private MSG_GETBLKS DecodeMSG_GETBLKS(byte[] data, ref int index) { MSG_GETBLKS ret = new MSG_GETBLKS(); ret.SizeOfSegmentID = MarshalHelper.GetUInt32(data, ref index, false); ret.SegmentID = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID); ret.ZeroPad = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfSegmentID % 4); if (ret.ZeroPad == null) { ret.ZeroPad = new byte[0]; } ret.ReqBlockRangeCount = MarshalHelper.GetUInt32(data, ref index, false); ret.ReqBlockRanges = new BLOCK_RANGE[ret.ReqBlockRangeCount]; for (int i = 0; i < ret.ReqBlockRangeCount; i++) { ret.ReqBlockRanges[i].Index = MarshalHelper.GetUInt32(data, ref index, false); ret.ReqBlockRanges[i].Count = MarshalHelper.GetUInt32(data, ref index, false); } ret.SizeOfDataForVrfBlock = MarshalHelper.GetUInt32(data, ref index, false); ret.DataForVrfBlock = MarshalHelper.GetBytes(data, ref index, (int)ret.SizeOfDataForVrfBlock); if (ret.DataForVrfBlock == null) { ret.DataForVrfBlock = new byte[0]; } return ret; }
/// <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> /// MSG_GETBLKS structure capture /// </summary> /// <param name="getBlks">MSG_GETBLKS object</param> private void VerifyGetBlocks(MSG_GETBLKS getBlks) { // Verify requirement MS-PCCRR_R61 and MS-PCCRR_R113 string isR61Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R61Implementated"); bool isR113Satisfied = getBlks.ReqBlockRanges.Length == 1; if (isWindows) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R113"); // Verify MS-PCCRR requirement: MS-PCCRR_R113 Site.CaptureRequirementIfIsTrue( isR113Satisfied, 113, @"[In MESSAGE_HEADER][MsgType (4 bytes)] Since only one block will be returned, a MSG_GETBLKS message specify only a single range containing only a single block.[In windows]"); if (null == isR61Implementated) { Site.Properties.Add("PCCRR.SHOULDMAY.R61Implementated", Boolean.TrueString); isR61Implementated = Boolean.TrueString; } } if (null != isR61Implementated) { bool implement = Boolean.Parse(isR61Implementated); bool isSatisfied = isR113Satisfied; // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R61"); // Verify MS-PCCRR requirement: MS-PCCRR_R61 Site.CaptureRequirementIfAreEqual<bool>( implement, isSatisfied, 61, @"[In MESSAGE_HEADER][MsgType (4 bytes)] Since only one block will be returned, a MSG_GETBLKS message SHOULD specify only a single range containing only a single block."); } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R101"); // Verify MS-PCCRR requirement: MS-PCCRR_R101 Site.CaptureRequirementIfAreEqual<uint>( (uint)getBlks.SegmentID.Length, getBlks.SizeOfSegmentID, 101, @"[In MSG_GETBLKS]SizeOfSegmentID (4 bytes): Size in bytes of the subsequent SegmentID field."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R102"); // Verify MS-PCCRR requirement: MS-PCCRR_R102 bool isVerifyR102 = getBlks.SizeOfSegmentID >= 0x00000000 && getBlks.SizeOfSegmentID <= 0xFFFFFFFF; Site.CaptureRequirementIfIsTrue( isVerifyR102, 102, @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)]The syntactic range of this field[SegmentID field] is from 0x00000000 to 0xFFFFFFFF."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R105"); // Verify MS-PCCRR requirement: MS-PCCRR_R105 Site.CaptureRequirementIfAreEqual<int>( 32, getBlks.SegmentID.Length, 105, @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)][Implementations]MUST support content with 32-byte SegmentIDs.<6>"); if (null != getBlks.ZeroPad) { bool isAllZero = true; // If the length is zero, the flag will remain in true // else, the bytes will be checked in foreach statements foreach (byte b in getBlks.ZeroPad) { if (b != 0) { isAllZero = false; break; } } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R110"); // Verify MS-PCCRR requirement: MS-PCCRR_R110 bool isVerifyR110 = getBlks.ZeroPad.Length >= 0 && getBlks.ZeroPad.Length <= 3; Site.CaptureRequirementIfIsTrue( isVerifyR110, 110, @"[In MSG_GETBLKS]This field[ZeroPad (variable)] is 0 to 3 bytes in length, as required."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R109"); // Verify MS-PCCRR requirement: MS-PCCRR_R109 bool isVerifyR109 = isAllZero; Site.CaptureRequirementIfIsTrue( isVerifyR109, 109, @"[In MSG_GETBLKS][ZeroPad (variable)]The value of each byte MUST be set to zero."); } // Verify requirement MS-PCCRR_R104 and MS-PCCRR_R111 string isR104Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R104Implementated"); bool isR111Satisfied = getBlks.SizeOfSegmentID >= 0x00000000 && getBlks.SizeOfSegmentID <= 0xFFFFFFFF; if (isWindows) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R111"); // Verify MS-PCCRR requirement: MS-PCCRR_R111 Site.CaptureRequirementIfIsTrue( isR111Satisfied, 111, @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)]Implementations support all allowed SegmentID lengths.[In windows]"); if (null == isR104Implementated) { Site.Properties.Add("PCCRR.SHOULDMAY.R104Implementated", Boolean.TrueString); isR104Implementated = Boolean.TrueString; } } if (null != isR104Implementated) { bool implement = Boolean.Parse(isR104Implementated); bool isSatisfied = isR111Satisfied; // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R104"); // Verify MS-PCCRR requirement: MS-PCCRR_R104 Site.CaptureRequirementIfAreEqual<bool>( implement, isSatisfied, 104, @"[In MSG_GETBLKS][SizeOfSegmentID (4 bytes)]Implementations SHOULD support all allowed SegmentID lengths"); } // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R114"); // Verify MS-PCCRR requirement: MS-PCCRR_R114 Site.CaptureRequirementIfAreEqual<uint>( (uint)getBlks.ReqBlockRanges.Length, getBlks.ReqBlockRangeCount, 114, @"[In MSG_GETBLKS]ReqBlockRangeCount (4 bytes): Number of items in the subsequent block range array."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R115"); // Verify MS-PCCRR requirement: MS-PCCRR_R115 bool isVerifyR115 = getBlks.ReqBlockRangeCount >= 0x00000000 && getBlks.ReqBlockRangeCount <= 0xFFFFFFFF; Site.CaptureRequirementIfIsTrue( isVerifyR115, 115, @"[In MSG_GETBLKS]The syntactic range of this field[ReqBlockRangeCount (4 bytes)] is from 0x00000000 to 0xFFFFFFFF."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R116"); // Verify MS-PCCRR requirement: MS-PCCRR_R116 bool isVerifyR116 = getBlks.ReqBlockRangeCount >= 1 && getBlks.ReqBlockRangeCount <= 256; Site.CaptureRequirementIfIsTrue( isVerifyR116, 116, @"[In MSG_GETBLKS][ReqBlockRangeCount (4 bytes)]The effective range of this field MUST be between 1 and 256 inclusive, because there cannot be more than 256 non-overlapping and non-contiguous ranges in a maximum segment size of 512 blocks."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R118"); Site.CaptureRequirement( 118, @"[In MSG_GETBLKS][ReqBlockRanges (variable)]RegBlockRanges MUST specify a block range containing only one block."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R119"); // Verify MS-PCCRR requirement: MS-PCCRR_R119 Site.CaptureRequirementIfAreEqual<int>( getBlks.DataForVrfBlock.Length, (int)getBlks.SizeOfDataForVrfBlock, 119, @"[In MSG_GETBLKS]SizeOfDataForVrfBlock (4 bytes): Size in bytes of the subsequent DataForVrfBlock field."); // Verify requirement MS-PCCRR_R120 and MS-PCCRR_R121 string isR120Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R120Implementated"); bool isR121Satisfied = getBlks.SizeOfDataForVrfBlock == 0; if (isWindows) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R121"); // Verify MS-PCCRR requirement: MS-PCCRR_R121 Site.CaptureRequirementIfIsTrue( isR121Satisfied, 121, @"[In MSG_GETBLKS]This[SizeOfDataForVrfBlock (4 bytes)] field is zero.[In windows]"); if (null == isR120Implementated) { Site.Properties.Add("PCCRR.SHOULDMAY.R120Implementated", Boolean.TrueString); isR120Implementated = Boolean.TrueString; } } if (null != isR120Implementated) { bool implement = Boolean.Parse(isR120Implementated); bool isSatisfied = isR121Satisfied; // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R120"); // Verify MS-PCCRR requirement: MS-PCCRR_R120 Site.CaptureRequirementIfAreEqual<bool>( implement, isSatisfied, 120, @"[In MSG_GETBLKS]This[SizeOfDataForVrfBlock (4 bytes)] field SHOULD be zero."); } // Verify requirement MS-PCCRR_R123 and MS-PCCRR_R124 string isR123Implementated = Site.Properties.Get("PCCRR.SHOULDMAY.R123Implementated"); bool isR124Satisfied = getBlks.DataForVrfBlock.Length == 0; if (isWindows) { // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R124"); // Verify MS-PCCRR requirement: MS-PCCRR_R124 Site.CaptureRequirementIfIsTrue( isR124Satisfied, 124, @"[In MSG_GETBLKS][DataForVrfBlock (variable)]This field is empty.[In windows]"); if (null == isR123Implementated) { Site.Properties.Add("PCCRR.SHOULDMAY.R123Implementated", Boolean.TrueString); isR123Implementated = Boolean.TrueString; } } if (null != isR123Implementated) { bool implement = Boolean.Parse(isR123Implementated); bool isSatisfied = isR124Satisfied; // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R123"); // Verify MS-PCCRR requirement: MS-PCCRR_R123 Site.CaptureRequirementIfAreEqual<bool>( implement, isSatisfied, 123, @"[In MSG_GETBLKS][DataForVrfBlock (variable)]This field SHOULD be empty."); } // Capture directly, because it won't get the packet if the client didn't specify a right server address. Site.CaptureRequirement( 201, @"[In MSG_GETBLKS Initiation]To initiate a Retrieval Protocol request for specific block ranges, the higher-layer applications MUST specify a server address."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R202"); // Verify MS-PCCRR requirement: MS-PCCRR_R202 bool isVerifyR202 = true; Site.CaptureRequirementIfIsTrue( isVerifyR202, 202, @"[In MSG_GETBLKS Initiation]To initiate a Retrieval Protocol request for specific block ranges, the higher-layer applications MUST specify a segment ID."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R203"); // Verify MS-PCCRR requirement: MS-PCCRR_R203 bool isVerifyR203 = (uint)getBlks.ReqBlockRanges.Length == getBlks.ReqBlockRangeCount && true; Site.CaptureRequirementIfIsTrue( isVerifyR203, 203, @"[In MSG_GETBLKS Initiation]To initiate a Retrieval Protocol request for specific block ranges, the higher-layer applications MUST specify a set of block ranges with the segment identified by the segment ID."); // Capture directly, because it won't send a GetBlocklist message to the server if the client // did not construct an instance of the Retrieval Protocol instantiation. Site.CaptureRequirement( 204, @"[In MSG_GETBLKS Initiation]The client instance of the Retrieval Protocol MUST construct a GetBlocks message."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R174"); // Verify MS-PCCRR requirement: MS-PCCRR_R174 bool isVerifyR174 = getBlks.ReqBlockRanges != null && getBlks.SegmentID != null; Site.CaptureRequirementIfIsTrue( isVerifyR174, 174, @"[In Protocol Details]Blocks request/response: A client initiates a GetBlocks request (MSG_GETBLKS (section 2.2.4.3)) to a server to retrieve a specific block of a given segment, which is identified by the segment ID and the index of the block in the segment."); // // Add the debug information // Site.Log.Add(LogEntryKind.Debug, "Verify MS-PCCRR_R175"); // Since the request is received, the following requirement can be verified directly Site.CaptureRequirement( 175, @"[In Protocol Details][Blocks request/response]It[client] does this by sending a MSG_GETBLKS request."); }