Skip to content

Commit

Permalink
Merge pull request #35 from mkoesem/feature/additional-signature-secret
Browse files Browse the repository at this point in the history
Feature/additional signature secret
  • Loading branch information
ckuetbach authored Sep 16, 2024
2 parents 07e8db4 + ff04a0a commit eb76b0b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,38 @@ public async Task BaseUriHeaderAndNullDefaultBaseUri_ShouldUseHeaderAndInvokeNex
nextMiddleware.HasBeenInvoked.Should().BeTrue("next middleware should have been invoked");
}

[TestMethod, UnitUnderTest(typeof(TenantMiddleware))]
public async Task WrongSignatureWithValidAdditionalSignatureSecret_ShouldUseHeaderAndInvokeNext()
{
const string systemBaseUriFromHeader = "https://sample.mydomain.de";

var context = new DefaultHttpContext();
context.Request.Headers.Add(SystemBaseUriHeader, new StringValues(new[] {systemBaseUriFromHeader}));
context.Request.Headers.Add(SignatureHeader, new[] {GetBase64SignatureFor(systemBaseUriFromHeader, _signatureKey)});

var wrongSignatureKey = new byte[]
{
167, 219, 144, 209, 189, 1, 178, 73, 139, 47, 21, 236, 142, 56, 71, 245, 43, 188, 163, 52, 239, 102, 94, 153, 255, 159, 199, 149, 163,
145, 161, 24
};

var systemBaseUriSetByMiddleware = "null";
var nextMiddleware = new MiddlewarMock(null);
await new TenantMiddleware(nextMiddleware.InvokeAsync,
new TenantMiddlewareOptions
{
DefaultSystemBaseUri = null,
SignatureSecretKey = wrongSignatureKey,
AdditionalSignatureSecretKeys = new [] {
_signatureKey
},
OnTenantIdentified = (tenantId, systemBaseUri) => { systemBaseUriSetByMiddleware = systemBaseUri; }
})
.InvokeAsync(context).ConfigureAwait(false);

systemBaseUriSetByMiddleware.Should().Be(systemBaseUriFromHeader);
nextMiddleware.HasBeenInvoked.Should().BeTrue("next middleware should have been invoked");
}

[TestMethod, UnitUnderTest(typeof(TenantMiddleware))]
public async Task NoBaseUriHeaderAndDefaultBaseUri_ShouldUseDefaultBaseUriAndInvokeNext()
Expand Down
27 changes: 24 additions & 3 deletions dvelop-sdk-tenant/TenantMiddleware/TenantMiddleware.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
Expand Down Expand Up @@ -79,7 +81,11 @@ internal static HttpStatusCode Invoke(TenantMiddlewareOptions tenantMiddlewareOp
try
{
var signature = Convert.FromBase64String(base64Signature);
if (!SignatureIsValid(messageBytes, signature, tenantMiddlewareOptions.SignatureSecretKey))
if (!SignatureIsValid(
messageBytes,
signature,
tenantMiddlewareOptions.SignatureSecretKey,
tenantMiddlewareOptions.AdditionalSignatureSecretKeys))
{
tenantMiddlewareOptions.LogCallback?.Invoke(TenantMiddlewareLogLevel.Debug,
"Signature does not match");
Expand Down Expand Up @@ -109,13 +115,28 @@ internal static HttpStatusCode Invoke(TenantMiddlewareOptions tenantMiddlewareOp
return 0;
}

private static bool SignatureIsValid(byte[] message, byte[] signature, byte[] sigKey)
private static bool SignatureIsValid(byte[] message, byte[] signature, byte[] sigKey, IList<byte[]> additionalSigKeys)
{
var result = false;

using (var mac = new HMACSHA256(sigKey))
{
var expectedSignature = mac.ComputeHash(message);
return AreEqualConstantTime(expectedSignature, signature);
result = AreEqualConstantTime(expectedSignature, signature);
}

if (!result && additionalSigKeys != null)
{
result = additionalSigKeys.Any(addSigKey =>
{
using (HMACSHA256 hmacshA256 = new HMACSHA256(addSigKey))
{
return AreEqualConstantTime(hmacshA256.ComputeHash(message), signature);
}
});
}

return result;
}

/// <summary>
Expand Down
3 changes: 3 additions & 0 deletions dvelop-sdk-tenant/TenantMiddleware/TenantMiddlewareOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

namespace Dvelop.Sdk.TenantMiddleware
{
Expand Down Expand Up @@ -29,6 +30,8 @@ public class TenantMiddlewareOptions
public string DefaultTenantId { get; set; }

public byte[] SignatureSecretKey { get; set; }

public IList<byte[]> AdditionalSignatureSecretKeys { get; set; }

/// <summary>
/// Ist diese Option gesetzt, so wird die TenantId aus dem HttpHeader verwendet, auch wenn die Signatur falsch ist (nur zu Testzwecken)
Expand Down

0 comments on commit eb76b0b

Please sign in to comment.