WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 11  →  ?path2? @ 12
/trunk/WingMan/Communication/MqttCommunication.cs
@@ -1,4 +1,5 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
@@ -182,12 +183,8 @@
{
try
{
var load = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
e.ApplicationMessage.Payload = await AES.Decrypt(e.ApplicationMessage.Payload, Password);
 
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);
}
@@ -221,8 +218,6 @@
{
var optionsBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(IpAddress)
.WithSubscriptionInterceptor(MqttSubscriptionIntercept)
.WithConnectionValidator(MqttConnectionValidator)
.WithDefaultEndpointPort(Port);
 
BindServerHandlers();
@@ -241,11 +236,6 @@
return Running;
}
 
private void MqttConnectionValidator(MqttConnectionValidatorContext context)
{
context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
}
 
private async Task StopServer()
{
UnbindServerHandlers();
@@ -253,21 +243,6 @@
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;
@@ -294,12 +269,8 @@
{
try
{
var load = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
e.ApplicationMessage.Payload = await AES.Decrypt(e.ApplicationMessage.Payload, Password);
 
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);
}
@@ -343,14 +314,16 @@
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
 
private void ServerOnStopped(object sender, EventArgs e)
private async void ServerOnStopped(object sender, EventArgs e)
{
OnServerStopped?.Invoke(sender, e);
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnServerStopped?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
 
private void ServerOnStarted(object sender, EventArgs e)
private async void ServerOnStarted(object sender, EventArgs e)
{
OnServerStarted?.Invoke(sender, e);
await Task.Delay(0, CancellationToken).ContinueWith(_ => OnServerStarted?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
 
public async Task Stop()
@@ -370,21 +343,33 @@
 
public async Task Broadcast(string topic, byte[] payload)
{
var encryptedPayload = AES.Encrypt(payload, Password);
 
var load = Encoding.UTF8.GetString(encryptedPayload);
 
switch (Type)
using (var payloadStream = new MemoryStream(await AES.Encrypt(payload, Password)))
{
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;
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;
}
}
}
}
/trunk/WingMan/Utilities/AES.cs
@@ -1,12 +1,15 @@
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;
@@ -23,7 +26,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 byte[] Encrypt(byte[] data, string key, string separator = ":")
public static async Task<byte[]> Encrypt(byte[] data, string key, string separator = ":")
{
using (var rijdanelManaged = new RijndaelManaged())
{
@@ -35,31 +38,24 @@
// Compute the salt and the IV from the key.
var salt = new byte[AesKeySaltBytes];
Rng.GetBytes(salt);
using (var derivedKey = new Rfc2898DeriveBytes(key, salt))
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations);
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
 
using (var encryptor = rijdanelManaged.CreateEncryptor(rijdanelManaged.Key, rijdanelManaged.IV))
{
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 memoryStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
using (var inputStream = new MemoryStream(data))
{
using (var inputStream = new MemoryStream(data))
{
inputStream.CopyTo(cryptoStream);
cryptoStream.FlushFinalBlock();
await inputStream.CopyToAsync(cryptoStream);
cryptoStream.FlushFinalBlock();
 
inputStream.Position = 0L;
inputStream.Position = 0L;
 
var payload = memoryStream.ToArray();
 
var base64Salt = Convert.ToBase64String(salt);
var base64Payload = Convert.ToBase64String(payload);
 
return Encoding.UTF8.GetBytes($"{base64Salt}{separator}{base64Payload}");
}
return salt.Concat(memoryStream.ToArray()).ToArray();
}
}
}
@@ -80,15 +76,11 @@
/// <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 byte[] Decrypt(byte[] data, string key, string separator = ":")
public static async Task<byte[]> Decrypt(byte[] data, string key, string separator = ":")
{
var input = Encoding.UTF8.GetString(data);
var salt = data.Take(AesKeySaltBytes).ToArray();
var text = data.Skip(AesKeySaltBytes).ToArray();
 
// 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
@@ -97,21 +89,23 @@
rijdanelManaged.Padding = AesPaddingMode;
 
// Retrieve the key and the IV from the salt.
using (var derivedKey = new Rfc2898DeriveBytes(key, Convert.FromBase64String(segments[0].Trim())))
var derivedKey = new Rfc2898DeriveBytes(key, salt, AesKeyIterations);
rijdanelManaged.Key = derivedKey.GetBytes(rijdanelManaged.KeySize / 8);
rijdanelManaged.IV = derivedKey.GetBytes(rijdanelManaged.BlockSize / 8);
 
using (var decryptor = rijdanelManaged.CreateDecryptor(rijdanelManaged.Key, rijdanelManaged.IV))
{
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 memoryStream = new MemoryStream(Convert.FromBase64String(segments[1].Trim())))
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
using (var outputStream = new MemoryStream())
{
using (var streamReader = new StreamReader(cryptoStream))
{
return Encoding.UTF8.GetBytes(streamReader.ReadToEnd());
}
await cryptoStream.CopyToAsync(outputStream);
 
outputStream.Position = 0L;
 
return outputStream.ToArray();
}
}
}
/trunk/WingMan/WingManForm.Designer.cs
@@ -164,8 +164,9 @@
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, 20);
this.button5.Size = new System.Drawing.Size(40, 24);
this.button5.TabIndex = 2;
this.button5.Text = "Say";
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.LobbySayButtonClick);
//
@@ -172,7 +173,7 @@
// LobbySayTextBox
//
this.LobbySayTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.LobbySayTextBox.Location = new System.Drawing.Point(8, 280);
this.LobbySayTextBox.Location = new System.Drawing.Point(8, 282);
this.LobbySayTextBox.Name = "LobbySayTextBox";
this.LobbySayTextBox.Size = new System.Drawing.Size(464, 20);
this.LobbySayTextBox.TabIndex = 1;