/// <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; }
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; }
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; }
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; } }
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; }
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; } } }
/// <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; }
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); }
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 }