Exemple #1
0
        public Record Read(RecordType type, TLSVersion version, ushort length)
        {
            var cipher = GetCipher();

            cipher.Init(GetParameters(ConnectionDirection.Read));

            var payload   = _connection.Reader.ReadBytes(length);
            var plaintext = new byte[payload.Length];

            cipher.Decrypt(payload, 0, plaintext, 0, payload.Length);

            var macAlgo       = GetMAC(ConnectionDirection.Read);
            var macLength     = macAlgo.HashSize / 8;
            var contentLength = plaintext.Length - macLength;

            SecurityAssert.Assert(contentLength >= 0);

            var mac = new byte[macLength];

            Array.Copy(plaintext, contentLength, mac, 0, macLength);

            var content = new byte[contentLength];

            Array.Copy(plaintext, 0, content, 0, content.Length);

            var seqNum      = _sequenceConfig.GetThenIncrement(ConnectionDirection.Read);
            var computedMac = ComputeMAC(macAlgo, seqNum, type, version, content);

            SecurityAssert.AssertHash(mac, computedMac);

            return(new Record(type, version, content));
        }
        public Record Read(RecordType type, TLSVersion version, ushort length)
        {
            var cipher = GetCipher();

            // TODO parametrised from CipherSpec
            var explicitNonceLength = 8;

            var nonce   = _connection.Reader.ReadBytes(explicitNonceLength);
            var payload = _connection.Reader.ReadBytes(length - explicitNonceLength);

            var aad = new byte[13];

            Array.Copy(EndianBitConverter.Big.GetBytes(_sequenceConfig.GetThenIncrement(ConnectionDirection.Read)), 0, aad, 0, 8);
            Array.Copy(new[] { (byte)type, version.Major, version.Major }, 0, aad, 8, 3);
            Array.Copy(EndianBitConverter.Big.GetBytes((ushort)(length - explicitNonceLength - cipher.TagLength)), 0, aad, 11, 2);

            cipher.Init(GetParameters(ConnectionDirection.Read, aad, nonce));

            var plaintext = new byte[payload.Length - cipher.TagLength];

            var input  = payload.AsSpan();
            var output = plaintext.AsSpan();

            var result = cipher.DecryptAll(input, output);

            Array.Resize(ref plaintext, plaintext.Length - result.RemainingOutput.Length);

            return(new Record(type, version, plaintext));
        }
        public Record Read(RecordType type, TLSVersion version, ushort length)
        {
            var cipher = GetCipher();

            var blockLength = cipher.BlockLength;
            var iv          = _connection.Reader.ReadBytes(blockLength);

            cipher.Init(new IVParameter(GetParameters(ConnectionDirection.Read), iv));

            var payload   = _connection.Reader.ReadBytes(length - blockLength);
            var plaintext = new byte[payload.Length];

            cipher.Decrypt(payload, 0, plaintext, 0, payload.Length);

            var macAlgo       = GetMAC(ConnectionDirection.Read);
            var macLength     = macAlgo.HashSize / 8;
            var paddingLength = plaintext[plaintext.Length - 1];
            var contentLength = plaintext.Length - paddingLength - macLength - 1;

            SecurityAssert.Assert(contentLength >= 0);

            //TODO constant time
            for (var i = plaintext.Length - 1; i > plaintext.Length - paddingLength; i--)
            {
                SecurityAssert.Assert(plaintext[i] == paddingLength);
            }

            var mac = new byte[macLength];

            Array.Copy(plaintext, contentLength, mac, 0, macLength);

            var content = new byte[contentLength];

            Array.Copy(plaintext, 0, content, 0, content.Length);

            var seqNum      = _sequenceConfig.GetThenIncrement(ConnectionDirection.Read);
            var computedMac = ComputeMAC(macAlgo, seqNum, type, version, content);

            SecurityAssert.AssertHash(mac, computedMac);

            return(new Record(type, version, content));
        }