Browse Source

Update libsodium wrapper to prevent segfaults

pull/141/head
Finite Reality 9 years ago
parent
commit
9bbde4ccea
3 changed files with 62 additions and 3 deletions
  1. +60
    -1
      src/Discord.Net/Audio/Sodium/SecretBox.cs
  2. +1
    -1
      src/Discord.Net/Audio/Streams/RTPReadStream.cs
  3. +1
    -1
      src/Discord.Net/Audio/Streams/RTPWriteStream.cs

+ 60
- 1
src/Discord.Net/Audio/Sodium/SecretBox.cs View File

@@ -1,9 +1,67 @@
using System.Runtime.InteropServices;
using System;
using System.Runtime.InteropServices;


namespace Discord.Audio namespace Discord.Audio
{ {
public unsafe static class SecretBox public unsafe static class SecretBox
{ {
// from crypto_secretbox.h and crypto_secretbox_xsalsa20poly1305.h
private const uint crypto_secretbox_KEYBYTES = 32U;
private const uint crypto_secretbox_NONCEBYTES = 24U;
private const uint crypto_secretbox_MACBYTES = 16U;

[DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
private static extern int crypto_secretbox_easy(
[Out] byte[] c, // ciphertext
[In] byte[] m, // message
[MarshalAs(UnmanagedType.U8)] ulong mlen, // length of message
[In] byte[] n, // nonce
[In] byte[] k // key
);

[DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)]
private static extern int crypto_secretbox_open_easy(
[Out] byte[] m, // message
[In] byte[] c, // ciphertext
[MarshalAs(UnmanagedType.U8)] ulong clen, // length of ciphertext
[In] byte[] n, // nonce
[In] byte[] k // key
);

// Both of the above functions return 0 on success, -1 on error

public static void Encrypt(byte[] input, int inputOffset, ulong inputLength, byte[] output, int outputOffset, byte[] nonce, byte[] secret)
{
byte[] _input = new byte[inputLength];
Buffer.BlockCopy(input, inputOffset, _input, 0, (int)inputLength); // TODO: this will probably cause an overflow or throw an exception...

byte[] _output = new byte[crypto_secretbox_MACBYTES + inputLength];
int result = crypto_secretbox_easy(_output, _input, inputLength, nonce, secret);

if (result == -1)
throw new InvalidOperationException("Failed to encrypt the provided payload");

Buffer.BlockCopy(_output, 0, output, outputOffset, _output.Length);
}

public static void Decrypt(byte[] input, int inputOffset, ulong inputLength, byte[] output, int outputOffset, byte[] nonce, byte[] secret)
{
if (inputLength < crypto_secretbox_MACBYTES)
throw new ArgumentException($"the length of the input arary must be greater than {crypto_secretbox_MACBYTES} bytes", "inputLength");

byte[] _input = new byte[inputLength];
Buffer.BlockCopy(input, inputOffset, _input, 0, (int)inputLength); // TODO: this will also probably overflow or throw an exception

byte[] _output = new byte[inputLength - crypto_secretbox_MACBYTES];
int result = crypto_secretbox_open_easy(_output, _input, inputLength, nonce, secret);

if (result == -1)
throw new InvalidOperationException("Failed to verify the decrypted payload");

Buffer.BlockCopy(_output, 0, output, outputOffset, _output.Length);
}

/* I kept the old code here to refer to in case it is needed
[DllImport("libsodium", EntryPoint = "crypto_secretbox_easy", CallingConvention = CallingConvention.Cdecl)] [DllImport("libsodium", EntryPoint = "crypto_secretbox_easy", CallingConvention = CallingConvention.Cdecl)]
private static extern int SecretBoxEasy(byte* output, byte* input, long inputLength, byte[] nonce, byte[] secret); private static extern int SecretBoxEasy(byte* output, byte* input, long inputLength, byte[] nonce, byte[] secret);
[DllImport("libsodium", EntryPoint = "crypto_secretbox_open_easy", CallingConvention = CallingConvention.Cdecl)] [DllImport("libsodium", EntryPoint = "crypto_secretbox_open_easy", CallingConvention = CallingConvention.Cdecl)]
@@ -21,5 +79,6 @@ namespace Discord.Audio
fixed (byte* outPtr = output) fixed (byte* outPtr = output)
return SecretBoxOpenEasy(outPtr + outputOffset, inPtr + inputOffset, inputLength, nonce, secret); return SecretBoxOpenEasy(outPtr + outputOffset, inPtr + inputOffset, inputLength, nonce, secret);
} }
*/
} }
} }

+ 1
- 1
src/Discord.Net/Audio/Streams/RTPReadStream.cs View File

@@ -32,7 +32,7 @@ namespace Discord.Audio
public override void Write(byte[] buffer, int offset, int count) public override void Write(byte[] buffer, int offset, int count)
{ {
Buffer.BlockCopy(buffer, 0, _nonce, 0, 12); Buffer.BlockCopy(buffer, 0, _nonce, 0, 12);
count = SecretBox.Decrypt(buffer, offset, count, _buffer, 0, _nonce, _secretKey);
SecretBox.Decrypt(buffer, offset, (ulong)count, _buffer, 0, _nonce, _secretKey);
var newBuffer = new byte[count]; var newBuffer = new byte[count];
Buffer.BlockCopy(_buffer, 0, newBuffer, 0, count); Buffer.BlockCopy(_buffer, 0, newBuffer, 0, count);
_queuedData.Add(newBuffer); _queuedData.Add(newBuffer);


+ 1
- 1
src/Discord.Net/Audio/Streams/RTPWriteStream.cs View File

@@ -46,7 +46,7 @@ namespace Discord.Audio
} }


Buffer.BlockCopy(buffer, 0, _nonce, 0, 12); Buffer.BlockCopy(buffer, 0, _nonce, 0, 12);
count = SecretBox.Encrypt(buffer, offset, count, _buffer, 12, _nonce, _secretKey);
SecretBox.Encrypt(buffer, offset, (ulong)count, _buffer, 12, _nonce, _secretKey);
_audioClient.Send(_buffer, count); _audioClient.Send(_buffer, count);
} }




Loading…
Cancel
Save