Example #1
0
        public void TestRecordEncryptSequenceChange()
        {
            var prov = new BulkCipherProvider();
            var bKey = (AeadBulkCipherInstance)prov.GetCipherKey(BulkCipherType.AES_128_GCM);

            bKey.SetKey(key);
            bKey.SetIV(iv);
            bKey.WithPadding(paddingLength);
            for (int i = 0; i < sequenceChange; i++)
            {
                bKey.IncrementSequence();
            }
            using (var factory = new PipelineFactory())
            {
                var pipe       = factory.Create();
                var pipeWriter = factory.Create();
                var state      = new ServerStateTls13Draft18(_listener);
                //state.WriteKey = bKey;
                var buff      = pipe.Alloc();
                var buffWrite = pipeWriter.Alloc();
                buffWrite.Write(plainText);
                var reader = buffWrite.AsReadableBuffer();
                RecordProcessor.WriteRecord(ref buff, (RecordType)plainText[0], reader.Slice(5), state);
                var result = buff.AsReadableBuffer().ToArray();
                Assert.Equal <byte>(message2, result);
                buff.FlushAsync().Wait();
            }
        }
Example #2
0
        internal unsafe static void ReadClientFinished(ReadableBuffer messageBuffer, ServerStateTls13Draft18 state)
        {
            messageBuffer = messageBuffer.Slice(4);
            var hashSize = state.HandshakeHash.HashSize;

            //We could let the equals function worry about this
            //however to avoid allocations we will copy a fragmented
            //client hash into the stack as it is small
            //however an attacker could send a large messge
            //and cause a stack overflow
            if (messageBuffer.Length != hashSize)
            {
                Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.decode_error, "Client finished is the wrong size (not equal to hash size)");
            }
            //We have the client hash so we need to grab the client base key
            //and the hash up until now and make sure that the data is good
            var hash = stackalloc byte[hashSize];

            state.HandshakeHash.InterimHash(hash, hashSize);

            var key = state.KeySchedule.GenerateClientFinishedKey();

            fixed(byte *kPtr = key)
            {
                state.CryptoProvider.HashProvider.HmacData(state.CipherSuite.HashType, kPtr, key.Length, hash, hashSize, hash, hashSize);
            }

            Span <byte> clientHash;
            GCHandle    handle = default(GCHandle);

            if (messageBuffer.IsSingleSpan)
            {
                var ptr = messageBuffer.First.GetPointer(out handle);
                clientHash = new Span <byte>(ptr, hashSize);
            }
            else
            {
                var bptr = stackalloc byte[hashSize];
                clientHash = new Span <byte>(bptr, hashSize);
                messageBuffer.CopyTo(clientHash);
            }
            try
            {
                if (!Internal.CompareFunctions.ConstantTimeEquals(clientHash, new Span <byte>(hash, hashSize)))
                {
                    Alerts.AlertException.ThrowAlert(Alerts.AlertLevel.Fatal, Alerts.AlertDescription.bad_record_mac, "The mac of the client finished did not match the expected");
                }
            }
            finally
            {
                if (handle.IsAllocated)
                {
                    handle.Free();
                }
            }
        }
Example #3
0
        public void TestRecordDecrypt()
        {
            var prov = new BulkCipherProvider();
            var bKey = prov.GetCipherKey(BulkCipherType.AES_128_GCM);

            bKey.SetKey(key);
            bKey.SetIV(iv);
            using (var factory = new PipelineFactory())
            {
                var pipe   = factory.Create();
                var buffer = pipe.Alloc();
                buffer.Write(message1);
                buffer.FlushAsync().Wait();
                var reader = pipe.ReadAsync();
                var result = reader.GetResult().Buffer;
                var state  = new ServerStateTls13Draft18(_listener);
                //state.ReadKey = bKey;
                var header = RecordProcessor.ReadRecord(ref result, state);
                Assert.Equal(RecordType.Alert, header);
                Assert.Equal <byte>(plainText.Skip(5), result.ToArray());
            }
        }
Example #4
0
        public void TestRecordEncryptNoPadding()
        {
            var prov = new BulkCipherProvider();
            var bKey = prov.GetCipherKey(BulkCipherType.AES_128_GCM);

            bKey.SetKey(key);
            bKey.SetIV(iv);
            using (var factory = new PipelineFactory())
            {
                var pipe       = factory.Create();
                var pipeWriter = factory.Create();
                var state      = new ServerStateTls13Draft18(_listener);
                //state.WriteKey = bKey;
                var buff      = pipe.Alloc();
                var buffWrite = pipeWriter.Alloc();
                buffWrite.Write(plainText);
                var reader = buffWrite.AsReadableBuffer();
                RecordProcessor.WriteRecord(ref buff, (RecordType)plainText[0], reader.Slice(5), state);
                var result = buff.AsReadableBuffer().ToArray();
                Assert.Equal <byte>(message0, result);
                buff.FlushAsync().Wait();
            }
        }