From 2387f183e9c0d8d26df93f81bf0ddce94d746bd0 Mon Sep 17 00:00:00 2001 From: David Sparer Date: Sun, 2 Apr 2017 21:28:50 -0600 Subject: [PATCH] added password decryption decorator --- ...edentialPasswordDecryptorDecoratorTests.cs | 43 +++++++++++++++++ mRemoteNGTests/mRemoteNGTests.csproj | 1 + ...XmlCredentialPasswordDecryptorDecorator.cs | 46 +++++++++++++++++++ .../XmlCredentialRecordDeserializer.cs | 3 +- mRemoteV1/mRemoteV1.csproj | 1 + 5 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialPasswordDecryptorDecoratorTests.cs create mode 100644 mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialPasswordDecryptorDecorator.cs diff --git a/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialPasswordDecryptorDecoratorTests.cs b/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialPasswordDecryptorDecoratorTests.cs new file mode 100644 index 000000000..8c029c558 --- /dev/null +++ b/mRemoteNGTests/Config/Serializers/CredentialSerializers/XmlCredentialPasswordDecryptorDecoratorTests.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Security; +using mRemoteNG.Config.Serializers.CredentialSerializer; +using mRemoteNG.Security; +using mRemoteNG.Security.SymmetricEncryption; +using NUnit.Framework; + +namespace mRemoteNGTests.Config.Serializers.CredentialSerializers +{ + public class XmlCredentialPasswordDecryptorDecoratorTests + { + private XmlCredentialPasswordDecryptorDecorator _sut; + private readonly SecureString _decryptionKey = "myKey1".ConvertToSecureString(); + private string _unencryptedPassword = "myPassword1"; + + [SetUp] + public void Setup() + { + var baseDeserializer = new XmlCredentialRecordDeserializer(); + _sut = new XmlCredentialPasswordDecryptorDecorator(_decryptionKey, baseDeserializer); + } + + [Test] + public void OutputedCredentialHasDecryptedPassword() + { + var xml = GenerateXml(); + var output = _sut.Deserialize(xml); + Assert.That(output.First().Password.ConvertToUnsecureString(), Is.EqualTo(_unencryptedPassword)); + } + + + private string GenerateXml() + { + var cryptoProvider = new AeadCryptographyProvider(); + var encryptedPassword = cryptoProvider.Encrypt(_unencryptedPassword, _decryptionKey); + return + "" + + $"" + + $"" + + ""; + } + } +} \ No newline at end of file diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 4f46155d6..27ec7f29f 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -113,6 +113,7 @@ + diff --git a/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialPasswordDecryptorDecorator.cs b/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialPasswordDecryptorDecorator.cs new file mode 100644 index 000000000..4941cdb28 --- /dev/null +++ b/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialPasswordDecryptorDecorator.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Security; +using System.Xml.Linq; +using mRemoteNG.Credential; +using mRemoteNG.Security; + +namespace mRemoteNG.Config.Serializers.CredentialSerializer +{ + public class XmlCredentialPasswordDecryptorDecorator : IDeserializer> + { + private readonly IDeserializer> _baseDeserializer; + private readonly SecureString _decryptionKey; + + public XmlCredentialPasswordDecryptorDecorator(SecureString decryptionKey, IDeserializer> baseDeserializer) + { + if (decryptionKey == null) + throw new ArgumentNullException(nameof(decryptionKey)); + if (baseDeserializer == null) + throw new ArgumentNullException(nameof(baseDeserializer)); + + _decryptionKey = decryptionKey; + _baseDeserializer = baseDeserializer; + } + + public IEnumerable Deserialize(string xml) + { + var decryptedXml = DecryptPasswords(xml); + return _baseDeserializer.Deserialize(decryptedXml); + } + + private string DecryptPasswords(string xml) + { + var xdoc = XDocument.Parse(xml); + var cryptoProvider = CryptographyProviderFactory.BuildFromXml(xdoc.Root); + foreach (var credentialElement in xdoc.Descendants()) + { + var passwordAttribute = credentialElement.Attribute("Password"); + if (passwordAttribute == null) continue; + var decryptedPassword = cryptoProvider.Decrypt(passwordAttribute.Value, _decryptionKey); + passwordAttribute.SetValue(decryptedPassword); + } + return xdoc.ToString(); + } + } +} \ No newline at end of file diff --git a/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordDeserializer.cs b/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordDeserializer.cs index aea0177bb..a90f23565 100644 --- a/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordDeserializer.cs +++ b/mRemoteV1/Config/Serializers/CredentialSerializer/XmlCredentialRecordDeserializer.cs @@ -1,14 +1,13 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Security; using System.Xml.Linq; using mRemoteNG.Credential; using mRemoteNG.Security; namespace mRemoteNG.Config.Serializers.CredentialSerializer { - public class XmlCredentialRecordDeserializer + public class XmlCredentialRecordDeserializer : IDeserializer> { public string SchemaVersion { get; } = "1.0"; diff --git a/mRemoteV1/mRemoteV1.csproj b/mRemoteV1/mRemoteV1.csproj index 181f38209..ba858f08e 100644 --- a/mRemoteV1/mRemoteV1.csproj +++ b/mRemoteV1/mRemoteV1.csproj @@ -142,6 +142,7 @@ +