Skip to content

joacar/ancc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ASP.NET Core Certificate

Trying to get my head around mTLS and client certificate authentication.

Mutual TLS

  1. Application owner generates a root certificate
  2. Generated root certificate is used to generate a server certificate
  3. Generated root certificate is used to generate a client certificate
  4. Client certificate is sent to client to grant access to application

Could it possibly be used like this

  1. Application owner generates a root certificate
  2. Generated root certificate is used to generate a server certificate
  3. Client sends a certificate to be signed by root certificate
  4. Signed client certificate is used to grant access to application

TODOS

  • Instruct IIS Express to use server certificate and thus only accept client certificates issued by server certificate.
  • Instruct Kestrel only accept client certificates signed by/issued by server certificate. Is this m-TLS?

Observations

  • CertificateAuthenticationEvents.OnCertificateValidated is not called if app.UseAuthentication() is missing.
  • If revocation check fails the user can navigate to Home.

Certificates

  1. Run file certcrt.cmd and follow the instructions
  2. Import client certificate to Current User\Personal. This is usually done during creation.
    1. Windows+R
    2. Type certmgr.exe then enter
    3. Right click Personal
    4. All Tasks > Import
    5. Select the generated .cer client file
  3. Import server certificate to Local Computer\Trusted Root Certitificates Authorities
    1. Windows+R
    2. Type certlm.exe then Ctrl+Shift+Enter (start as admin)
    3. Right click Trusted Root Certitificates Authorities
    4. All Tasks > Import
    5. Select the generated .cer file
  4. Import certificate revocation list. Same as above but select .crl file

Kestrel

Follow the steps in Application to setup authentication.

The certificate and password are read from environment variables and I've created a function to read them and create the certificate used for the server.

private static X509Certificate2 CreateServerCertificate()
{
    // Error handling removed for brevity
    const string envFilePath = "ASPNETCORE_Kestrel__Certificates__Default__Path";
    const string envPassword = "ASPNETCORE_Kestrel__Certificates__Default__Password";
    var cert = var password = Environment.GetEnvironmentVariable(envFilePath);
    var password = Environment.GetEnvironmentVariable(envPassword);
    return new X509Certificate2(cert, password);
}

We need to configure Kestrel to request client certificate and we must provide a server certificate used to validate the client certificate. This is configured when the host is built, in this case in Program.cs.

webBuilder
    .UseStartup<Startup>()
    .ConfigureKestrel(options =>
    {
        options.ConfigureHttpsDefaults(https =>
        {
            https.ClientCertificateValidation += (certificate2, chain, errors) =>
            {
                // Perform any checks here
                return true;
            };
            https.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
            https.ServerCertificate = CreateServerCertificate();
        });
    });

Is the above the mTLS part? Then the certificate authentication might not be needed if another security scheme is employed, example OAuth2 Client Credentials grant with bearer token. I would like to see that only client certificates signed by/issued by the server certificate are allowed to connect.

Observations

  • Should Kestrel configure server certificate automatically if present with values in ASPNETCORE_Kestrel__Certificates__Default__{Path,Password}?

    It does, but the value in HttpsConnectionAdapterOptions.ServerCertificate is not accessible.

  • How to ensure that only client certificates signed by/issued by server certificate are allowed?

Issues

The specified network password is not correct

I saw this when I specified only file name in ASPNETCORE_Kestre__..Path and moved pfx to bin\Debug\netcoreapp3.1\. Trying it again later correctly shows The specified file couldn't be found. Check that the .pfx files are imported and not only .cer - maybe.

IIS/IIS Express

Run file iis.cmd to update relevant configuration sections. The section iisClientCertificateMappingAuthentication must be enabled and the section access should have sslFlags set to "Ssl, SslNegotiateCert, SslRequireCert"`.

Application

  1. Add Microsoft.AspNetCore.Authentication.Certificate nuget package

  2. Configure authentication protocol

    services
         .AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
         .AddCertificate(options =>
         {
             options.AllowedCertificateTypes = CertificateTypes.All;
             options.Events = new CertificateAuthenticationEvents
             {
                 OnCertificateValidated = context =>
                 {
                     // Do validation on context.Certificate here
                     return Task.CompletedTask;
                 },
                 OnAuthenticationFailed = context =>
                 {
    
                     return Task.CompletedTask;
                 }
             };
         });
  3. Add app.UseAuthentication() before app.UseAuthorization() to hook into CertificateAuthenticationEvents.OnCertificateValidated. This is never called otherwise, leaving open for any certificate.

ISSUES

HTTP Error 403.16 - Forbidden Your client certificate is either not trusted or is invalid.

See certificates step 2.

Warning: Certificate validation failed, subject was CN=ancc_client. RevocationStatusUnknown The revocation function was unable to check revocation for the certificate.

See certificates step 3 or disable recovation check options.RevocationMode = X509RevocationMode.NoCheck

Thanks to

About

Adventures in ASP.NET Core Certificates management and authentication

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published