Example #1
0
        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();
 }
Example #4
0
 /// <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);
     }
 }
Example #5
0
 /// <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);
     }
 }
Example #6
0
        void regenAddr()
        {
            var b = new byte[16];

            r.NextBytes(b);
            addr         = new ErebusAddress(b);
            address.Text = addr.ToString();
        }
Example #7
0
 /// <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];
 });
Example #8
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);
        }
Example #9
0
 /// <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());
         }
 });
Example #10
0
        /// <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();
        }
Example #11
0
        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 { }
        }
Example #12
0
 /// <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);
         }
 });
Example #13
0
 /// <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);
         }
 });
Example #14
0
 /// <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);
 });
Example #15
0
 /// <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());
Example #17
0
 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);
     }
 }
Example #18
0
        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;
 }
Example #20
0
 /// <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();
 }
Example #22
0
 /// <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;
 }
Example #23
0
 /// <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;
 }
Example #24
0
 public User(string name, ErebusAddress addr)
 {
     Name    = name;
     Address = addr;
 }
Example #25
0
 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;
 }
Example #27
0
 /// <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();
Example #29
0
 /// <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)));