// Derived class can override this method to modify the buffer. public virtual DataFragment Close(Cipher cipher, MAC mac, int sequence) { if (!_isOpen) { throw new SSHException("internal state error"); } int blocksize = cipher == null ? 8 : cipher.BlockSize; int payloadLength = _writer.Length - (SEQUENCE_MARGIN + LENGTH_MARGIN + PADDING_MARGIN); int paddingLength = 11 - payloadLength % blocksize; while (paddingLength < 4) { paddingLength += blocksize; } int packetLength = PADDING_MARGIN + payloadLength + paddingLength; int imageLength = packetLength + LENGTH_MARGIN; //fill padding byte[] tmp = new byte[4]; Rng rng = RngManager.GetSecureRng(); for (int i = 0; i < paddingLength; i += 4) { rng.GetBytes(tmp); _writer.Write(tmp); } //manipulate stream byte[] rawbuf = _writer.UnderlyingBuffer; SSHUtil.WriteIntToByteArray(rawbuf, 0, sequence); SSHUtil.WriteIntToByteArray(rawbuf, SEQUENCE_MARGIN, packetLength); rawbuf[SEQUENCE_MARGIN + LENGTH_MARGIN] = (byte)paddingLength; //mac if (mac != null) { byte[] macCode = mac.ComputeHash(rawbuf, 0, packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN); Array.Copy(macCode, 0, rawbuf, packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN, macCode.Length); imageLength += macCode.Length; } //encrypt if (cipher != null) { cipher.Encrypt(rawbuf, SEQUENCE_MARGIN, packetLength + LENGTH_MARGIN, rawbuf, SEQUENCE_MARGIN); } _dataFragment.Init(rawbuf, SEQUENCE_MARGIN, imageLength); _isOpen = false; return(_dataFragment); }
public void Close(Cipher cipher, Random rnd, MAC mac, int sequence, DataFragment result) { if (!_is_open) { throw new SSHException("internal state error"); } int blocksize = cipher == null? 8 : cipher.BlockSize; int payload_length = _writer.Length - (SEQUENCE_MARGIN + LENGTH_MARGIN + PADDING_MARGIN); int r = 11 - payload_length % blocksize; while (r < 4) { r += blocksize; } _paddingLength = r; _packetLength = PADDING_MARGIN + payload_length + _paddingLength; int image_length = _packetLength + LENGTH_MARGIN; //fill padding for (int i = 0; i < _paddingLength; i += 4) { _writer.Write(rnd.Next()); } //manipulate stream byte[] rawbuf = _writer.UnderlyingBuffer; SSHUtil.WriteIntToByteArray(rawbuf, 0, sequence); SSHUtil.WriteIntToByteArray(rawbuf, SEQUENCE_MARGIN, _packetLength); rawbuf[SEQUENCE_MARGIN + LENGTH_MARGIN] = (byte)_paddingLength; //mac if (mac != null) { _mac = mac.ComputeHash(rawbuf, 0, _packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN); Array.Copy(_mac, 0, rawbuf, _packetLength + LENGTH_MARGIN + SEQUENCE_MARGIN, _mac.Length); image_length += _mac.Length; } //encrypt if (cipher != null) { cipher.Encrypt(rawbuf, SEQUENCE_MARGIN, _packetLength + LENGTH_MARGIN, rawbuf, SEQUENCE_MARGIN); } result.Init(rawbuf, SEQUENCE_MARGIN, image_length); _is_open = false; }