private void ExchangeKeys(Stream baseStream, ISymmetricAlgorithmDescriptor transportAlgorithmDescriptor, IKeyExchangeAlgorithm keyExchangeAlgorithm, out ICryptoTransform decryptor, out ICryptoTransform encryptor)
        {
            var encryptionAlgorithm = transportAlgorithmDescriptor.Build();
            var key = new byte[encryptionAlgorithm.KeySize / 8];
            var iv  = new byte[encryptionAlgorithm.BlockSize / 8];

            prng.GetBytes(key);
            prng.GetBytes(iv);
            encryptionAlgorithm.Key = key;
            encryptionAlgorithm.IV  = iv;
            var keyPackage = new KeyPackage
            {
                Key = encryptionAlgorithm.Key,
                InitializationVector = encryptionAlgorithm.IV,
            };

            byte[] keyBuffer;
            using (var memoryStream = new MemoryStream())
            {
                Serializer.Serialize(memoryStream, keyPackage);
                keyBuffer = keyExchangeAlgorithm.Encrypt(memoryStream.ToArray());
            }
            var buffer = bitConverter.GetBytes(keyBuffer.Length);

            baseStream.Write(buffer, 0, buffer.Length);
            baseStream.Write(keyBuffer, 0, keyBuffer.Length);
            buffer = new byte[sizeof(int)];
            baseStream.Read(buffer, 0, buffer.Length);
            var length = bitConverter.ToInt32(buffer);

            if (0 > length)
            {
                throw new InvalidDataException();
            }
            buffer = new byte[length];
            baseStream.Read(buffer, 0, buffer.Length);
            buffer = keyExchangeAlgorithm.Decrypt(buffer);
            var        decryptionAlgorithm = transportAlgorithmDescriptor.Build();
            KeyPackage remoteKeyPackage;

            using (var memoryStream = new MemoryStream(buffer))
                remoteKeyPackage = Serializer.Deserialize <KeyPackage>(memoryStream);
            decryptionAlgorithm.Key = remoteKeyPackage.Key;
            decryptionAlgorithm.IV  = remoteKeyPackage.InitializationVector;
            encryptor = encryptionAlgorithm.CreateEncryptor();
            decryptor = decryptionAlgorithm.CreateDecryptor();
        }
        public T ReadNext(out int size)
        {
            var      buffer         = new byte[4];
            EndPoint remoteEndpoint = null;

            socket.FillReceiveFrom(buffer, ref remoteEndpoint);
            var messageLength = bitConverter.ToInt32(buffer);

            if (0 > messageLength)
            {
                size = -1;
                return(default(T));
            }
            buffer = new byte[messageLength];
            socket.FillReceive(buffer);
            size = 4 + messageLength;
            using (var stream = new MemoryStream(buffer))
                return(serializer.Deserialize(stream));
        }
예제 #3
0
        static Reader()
        {
            //positive fixint	0xxxxxxx	0x00 - 0x7f
            _lookup.AddRange(0, 0x7F,
                             (b, s) => new MPack(b, MPackType.SInt),
                             (b, s, c) => Task.FromResult(new MPack(b, MPackType.SInt)));

            //positive fixint	0xxxxxxx	0x00 - 0x7f
            _lookup.AddRange(0x80, 0x8F, (b, s) =>
            {
                MPackMap map = new MPackMap();
                int len      = b - 0x80;
                for (int i = 0; i < len; i++)
                {
                    map.Add(ParseFromStream(s), ParseFromStream(s));
                }
                return(map);
            }, async(b, s, c) =>
            {
                MPackMap map = new MPackMap();
                int len      = b - 0x80;
                for (int i = 0; i < len; i++)
                {
                    map.Add(await ParseFromStreamAsync(s, c), await ParseFromStreamAsync(s, c));
                }
                return(map);
            });

            //fixarray	1001xxxx	0x90 - 0x9f
            _lookup.AddRange(0x90, 0x9f, (b, s) =>
            {
                MPackArray array = new MPackArray();
                int len          = b - 0x90;
                for (int i = 0; i < len; i++)
                {
                    array.Add(ParseFromStream(s));
                }
                return(array);
            }, async(b, s, c) =>
            {
                MPackArray array = new MPackArray();
                int len          = b - 0x90;
                for (int i = 0; i < len; i++)
                {
                    array.Add(await ParseFromStreamAsync(s, c));
                }
                return(array);
            });

            // fixstr	101xxxxx	0xa0 - 0xbf
            _lookup.AddRange(0xA0, 0xBF, (b, s) =>
            {
                int len = b - 0xA0;
                return(new MPack(_encoding.GetString(s.Read(len)), MPackType.String));
            }, async(b, s, c) =>
            {
                int len = b - 0xA0;
                return(new MPack(_encoding.GetString(await s.ReadAsync(len, c)), MPackType.String));
            });

            // negative fixnum stores 5-bit negative integer 111xxxxx
            _lookup.AddRange(0xE0, 0xFF,
                             (b, s) => new MPack((sbyte)b, MPackType.SInt),
                             (b, s, c) => Task.FromResult(new MPack((sbyte)b, MPackType.SInt)));

            // null
            _lookup.Add(0xC0,
                        (b, s) => MPack.Null(),
                        (b, s, c) => Task.FromResult(MPack.Null()));

            // note, no 0xC1, it's not used.

            // bool: false
            _lookup.Add(0xC2,
                        (b, s) => new MPack(false, MPackType.Bool),
                        (b, s, c) => Task.FromResult(new MPack(false, MPackType.Bool)));

            // bool: true
            _lookup.Add(0xC3,
                        (b, s) => new MPack(true, MPackType.Bool),
                        (b, s, c) => Task.FromResult(new MPack(true, MPackType.Bool)));

            // binary array, max 255
            _lookup.Add(0xC4, (b, s) =>
            {
                byte len = (byte)s.ReadByte();
                return(new MPack(s.Read(len), MPackType.Binary));
            }, async(b, s, c) =>
            {
                byte len = await s.ReadByteAsync(c);
                return(new MPack(await s.ReadAsync(len, c), MPackType.Binary));
            });

            // binary array, max 65535
            _lookup.Add(0xC5, (b, s) =>
            {
                int len = _convert.ToUInt16(s.Read(2), 0);
                return(new MPack(s.Read(len), MPackType.Binary));
            }, async(b, s, c) =>
            {
                int len = _convert.ToUInt16((await s.ReadAsync(2, c)), 0);
                return(new MPack(await s.ReadAsync(len, c), MPackType.Binary));
            });

            // binary max: 2^32-1
            _lookup.Add(0xC6, (b, s) =>
            {
                uint len = _convert.ToUInt32(s.Read(4), 0);
                return(new MPack(s.Read(len), MPackType.Binary));
            }, async(b, s, c) =>
            {
                uint len = _convert.ToUInt32((await s.ReadAsync(4, c)), 0);
                return(new MPack(await s.ReadAsync(len, c), MPackType.Binary));
            });

            // note 0xC7, 0xC8, 0xC9, not used.

            // float 32 stores a floating point number in IEEE 754 single precision floating point number
            _lookup.Add(0xCA, (b, s) =>
            {
                var raw = s.Read(4);
                return(new MPack(_convert.ToSingle(raw, 0), MPackType.Single));
            }, async(b, s, c) =>
            {
                var raw = (await s.ReadAsync(4, c));
                return(new MPack(_convert.ToSingle(raw, 0), MPackType.Single));
            });

            // float 64 stores a floating point number in IEEE 754 double precision floating point number
            _lookup.Add(0xCB, (b, s) =>
            {
                var raw = s.Read(8);
                return(new MPack(_convert.ToDouble(raw, 0), MPackType.Double));
            }, async(b, s, c) =>
            {
                var raw = (await s.ReadAsync(8, c));
                return(new MPack(_convert.ToDouble(raw, 0), MPackType.Double));
            });

            // uint8   0xcc   xxxxxxxx
            _lookup.Add(0xCC,
                        (b, s) => new MPack((byte)s.ReadByte(), MPackType.UInt),
                        async(b, s, c) => new MPack((byte)await s.ReadByteAsync(c), MPackType.UInt));

            // uint16   0xcd xxxxxxxx xxxxxxxx
            _lookup.Add(0xCD, (b, s) =>
            {
                var v = _convert.ToUInt16(s.Read(2), 0);
                return(new MPack(v, MPackType.UInt));
            }, async(b, s, c) =>
            {
                var v = _convert.ToUInt16((await s.ReadAsync(2, c))
                                          , 0);
                return(new MPack(v, MPackType.UInt));
            });

            // uint32   0xce xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
            _lookup.Add(0xCE, (b, s) =>
            {
                var v = _convert.ToUInt32(s.Read(4), 0);
                return(new MPack(v, MPackType.UInt));
            }, async(b, s, c) =>
            {
                var v = _convert.ToUInt32((await s.ReadAsync(4, c))
                                          , 0);
                return(new MPack(v, MPackType.UInt));
            });

            // uint64   0xcF   xxxxxxxx (x4)
            _lookup.Add(0xCF, (b, s) =>
            {
                var v = _convert.ToUInt64(s.Read(8), 0);
                return(new MPack(v, MPackType.UInt));
            }, async(b, s, c) =>
            {
                var v = _convert.ToUInt64((await s.ReadAsync(8, c)), 0);
                return(new MPack(v, MPackType.UInt));
            });

            // array (uint16 length)
            _lookup.Add(0xDC, (b, s) =>
            {
                ushort len       = _convert.ToUInt16(s.Read(2), 0);
                MPackArray array = new MPackArray();
                for (ushort i = 0; i < len; i++)
                {
                    array.Add(ParseFromStream(s));
                }
                return(array);
            }, async(b, s, c) =>
            {
                ushort len       = _convert.ToUInt16((await s.ReadAsync(2, c)), 0);
                MPackArray array = new MPackArray();
                for (ushort i = 0; i < len; i++)
                {
                    array.Add(await ParseFromStreamAsync(s, c));
                }
                return(array);
            });

            // array (uint32 length)
            _lookup.Add(0xDD, (b, s) =>
            {
                uint len         = _convert.ToUInt32(s.Read(4), 0);
                MPackArray array = new MPackArray();
                for (uint i = 0; i < len; i++)
                {
                    array.Add(ParseFromStream(s));
                }
                return(array);
            }, async(b, s, c) =>
            {
                uint len         = _convert.ToUInt32(await s.ReadAsync(4, c), 0);
                MPackArray array = new MPackArray();
                for (uint i = 0; i < len; i++)
                {
                    array.Add(await ParseFromStreamAsync(s, c));
                }
                return(array);
            });

            // map (uint16 length)
            _lookup.Add(0xDE, (b, s) =>
            {
                ushort len   = _convert.ToUInt16(s.Read(2), 0);
                MPackMap map = new MPackMap();
                for (ushort i = 0; i < len; i++)
                {
                    var flag = (byte)s.ReadByte();
                    var key  = ReadString(flag, s);
                    var val  = ParseFromStream(s);
                    map.Add(key, val);
                }
                return(map);
            }, async(b, s, c) =>
            {
                ushort len   = _convert.ToUInt16(await s.ReadAsync(2, c), 0);
                MPackMap map = new MPackMap();
                for (ushort i = 0; i < len; i++)
                {
                    var flag = await s.ReadByteAsync(c);
                    var key  = await ReadStringAsync(flag, s, c);
                    var val  = await ParseFromStreamAsync(s, c);
                    map.Add(key, val);
                }
                return(map);
            });

            // map (uint32 length)
            _lookup.Add(0xDF, (b, s) =>
            {
                uint len     = _convert.ToUInt32(s.Read(4), 0);
                MPackMap map = new MPackMap();
                for (uint i = 0; i < len; i++)
                {
                    var flag = (byte)s.ReadByte();
                    var key  = ReadString(flag, s);
                    var val  = ParseFromStream(s);
                    map.Add(key, val);
                }
                return(map);
            }, async(b, s, c) =>
            {
                uint len     = _convert.ToUInt32((await s.ReadAsync(4, c)), 0);
                MPackMap map = new MPackMap();
                for (uint i = 0; i < len; i++)
                {
                    var flag = await s.ReadByteAsync(c);
                    var key  = await ReadStringAsync(flag, s, c);
                    var val  = await ParseFromStreamAsync(s, c);
                    map.Add(key, val);
                }
                return(map);
            });

            //  str family
            _lookup.AddRange(0xD9, 0xDB,
                             (b, s) => new MPack(ReadString(b, s), MPackType.String),
                             async(b, s, c) => new MPack((await ReadStringAsync(b, s, c)), MPackType.String));

            // int8   0xD0   xxxxxxxx
            _lookup.Add(0xD0,
                        (b, s) => new MPack((sbyte)s.ReadByte(), MPackType.SInt),
                        async(b, s, c) => new MPack((sbyte)await s.ReadByteAsync(c), MPackType.SInt));

            // int16   0xd1 xxxxxxxx xxxxxxxx
            _lookup.Add(0xD1, (b, s) =>
            {
                var v = _convert.ToInt16(s.Read(2), 0);
                return(new MPack(v, MPackType.SInt));
            }, async(b, s, c) =>
            {
                var v = _convert.ToInt16((await s.ReadAsync(2, c))
                                         , 0);
                return(new MPack(v, MPackType.SInt));
            });

            // int32    0xD2 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
            _lookup.Add(0xD2, (b, s) =>
            {
                var v = _convert.ToInt32(s.Read(4), 0);
                return(new MPack(v, MPackType.SInt));
            }, async(b, s, c) =>
            {
                var v = _convert.ToInt32((await s.ReadAsync(4, c))
                                         , 0);
                return(new MPack(v, MPackType.SInt));
            });

            // int64      0xD3 xxxxxxxx (x8)
            _lookup.Add(0xD3, (b, s) =>
            {
                var v = _convert.ToInt64(s.Read(8), 0);
                return(new MPack(v, MPackType.SInt));
            }, async(b, s, c) =>
            {
                var v = _convert.ToInt64((await s.ReadAsync(8, c))
                                         , 0);
                return(new MPack(v, MPackType.SInt));
            });
        }