Skip to content

Add API to control trust during TLS handshake #54219

Closed
@wfurt

Description

@wfurt

Background and Motivation

This was originally requested as #45456 (pri-1) to get parity with IIS/http.sys. After iterations with @bartonjs this was slightly extended to solve few more problems related to managing trust with TLS/SSL handshake. This will allow us to partition trust for multi-tenant services when one service may trust different set of certificates then other.

Proposed API

namespace System.Net.Security
{
    public sealed class SslStreamCertificateContext
    {
       public static SslStreamCertificateContext Create(
                                 X509Certificate2 target, 
                                 X509Certificate2Collection? additionalCertificates, 
                                 bool offline = false);
+      public static SslStreamCertificateContext CreateWithTrust( 
+                                  X509Certificate2 target,  
+                                  X509Certificate2Collection? additionalCerts,  
+                                  SslCertificateTrust trust,  
+                                  bool offline = false);
    }

+   public sealed class SslCertificateTrust
+   {
+       public static SslCertificateTrust CreateForX509Store(
+                                               X509Store store, 
+                                               X509ChainTrustMode trustMode = X509ChainTrustMode.CustomRootTrust,
+                                               bool sendTrustInHandshake = false );
+
+       [UnsupportedPlatform("windows")]
+       public static SslCertificateTrust CreateForX509Collection(
+                                               X509Certificate2Collection trustList,
+                                               X509ChainTrustMode trustMode = X509ChainTrustMode.CustomRootTrust,
+                                               bool sendTrustInHandshake = false );
+  }
}

Alternative design

We originally started with something like:

public static SslStreamCertificateContext CreateWithTrust(
  X509Certificate2 target,
  X509Certificate2Collection? additionalCerts,
  X509ChainTrustMode trustMode,
  X509Certificate2Collection? customTrustStore,
  bool offline = false,
  bool sendTrustInHandshake = false);

however, on Windows we are not able to support collection for sending trust at this moment (and it it is not clear if we ever will).

For the SslCertificateTrust we may use constructor with overlords. It is not clear if we can annotate the platforms and if it is desirable to throw in constructor. As mentioned above, on Windows we cannot support collection so we will throw PNSP. The certificate stores are restricted to System location only and we will throw if user or custom store is passed in.

Risk

The main risk comes from Windows support. While the main ask is to mimic existing behavior so it is possible to migrate to Kestrel, the available API is sub-optimal. Originally, this is was available only in Kernel mode and that what brings restriction to System certificate stores. (in memory stores or anything else is not possible). Also the behavior to send the trust list in handshake is controlled by global Windows registry. We will need to document this and most likely ignore the setting. Support for same feature in user mode is in some private builds and there is official request to back port it to Server 2019. Note that this applies only the the ability to advertise the trust. We can internally take certificate collection and we can pass it to X509Chain and calculate trust accordingly.

The other part is not specific to tis proposal. When SslStreamCertificateContext was created it basically sealed blob that is used internally in SslStream. However, in 6.0 we will also support SslOptions in System.Net.Quick. For now we use reflection to do that and that is not optimal - see #53507. At some point we may need to add properties to expose internal state and passed parameters.

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Net.SecurityblockingMarks issues that we want to fast track in order to unblock other important work

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions