Skip to content

Kestrel support for "path based" TLS renegotiation. #23948

Closed

Description

@avparuch

Is your feature request related to a problem? Please describe.

We have a reverse proxy running on ASP.NET Core, hosted in IIS in-process. During the initial TLS handshake with the client, the server is configured to not ask for a client certificate. However, if the path of the request contains, say "pksecure", IIS triggers a TLS renegotiation and sends a client certificate request.

The following configuration in IIS is how it works:

<location path="pksecure">
    <system.webServer>
      <security>
        <access sslFlags="Ssl, SslNegotiateCert, SslRequireCert"/>
      </security>
    </system.webServer>
</location>

Describe the solution you'd like

We would like Kestrel to have the same capability. This is supported on IIS, both in ASP.NET Core and ASP.NET

Additional context

Add any other context or screenshots about the feature request here.

Activity

  1. Tratcher commented on Jul 15, 2020

    @Tratcher
    Member

    That feature is outdated and will not be added to kestrel.

    See the following doc for an alternative.
    https://docs.microsoft.com/en-us/aspnet/core/security/authentication/certauth?view=aspnetcore-3.1#optional-client-certificates

  2. avparuch commented on Jul 15, 2020

    @avparuch
    ContributorAuthor

    The linked document does not capture the same scenario. The recommendation there is using a separate hostname to mimic optional client certificates. However, the required scenario is the ability to keep the hostname the same and however renegotiate TLS based on path. The renegotiation of TLS is necessary because path is a http construct and the initial TLS handshake is already done by then and we are choosing to change the parameters of TLS based on http constructs.

  3. Tratcher commented on Jul 15, 2020

    @Tratcher
    Member

    That model isn't going to work anymore, renegotiation is obsolete in modern protocols. It's prohibited by the HTTP/2 spec and has been complete removed from TLS 1.3 (HTTP/3 & QUIC).

    Even in HTTP/1.1 it was problematic. It could cause a POST request to deadlock if the request body filled up the TCP window and blocked the renegotiate packets.

    The proposal outlined in the linked doc should work with all existing implementations and protocols. I understand that it will require some application redesign, but you'll need to address that in the long term anyways.

  4. avparuch commented on Jul 15, 2020

    @avparuch
    ContributorAuthor

    Makes sense. I didn't know it was prohibited by Http/2. This is a good thing, this gives us leverage when talking to partners to put this pattern on the deprecation path.

  5. Tratcher commented on Jul 16, 2020

    @Tratcher
    Member

    Interestingly TLS 1.3 does define a new way to request the client certificate after the connection has been established, it's called post-handshake authentication. https://tools.ietf.org/html/rfc8446#section-4.6.2

    However, this feature is also explicitly prohibited for use with HTTP/2 https://tools.ietf.org/html/rfc8740#section-3. I wonder if HTTP/3 will support it.

    Either way, it's still better to use a strategy that works across all versions.

  6. ghost locked as resolved and limited conversation to collaborators on Aug 15, 2020
  7. added
    blockedThe work on this issue is blocked due to some dependency
    and removed
    ✔️ Resolution: AnsweredResolved because the question asked by the original author has been answered.
    on Mar 9, 2021
  8. 6 remaining items

  9. Tratcher commented on Apr 27, 2021

    @Tratcher
    Member

    The existing GetClientCertificateAsync API should cover it.

    public Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken)

  10. davidfowl commented on Apr 27, 2021

    @davidfowl
    Member

    Will the sync API be blocking? I think it should return null.

  11. Tratcher commented on Apr 27, 2021

    @Tratcher
    Member

    Will the sync API be blocking? I think it should return null.

    The property will return the current value, if any. That's how HttpSys works now.

  12. Tratcher commented on Apr 27, 2021

    @Tratcher
    Member

    HttpSys does have one other API controlling this:

    /// <summary>
    /// The TLS session can be renegotiated to request a client certificate.
    /// </summary>
    AllowRenegotation

  13. Tratcher commented on Apr 27, 2021

    @Tratcher
    Member

    @davidfowl raises a good point that people using the cert auth handler will still have to be careful not to deadlock POST requests for the reasons outlined above, auth runs before model binding consumes the request body. We'll want to consider mitigations to at least make it fail instead of deadlock.

  14. self-assigned this
    on May 28, 2021
  15. Tratcher commented on May 28, 2021

    @Tratcher
    Member

    Here's Kestrel's current implementation:

    public Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken)
    {
    return Task.FromResult(ClientCertificate);
    }

    And here's where the client cert is currently assigned:

    feature.ClientCertificate = ConvertToX509Certificate2(sslStream.RemoteCertificate);

    It may be interesting to note that a renegotiation may cause some/all of these other fields to change:

    feature.CipherAlgorithm = sslStream.CipherAlgorithm;
    feature.CipherStrength = sslStream.CipherStrength;
    feature.HashAlgorithm = sslStream.HashAlgorithm;
    feature.HashStrength = sslStream.HashStrength;
    feature.KeyExchangeAlgorithm = sslStream.KeyExchangeAlgorithm;
    feature.KeyExchangeStrength = sslStream.KeyExchangeStrength;
    feature.Protocol = sslStream.SslProtocol;

  16. davidfowl commented on May 28, 2021

    @davidfowl
    Member

    Cache that allocation 😄

  17. removed
    blockedThe work on this issue is blocked due to some dependency
    on Jun 3, 2021
  18. added
    area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions
    and removed on Jun 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsfeature-kestrelpartnerPartner ask

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions