diff --git a/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs b/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs index 8dbe695b8..0bce28ce0 100644 --- a/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs +++ b/mRemoteNGTests/Config/Serializers/XmlConnectionsSerializerTests.cs @@ -1,7 +1,11 @@ -using System.Xml; +using System; +using System.Collections; +using System.Xml; using mRemoteNG.Config.Serializers; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNG.Security; +using mRemoteNG.Security.SymmetricEncryption; using mRemoteNG.Tree; using mRemoteNG.Tree.Root; using NUnit.Framework; @@ -25,7 +29,8 @@ namespace mRemoteNGTests.Config.Serializers [SetUp] public void Setup() { - _serializer = new XmlConnectionsSerializer(); + var encryptor = new AeadCryptographyProvider(); + _serializer = new XmlConnectionsSerializer(encryptor); _connectionTreeModel = SetupConnectionTreeModel(); } @@ -39,6 +44,32 @@ namespace mRemoteNGTests.Config.Serializers Assert.That(nodeCon4, Is.Not.Null); } + [TestCaseSource(typeof(TestCaseSources), nameof(TestCaseSources.AllEngineAndModeCombos))] + public void EncryptionEngineSerialized(BlockCipherEngines engine, BlockCipherModes mode) + { + var encryptor = new CryptographyProviderFactory().CreateAeadCryptographyProvider(engine, mode); + _serializer = new XmlConnectionsSerializer(encryptor); + var serializedData = _serializer.Serialize(new ConnectionInfo()); + var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(serializedData); + var serializedEncryptionEngine = xmlDoc.DocumentElement?.Attributes["EncryptionEngine"].Value; + var expectedEngineAsString = Enum.GetName(typeof(BlockCipherEngines), engine); + Assert.That(serializedEncryptionEngine, Is.EqualTo(expectedEngineAsString)); + } + + [TestCaseSource(typeof(TestCaseSources), nameof(TestCaseSources.AllEngineAndModeCombos))] + public void EncryptionModeSerialized(BlockCipherEngines engine, BlockCipherModes mode) + { + var encryptor = new CryptographyProviderFactory().CreateAeadCryptographyProvider(engine, mode); + _serializer = new XmlConnectionsSerializer(encryptor); + var serializedData = _serializer.Serialize(new ConnectionInfo()); + var xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(serializedData); + var serializedEncryptionMode = xmlDoc.DocumentElement?.Attributes["BlockCipherMode"].Value; + var expectedModeAsString = Enum.GetName(typeof(BlockCipherModes), mode); + Assert.That(serializedEncryptionMode, Is.EqualTo(expectedModeAsString)); + } + private ConnectionTreeModel SetupConnectionTreeModel() { /* @@ -78,5 +109,23 @@ namespace mRemoteNGTests.Config.Serializers _con3 = new ConnectionInfo { Name = "con3" }; _con4 = new ConnectionInfo { Name = "con4" }; } + + + private class TestCaseSources + { + public static IEnumerable AllEngineAndModeCombos + { + get + { + foreach (var engine in Enum.GetValues(typeof(BlockCipherEngines))) + { + foreach (var mode in Enum.GetValues(typeof(BlockCipherModes))) + { + yield return new TestCaseData(engine, mode); + } + } + } + } + } } } \ No newline at end of file diff --git a/mRemoteV1/App/Export.cs b/mRemoteV1/App/Export.cs index 120e45bfd..3df3b7f74 100644 --- a/mRemoteV1/App/Export.cs +++ b/mRemoteV1/App/Export.cs @@ -73,7 +73,9 @@ namespace mRemoteNG.App switch (saveFormat) { case ConnectionsSaver.Format.mRXML: - serializer = new XmlConnectionsSerializer(); + var factory = new CryptographyProviderFactory(); + var cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode); + serializer = new XmlConnectionsSerializer(cryptographyProvider); ((XmlConnectionsSerializer) serializer).SaveFilter = saveFilter; break; case ConnectionsSaver.Format.mRCSV: diff --git a/mRemoteV1/Config/Connections/ConnectionsSaver.cs b/mRemoteV1/Config/Connections/ConnectionsSaver.cs index 1029673f4..349bdf771 100644 --- a/mRemoteV1/Config/Connections/ConnectionsSaver.cs +++ b/mRemoteV1/Config/Connections/ConnectionsSaver.cs @@ -233,7 +233,9 @@ namespace mRemoteNG.Config.Connections { try { - var xmlConnectionsSerializer = new XmlConnectionsSerializer() + var factory = new CryptographyProviderFactory(); + var cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode); + var xmlConnectionsSerializer = new XmlConnectionsSerializer(cryptographyProvider) { Export = Export, SaveFilter = SaveFilter, diff --git a/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs b/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs index 94bce0833..6fbb1a0ff 100644 --- a/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs +++ b/mRemoteV1/Config/Serializers/XmlConnectionsSerializer.cs @@ -20,23 +20,25 @@ namespace mRemoteNG.Config.Serializers { private SecureString _password = Runtime.EncryptionKey; private XmlTextWriter _xmlTextWriter; - private ICryptographyProvider _cryptographyProvider; + private readonly ICryptographyProvider _cryptographyProvider; public bool Export { get; set; } public SaveFilter SaveFilter { get; set; } = new SaveFilter(); public bool UseFullEncryption { get; set; } + public XmlConnectionsSerializer(ICryptographyProvider cryptographyProvider) + { + _cryptographyProvider = cryptographyProvider; + } public string Serialize(ConnectionTreeModel connectionTreeModel) { var rootNode = (RootNodeInfo)connectionTreeModel.RootNodes.First(node => node is RootNodeInfo); - return Serialize(rootNode); + return SerializeConnectionsData(rootNode); } public string Serialize(ConnectionInfo serializationTarget) { - var factory = new CryptographyProviderFactory(); - _cryptographyProvider = factory.CreateAeadCryptographyProvider(mRemoteNG.Settings.Default.EncryptionEngine, mRemoteNG.Settings.Default.EncryptionBlockCipherMode); return SerializeConnectionsData(serializationTarget); } @@ -76,7 +78,7 @@ namespace mRemoteNG.Config.Serializers { var connectionInfoAsRootNode = connectionInfo as RootNodeInfo; if (connectionInfoAsRootNode != null) return connectionInfoAsRootNode; - connectionInfo = connectionInfo.Parent; + connectionInfo = connectionInfo?.Parent ?? new RootNodeInfo(RootNodeType.Connection); } } @@ -148,9 +150,9 @@ namespace mRemoteNG.Config.Serializers _xmlTextWriter.WriteStartElement("Connections"); // Do not localize _xmlTextWriter.WriteAttributeString("Name", "", rootNodeInfo.Name); _xmlTextWriter.WriteAttributeString("Export", "", Convert.ToString(Export)); - var cipherEngine = Enum.GetName(typeof(BlockCipherEngines), mRemoteNG.Settings.Default.EncryptionEngine); + var cipherEngine = Enum.GetName(typeof(BlockCipherEngines), _cryptographyProvider.CipherEngine); _xmlTextWriter.WriteAttributeString("EncryptionEngine", "", cipherEngine ?? ""); - var cipherMode = Enum.GetName(typeof(BlockCipherModes), mRemoteNG.Settings.Default.EncryptionBlockCipherMode); + var cipherMode = Enum.GetName(typeof(BlockCipherModes), _cryptographyProvider.CipherMode); _xmlTextWriter.WriteAttributeString("BlockCipherMode", "", cipherMode ?? ""); _xmlTextWriter.WriteAttributeString("KdfIterations", "", mRemoteNG.Settings.Default.EncryptionKeyDerivationIterations.ToString()); _xmlTextWriter.WriteAttributeString("FullFileEncryption", "", UseFullEncryption.ToString());