/// <summary> /// Build packet binary data /// </summary> /// <returns>a byte buffer</returns> private ByteBuffer BuildImage() { ByteBuffer image = _imageBuffer.Value; image.Clear(); int packetLength = _payload.Length + 5; //type and CRC int paddingLength = 8 - (packetLength % 8); image.WriteInt32(packetLength); image.WriteSecureRandomBytes(paddingLength); image.WriteByte((byte)_type); if (_payload.Length > 0) { image.Append(_payload); } uint crc = CRC.Calc( image.RawBuffer, image.RawBufferOffset + PACKET_LENGTH_FIELD_LEN, image.Length - PACKET_LENGTH_FIELD_LEN); image.WriteUInt32(crc); return(image); }
private byte[] BuildImage() { int packet_length = (_data == null ? 0 : _data.Length) + 5; //type and CRC int padding_length = 8 - (packet_length % 8); byte[] image = new byte[packet_length + padding_length + 4]; SSHUtil.WriteIntToByteArray(image, 0, packet_length); for (int i = 0; i < padding_length; i++) { image[4 + i] = 0; //padding: filling by random values is better } image[4 + padding_length] = _type; if (_data != null) { Array.Copy(_data, 0, image, 4 + padding_length + 1, _data.Length); } _CRC = CRC.Calc(image, 4, image.Length - 8); SSHUtil.WriteIntToByteArray(image, image.Length - 4, (int)_CRC); return(image); }
/// <summary> /// Extracts SSH packet from the internal buffer. /// </summary> /// <returns> /// true if one SSH packet has been extracted. /// in this case, _packetImage contains Packet Type field and Data field of the SSH packet. /// </returns> private bool ConstructPacket() { const int PACKET_LENGTH_FIELD_LEN = 4; const int CHECK_BYTES_FIELD_LEN = 4; if (_packetLength < 0) { if (_inputBuffer.Length < PACKET_LENGTH_FIELD_LEN) { return(false); } uint packetLength = SSHUtil.ReadUInt32(_inputBuffer.RawBuffer, _inputBuffer.RawBufferOffset); _inputBuffer.RemoveHead(PACKET_LENGTH_FIELD_LEN); if (packetLength < MIN_PACKET_LENGTH || packetLength > MAX_PACKET_LENGTH) { throw new SSHException(String.Format("invalid packet length : {0}", packetLength)); } _packetLength = (int)packetLength; } int paddingLength = 8 - (_packetLength % 8); int requiredLength = paddingLength + _packetLength; if (_inputBuffer.Length < requiredLength) { return(false); } _packetImage.Clear(); _packetImage.Append(_inputBuffer, 0, requiredLength); // Padding, Packet Type, Data, and Check fields _inputBuffer.RemoveHead(requiredLength); if (_cipher != null) { _cipher.Decrypt( _packetImage.RawBuffer, _packetImage.RawBufferOffset, requiredLength, _packetImage.RawBuffer, _packetImage.RawBufferOffset); } if (_checkMAC) { uint crc = CRC.Calc( _packetImage.RawBuffer, _packetImage.RawBufferOffset, requiredLength - CHECK_BYTES_FIELD_LEN); uint expected = SSHUtil.ReadUInt32( _packetImage.RawBuffer, _packetImage.RawBufferOffset + requiredLength - CHECK_BYTES_FIELD_LEN); if (crc != expected) { throw new SSHException("CRC Error"); } } // retain only Packet Type and Data fields _packetImage.RemoveHead(paddingLength); _packetImage.RemoveTail(CHECK_BYTES_FIELD_LEN); // sanity check if (_packetImage.Length != _packetLength - CHECK_BYTES_FIELD_LEN) { throw new InvalidOperationException(); } // prepare for the next packet _packetLength = -1; return(true); }