Runtime: X509Certificate2: Unclear error message when permission denied to file

Created on 5 Nov 2017  路  9Comments  路  Source: dotnet/runtime

If the user running an ASP.NET Core app on Linux does not have permission to access the PFX file, this confusing error message is thrown:

Unhandled Exception: Interop+Crypto+OpenSslCryptographicException: error:2006D002:BIO routines:BIO_new_file:system lib
   at Interop.Crypto.CheckValidOpenSslHandle(SafeHandle handle)
   at Internal.Cryptography.Pal.CertificatePal.FromFile(String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags)
   at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password)
   at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, String fileName, String password)
   at SecureSign.Web.Program.<>c__DisplayClass1_0.<BuildWebHost>b__2(ListenOptions listenOptions) in C:\src\SecureSign\src\SecureSign.Web\Program.cs:line 53
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPEndPoint endPoint, Action`1 configure)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServerOptions.Listen(IPAddress address, Int32 port, Action`1 configure)
   at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.CreateServiceContext(IOptions`1 options, ILoggerFactory loggerFactory)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer..ctor(IOptions`1 options, ITransportFactory transportFactory, ILoggerFactory loggerFactory)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureServer()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at SecureSign.Web.Program.Main(String[] args) in C:\src\SecureSign\src\SecureSign.Web\Program.cs:line 20

Can this be improved to explain what the error actually is?

area-System.Security

Most helpful comment

Had the same error with ASP.NET Core 3.1. The certificate was not in the folder.

version: '3.4'

services:
  webapp:
    image: aspnetcoreimg
    ports:
      - 80
      - 443
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=password
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro

Generated a dev cert with :

dotnet dev-certs https -ep ${home}\.aspnet\https\aspnetapp.pfx -p password

Then everything succedded :

webapp_1  | info: IdentityServer4.Startup[0]
webapp_1  |       Starting IdentityServer4 version 3.0.0.0
webapp_1  | info: IdentityServer4.Startup[0]
webapp_1  |       Using explicitly configured authentication scheme Identity.Application for IdentityServer
webapp_1  | info: Microsoft.Hosting.Lifetime[0]
webapp_1  |       Now listening on: https://[::]:443

A check before a call to OpenSsl could be done as it is a Kestrel environnent variable
ASPNETCORE_Kestrel__Certificates__Default__Path.
Then a

FileNotFoundException("The certificate file was not found in {certPath}.")

All 9 comments

@bartonjs have we considered trying to add our own messages for any OpenSsl error codes ? It looks like some of the messages that it gives us are not very readable. It seems this one is an expected message.

Our current position is that we do not want to be in the way of interpreting error codes, either from Windows or from OpenSSL (or from Security.framework).

Certainly, user feedback can help us decide that we want to get into a new position... but our current position is "considered, and rejected".

It might be worth asking OpenSSL whether they could make their messages more readable, but I'm guessing they're happy with it.

Our current position is that we do not want to be in the way of interpreting error codes,

That is unfortunate... How is anyone supposed to know that "error:2006D002:BIO routines:BIO_new_file:system lib" means "access denied"? It also introduces inconsistency across platforms, in that certificate-related exceptions on Windows are totally different than on other languages ;(

@daniel15 is there a list of common such errors you can find, e.g. In the OpenSSL sources? Also is their numeric code stable?

I have no idea, sorry. I'm not very familiar with the OpenSSL codebase.

Just wanted to say that this issue helped me figure out what was wrong.
馃憤 for clearer message.

Got this when I failed to set execute flag.

Had the same error with ASP.NET Core 3.1. The certificate was not in the folder.

version: '3.4'

services:
  webapp:
    image: aspnetcoreimg
    ports:
      - 80
      - 443
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=https://+:443;http://+:80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=password
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes:
      - ~/.aspnet/https:/https:ro

Generated a dev cert with :

dotnet dev-certs https -ep ${home}\.aspnet\https\aspnetapp.pfx -p password

Then everything succedded :

webapp_1  | info: IdentityServer4.Startup[0]
webapp_1  |       Starting IdentityServer4 version 3.0.0.0
webapp_1  | info: IdentityServer4.Startup[0]
webapp_1  |       Using explicitly configured authentication scheme Identity.Application for IdentityServer
webapp_1  | info: Microsoft.Hosting.Lifetime[0]
webapp_1  |       Now listening on: https://[::]:443

A check before a call to OpenSsl could be done as it is a Kestrel environnent variable
ASPNETCORE_Kestrel__Certificates__Default__Path.
Then a

FileNotFoundException("The certificate file was not found in {certPath}.")
Was this page helpful?
0 / 5 - 0 ratings