Example #1
0
        public byte[] Serialize <T>(CryptoDtoChannel channel, CryptoDtoMode mode, T obj)
        {
            ArrayBufferWriter <byte> arrayBufferWriter = new ArrayBufferWriter <byte>();

            Serialize(arrayBufferWriter, channel, mode, obj);
            return(arrayBufferWriter.WrittenSpan.ToArray());
        }
        public void Setup()
        {
            cryptoChannelStore = new CryptoDtoChannelStore();
            cryptoChannelStore.CreateChannel("Benchmark");
            var dto = new BenchmarkDto()
            {
                Callsign        = "Benchmark",
                SequenceCounter = 0,
                Audio           = new byte[200],
                LastPacket      = false
            };
            Random rnd = new Random();

            rnd.NextBytes(dto.Audio);
            MemoryStream ms = new MemoryStream();

            MessagePackSerializer.Serialize(ms, dto);

            cryptoChannelStore.TryGetChannel("Benchmark", out var channel);
            var config = channel.GetRemoteEndpointChannelConfig();

            remoteChannel = new CryptoDtoChannel(config);

            cryptoDtoPacket = serializer.Serialize(cryptoChannelStore, "Benchmark", CryptoDtoMode.ChaCha20Poly1305, dto);
        }
Example #3
0
 // Hint for callers using ArrayBufferWriter<byte> - output.WrittenSpan contains the serialised data
 public void Serialize <T>(IBufferWriter <byte> output, CryptoDtoChannel channel, CryptoDtoMode mode, T dto)
 {
     lock (bufferLock)
     {
         ReadOnlySpan <byte> dtoNameBuffer = GetDtoNameBytes <T>();
         dtoBuffer.Clear();
         MessagePackSerializer.Serialize(dtoBuffer, dto);
         Pack(output, channel, mode, dtoNameBuffer, dtoBuffer.WrittenSpan);
     }
 }
Example #4
0
        public void CreateCryptoChannels()
        {
            if (Tokens == null)
            {
                throw new Exception(nameof(Tokens) + " not set");
            }

            VoiceCryptoChannel = new CryptoDtoChannel(Tokens.VoiceServer.ChannelConfig);
            //DataCryptoChannel = new CryptoDtoChannel(Tokens.DataServer.ChannelConfig);
        }
Example #5
0
        //[Obsolete]
        //public byte[] Pack(CryptoDtoChannelStore channelStore, string channelTag, CryptoDtoMode mode, ReadOnlySpan<byte> dtoNameBuffer, ReadOnlySpan<byte> dtoBuffer)
        //{
        //    var channel = channelStore.GetChannel(channelTag);
        //    return Pack(channel, mode, dtoNameBuffer, dtoBuffer);
        //}

        //[Obsolete]
        //public byte[] Pack(CryptoDtoChannel channel, CryptoDtoMode mode, ReadOnlySpan<byte> dtoNameBuffer, ReadOnlySpan<byte> dtoBuffer)
        //{
        //    ArrayBufferWriter<byte> arrayBufferWriter = new ArrayBufferWriter<byte>();
        //    Pack(arrayBufferWriter, channel, mode, dtoNameBuffer, dtoBuffer);
        //    return arrayBufferWriter.WrittenSpan.ToArray();
        //}

        public void Pack(IBufferWriter <byte> output, CryptoDtoChannel channel, CryptoDtoMode mode, ReadOnlySpan <byte> dtoNameBuffer, ReadOnlySpan <byte> dtoBuffer)
        {
            channel.GetTransmitKey(mode, out ulong sequenceToSend);
            CryptoDtoHeaderDto header = new CryptoDtoHeaderDto
            {
                ChannelTag = channel.ChannelTag,
                Mode       = mode,
                Sequence   = sequenceToSend
            };

            Pack(output, header, channel.TransmitChaCha20Poly1305, dtoNameBuffer, dtoBuffer);
        }
Example #6
0
        public static long SerialiseCryptoDto <T>(this DealerSocket dealerSocket, object data, CryptoDtoChannel channel, CryptoDtoMode mode)
        {
            T typedData = (T)data;

            byte[] cryptoData = CryptoDtoSerializer.Serialize(channel, mode, typedData);

            dealerSocket
            .SendMoreFrameEmpty()
            .SendFrame(cryptoData);

            return(cryptoData.Length);
        }
        public static byte[] Pack(CryptoDtoChannel channel, CryptoDtoMode mode, byte[] dtoNameBuffer, byte[] dtoBuffer)
        {
            var transmitKey = channel.GetTransmitKey(mode, out ulong sequenceToSend);

            return(Pack(channel.ChannelTag, mode, transmitKey, sequenceToSend, dtoNameBuffer, dtoBuffer));
        }
        public static byte[] Serialize <T>(CryptoDtoChannel channel, CryptoDtoMode mode, T obj)
        {
            var transmitKey = channel.GetTransmitKey(mode, out ulong sequenceToSend);

            return(Serialise(channel.ChannelTag, mode, transmitKey, sequenceToSend, obj));
        }
            internal Deserializer(CryptoDtoChannel channel, ReadOnlySpan <byte> bytes, bool ignoreSequence)
            {
                sequenceValid = false;
                headerLength  = Unsafe.ReadUnaligned <ushort>(ref MemoryMarshal.GetReference(bytes));                               //.NET Standard 2.0 doesn't have BitConverter.ToUInt16(Span<T>)
                if (bytes.Length < (2 + headerLength))
                {
                    throw new CryptographicException("Not enough bytes to process packet.");
                }

                ReadOnlySpan <byte> headerBuffer = bytes.Slice(2, headerLength);

                header = MessagePackSerializer.Deserialize <CryptoDtoHeaderDto>(headerBuffer.ToArray());

                if (header.ChannelTag != channel.ChannelTag)
                {
                    throw new CryptographicException("Channel Tag doesn't match provided Channel");
                }

                switch (header.Mode)
                {
                case CryptoDtoMode.ChaCha20Poly1305:
                {
                    int aeLength = bytes.Length - (2 + headerLength);
                    ReadOnlySpan <byte> aePayloadBuffer = bytes.Slice(2 + headerLength, aeLength);

                    ReadOnlySpan <byte> adBuffer = bytes.Slice(0, 2 + headerLength);

                    Span <byte> nonceBuffer = stackalloc byte[Aead.NonceSize];
                    BinaryPrimitives.WriteUInt64LittleEndian(nonceBuffer.Slice(4), header.Sequence);

                    ReadOnlySpan <byte> receiveKey = channel.GetReceiveKey(header.Mode);
                    var aead = new ChaCha20Poly1305(receiveKey.ToArray());
                    ReadOnlySpan <byte> decryptedPayload = aead.Decrypt(aePayloadBuffer.ToArray(), adBuffer.ToArray(), nonceBuffer);

                    if (ignoreSequence)
                    {
                        sequenceValid = channel.IsReceivedSequenceAllowed(header.Sequence);
                    }
                    else
                    {
                        channel.CheckReceivedSequence(header.Sequence);             //The packet has passed MAC, so now check if it's being duplicated or replayed
                        sequenceValid = true;
                    }

                    dtoNameLength = Unsafe.ReadUnaligned <ushort>(ref MemoryMarshal.GetReference(decryptedPayload));           //.NET Standard 2.0 doesn't have BitConverter.ToUInt16(Span<T>)

                    if (decryptedPayload.Length < (2 + dtoNameLength))
                    {
                        throw new CryptographicException("Not enough bytes to process packet. (2) " + dtoNameLength + " " + decryptedPayload.Length);
                    }

                    dtoNameBuffer = decryptedPayload.Slice(2, dtoNameLength);

                    dataLength = Unsafe.ReadUnaligned <ushort>(ref MemoryMarshal.GetReference(decryptedPayload.Slice(2 + dtoNameLength, 2)));           //.NET Standard 2.0 doesn't have BitConverter.ToUInt16(Span<T>)

                    if (decryptedPayload.Length < (2 + dtoNameLength + 2 + dataLength))
                    {
                        throw new CryptographicException("Not enough bytes to process packet. (3) " + dataLength + " " + decryptedPayload.Length);
                    }
                    dataBuffer = decryptedPayload.Slice(2 + dtoNameLength + 2, dataLength);
                    break;
                }

                default:
                    throw new CryptographicException("Mode not recognised");
                }
            }
 public static Deserializer DeserializeIgnoreSequence(CryptoDtoChannel channel, ReadOnlySpan <byte> bytes)            //This is used for UDP channels where duplication is possible
 {
     return(new Deserializer(channel, bytes, true));
 }
 public static Deserializer Deserialize(CryptoDtoChannel channel, ReadOnlySpan <byte> bytes)
 {
     return(new Deserializer(channel, bytes, false));
 }