Пример #1
0
        // 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);
        }
Пример #2
0
        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;
        }