-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add CertificateChainPolicy to ssl options #71961
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/ncl, @vcsjones Issue DetailsThis is replacement for #69908 This adds API approved in #71191 so callers of SslStream can specify custom X509ChainPolicy to specify custom trust, AIA download behavior or other options available in X509ChainPolicy. Unlike original PoC there is no attempt to enforce consistency with other validation fragments. When custom policy is specified it will be used exclusively instead of fragments we currently use to construct it it internally. TODO: This changes only SslStream. I will follow-up with PR for QUIC once the code there is stable. (#71783 done)
|
src/libraries/System.Net.Security/src/System/Net/Security/SslClientAuthenticationOptions.cs
Outdated
Show resolved
Hide resolved
/// </summary> | ||
public X509ChainPolicy? ValidationPolicy { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties are supposed to have both a summary and a value tag.
https://github.com/dotnet/dotnet-api-docs/wiki/Property-Value
/// </summary> | |
public X509ChainPolicy? ValidationPolicy { get; set; } | |
/// </summary> | |
/// <value> | |
/// An optional customized policy for certificate chain validation. | |
/// The default is <see langword="null" />. | |
/// </value> | |
public X509ChainPolicy? ValidationPolicy { get; set; } |
src/libraries/System.Net.Security/src/System/Net/Security/SslClientAuthenticationOptions.cs
Outdated
Show resolved
Hide resolved
/// Specifies X509ChainPolicy to use for remote certificate | ||
/// validation. If set, CertificateRevocationCheckMode and SslCertificateTrust is ignored. | ||
/// </summary> | ||
public X509ChainPolicy? ValidationPolicy { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the feedback from the API docs for the client version also applies here.
if (_sslAuthenticationOptions.ValidationPolicy.VerificationTimeIgnored) | ||
{ | ||
chain.ChainPolicy.CustomTrustStore.AddRange(trust._store.Certificates); | ||
// Update VerificationTime to 'Now' unless explicitly set for whatever reason. | ||
chain.ChainPolicy.VerificationTime = DateTime.Now; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (VerificationTime acting as DateTime.Now when VerificationTimeIgnored is set) should be an implementation detail of X509Chain, not acted upon here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line 136 in c9feedf
chainPolicy.VerificationTime, |
Change
-chainPolicy.VerificationTime,
+chainPolicy.VerificationTimeIgnored ? DateTime.Now : VerificationTime,
src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs
Outdated
Show resolved
Hide resolved
...m.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs
Outdated
Show resolved
Hide resolved
...m.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs
Outdated
Show resolved
Hide resolved
...m.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs
Outdated
Show resolved
Hide resolved
|
||
public X509ChainPolicy Clone() | ||
{ | ||
return (X509ChainPolicy)MemberwiseClone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want this written by hand.
return (X509ChainPolicy)MemberwiseClone(); | |
X509ChainPolicy clone = new X509ChainPolicy | |
{ | |
DisableCertificateDownloads = DisableCertificateDownloads, | |
_revocationMode = _revocationMode, | |
_revocationFlag = _revocationFlag, | |
_verificationFlags = _verificationFlags, | |
_trustMode = _trustMode, | |
_verificationTime = _verificationTime, | |
VerificationTimeIgnored = VerificationTimeIgnored, | |
UrlRetrievalTimeout = UrlRetrievalTimeout, | |
}; | |
if (_applicationPolicy?.Count > 0) | |
{ | |
clone.ApplicationPolicy.AddRange(_applicationPolicy); | |
} | |
if (_certificatePolicy?.Count > 0) | |
{ | |
... | |
} | |
if (_customTrustStore?.Count > 0) | |
{ | |
... | |
} | |
} |
And then in tests, Assert.NotSame(orig.ApplicationPolicy, clone.ApplicationPolicy);
and Assert.Equal(orig.ApplicationPolicy, clone.ApplicationPolicy);
(and similar for the other collections)
...m.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509ChainPolicy.cs
Outdated
Show resolved
Hide resolved
…lientAuthenticationOptions.cs Co-authored-by: Jeremy Barton <jbarton@microsoft.com>
Co-authored-by: Jeremy Barton <jbarton@microsoft.com>
foreach (var item in _applicationPolicy) | ||
{ | ||
clone.ApplicationPolicy.Add(item); | ||
} | ||
} | ||
|
||
if (_certificatePolicy?.Count > 0) | ||
{ | ||
foreach (var item in _certificatePolicy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These shouldn't be var
, and there should be some tests for clone, but those can get done as a followup if the tests are all green.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor issues, but nothing worth missing the branch over.
Added When you commit this breaking change:
Tagging @dotnet/compat for awareness of the breaking change. |
(Waiting on sending the mail until we actually merge) |
Thanks @bartonjs. Is this breaking because of the time change in |
Yep.
Did that prior to merging it in 😄 |
ChainPolicy.ExtraStore is written into by GetRemoteCertificate as part of establishing connections. If the caller now provides an X509ChainPolicy instance with this feature, doesn't that mean we're then storing into that shared ExtraStore each time? Which would have implications on thread-safety (multiple connections all calling GetRemoteCertificate concurrently and adding to this non-thread-safe collection concurrently), memory leaks (unbounded additions to that ExtraStore each time a new connection is created / the remote is validated), and potentially security issues with the cert from one connection being then used as part of validation / chain building for another connection? |
@bartonjs pointed out to me offline that we always clone the policy and ensure the clone is only used once. |
This is replacement for #69908
fixes #71191 #59979 #35839 #59944 #40423
This adds API approved in #71191 so callers of SslStream can specify custom X509ChainPolicy to specify custom trust, AIA download behavior or other options available in X509ChainPolicy.
Unlike original PoC there is no attempt to enforce consistency with other validation fragments. When custom policy is specified it will be used exclusively instead of fragments we currently use to construct it it internally.
TODO: This changes only SslStream. I will follow-up with PR for QUIC once the code there is stable. (#71783 done)