Beispiel #1
0
        /// <summary>
        ///     <see cref="Decrypt" /> this instance.
        /// </summary>
        public virtual void Decrypt()
        {
            if (this.Client.State >= State.LOGGED)
            {
                this.Client.SNonce.Increment();

                this.Data = Sodium.Decrypt(
                    new byte[16].Concat(this.Data).ToArray(),
                    this.Client.SNonce,
                    this.Client.PublicKey);
                this.Reader = new Reader(this.Data);
                this.Length = this.Data.Length;
            }
        }
        internal override void Decrypt()
        {
            this.Device.Keys.SNonce.Increment();

            byte[] Decrypted = Sodium.Decrypt(new byte[16].Concat(this.Reader.ReadBytes(this.Length)).ToArray(), this.Device.Keys.SNonce, this.Device.Keys.PublicKey);

            if (Decrypted == null)
            {
                throw new CryptographicException("Tried to decrypt an incomplete message.");
            }

            this.Reader = new Reader(Decrypted);
            this.Length = (ushort)this.Reader.BaseStream.Length;
        }
Beispiel #3
0
        internal virtual void DecryptSodium()
        {
            if (this.Device.PlayerState >= Client_State.LOGGED)
            {
                this.Device.Crypto.SNonce.Increment();

                byte[] Decrypted = Sodium.Decrypt(new byte[16].Concat(this.Reader.ReadBytes(this.Length)).ToArray(), this.Device.Crypto.SNonce, this.Device.Crypto.PublicKey);

                if (Decrypted == null)
                {
                    Server_Resources.Exceptions.Catch(new CryptographicException());
                }

                this.Reader = new Reader(Decrypted);
                this.Length = (ushort)this.Reader.BaseStream.Length;
            }
        }
        internal override void Decrypt()
        {
            var data = this.Reader.ReadBytes(this.Length);

            this.Device.Keys.SNonce.Increment();
            Console.WriteLine(BitConverter.ToString(data.ToArray()));
            Console.WriteLine(Encoding.UTF8.GetString(data.ToArray()));
            byte[] Decrypted = Sodium.Decrypt(data.ToArray(), this.Device.Keys.SNonce, this.Device.Keys.PublicKey);

            if (Decrypted == null)
            {
                throw new CryptographicException("Tried to decrypt an incomplete message.");
            }

            this.Reader = new Reader(Decrypted);
            this.Length = (ushort)this.Reader.BaseStream.Length;
        }
Beispiel #5
0
        internal override void Decrypt()
        {
            byte[] Buffer = this.Reader.ReadBytes(this.Length);
            this.Device.Keys.PublicKey = Buffer.Take(32).ToArray();

            Blake2BHasher Blake = new Blake2BHasher();

            Blake.Update(this.Device.Keys.PublicKey);
            Blake.Update(Key.PublicKey);

            this.Device.Keys.RNonce = Blake.Finish();

            Buffer = Sodium.Decrypt(Buffer.Skip(32).ToArray(), this.Device.Keys.RNonce, Key.PrivateKey, this.Device.Keys.PublicKey);
            this.Device.Keys.SNonce = Buffer.Skip(24).Take(24).ToArray();
            this.Reader             = new Reader(Buffer.Skip(48).ToArray());

            this.Length = (ushort)Buffer.Length;
        }
Beispiel #6
0
        internal virtual void Decrypt()
        {
            if (Device.PlayerState >= State.LOGGED)
            {
                Device.Keys.SNonce.Increment();

                var Decrypted = Sodium.Decrypt(new byte[16].Concat(Reader.ReadBytes(Length)).ToArray(),
                                               Device.Keys.SNonce, Device.Keys.PublicKey);

                if (Decrypted == null)
                {
                    throw new CryptographicException("Tried to decrypt an incomplete message.");
                }

                Reader = new Reader(Decrypted);
                Length = (ushort)Reader.BaseStream.Length;
            }
        }
Beispiel #7
0
        public override void Decrypt()
        {
            var buffer = Reader.ReadBytes(Length);

            Device.PublicKey = buffer.Take(32).ToArray();

            var Blake = new Blake2BHasher();

            Blake.Update(Device.PublicKey);
            Blake.Update(Key.PublicKey);

            Device.RNonce = Blake.Finish();

            buffer        = Sodium.Decrypt(buffer.Skip(32).ToArray(), Device.RNonce, Key.PrivateKey, Device.PublicKey);
            Device.SNonce = buffer.Skip(24).Take(24).ToArray();
            Reader        = new Reader(buffer.Skip(48).ToArray());

            Length = (ushort)buffer.Length;
        }
Beispiel #8
0
        public virtual void Decrypt()
        {
            if (Device.State >= State.LOGGED)
            {
                Device.SNonce.Increment();

                var buffer = Reader.ReadBytes(Length);
                buffer = Sodium.Decrypt(new byte[16].Concat(buffer).ToArray(), Device.SNonce,
                                        Device.PublicKey);

                if (buffer != null)
                {
                    Reader = new Reader(buffer);
                    Length = buffer.Length;
                }
                else
                {
                    Length = 0;
                }
            }
        }
Beispiel #9
0
        /// <summary>
        ///     <see cref="Decrypt" /> this instance.
        /// </summary>
        public override void Decrypt()
        {
            byte[] _Payload = this.Data;
            this.Client.PublicKey = _Payload.Take(32).ToArray();

            Blake2BHasher _Blake = new Blake2BHasher();

            _Blake.Update(this.Client.PublicKey);
            _Blake.Update(Keys.Sodium.PublicKey);

            this.Client.RNonce = _Blake.Finish();

            byte[] _Decrypted = Sodium.Decrypt(
                _Payload.Skip(32).ToArray(),
                this.Client.RNonce,
                Keys.Sodium.PrivateKey,
                this.Client.PublicKey);

            this.Client.SNonce = _Decrypted.Skip(24).Take(24).ToArray();
            this.Data          = _Decrypted.Skip(48).ToArray();

            this.Reader = new Reader(this.Data);
            this.Length = this.Data.Length;
        }
Beispiel #10
0
        private bool ProcessPacket(ReadOnlySpan <byte> data, ref Memory <byte> opus, ref Memory <byte> pcm, IList <ReadOnlyMemory <byte> > pcmPackets, out AudioSender voiceSender, out AudioFormat outputFormat)
        {
            voiceSender  = null;
            outputFormat = default;
            if (!Rtp.IsRtpHeader(data))
            {
                return(false);
            }

            Rtp.DecodeHeader(data, out var sequence, out var timestamp, out var ssrc, out var hasExtension);

            var vtx = TransmittingSSRCs[ssrc];

            voiceSender = vtx;
            if (sequence <= vtx.LastSequence) // out-of-order packet; discard
            {
                return(false);
            }
            var gap = vtx.LastSequence != 0 ? sequence - 1 - vtx.LastSequence : 0;

            if (gap >= 5)
            {
                Discord.DebugLogger.LogMessage(LogLevel.Warning, "VNext RX", "5 or more voice packets were dropped when receiving", DateTime.Now);
            }

            Span <byte> nonce = new byte[Sodium.NonceSize];

            Sodium.GetNonce(data, nonce, SelectedEncryptionMode);
            Rtp.GetDataFromPacket(data, out var encryptedOpus, SelectedEncryptionMode);

            var opusSize = Sodium.CalculateSourceSize(encryptedOpus);

            opus = opus.Slice(0, opusSize);
            var opusSpan = opus.Span;

            try
            {
                Sodium.Decrypt(encryptedOpus, opusSpan, nonce);

                // Strip extensions, if any
                if (hasExtension)
                {
                    // RFC 5285, 4.2 One-Byte header
                    // http://www.rfcreader.com/#rfc5285_line186
                    if (opusSpan[0] == 0xBE && opusSpan[1] == 0xDE)
                    {
                        var headerLen = opusSpan[2] << 8 | opusSpan[3];
                        var i         = 4;
                        for (; i < headerLen + 4; i++)
                        {
                            var @byte = opusSpan[i];

                            // ID is currently unused since we skip it anyway
                            //var id = (byte)(@byte >> 4);
                            var length = (byte)(@byte & 0x0F) + 1;

                            i += length;
                        }

                        // Strip extension padding too
                        while (opusSpan[i] == 0)
                        {
                            i++;
                        }

                        opusSpan = opusSpan.Slice(i);
                    }

                    // TODO: consider implementing RFC 5285, 4.3. Two-Byte Header
                }

                if (gap == 1)
                {
                    var lastSampleCount = Opus.GetLastPacketSampleCount(vtx.Decoder);
                    var fecpcm          = new byte[AudioFormat.SampleCountToSampleSize(lastSampleCount)];
                    var fecpcmMem       = fecpcm.AsSpan();
                    Opus.Decode(vtx.Decoder, opusSpan, ref fecpcmMem, true, out _);
                    pcmPackets.Add(fecpcm.AsMemory(0, fecpcmMem.Length));
                }
                else if (gap > 1)
                {
                    var lastSampleCount = Opus.GetLastPacketSampleCount(vtx.Decoder);
                    for (var i = 0; i < gap; i++)
                    {
                        var fecpcm    = new byte[AudioFormat.SampleCountToSampleSize(lastSampleCount)];
                        var fecpcmMem = fecpcm.AsSpan();
                        Opus.ProcessPacketLoss(vtx.Decoder, lastSampleCount, ref fecpcmMem);
                        pcmPackets.Add(fecpcm.AsMemory(0, fecpcmMem.Length));
                    }
                }

                var pcmSpan = pcm.Span;
                Opus.Decode(vtx.Decoder, opusSpan, ref pcmSpan, false, out outputFormat);
                pcm = pcm.Slice(0, pcmSpan.Length);
            }
            finally
            {
                vtx.LastSequence = sequence;
            }

            return(true);
        }
Beispiel #11
0
        private void ReceiveVoiceAsync(CancellationToken cancelToken)
        {
            try
            {
                byte[]     packet, decodingBuffer = null, nonce = null, result;
                int        packetLength, resultOffset, resultLength;
                IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0);

                if ((_client.Config.VoiceMode & DiscordVoiceMode.Incoming) != 0)
                {
                    decodingBuffer = new byte[MaxOpusSize];
                    nonce          = new byte[24];
                }

                while (!cancelToken.IsCancellationRequested)
                {
                    Thread.Sleep(1);
                    if (_udp.Available > 0)
                    {
                        packet       = _udp.Receive(ref endpoint);
                        packetLength = packet.Length;

                        if (packetLength > 0 && endpoint.Equals(_endpoint))
                        {
                            if (_state != (int)WebSocketState.Connected)
                            {
                                if (packetLength != 70)
                                {
                                    return;
                                }

                                int    port = packet[68] | packet[69] << 8;
                                string ip   = Encoding.ASCII.GetString(packet, 4, 70 - 6).TrimEnd('\0');

                                var login2 = new VoiceLogin2Command();
                                login2.Payload.Protocol           = "udp";
                                login2.Payload.SocketData.Address = ip;
                                login2.Payload.SocketData.Mode    = _encryptionMode;
                                login2.Payload.SocketData.Port    = port;
                                QueueMessage(login2);
                                if ((_client.Config.VoiceMode & DiscordVoiceMode.Incoming) == 0)
                                {
                                    return;
                                }
                            }
                            else
                            {
                                //Parse RTP Data
                                if (packetLength < 12)
                                {
                                    return;
                                }

                                byte flags = packet[0];
                                if (flags != 0x80)
                                {
                                    return;
                                }

                                byte payloadType = packet[1];
                                if (payloadType != 0x78)
                                {
                                    return;
                                }

                                ushort sequenceNumber = (ushort)((packet[2] << 8) |
                                                                 packet[3] << 0);
                                uint timestamp = (uint)((packet[4] << 24) |
                                                        (packet[5] << 16) |
                                                        (packet[6] << 8) |
                                                        (packet[7] << 0));
                                uint ssrc = (uint)((packet[8] << 24) |
                                                   (packet[9] << 16) |
                                                   (packet[10] << 8) |
                                                   (packet[11] << 0));

                                //Decrypt
                                if (_isEncrypted)
                                {
                                    if (packetLength < 28)                                     //12 + 16 (RTP + Poly1305 MAC)
                                    {
                                        return;
                                    }

                                    Buffer.BlockCopy(packet, 0, nonce, 0, 12);
                                    int ret = Sodium.Decrypt(packet, 12, packetLength - 12, decodingBuffer, nonce, _secretKey);
                                    if (ret != 0)
                                    {
                                        continue;
                                    }
                                    result       = decodingBuffer;
                                    resultOffset = 0;
                                    resultLength = packetLength - 28;
                                }
                                else                                 //Plain
                                {
                                    result       = packet;
                                    resultOffset = 12;
                                    resultLength = packetLength - 12;
                                }

                                /*if (_logLevel >= LogMessageSeverity.Debug)
                                 *      RaiseOnLog(LogMessageSeverity.Debug, $"Received {buffer.Length - 12} bytes.");*/

                                string userId;
                                if (_ssrcMapping.TryGetValue(ssrc, out userId))
                                {
                                    RaiseOnPacket(userId, _channelId, result, resultOffset, resultLength);
                                }
                            }
                        }
                    }
                }
            }
            catch (OperationCanceledException) { }
            catch (InvalidOperationException) { }             //Includes ObjectDisposedException
        }