Browse Source

Bump Wilson to 6.7.0 and use the new SecurityKey.IsSupportedAlgorithm() API

pull/995/head
Kévin Chalet 6 years ago
parent
commit
5169c28d97
  1. 4
      Directory.Packages.props
  2. 26
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  3. 27
      src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs
  4. 7
      src/OpenIddict.Validation/OpenIddictValidationBuilder.cs
  5. 3
      test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs
  6. 127
      test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

4
Directory.Packages.props

@ -6,8 +6,8 @@
<PackageVersion Include="JetBrains.Annotations" Version="2019.1.3" />
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="1.1.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.0.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="6.6.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.6.0" />
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="6.7.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.7.0" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" />
<PackageVersion Include="Microsoft.Owin.Security" Version="4.1.0" />
<PackageVersion Include="Microsoft.Owin.Testing" Version="4.1.0" />

26
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -174,13 +174,13 @@ namespace Microsoft.Extensions.DependencyInjection
throw new InvalidOperationException("The asymmetric encryption key doesn't contain the required private key.");
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.Aes256KW))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.Aes256KW))
{
return AddEncryptionCredentials(new EncryptingCredentials(key,
SecurityAlgorithms.Aes256KW, SecurityAlgorithms.Aes256CbcHmacSha512));
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.RsaOAEP))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.RsaOAEP))
{
return AddEncryptionCredentials(new EncryptingCredentials(key,
SecurityAlgorithms.RsaOAEP, SecurityAlgorithms.Aes256CbcHmacSha512));
@ -190,9 +190,6 @@ namespace Microsoft.Extensions.DependencyInjection
.AppendLine("An encryption algorithm cannot be automatically inferred from the encrypting key.")
.Append("Consider using 'options.AddEncryptionCredentials(EncryptingCredentials)' instead.")
.ToString());
static bool IsAlgorithmSupported(SecurityKey key, string algorithm) =>
key.CryptoProviderFactory.IsSupportedAlgorithm(algorithm, key);
}
/// <summary>
@ -606,36 +603,36 @@ namespace Microsoft.Extensions.DependencyInjection
throw new InvalidOperationException("The asymmetric signing key doesn't contain the required private key.");
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.RsaSha256))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSha256))
{
return AddSigningCredentials(new SigningCredentials(key, SecurityAlgorithms.RsaSha256));
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.HmacSha256))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.HmacSha256))
{
return AddSigningCredentials(new SigningCredentials(key, SecurityAlgorithms.HmacSha256));
}
#if SUPPORTS_ECDSA
// Note: ECDSA algorithms are bound to specific curves and must be treated separately.
if (IsAlgorithmSupported(key, SecurityAlgorithms.EcdsaSha256))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha256))
{
return AddSigningCredentials(new SigningCredentials(key, SecurityAlgorithms.EcdsaSha256));
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.EcdsaSha384))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha384))
{
return AddSigningCredentials(new SigningCredentials(key, SecurityAlgorithms.EcdsaSha384));
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.EcdsaSha512))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha512))
{
return AddSigningCredentials(new SigningCredentials(key, SecurityAlgorithms.EcdsaSha512));
}
#else
if (IsAlgorithmSupported(key, SecurityAlgorithms.EcdsaSha256) ||
IsAlgorithmSupported(key, SecurityAlgorithms.EcdsaSha384) ||
IsAlgorithmSupported(key, SecurityAlgorithms.EcdsaSha512))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha256) ||
key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha384) ||
key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha512))
{
throw new PlatformNotSupportedException("ECDSA signing keys are not supported on this platform.");
}
@ -645,9 +642,6 @@ namespace Microsoft.Extensions.DependencyInjection
.AppendLine("A signature algorithm cannot be automatically inferred from the signing key.")
.Append("Consider using 'options.AddSigningCredentials(SigningCredentials)' instead.")
.ToString());
static bool IsAlgorithmSupported(SecurityKey key, string algorithm) =>
key.CryptoProviderFactory.IsSupportedAlgorithm(algorithm, key);
}
/// <summary>

27
src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs

@ -1249,11 +1249,11 @@ namespace OpenIddict.Server
foreach (var credentials in context.Options.SigningCredentials)
{
#if SUPPORTS_ECDSA
if (!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.RsaSha256) &&
!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.RsaSsaPssSha256) &&
!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.EcdsaSha256) &&
!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.EcdsaSha384) &&
!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.EcdsaSha512))
if (!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSha256) &&
!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSsaPssSha256) &&
!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha256) &&
!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha384) &&
!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha512))
{
context.Logger.LogInformation("An unsupported signing key of type '{Type}' was ignored and excluded " +
"from the key set. Only RSA and ECDSA asymmetric security keys can be " +
@ -1262,8 +1262,8 @@ namespace OpenIddict.Server
continue;
}
#else
if (!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.RsaSha256) &&
!IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.RsaSsaPssSha256))
if (!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSha256) &&
!credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSsaPssSha256))
{
context.Logger.LogInformation("An unsupported signing key of type '{Type}' was ignored and excluded " +
"from the key set. Only RSA asymmetric security keys can be exposed " +
@ -1309,8 +1309,8 @@ namespace OpenIddict.Server
Kid = credentials.Kid
};
if (IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.RsaSha256) ||
IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.RsaSsaPssSha256))
if (credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSha256) ||
credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.RsaSsaPssSha256))
{
// Note: IdentityModel 5 doesn't expose a method allowing to retrieve the underlying algorithm
// from a generic asymmetric security key. To work around this limitation, try to cast
@ -1351,9 +1351,9 @@ namespace OpenIddict.Server
}
#if SUPPORTS_ECDSA
else if (IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.EcdsaSha256) ||
IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.EcdsaSha384) ||
IsAlgorithmSupported(credentials.Key, SecurityAlgorithms.EcdsaSha512))
else if (credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha256) ||
credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha384) ||
credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha512))
{
var parameters = credentials.Key switch
{
@ -1417,9 +1417,6 @@ namespace OpenIddict.Server
return default;
static bool IsAlgorithmSupported(SecurityKey key, string algorithm) =>
key.CryptoProviderFactory.IsSupportedAlgorithm(algorithm, key);
#if SUPPORTS_ECDSA
static bool IsCurve(ECParameters parameters, ECCurve curve) =>
string.Equals(parameters.Curve.Oid.FriendlyName, curve.Oid.FriendlyName, StringComparison.Ordinal);

7
src/OpenIddict.Validation/OpenIddictValidationBuilder.cs

@ -164,13 +164,13 @@ namespace Microsoft.Extensions.DependencyInjection
throw new InvalidOperationException("The asymmetric encryption key doesn't contain the required private key.");
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.Aes256KW))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.Aes256KW))
{
return AddEncryptionCredentials(new EncryptingCredentials(key,
SecurityAlgorithms.Aes256KW, SecurityAlgorithms.Aes256CbcHmacSha512));
}
if (IsAlgorithmSupported(key, SecurityAlgorithms.RsaOAEP))
if (key.IsSupportedAlgorithm(SecurityAlgorithms.RsaOAEP))
{
return AddEncryptionCredentials(new EncryptingCredentials(key,
SecurityAlgorithms.RsaOAEP, SecurityAlgorithms.Aes256CbcHmacSha512));
@ -180,9 +180,6 @@ namespace Microsoft.Extensions.DependencyInjection
.AppendLine("An encryption algorithm cannot be automatically inferred from the encrypting key.")
.Append("Consider using 'options.AddEncryptionCredentials(EncryptingCredentials)' instead.")
.ToString());
static bool IsAlgorithmSupported(SecurityKey key, string algorithm) =>
key.CryptoProviderFactory.IsSupportedAlgorithm(algorithm, key);
}
/// <summary>

3
test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs

@ -1213,8 +1213,7 @@ namespace OpenIddict.Server.FunctionalTests
public async Task HandleCryptographyRequest_UnsupportedSecurityKeysAreIgnored(string algorithm)
{
// Arrange
var factory = Mock.Of<CryptoProviderFactory>(mock => !mock.IsSupportedAlgorithm(algorithm, It.IsAny<SecurityKey>()));
var key = Mock.Of<SecurityKey>(mock => mock.CryptoProviderFactory == factory);
var key = Mock.Of<SecurityKey>(mock => !mock.IsSupportedAlgorithm(algorithm));
await using var server = await CreateServerAsync(options =>
{

127
test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs

@ -168,6 +168,24 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The asymmetric encryption key doesn't contain the required private key.", exception.Message);
}
[Fact]
public void AddEncryptionKey_EncryptingKeyIsCorrectlyAdded()
{
// Arrange
var services = CreateServices();
var builder = CreateBuilder(services);
var key = Mock.Of<SecurityKey>(mock => mock.IsSupportedAlgorithm(SecurityAlgorithms.Aes256KW));
// Act
builder.AddEncryptionKey(key);
var options = GetOptions(services);
// Assert
Assert.Same(key, options.EncryptionCredentials[0].Key);
}
[Fact]
public void RemoveEventHandler_ThrowsAnExceptionWhenDescriptorIsNull()
{
@ -336,27 +354,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal(algorithm, credentials.Algorithm);
}
//[Fact]
//public void AddEncryptingKey_EncryptingKeyIsCorrectlyAdded()
//{
// // Arrange
// var services = CreateServices();
// var builder = CreateBuilder(services);
// var factory = Mock.Of<CryptoProviderFactory>(mock =>
// mock.IsSupportedAlgorithm(SecurityAlgorithms.Aes256KW, It.IsAny<SecurityKey>()));
// var key = Mock.Of<SecurityKey>(mock => mock.CryptoProviderFactory == factory);
// // Act
// builder.AddEncryptingKey(key);
// var options = GetOptions(services);
// // Assert
// Assert.Same(key, options.EncryptingCredentials[0].Key);
//}
[Theory]
[InlineData(SecurityAlgorithms.HmacSha256)]
[InlineData(SecurityAlgorithms.RsaSha256)]
@ -371,10 +368,7 @@ namespace OpenIddict.Server.Tests
var services = CreateServices();
var builder = CreateBuilder(services);
var factory = Mock.Of<CryptoProviderFactory>(mock =>
mock.IsSupportedAlgorithm(algorithm, It.IsAny<SecurityKey>()));
var key = Mock.Of<SecurityKey>(mock => mock.CryptoProviderFactory == factory);
var key = Mock.Of<SecurityKey>(mock => mock.IsSupportedAlgorithm(algorithm));
// Act
builder.AddSigningKey(key);
@ -1035,22 +1029,6 @@ namespace OpenIddict.Server.Tests
Assert.Contains(new Uri("http://localhost/endpoint-path"), options.LogoutEndpointUris);
}
//[Fact]
//public void EnableRequestCaching_RequestCachingIsEnabled()
//{
// // Arrange
// var services = CreateServices();
// var builder = CreateBuilder(services);
// // Act
// builder.EnableRequestCaching();
// var options = GetOptions(services);
// // Assert
// Assert.True(options.EnableRequestCaching);
//}
[Fact]
public void SetRevocationEndpointUris_ThrowsExceptionWhenAddressesIsNull()
{
@ -1494,73 +1472,6 @@ namespace OpenIddict.Server.Tests
Assert.Null(options.RefreshTokenLifetime);
}
//[Fact]
//public void SetRequestCachingPolicy_ThrowsAnExceptionForNullPolicy()
//{
// // Arrange
// var services = CreateServices();
// var builder = CreateBuilder(services);
// // Act and assert
// var exception = Assert.Throws<ArgumentNullException>(() => builder.SetRequestCachingPolicy(null));
// Assert.Equal("policy", exception.ParamName);
//}
//[Fact]
//public void SetRequestCachingPolicy_PolicyIsUpdated()
//{
// // Arrange
// var services = CreateServices();
// var builder = CreateBuilder(services);
// var policy = new DistributedCacheEntryOptions
// {
// AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(42),
// SlidingExpiration = TimeSpan.FromSeconds(42)
// };
// // Act
// builder.SetRequestCachingPolicy(policy);
// var options = GetOptions(services);
// // Assert
// Assert.Same(policy, options.RequestCachingPolicy);
//}
//[Fact]
//public void UseDataProtectionProvider_DefaultProviderIsReplaced()
//{
// // Arrange
// var services = CreateServices();
// var builder = CreateBuilder(services);
// // Act
// builder.UseDataProtectionProvider(new EphemeralDataProtectionProvider());
// var options = GetOptions(services);
// // Assert
// Assert.IsType<EphemeralDataProtectionProvider>(options.DataProtectionProvider);
//}
//[Fact]
//public void UseJsonWebTokens_AccessTokenHandlerIsCorrectlySet()
//{
// // Arrange
// var services = CreateServices();
// var builder = CreateBuilder(services);
// // Act
// builder.UseJsonWebTokens();
// var options = GetOptions(services);
// // Assert
// Assert.IsType<JwtSecurityTokenHandler>(options.AccessTokenHandler);
//}
[Fact]
public void SetIssuer_ThrowsAnExceptionForNullIssuer()
{

Loading…
Cancel
Save