Skip to content

Commit

Permalink
Rewrite required due to the configuration section expired keys collec…
Browse files Browse the repository at this point in the history
…tion requiring unique items.

Acceptance test to test that a message without a key identifier is still processed properly.
Expired keys can also have a KeyFormat attribute, validations now done on the configuration object before conversion.
  • Loading branch information
ramonsmits committed Oct 13, 2015
1 parent 75240b0 commit aff34f5
Show file tree
Hide file tree
Showing 14 changed files with 608 additions and 175 deletions.
Expand Up @@ -16,7 +16,7 @@ public void Should_receive_decrypted_message()
.WithEndpoint<Endpoint>(b => b.Given(bus => bus.SendLocal(new MessageWithSecretData
{
Secret = "betcha can't guess my secret",
SubProperty = new MySecretSubProperty {Secret = "My sub secret"},
SubProperty = new MySecretSubProperty { Secret = "My sub secret" },
CreditCards = new List<CreditCardDetails>
{
new CreditCardDetails
Expand Down Expand Up @@ -54,7 +54,12 @@ public class Endpoint : EndpointConfigurationBuilder
{
public Endpoint()
{
EndpointSetup<DefaultServer>(builder => builder.RijndaelEncryptionService("1st", Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6")));
var keys = new Dictionary<string, byte[]>
{
{"1st", Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6")}
};

EndpointSetup<DefaultServer>(builder => builder.RijndaelEncryptionService("1st", keys));
}

public class Handler : IHandleMessages<MessageWithSecretData>
Expand Down
Expand Up @@ -8,7 +8,7 @@
using NUnit.Framework;
using ScenarioDescriptors;

public class When_using_Rijndael_with_multikey: NServiceBusAcceptanceTest
public class When_using_Rijndael_with_multikey : NServiceBusAcceptanceTest
{
[Test]
public void Should_receive_decrypted_message()
Expand Down Expand Up @@ -45,11 +45,15 @@ public class Receiver : EndpointConfigurationBuilder
{
public Receiver()
{
var expiredKeys = new List<KeyValuePair<string, byte[]>>
byte[] key = Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6");
var keys = new Dictionary<string, byte[]>
{
new KeyValuePair<string,byte[]>("1st", Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6"))
{"2nd", Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6") },
{"1st", key }
};
EndpointSetup<DefaultServer>(builder => builder.RijndaelEncryptionService("2nd", Encoding.ASCII.GetBytes("gdDbqRpqdRbTs3mhdZh9qCaDaxJXl+e6"), expiredKeys));

var expiredKeys = new[] { key };
EndpointSetup<DefaultServer>(builder => builder.RijndaelEncryptionService("2nd", keys, expiredKeys));
}

public class Handler : IHandleMessages<MessageWithSecretData>
Expand Down
@@ -0,0 +1,90 @@
namespace NServiceBus.AcceptanceTests.Encryption
{
using System;
using System.Collections.Generic;
using System.Text;
using EndpointTemplates;
using AcceptanceTesting;
using NServiceBus.MessageMutator;
using NUnit.Framework;
using ScenarioDescriptors;

public class When_using_Rijndael_without_incoming_key_identifier : NServiceBusAcceptanceTest
{
[Test]
public void Should_process_decrypted_message_without_key_identifier()
{
Scenario.Define<Context>()
.WithEndpoint<Sender>(b => b.Given((bus, context) => bus.Send(new MessageWithSecretData
{
Secret = "betcha can't guess my secret",
})))
.WithEndpoint<Receiver>()
.Done(c => c.Done)
.Repeat(r => r.For(Transports.Default))
.Should(c => Assert.AreEqual("betcha can't guess my secret", c.Secret))
.Run();
}

public class Context : ScenarioContext
{
public bool Done { get; set; }
public string Secret { get; set; }
}

public class Sender : EndpointConfigurationBuilder
{
public Sender()
{
EndpointSetup<DefaultServer>(builder => builder.RijndaelEncryptionService("will-be-removed-by-transport-mutator", Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")))
.AddMapping<MessageWithSecretData>(typeof(Receiver));
}
}

public class Receiver : EndpointConfigurationBuilder
{
public Receiver()
{
var keys = new Dictionary<string, byte[]>
{
{"new", Encoding.ASCII.GetBytes("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb") },
};

var expiredKeys = new[] { Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") };
EndpointSetup<DefaultServer>(builder => builder.RijndaelEncryptionService("new", keys, expiredKeys));

}

public class Handler : IHandleMessages<MessageWithSecretData>
{
public Context Context { get; set; }

public void Handle(MessageWithSecretData message)
{
Context.Secret = message.Secret.Value;
Context.Done = true;
}
}
}

[Serializable]
public class MessageWithSecretData : IMessage
{
public WireEncryptedString Secret { get; set; }
}


class RemoveKeyIdentifierHeaderMutator : IMutateIncomingTransportMessages, INeedInitialization
{
public void MutateIncoming(TransportMessage transportMessage)
{
transportMessage.Headers.Remove(Headers.KeyIdentifier);
}

public void Customize(BusConfiguration configuration)
{
configuration.RegisterComponents(c => c.ConfigureComponent<RemoveKeyIdentifierHeaderMutator>(DependencyLifecycle.InstancePerCall));
}
}
}
}
Expand Up @@ -84,6 +84,7 @@
<Compile Include="Basic\When_TimeToBeReceived_has_expired.cs" />
<Compile Include="Basic\When_Deferring_a_message.cs" />
<Compile Include="Basic\When_using_callback_to_get_message.cs" />
<Compile Include="Encryption\When_using_Rijndael_without_incoming_key_identifier.cs" />
<Compile Include="HostInformation\When_feature_overrides_hostid.cs" />
<Compile Include="PerfMon\CriticalTime\When_deferring_a_message.cs" />
<Compile Include="PubSub\When_publishing_from_sendonly.cs" />
Expand Down
Expand Up @@ -5,6 +5,7 @@
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using NServiceBus.Config;
using NUnit.Framework;

Expand All @@ -29,9 +30,9 @@ public void Can_read_from_xml()
name='RijndaelEncryptionServiceConfig'
type='NServiceBus.Config.RijndaelEncryptionServiceConfig, NServiceBus.Core'/>
</configSections>
<RijndaelEncryptionServiceConfig Key='key1'>
<RijndaelEncryptionServiceConfig Key='key1' KeyIdentifier='A' KeyFormat='Base64'>
<ExpiredKeys>
<add Key='key2' />
<add Key='key2' KeyIdentifier='B' KeyFormat='Base64' />
<add Key='key3' />
</ExpiredKeys>
</RijndaelEncryptionServiceConfig>
Expand All @@ -44,7 +45,10 @@ public void Can_read_from_xml()
Assert.AreEqual("key1", section.Key);
Assert.AreEqual(2, keys.Count);
Assert.Contains("key2", keys);
Assert.Contains("key3", keys);
Assert.AreEqual("A", section.KeyIdentifier);
Assert.AreEqual(KeyFormat.Base64, section.KeyFormat);
Assert.AreEqual("B", section.ExpiredKeys["key2"].KeyIdentifier);
Assert.AreEqual(KeyFormat.Base64, section.ExpiredKeys["key2"].KeyFormat, "Expired key KeyFormat");
}

static T ReadSectionFromText<T>(string s) where T : ConfigurationSection
Expand Down Expand Up @@ -143,7 +147,7 @@ public void Should_throw_for_whitespace_keys_in_config()
}
}
};
var exception = Assert.Throws<Exception>(() => ConfigureRijndaelEncryptionService.ExtractExpiredKeysFromConfigSection(config));
var exception = Assert.Throws<Exception>(() => ConfigureRijndaelEncryptionService.ValidateConfigSection(config));
Assert.AreEqual("The RijndaelEncryptionServiceConfig has a 'ExpiredKeys' property defined however some keys have no 'Key' property set.", exception.Message);
}

Expand All @@ -157,103 +161,122 @@ public void Should_throw_for_null_keys_in_config()
new RijndaelExpiredKey()
}
};
var exception = Assert.Throws<Exception>(() => ConfigureRijndaelEncryptionService.ExtractExpiredKeysFromConfigSection(config));
var exception = Assert.Throws<Exception>(() => ConfigureRijndaelEncryptionService.ValidateConfigSection(config));
Assert.AreEqual("The RijndaelEncryptionServiceConfig has a 'ExpiredKeys' property defined however some keys have no 'Key' property set.", exception.Message);
}

[Test]
public void Duplicates_should_be_skipped()
public void Should_correctly_parse_key_identifiers_containing_multiple_keys()
{
var config = new RijndaelEncryptionServiceConfig
var section = new RijndaelEncryptionServiceConfig
{
ExpiredKeys = new RijndaelExpiredKeyCollection
KeyIdentifier = "1;2",
ExpiredKeys =
{
new RijndaelExpiredKey
{
Key = "a"
},
new RijndaelExpiredKey
{
Key = "a"
KeyIdentifier = "3;4",
Key = "Key"
}
}
};
var keys = ConfigureRijndaelEncryptionService.ExtractExpiredKeysFromConfigSection(config);

Assert.That(new[] { new KeyValuePair<string, string>(String.Empty, "a") }, Is.EquivalentTo(keys));
}


[TestFixture]
public class ValidationFixture
{
[Test]
public void EncryptionKeyListedInExpiredKeysTest()
{
var section = new RijndaelEncryptionServiceConfig();
var expiredKeys = new List<KeyValuePair<string, string>>();

Assert.IsFalse(ConfigureRijndaelEncryptionService.Validations.EncryptionKeyListedInExpiredKeys(section, expiredKeys));

section.Key = "Key";
expiredKeys.Add(new KeyValuePair<string, string>(null, "Key"));

Assert.IsTrue(ConfigureRijndaelEncryptionService.Validations.EncryptionKeyListedInExpiredKeys(section, expiredKeys));
}
IDictionary<string, byte[]> keys = ConfigureRijndaelEncryptionService.ExtractKeysFromConfigSection(section);

[Test]
public void ExpiredKeysHasDuplicateKeyIdentifiersTest()
ICollection<string> expected = new[]
{
var expiredKeys = new List<KeyValuePair<string, string>>();
expiredKeys.Add(new KeyValuePair<string, string>(null, "Key"));
"1",
"2",
"3",
"4"
};

Assert.IsFalse(ConfigureRijndaelEncryptionService.Validations.ExpiredKeysHasDuplicateKeyIdentifiers(expiredKeys));
Assert.AreEqual(expected, keys.Keys);
}

expiredKeys.Add(new KeyValuePair<string, string>(null, "Key1"));
[Test]
public void Should_correctly_convert_base64_key()
{
byte[] key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };

Assert.IsTrue(ConfigureRijndaelEncryptionService.Validations.ExpiredKeysHasDuplicateKeyIdentifiers(expiredKeys));
}
var base64 = Convert.ToBase64String(key);

[Test]
public void ExpiredKeysHaveDuplicateKeysTest()
var section = new RijndaelEncryptionServiceConfig
{
var expiredKeys = new List<KeyValuePair<string, string>>();
expiredKeys.Add(new KeyValuePair<string, string>(null, "Key"));
Key = base64,
KeyFormat = KeyFormat.Base64,
KeyIdentifier = "1",
ExpiredKeys =
{
new RijndaelExpiredKey
{
KeyIdentifier = "2",
Key = base64,
KeyFormat = KeyFormat.Base64
}
}
};

Assert.IsFalse(ConfigureRijndaelEncryptionService.Validations.ExpiredKeysHaveDuplicateKeys(expiredKeys));
IDictionary<string, byte[]> keys = ConfigureRijndaelEncryptionService.ExtractKeysFromConfigSection(section);

expiredKeys.Add(new KeyValuePair<string, string>(null, "Key"));
Assert.AreEqual(key, keys["1"], "Key in configuration root incorrectly converted");
Assert.AreEqual(key, keys["2"], "Key in expired keys incorrectly converted");
}

Assert.IsTrue(ConfigureRijndaelEncryptionService.Validations.ExpiredKeysHaveDuplicateKeys(expiredKeys));
}
[Test]
public void Should_correctly_convert_ascii_key()
{
string asciiKey = "0123456789123456";

var key = Encoding.ASCII.GetBytes("0123456789123456");

[Test]
public void ExpiredKeysHaveWhiteSpaceTest()
var section = new RijndaelEncryptionServiceConfig
{
var expiredKeys = new List<KeyValuePair<string, string>>();
expiredKeys.Add(new KeyValuePair<string, string>(null, "Key"));
Key = asciiKey,
KeyFormat = KeyFormat.Ascii,
KeyIdentifier = "1",
ExpiredKeys =
{
new RijndaelExpiredKey
{
KeyIdentifier = "2",
Key = asciiKey,
KeyFormat = KeyFormat.Ascii
}
}
};

Assert.IsFalse(ConfigureRijndaelEncryptionService.Validations.ExpiredKeysHaveWhiteSpace(expiredKeys));
IDictionary<string, byte[]> keys = ConfigureRijndaelEncryptionService.ExtractKeysFromConfigSection(section);

expiredKeys.Add(new KeyValuePair<string, string>(null, ""));
Assert.AreEqual(key, keys["1"], "Key in configuration root incorrectly converted");
Assert.AreEqual(key, keys["2"], "Key in expired keys incorrectly converted");
}

Assert.IsTrue(ConfigureRijndaelEncryptionService.Validations.ExpiredKeysHaveWhiteSpace(expiredKeys));
}
[Test]
public void Should_correctly_convert_ascii_key_when_no_value()
{
string asciiKey = "0123456789123456";

[Test]
public void OneOrMoreExpiredKeysHaveNoKeyIdentifierTest()
{
var expiredKeys = new List<KeyValuePair<string, string>>();
expiredKeys.Add(new KeyValuePair<string, string>("ID", "Key"));
var key = Encoding.ASCII.GetBytes("0123456789123456");

Assert.IsFalse(ConfigureRijndaelEncryptionService.Validations.OneOrMoreExpiredKeysHaveNoKeyIdentifier(expiredKeys));
var section = new RijndaelEncryptionServiceConfig
{
Key = asciiKey,
KeyIdentifier = "1",
ExpiredKeys =
{
new RijndaelExpiredKey
{
KeyIdentifier = "2",
Key = asciiKey,
}
}
};

expiredKeys.Add(new KeyValuePair<string, string>(null, " Key "));
IDictionary<string, byte[]> keys = ConfigureRijndaelEncryptionService.ExtractKeysFromConfigSection(section);

Assert.IsTrue(ConfigureRijndaelEncryptionService.Validations.OneOrMoreExpiredKeysHaveNoKeyIdentifier(expiredKeys));
}
Assert.AreEqual(key, keys["1"], "Key in configuration root incorrectly converted");
Assert.AreEqual(key, keys["2"], "Key in expired keys incorrectly converted");
}
}

}

0 comments on commit aff34f5

Please sign in to comment.