void retrieveKeys(ErebusAddress other) { var keys = PlatformServiceProvider.Create("VerificationKeyProvider").GetKeyPair(other); myKey = keys.Item1; otherKey = keys.Item2; }
private void key(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { ErebusAddress addr; try { addr = new ErebusAddress(address.Text); } catch { MessageBox.Show(Application.Current.MainWindow, "The address that you have entered appears to be in an invalid format.", "Erebus"); return; } var ns = NavigationService; var d = Dispatcher; done = true; ns.Navigate(new Uri("/Views/Loading.xaml", UriKind.Relative)); Task.Run(() => d.Invoke(new CNP(App.Instance).RequestContact(addr, pin => d.Invoke(() => MessageBox.Show(Application.Current.MainWindow, $"Please verify that the following PIN matches the one displayed by {addr}: {pin}", "Add Contact", MessageBoxButton.YesNo)) == MessageBoxResult.Yes) ? new Action(() => { ns.GoBack(); App.AddContactData = new { Address = addr, Name = addr.ToString() }; ns.Navigated += Ns_Navigated; }) : ns.GoBack)); } }
/// <summary> /// Creates a new listener. /// </summary> /// <param name="address">The local address to use.</param> /// <param name="handler">The function to call when a request is received.</param> public BluetoothContactRequestListener(ErebusAddress address, Func <ErebusAddress, string, bool> handler) { addr = address; h = handler; l = BluetoothAdapter.DefaultAdapter.ListenUsingRfcommWithServiceRecord("ErebusContactRequest", BluetoothUtils.RfcommAddContactService); lt = listenProcess(); }
/// <summary> /// Sends a contact request to the specified Bluetooth device. /// </summary> /// <param name="device">The device to send the request to.</param> /// <param name="myAddress">The local address to send to the device.</param> /// <returns>The Erebus address of the device if the request was accepted; otherwise null.</returns> public static ErebusAddress?RequestAddContact(RfcommDeviceService device, ErebusAddress myAddress) { Log.RecordEvent(typeof(BluetoothUtils), $"Attempting to add Bluetooth device '{device.ConnectionHostName.CanonicalName}' as a contact.", LogEntrySeverity.Info); try { var socket = new StreamSocket(); new Func <Task>(async() => { await socket.ConnectAsync(device.ConnectionHostName, RfcommAddContactService.AsString(), SocketProtectionLevel.BluetoothEncryptionWithAuthentication); })().Wait(); using (var r = new BinaryReader(socket.InputStream.AsStreamForRead())) using (var w = new BinaryWriter(socket.OutputStream.AsStreamForWrite())) { w.Write(myAddress); var addr = r.ReadErebusAddress(); var vkp = PlatformServiceProvider.Create("VerificationKeyProvider"); var local = vkp.CreatePrivateKey(); w.Write(local.Item2.Length); w.Write(local.Item2); vkp.AddKeyPair(addr, local.Item1, r.ReadBytes(r.ReadInt32())); Log.RecordEvent(typeof(BluetoothUtils), $"Successfully negotiated contact with {addr} via Bluetooth RFCOMM.", LogEntrySeverity.Info); return(addr); } } catch (Exception e) { Log.RecordEvent(typeof(BluetoothUtils), $"Exception adding contact: {e.Message}; assuming other user rejected request.", LogEntrySeverity.Error); return(null); } }
/// <summary> /// Sends a contact request to the specified Bluetooth device. /// </summary> /// <param name="device">The device to send the request to.</param> /// <param name="myAddress">The local address to send to the device.</param> /// <returns>The Erebus address of the device if the request was accepted; otherwise null.</returns> public static ErebusAddress?RequestAddContact(BluetoothDevice device, ErebusAddress myAddress) { Log.RecordEvent(typeof(BluetoothUtils), $"Attempting to add Bluetooth device '{device.Name}' as a contact.", LogEntrySeverity.Info); try { var s = device.CreateRfcommSocketToServiceRecord(RfcommAddContactService); s.Connect(); using (var r = new BinaryReader(s.InputStream)) using (var w = new BinaryWriter(s.OutputStream)) { w.Write(true); r.ReadBoolean(); w.Write(myAddress); var addr = r.ReadErebusAddress(); var vkp = new VerificationKeyProvider(); var local = vkp.CreatePrivateKey(); w.Write(local.Item2.Length); w.Write(local.Item2); vkp.AddKeyPair(addr, local.Item1, r.ReadBytes(r.ReadInt32())); Log.RecordEvent(typeof(BluetoothUtils), $"Successfully negotiated contact with {addr} via Bluetooth RFCOMM.", LogEntrySeverity.Info); return(addr); } } catch (Exception e) { Log.RecordEvent(typeof(BluetoothUtils), $"Exception adding contact: {e.Message}; assuming other user rejected request.", LogEntrySeverity.Error); return(null); } }
void regenAddr() { var b = new byte[16]; r.NextBytes(b); addr = new ErebusAddress(b); address.Text = addr.ToString(); }
/// <summary> /// Resets the in-memory configuration. /// </summary> /// <param name="address">The address of the new configuration.</param> public static void Reset(ErebusAddress address) => TSM.RunSafe(() => { Address = address; ConnectionTargets = new IConnectionTarget[0]; Contacts = new Contact[0]; Recents = new RecentEntry[0]; VerificationKeys = new KeyPair[0]; });
bool core(ErebusAddress addr, bool request, Guid id, byte[] otherKey, Predicate <int> pinCheck) { var vkp = PlatformServiceProvider.Create("VerificationKeyProvider"); var k = vkp.CreatePrivateKey(); byte[] lp = k.Item2; using (var ewh = new EventWaitHandle(false, EventResetMode.ManualReset)) { bool l = false, r = false; lock (arh) arh[id] = a => { r = a; ewh.Set(); lock (arh) arh.Remove(id); }; if (request) { using (var kewh = new EventWaitHandle(false, EventResetMode.ManualReset)) { lock (hrh) hrh[id] = _k => { otherKey = _k; kewh.Set(); }; SendPacket(new ErebusEndpoint(addr, 1), new byte[] { 0 }.Concat(id.ToByteArray()).Concat(lp).ToArray()); kewh.WaitOne(); } } else { SendPacket(new ErebusEndpoint(addr, 1), new byte[] { 1 }.Concat(id.ToByteArray()).Concat(lp).ToArray()); } var hash = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha512).HashData((request ? lp.Concat(otherKey) : otherKey.Concat(lp)).ToArray()); for (int i = 4; i < hash.Length; ++i) { hash[i % 4] ^= hash[i]; } l = pinCheck(BitConverter.ToInt32(hash, 0)); SendPacket(new ErebusEndpoint(addr, 1), new[] { (byte)(l ? 2 : 3) }.Concat(id.ToByteArray()).ToArray()); if (l) { ewh.WaitOne(); if (r) { vkp.AddKeyPair(addr, k.Item1, otherKey); return(true); } } } return(false); }
/// <summary> /// Retrieves the key pair assigned to the specified address from the store. /// </summary> /// <param name="addr">The address that the key pair is assigned to.</param> /// <returns>The key pair.</returns> public Tuple <byte[], byte[]> GetKeyPair(ErebusAddress addr) => tsm.RunSafe(() => { using (var s = File.OpenRead(_path)) using (var aes = new AesCryptoServiceProvider { Key = _key }) { using (var r = new BinaryReader(s, Encoding.Default, true)) aes.IV = r.ReadBytes(r.ReadInt32()); return((from e in read(s, aes) where e.Item1 == addr select Tuple.Create(e.Item2, e.Item3)).DefaultIfEmpty(null).FirstOrDefault()); } });
/// <summary> /// Creates a new instance of the <see cref="SSMP"/> to send and receive messages, and connects to the specified destination. /// </summary> /// <param name="instance">The current instance.</param> /// <param name="dest">The address of the other host.</param> public SSMP(ErebusInstance instance, ErebusAddress dest) : base(instance) { var s = RequestConnection(new ErebusEndpoint(dest, 20000)); if (s == null) { throw new IOException($"Connection to {dest} was rejected!"); } r = new BinaryReader(s, Encoding.UTF8, true); w = new BinaryWriter(s, Encoding.UTF8, true); Connected = true; recvTask = recvProcess(); }
public void ParseTest() { var addr = new ErebusAddress("{22-123A--DD9-8}"); Assert.AreEqual(new ErebusAddress(0x22, 0x123a, 0, 0, 0, 0, 0xdd9, 0x8), addr); try { ErebusAddress.Parse("{22-123A--DD9--F}"); ErebusAddress.Parse("{22---123A}"); Assert.Fail("Did not crash on double skip"); } catch { } }
/// <summary> /// Removes the key pair that is assigned to the specified address from the store. /// </summary> /// <param name="addr">The address of the key pair to remove.</param> public void RemoveKeyPair(ErebusAddress addr) => tsm.RunSafe(() => { using (var s = File.Open(_path, FileMode.Open, FileAccess.ReadWrite)) using (var aes = new AesCryptoServiceProvider { Key = _key }) { using (var r = new BinaryReader(s, Encoding.Default, true)) aes.IV = r.ReadBytes(r.ReadInt32()); var entries = read(s, aes); s.Position = 0; s.SetLength(0); using (var w = new BinaryWriter(s, Encoding.Default, true)) { w.Write(aes.IV.Length); w.Write(aes.IV); } save((from e in entries where e.Item1 != addr select e).ToArray(), s, aes); } });
/// <summary> /// Adds the specified key pair to the store, assigning it to the specified address. /// </summary> /// <param name="addr">The address to assign the key pair to.</param> /// <param name="myKey">The local private key.</param> /// <param name="otherKey">The remote public key.</param> public void AddKeyPair(ErebusAddress addr, byte[] myKey, byte[] otherKey) => tsm.RunSafe(() => { using (var s = File.Open(_path, FileMode.Open, FileAccess.ReadWrite)) using (var aes = new AesCryptoServiceProvider { Key = _key }) { using (var r = new BinaryReader(s, Encoding.Default, true)) aes.IV = r.ReadBytes(r.ReadInt32()); var entries = read(s, aes); s.Position = 0; s.SetLength(0); using (var w = new BinaryWriter(s, Encoding.Default, true)) { w.Write(aes.IV.Length); w.Write(aes.IV); } save(entries.Concat(new[] { Tuple.Create(addr, myKey, otherKey) }).ToArray(), s, aes); } });
/// <summary> /// Resets the in-memory configuration and saves it to disk with the specified PIN. /// </summary> /// <param name="address">The address of the new configuration.</param> /// <param name="pin">The personal identification number (PIN) to use as an encryption key.</param> public static void Configure(ErebusAddress address, int pin) => TSM.RunSafe(() => { Reset(address); Save(pin); });
/// <summary> /// Creates a new instance of the <see cref="Contact"/> structure, with the specified name and address. /// </summary> /// <param name="name">The contact's local name.</param> /// <param name="addr">The contact's address.</param> public Contact(string name, ErebusAddress addr) { Name = name; Address = addr; }
/// <summary> /// Removes the key pair that is assigned to the specified address from the store. /// </summary> /// <param name="addr">The address of the key pair to remove.</param> public void RemoveKeyPair(ErebusAddress addr) => Configuration.TSM.RunSafe(() => Configuration.VerificationKeys = (from k in Configuration.VerificationKeys where k.Address != addr select k).ToArray());
static async Task usersUpdateProcess() { User[] users = null, online = null, recent = null; while (process) { bool update = false; if (UsersTSM.RunSafe(() => { var y = MainUpdate; MainUpdate = false; return(y); })) { using (var k = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\472\Erebus\Client\Contacts")) users = (from c in k.GetValueNames() select new User(k.GetValue(c) as string, ErebusAddress.Parse(c))).ToArray(); update = true; } if (UsersTSM.RunSafe(() => { var y = onlineUpdate; onlineUpdate = false; return(y); })) { online = (from c in users where _online.Contains(c.Address) select c).ToArray(); update = true; } if (UsersTSM.RunSafe(() => { var y = RecentUpdate; RecentUpdate = false; return(y); })) { using (var k = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\472\Erebus\Client\Recent")) { var addresses = from a in k.GetValueNames() select new { Address = ErebusAddress.Parse(a), Text = a }; recent = (from c in users join a in addresses on c.Address equals a.Address orderby k.GetValue(a.Text) descending select c).ToArray(); } update = true; } if (UsersTSM.RunSafe(() => { var y = forceUpdate; forceUpdate = false; return(y); }) || update) { foreach (var u in users) { u.Online = online.Contains(u); } lock (uh) foreach (var h in uh) { h(null, new UserListUpdatedEventArgs(users, online, recent)); } Log.RecordEvent(typeof(App), "Users list updated.", LogEntrySeverity.Info); } await Task.Delay(100); } }
static void Main(string[] args) { Log.EntryRecorded += (sender, e) => Console.WriteLine($"{sender} ({e.Severity}): {e.Message}"); VerificationKeyProvider.Initialize("keyinfo.dat", "hello world"); var vkp = new VerificationKeyProvider(); Initialization.Run(); SSMP ssmp = null; SSMP.InvitationReceived += (sender, e) => { if (ssmp == null) { ssmp = e.Accept(); } ssmp.MessageReceived += Ssmp_MessageReceived; ssmp.ConnectionClosed += (_sender, _e) => ssmp = null; }; var ei = new ErebusInstance(new ErebusAddress(Console.ReadLine())); ei.Services = new[] { HDPService.SSMP }; var l = new TCPIPConnectionListener(int.Parse(Console.ReadLine()), ei); while (true) { try { var cmd = Console.ReadLine().Split(' '); switch (cmd[0]) { case "addlink": new ErebusLink(TCPIPConnectionUtils.Connect(cmd[1], int.Parse(cmd[2])), ei, false); break; case "listlink": foreach (var link in ei.Links) { Console.WriteLine(link.RemoteAddress); } break; case "hdp": var hdp = new HDP(ei, HDPService.SSMP); hdp.SendRequest(ErebusAddress.Broadcast); hdp.InitClose(); break; case "ssmp": ssmp = new SSMP(ei, new ErebusAddress(cmd[1])); ssmp.MessageReceived += Ssmp_MessageReceived; break; case "msg": ssmp?.SendMessage(cmd.Skip(1).Aggregate((x, y) => x + " " + y)); break; case "addkey": var addr = new ErebusAddress(cmd[1]); vkp.RemoveKeyPair(addr); var key = vkp.CreatePrivateKey(); Console.WriteLine("Key: " + key.Item2.Select(x => x.ToString()).Aggregate((x, y) => x + "," + y)); Console.Write("Please copy other key to clipboard, then press <enter> . . ."); Console.ReadLine(); vkp.AddKeyPair(addr, key.Item1, Clipboard.GetText().Split(',').Select(x => byte.Parse(x)).ToArray()); break; case "removekey": vkp.RemoveKeyPair(new ErebusAddress(cmd[1])); break; case "close": ssmp?.Dispose(); ssmp = null; break; case "exit": return; } } catch (Exception e) { Console.WriteLine(e); } } }
internal CNPRequestReceivedEventArgs(ErebusAddress addr, int pin, Action accept) { _addr = addr; _pin = pin; _accept = accept; }
/// <summary> /// Writes an <see cref="ErebusAddress"/> to the stream. /// </summary> /// <param name="w">The <see cref="BinaryWriter"/> that wraps the stream.</param> /// <param name="addr">The <see cref="ErebusAddress"/> to write.</param> public static void Write(this BinaryWriter w, ErebusAddress addr) => w.Write(addr.Serialize());
/// <summary> /// Creates a new listener. /// </summary> /// <param name="address">The local address to use.</param> /// <param name="handler">The function to call when a request is received.</param> public BluetoothContactRequestListener(ErebusAddress address, Func <ErebusAddress, string, bool> handler) { addr = address; h = handler; lt = listenProcess(); }
/// <summary> /// Creates a new instance of the <see cref="ErebusAddress"/> structure. /// </summary> /// <param name="addr"></param> /// <param name="port"></param> public ErebusEndpoint(ErebusAddress addr, ushort port) { Address = addr; Port = port; }
/// <summary> /// Creates a new instance of the <see cref="RecentEntry"/> structure, with the specified address and timestamp. /// </summary> /// <param name="addr">The address of the contact that the entry refers to.</param> /// <param name="time">The time that this contact was last used.</param> public RecentEntry(ErebusAddress addr, DateTime time) { Address = addr; Timestamp = time; }
public User(string name, ErebusAddress addr) { Name = name; Address = addr; }
public AddContact() { InitializeComponent(); addr = App.AddContactData.Address; text.Text = $"Please enter a name for your new contact ({App.AddContactData.Name}):"; }
internal SSMPInvitationReceivedEventArgs(ErebusAddress src, Func <SSMP> accept) { Source = src; _accept = accept; }
/// <summary> /// Sends a request to the specified destination. /// </summary> /// <param name="destination"></param> public void SendRequest(ErebusAddress destination) { SendPacket(new ErebusEndpoint(destination, 0), new byte[] { 0, (byte)_service }.Concat(id.ToByteArray()).ToArray()); Log.RecordEvent(this, $"HDP request for service {_service} sent to {destination}", LogEntrySeverity.Info); }
/// <summary> /// Retrieves the key pair assigned to the specified address from the store. /// </summary> /// <param name="addr">The address that the key pair is assigned to.</param> /// <returns>The key pair.</returns> public Tuple <byte[], byte[]> GetKeyPair(ErebusAddress addr) => (from k in Configuration.TSM.RunSafe(() => Configuration.VerificationKeys) where k.Address == addr select Tuple.Create(k.PrivateKey, k.PublicKey)).First();
/// <summary> /// Creates a new instace of the <see cref="KeyPair"/> structure, with the specified addresss and keys. /// </summary> /// <param name="addr">The address that the keys are associated with.</param> /// <param name="private">The local private key.</param> /// <param name="public">The remote public key.</param> public KeyPair(ErebusAddress addr, byte[] @private, byte[] @public) { Address = addr; PrivateKey = @private; PublicKey = @public; }
/// <summary> /// Adds the specified key pair to the store, assigning it to the specified address. /// </summary> /// <param name="addr">The address to assign the key pair to.</param> /// <param name="myKey">The local private key.</param> /// <param name="otherKey">The remote public key.</param> public void AddKeyPair(ErebusAddress addr, byte[] myKey, byte[] otherKey) => Configuration.TSM.RunSafe(() => Configuration.VerificationKeys = Configuration.VerificationKeys.Append(new KeyPair(addr, myKey, otherKey)));