public async Task ConvertUplink(IDuplexPipe client, IDuplexPipe server)
        {
            var up  = parameter.GetCrypto();
            var pmp = new ProtocolMessagePipe(server);
            var key = CryptoUtils.SSKDF(password, parameter.KeySize);

            var salt = new SaltMessage(parameter.NonceSize, true);
            await pmp.WriteAsync(salt);

            up.Init(key, salt.Salt.ToArray());
            Memory <byte> nonce = new byte[parameter.NonceSize];

            nonce.Span.Fill(0);
            // TODO write salt with data
            while (true)
            {
                var result = await client.Input.ReadAsync();

                if (result.IsCanceled || result.IsCompleted)
                {
                    return;
                }

                // TODO compress into one chunk when possible

                foreach (var item in result.Buffer)
                {
                    var mem = server.Output.GetMemory(item.Length);
                    var len = up.Encrypt(null, item.Span, mem.Span);
                    server.Output.Advance(len);
                }
                client.Input.AdvanceTo(result.Buffer.End);
            }
        }
Esempio n. 2
0
        public async Task ConvertUplink(IDuplexPipe client, IDuplexPipe server)
        {
            using var up = cryptoParameter.GetCrypto();
            var pmp  = new ProtocolMessagePipe(server);
            var salt = new SaltMessage(16, true);
            await pmp.WriteAsync(salt);

            var key = new byte[cryptoParameter.KeySize];

            HKDF.DeriveKey(HashAlgorithmName.SHA1, mainKey, key, salt.Salt.Span, _ssSubKeyInfo);
            up.Init(key, null);
            Memory <byte> nonce = new byte[cryptoParameter.NonceSize];

            nonce.Span.Fill(0);
            // TODO write salt with data
            while (true)
            {
                var result = await client.Input.ReadAsync();

                if (result.IsCanceled || result.IsCompleted)
                {
                    return;
                }

                // TODO compress into one chunk when possible

                foreach (var item in result.Buffer)
                {
                    foreach (var i in SplitBigChunk(item))
                    {
                        await pmp.WriteAsync(new AeadBlockMessage(up, nonce, cryptoParameter)
                        {
                            // in send routine, Data is readonly
                            Data = MemoryMarshal.AsMemory(i),
                        });
                    }
                }
                client.Input.AdvanceTo(result.Buffer.End);
            }
        }