Skip to content

Commit

Permalink
fix encryption + 2nd level retries bug
Browse files Browse the repository at this point in the history
  • Loading branch information
mookid8000 committed Apr 4, 2024
1 parent 5dad08e commit af552a8
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
49 changes: 49 additions & 0 deletions Rebus.Tests/Bugs/VerifySecondLevelRetriesAndEncryptionAreCool.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Rebus.Activation;
using Rebus.Config;
using Rebus.Encryption;
using Rebus.Retry.Simple;
using Rebus.Tests.Contracts;
using Rebus.Tests.Contracts.Extensions;
using Rebus.Transport.InMem;
// ReSharper disable AccessToDisposedClosure
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously

namespace Rebus.Tests.Bugs;

[TestFixture]
[Description("Exposed a bug that was caused by not removing the encryption headers from the transport message after descryption. This caused decryption to happen twice, but on un-encrypted contents the 2nd time around")]
public class VerifySecondLevelRetriesAndEncryptionAreCool : FixtureBase
{
static readonly string SecretKey = FixedRijndaelEncryptionKeyProvider.GenerateNewKey();

[Test]
public async Task ItWorks()
{
using var activator = new BuiltinHandlerActivator();
using var gotTheFailedMessage = new ManualResetEvent(initialState: false);

activator.Handle<string>(async _ => throw new IndexOutOfRangeException("it's out of range buddy"));

activator.Handle<IFailed<string>>(async failed =>
{
gotTheFailedMessage.Set();
});

var bus = Configure.With(activator)
.Transport(t => t.UseInMemoryTransport(new(), "whatever"))
.Options(o =>
{
o.RetryStrategy(secondLevelRetriesEnabled: true);
o.EnableEncryption(SecretKey);
})
.Start();

await bus.SendLocal("HEJ");

gotTheFailedMessage.WaitOrDie(TimeSpan.FromSeconds(3));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Rebus.Tests.Examples;

[TestFixture]
[Description("Demonstrates in full how the current principal can be changed in the pipeline and in some relevant transaction context callbacks")]
public class ChangeCurrentPrincipalInPipelineAndTransactionContextCallbacks : FixtureBase
public class ModifyCurrentPrincipalInPipelineAndTransactionContextCallbacks : FixtureBase
{
[Test]
public async Task CheckHowItWorks()
Expand Down
20 changes: 14 additions & 6 deletions Rebus/Encryption/DecryptMessagesIncomingStep.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,24 @@ public DecryptMessagesIncomingStep(IAsyncEncryptor encryptor)
public async Task Process(IncomingStepContext context, Func<Task> next)
{
var transportMessage = context.Load<TransportMessage>();
var originalHeaders = transportMessage.Headers;

if (transportMessage.Headers.TryGetValue(EncryptionHeaders.ContentEncryption, out var contentEncryptionValue)
if (originalHeaders.TryGetValue(EncryptionHeaders.ContentEncryption, out var contentEncryptionValue)
&& contentEncryptionValue == _encryptor.ContentEncryptionValue)
{
var headers = transportMessage.Headers.Clone();
var encryptedBodyBytes = transportMessage.Body;
var headers = originalHeaders.Clone();

// remove these to prevent subsequent invocations of the pipeline to decrypt the transport message again
headers.Remove(EncryptionHeaders.ContentEncryption);
headers.Remove(EncryptionHeaders.ContentInitializationVector);
headers.Remove(EncryptionHeaders.KeyId);

headers.TryGetValue(EncryptionHeaders.KeyId, out var keyId);

var iv = GetIv(headers);
// must look for key ID and IV in original headers :)
originalHeaders.TryGetValue(EncryptionHeaders.KeyId, out var keyId);

var iv = GetIv(originalHeaders);

var encryptedBodyBytes = transportMessage.Body;
var bodyBytes = await _encryptor.Decrypt(new EncryptedData(encryptedBodyBytes, iv, keyId));

context.Save(new TransportMessage(headers, bodyBytes));
Expand Down
2 changes: 1 addition & 1 deletion Rebus/Encryption/EncryptionConfigurationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ IAsyncEncryptor GetAsyncEncryptor()
catch (Exception exception)
{
throw new RebusConfigurationException(exception,
@"Could not get IAsyncEncryptor to use when enabling encryption on the data bus storage. Please either enable encryption on the transport (via .Options(o => o.EnableEncryption(...))) to have an IAsyncEncryptor registered.");
"Could not get IAsyncEncryptor to use when enabling encryption on the data bus storage. Please either enable encryption on the transport (via .Options(o => o.EnableEncryption(...))) to have an IAsyncEncryptor registered.");
}
}

Expand Down

0 comments on commit af552a8

Please sign in to comment.