/// <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]; });
/// <summary> /// Reloads the in-memory configuration from the configuration file. /// </summary> /// <param name="pin">The personal identification number (PIN) to use as a decryption key.</param> public static void Reload(int pin) => TSM.RunSafe(() => { using (var s = Application.Context.OpenFileInput(FILE_NAME)) using (var r = new BinaryReader(s)) { var v = r.ReadUInt16(); if (v != FILE_VERSION) { throw new InvalidDataException($"Config file had version {v}; expected {FILE_VERSION}."); } Address = r.ReadErebusAddress(); ConnectionTargets = new IConnectionTarget[r.ReadInt32()]; for (int i = 0; i < ConnectionTargets.Length; ++i) { var t = r.ReadByte(); switch (t) { case 0: ConnectionTargets[i] = new TCPIPConnectionTarget(r.ReadString472(), r.ReadInt32()); break; case 1: ConnectionTargets[i] = new BluetoothConnectionTarget(r.ReadString472()); break; default: throw new InvalidDataException($"Config file had invalid connection target type {t}."); } } Contacts = new Contact[r.ReadInt32()]; for (int i = 0; i < Contacts.Length; ++i) { Contacts[i] = new Contact(r.ReadString472(), r.ReadErebusAddress()); } Recents = new RecentEntry[r.ReadInt32()]; for (int i = 0; i < Recents.Length; ++i) { Recents[i] = new RecentEntry(r.ReadErebusAddress(), new DateTime(r.ReadInt64())); } Log.RecordEvent(typeof(Configuration), "Attempting to decrypt encrypted portion of configuration file.", LogEntrySeverity.Info); var aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7); var sha = WinRTCrypto.HashAlgorithmProvider.OpenAlgorithm(HashAlgorithm.Sha512); var bk = sha.HashData(BitConverter.GetBytes(pin)); var key = bk; var data = r.ReadBytes(r.ReadInt32()); for (int i = 0; i < data.Length / 64 + 1; ++i) { key = sha.HashData(key); for (int j = 0; j < 64 && (i < data.Length / 64 || j < data.Length % 64); ++j) { data[i * 64 + j] ^= key[j]; } } using (var ms = new MemoryStream(data)) /*using (var es = new EncryptedStream(ms, key)) * using (var ws = new WrapperStream(ms)) * using (var cs = new CryptoStream(ws, WinRTCrypto.CryptographicEngine.CreateDecryptor(aes.CreateSymmetricKey(key)), CryptoStreamMode.Read))*/ using (var cr = new BinaryReader(ms)) { if (!bk.SequenceEqual(cr.ReadBytes(64))) { throw new InvalidDataException("Incorrect PIN."); } VerificationKeys = new KeyPair[cr.ReadInt32()]; for (int i = 0; i < VerificationKeys.Length; ++i) { VerificationKeys[i] = new KeyPair(cr.ReadErebusAddress(), cr.ReadBytes(cr.ReadInt32()), cr.ReadBytes(cr.ReadInt32())); } } Log.RecordEvent(typeof(Configuration), "Decryption successful.", LogEntrySeverity.Info); } });