Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CryptographicException while calling /.well-known/openid-configuration (.NET 8) #1534

Closed
Tobias-08 opened this issue Feb 23, 2024 · 14 comments · Fixed by #1535
Closed

CryptographicException while calling /.well-known/openid-configuration (.NET 8) #1534

Tobias-08 opened this issue Feb 23, 2024 · 14 comments · Fixed by #1535
Assignees
Labels
bug Something isn't working
Milestone

Comments

@Tobias-08
Copy link

Which version of Duende IdentityServer are you using?

7.0.1

Which version of .NET are you using?

.NET 8

Describe the bug

Calling /.well-known/openid-configuration leads to CryptographicException: The system cannot find the file specified since we migrated from .NET 6/IdentityServer 6.x to .NET 8/IdentityServer 7.x.

To Reproduce

  • Setup an IdentityServer project in .NET 8 and serve it via IIS with Load user profile: false.
  • Call /.well-known/openid-configuration.

Expected behavior

It should work in .NET 8 even if Load user profile is set to false.

Log output/exception with stacktrace

CryptographicException: The system cannot find the file specified.
System.Security.Cryptography.X509Certificates.CertificatePal.FilterPFXStore(ReadOnlySpan<byte> rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
System.Security.Cryptography.X509Certificates.CertificatePal.FromBlobOrFile(ReadOnlySpan<byte> rawData, string fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
System.Security.Cryptography.X509Certificates.X509Certificate..ctor(ReadOnlySpan<byte> data)
System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(byte[] rawData)
Duende.IdentityServer.Services.KeyManagement.X509KeyContainer.ToSecurityKey() in X509KeyContainer.cs
Duende.IdentityServer.Services.KeyManagement.AutomaticKeyManagerKeyStore+<>c.<GetValidationKeysAsync>b__5_0(KeyContainer x) in AutomaticKeyManagerKeyStore.cs
System.Linq.Enumerable+SelectArrayIterator<TSource, TResult>.Fill(ReadOnlySpan<TSource> source, Span<TResult> destination, Func<TSource, TResult> func)
System.Linq.Enumerable+SelectArrayIterator<TSource, TResult>.ToArray()
Duende.IdentityServer.Services.KeyManagement.AutomaticKeyManagerKeyStore.GetValidationKeysAsync() in AutomaticKeyManagerKeyStore.cs
Duende.IdentityServer.Services.DefaultKeyMaterialService.GetValidationKeysAsync() in DefaultKeyMaterialService.cs
Duende.IdentityServer.ResponseHandling.DiscoveryResponseGenerator.CreateDiscoveryDocumentAsync(string baseUrl, string issuerUri) in DiscoveryResponseGenerator.cs
Duende.IdentityServer.Endpoints.DiscoveryEndpoint.ProcessAsync(HttpContext context) in DiscoveryEndpoint.cs
Duende.IdentityServer.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IdentityServerOptions options, IEndpointRouter router, IUserSession userSession, IEventService events, IIssuerNameService issuerNameService, ISessionCoordinationService sessionCoordinationService) in IdentityServerMiddleware.cs
Duende.IdentityServer.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IdentityServerOptions options, IEndpointRouter router, IUserSession userSession, IEventService events, IIssuerNameService issuerNameService, ISessionCoordinationService sessionCoordinationService) in IdentityServerMiddleware.cs
Duende.IdentityServer.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes) in MutualTlsEndpointMiddleware.cs
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Duende.IdentityServer.Hosting.DynamicProviders.DynamicSchemeAuthenticationMiddleware.Invoke(HttpContext context) in DynamicSchemeAuthenticationMiddleware.cs
Duende.IdentityServer.Hosting.BaseUrlMiddleware.Invoke(HttpContext context) in BaseUrlMiddleware.cs
Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

Additional context

Background:

  • We are running IdentityServer in IIS with an application pool configured with Load user profile: false.
  • This worked in .NET 6 but does not work in .NET 8.
  • It works in .NET 8 if we set Load user profile to true.

Theory:

  • The behaviour of X509Certificate2-constructor might have changed from .NET 6 to .NET 8 so that the workaround (type check) in IdentityServer's X509KeyContainer-implementation for the Load user profile: false-case might not work anymore.
@josephdecock
Copy link
Member

Thanks for the detailed info @Tobias-08. A couple of questions:

  • Are you using automatic key management with the UseX509Certificate enabled, or are you supplying an x509 cert as a manual signing key?
  • Do you need to avoid loading the user profile/is this preventing you from upgrading while we investigate?

@Tobias-08
Copy link
Author

@josephdecock Thanks for your response. Regarding your questions:

  • We are using automatic key management with UseX509Certificate enabled (because we are using RSK's WS-Federation plugin which requires this).
  • We are not in production yet so we are not blocked for the moment.

@AndersAbel
Copy link
Member

This has been asked about before in another support channel. I think that you are right @Tobias-08 that there is a change in behaviour of the constructor. It looks like the exception type thrown has changed in .NET 8 so we might need to update our code to detect the new exception type.

@AndersAbel AndersAbel self-assigned this Mar 6, 2024
@AndersAbel
Copy link
Member

It looks like this is due to a changed behaviour from .NET 7 and up: dotnet/runtime@43c4405

Moving to IdentityServer repo to fix it.

@AndersAbel AndersAbel transferred this issue from DuendeSoftware/Support Mar 20, 2024
@AndersAbel AndersAbel added bug Something isn't working and removed investigating labels Mar 20, 2024
@AndersAbel
Copy link
Member

@brockallen @josephdecock The exception type was changed in .NET 7. So technically we should patch IdSrv 6.x. But end of life for .NET 7 is less than two months away. I think a fix for IdSrv 7.x is enough. What do you think?

@AndersAbel
Copy link
Member

AndersAbel commented Mar 20, 2024

@Tobias-08 Do you think you could help me to get a value out of the exception thrown? I would need the value of CryptographicException.HResult. I assume that it should be 0x80070002 (= -2147024894), but I would like to verify before creating the patch.

@Tobias-08
Copy link
Author

@AndersAbel: Yes, you are right. CryptographicException.HResult is -2147024894.

@AndersAbel
Copy link
Member

@Tobias-08 Thank you!

@AndersAbel
Copy link
Member

@Tobias-08 If we merge this and put out a preview on Nuget, would you be able to help us test it?

@brockallen Could we merge this and put out another preview on 7.0.2 to get it tested in a proper environment? It's obviously not testable on a local development setup because the user profile is always available then.

@Tobias-08
Copy link
Author

@AndersAbel Yes, of course.

@brockallen brockallen modified the milestones: 7.0.2, 7.0.3 Mar 20, 2024
@brockallen
Copy link
Member

We're working on putting out a 7.0.3-preview.1 to test.

@brockallen
Copy link
Member

We've pushed a 7.0.3-preview.1 to NuGet with the proposed fix. Please have a look and let us know how it works. Thanks.

@Tobias-08
Copy link
Author

@brockallen @AndersAbel 7.0.3-preview.1 works as expected in my setup, i. e. it works with .NET 8 and Load user profile: false.

Thanks!

@brockallen
Copy link
Member

7.0.3 Has been pushed to NuGet. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants