diff --git a/Directory.Packages.props b/Directory.Packages.props index b06aac47..57174936 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,8 +6,8 @@ - - + + diff --git a/src/OpenIddict.Server/OpenIddictServerBuilder.cs b/src/OpenIddict.Server/OpenIddictServerBuilder.cs index 9a9fc12a..80006457 100644 --- a/src/OpenIddict.Server/OpenIddictServerBuilder.cs +++ b/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); } /// @@ -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); } /// diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs index 0598d175..62f5afff 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs +++ b/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); diff --git a/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs b/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs index f8695ff6..1576b7b8 100644 --- a/src/OpenIddict.Validation/OpenIddictValidationBuilder.cs +++ b/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); } /// diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs index 3a220d85..6ba83632 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs +++ b/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(mock => !mock.IsSupportedAlgorithm(algorithm, It.IsAny())); - var key = Mock.Of(mock => mock.CryptoProviderFactory == factory); + var key = Mock.Of(mock => !mock.IsSupportedAlgorithm(algorithm)); await using var server = await CreateServerAsync(options => { diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs index 3f244487..61fcf1f7 100644 --- a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs +++ b/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(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(mock => - // mock.IsSupportedAlgorithm(SecurityAlgorithms.Aes256KW, It.IsAny())); - - // var key = Mock.Of(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(mock => - mock.IsSupportedAlgorithm(algorithm, It.IsAny())); - - var key = Mock.Of(mock => mock.CryptoProviderFactory == factory); + var key = Mock.Of(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(() => 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(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(options.AccessTokenHandler); - //} - [Fact] public void SetIssuer_ThrowsAnExceptionForNullIssuer() {