Consider support for SNI certificate selection from X509Store
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
This is something that came up in YARP (https://github.com/microsoft/reverse-proxy/issues/86).
We should consider an "automatic" certificate selection option in Kestrel to select certificates from `X509Store` based on the server name in the SNI store.
The design proposed by @davidni in the YARP issue is something like this:
1. A background task periodically scans all _reasonable_ certs from a given cert store. More on what is a _reasonable_ cert below
2. Extract all SAN entries from each _reasonable_ cert, and build a dictionary mapping acceptable host names to certs. Wildcard entries are supported per [RFC6125 section 6.4.3](https://tools.ietf.org/html/rfc6125#section-6.4.3).
3. Deterministic logic selects the _best_ cert for a host name out of all available certs. More on the definition of _best_ below.
4. When any changes are detected, atomically swap the old dictionary with the new one
5. We expose an interface that can be called from Kestrel's server cert selection callback to produce the appropriate cert for a given host name, or `null` if none match. Cert selection is always O(1) w.r.t number of bound host names, including for wildcard matches.
With "reasonable" and "best" defined as:
* Definition of _reasonable_ cert: Similar to Kestrel's existing logic:
* `1.3.6.1.5.5.7.3.1` Enhanced Key Usage oid when the extension is present
* Private key is available
* Additional validity + revocation checks. we call `X509Certificate2.Verify()` to also check for revocation, whereas `X509CertificateStore.Find(... validOnly: true)` (used in Kestrel's defaults) does not check revocation.
* Definition of _best_ cert: The most recently-issued certificate that is _reasonable_.
Contributor guide
Assessment
This issue has not been assessed yet.