WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 12  →  ?path2? @ 11
/trunk/WingMan/Communication/MqttCommunication.cs
@@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
@@ -183,8 +182,12 @@
{
try
{
e.ApplicationMessage.Payload = await AES.Decrypt(e.ApplicationMessage.Payload, Password);
var load = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
 
e.ApplicationMessage.Payload = AES.Decrypt(e.ApplicationMessage.Payload, Password);
 
var load2 = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
 
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnMessageReceived?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
@@ -218,6 +221,8 @@
{
var optionsBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(IpAddress)
.WithSubscriptionInterceptor(MqttSubscriptionIntercept)
.WithConnectionValidator(MqttConnectionValidator)
.WithDefaultEndpointPort(Port);
 
BindServerHandlers();
@@ -236,6 +241,11 @@
return Running;
}
 
private void MqttConnectionValidator(MqttConnectionValidatorContext context)
{
context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
}
 
private async Task StopServer()
{
UnbindServerHandlers();
@@ -243,6 +253,21 @@
await Server.StopAsync();
}
 
private void MqttSubscriptionIntercept(MqttSubscriptionInterceptorContext context)
{
if (context.TopicFilter.Topic != "lobby" &&
context.TopicFilter.Topic != "exchange" &&
context.TopicFilter.Topic != "execute")
{
context.AcceptSubscription = false;
context.CloseConnection = true;
return;
}
 
context.AcceptSubscription = true;
context.CloseConnection = false;
}
 
private void BindServerHandlers()
{
Server.Started += ServerOnStarted;
@@ -269,8 +294,12 @@
{
try
{
e.ApplicationMessage.Payload = await AES.Decrypt(e.ApplicationMessage.Payload, Password);
var load = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
 
e.ApplicationMessage.Payload = AES.Decrypt(e.ApplicationMessage.Payload, Password);
 
var load2 = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
 
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnMessageReceived?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
@@ -314,16 +343,14 @@
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
 
private async void ServerOnStopped(object sender, EventArgs e)
private void ServerOnStopped(object sender, EventArgs e)
{
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnServerStopped?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
OnServerStopped?.Invoke(sender, e);
}
 
private async void ServerOnStarted(object sender, EventArgs e)
private void ServerOnStarted(object sender, EventArgs e)
{
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnServerStarted?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
OnServerStarted?.Invoke(sender, e);
}
 
public async Task Stop()
@@ -343,33 +370,21 @@
 
public async Task Broadcast(string topic, byte[] payload)
{
using (var payloadStream = new MemoryStream(await AES.Encrypt(payload, Password)))
var encryptedPayload = AES.Encrypt(payload, Password);
 
var load = Encoding.UTF8.GetString(encryptedPayload);
 
switch (Type)
{
switch (Type)
{
case MqttCommunicationType.Client:
await Client.PublishAsync(new []
{
new MqttApplicationMessage
{
Topic = topic,
Payload = payloadStream.ToArray(),
QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce
}
});
break;
case MqttCommunicationType.Server:
await Server.PublishAsync(new[]
{
new MqttApplicationMessage
{
Topic = topic,
Payload = payloadStream.ToArray(),
QualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce
}
});
break;
}
case MqttCommunicationType.Client:
await Client.PublishAsync(new ManagedMqttApplicationMessage
{
ApplicationMessage = new MqttApplicationMessage {Topic = topic, Payload = encryptedPayload }
});
break;
case MqttCommunicationType.Server:
await Server.PublishAsync(new MqttApplicationMessage {Topic = topic, Payload = encryptedPayload });
break;
}
}
}
/trunk/WingMan/Utilities/AES.cs
@@ -1,15 +1,12 @@
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan.Utilities
{
public static class AES
{
private const int AesKeyIterations = 4096;
private const int AesBlockSize = 128;
private const CipherMode AesCipherMode = CipherMode.CBC;
private const PaddingMode AesPaddingMode = PaddingMode.PKCS7;
@@ -26,7 +23,7 @@
/// <param name="key">the encryption key</param>
/// <param name="separator">the separator to use between the cyphertext and the IV</param>
/// <returns>Base64 encoded encrypted data</returns>
public static async Task<byte[]> Encrypt(byte[] data, string key, string separator = ":")
public static byte[] Encrypt(byte[] data, string key, string separator = ":")
{
using (var rijdanelManaged = new RijndaelManaged())
{
@@ -38,24 +35,31 @@
// Compute the salt and the IV from the key.
var salt = new byte[AesKeySaltBytes];
Rng.GetBytes(salt);
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations);
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
using (var derivedKey = new Rfc2898DeriveBytes(key, salt))
{
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
 
using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV))
{
using (var memoryStream = new MemoryStream())
using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV))
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
using (var memoryStream = new MemoryStream())
{
using (var inputStream = new MemoryStream(data))
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
await inputStream.CopyToAsync(cryptoStream);
cryptoStream.FlushFinalBlock();
using (var inputStream = new MemoryStream(data))
{
inputStream.CopyTo(cryptoStream);
cryptoStream.FlushFinalBlock();
 
inputStream.Position = 0L;
inputStream.Position = 0L;
 
return salt.Concat(memoryStream.ToArray()).ToArray();
var payload = memoryStream.ToArray();
 
var base64Salt = Convert.ToBase64String(salt);
var base64Payload = Convert.ToBase64String(payload);
 
return Encoding.UTF8.GetBytes($"{base64Salt}{separator}{base64Payload}");
}
}
}
}
@@ -76,11 +80,15 @@
/// <param name="key">the encryption key</param>
/// <param name="separator">the separator to use between the cyphertext and the IV</param>
/// <returns>the decrypted data</returns>
public static async Task<byte[]> Decrypt(byte[] data, string key, string separator = ":")
public static byte[] Decrypt(byte[] data, string key, string separator = ":")
{
var salt = data.Take(AesKeySaltBytes).ToArray();
var text = data.Skip(AesKeySaltBytes).ToArray();
var input = Encoding.UTF8.GetString(data);
 
// retrieve the salt from the data.
var segments = input.Split(new[] {separator}, StringSplitOptions.None);
if (segments.Length != 2)
throw new ArgumentException("Invalid data: " + input);
 
using (var rijdanelManaged = new RijndaelManaged())
{
// FIPS-197 / CBC
@@ -89,23 +97,21 @@
rijdanelManaged.Padding = AesPaddingMode;
 
// Retrieve the key and the IV from the salt.
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations);
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
using (var derivedKey = new Rfc2898DeriveBytes(key, Convert.FromBase64String(segments[0].Trim())))
{
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
 
using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV))
{
using (var memoryStream = new MemoryStream(text))
using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
using (var memoryStream = new MemoryStream(Convert.FromBase64String(segments[1].Trim())))
{
using (var outputStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
await cryptoStream.CopyToAsync(outputStream);
 
outputStream.Position = 0L;
 
return outputStream.ToArray();
using (var streamReader = new StreamReader(cryptoStream))
{
return Encoding.UTF8.GetBytes(streamReader.ReadToEnd());
}
}
}
}
/trunk/WingMan/WingManForm.Designer.cs
@@ -164,9 +164,8 @@
this.button5.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button5.Location = new System.Drawing.Point(480, 280);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(40, 24);
this.button5.Size = new System.Drawing.Size(40, 20);
this.button5.TabIndex = 2;
this.button5.Text = "Say";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.LobbySayButtonClick);
//
@@ -173,7 +172,7 @@
// LobbySayTextBox
//
this.LobbySayTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.LobbySayTextBox.Location = new System.Drawing.Point(8, 282);
this.LobbySayTextBox.Location = new System.Drawing.Point(8, 280);
this.LobbySayTextBox.Name = "LobbySayTextBox";
this.LobbySayTextBox.Size = new System.Drawing.Size(464, 20);
this.LobbySayTextBox.TabIndex = 1;