Fix | Perform ServerCertificate pin validation to verify with server provided cert - #4445
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refines Managed SNI’s TLS server-certificate validation so the ServerCertificate connection-string keyword behaves as an explicit certificate pin (and updates docs/tests to reflect the intended semantics).
Changes:
- Tightens the “
policyErrors == None” fast path so it only applies when noServerCertificatepin is provided. - Changes pin-load failures to fail closed by throwing an authentication exception.
- Adds unit tests for pin vs. no-pin behavior and updates documentation to clarify “additive” pinning semantics.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ManagedSni/SniCommon.netcore.cs |
Adjusts certificate-validation control flow for pin handling and fail-closed behavior. |
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/ManagedSni/SniCommonValidateSslServerCertificateTest.cs |
Adds unit coverage for SniCommon.ValidateSslServerCertificate pin/no-pin scenarios. |
doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml |
Documents ServerCertificate as an additive check (pin + standard validation). |
doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml |
Expands connection-string keyword docs to clarify additive pinning and fail-closed behavior. |
cheenamalhotra
force-pushed
the
dev/cheena/server-cert-fix
branch
from
July 14, 2026 00:58
3a048c7 to
59524a6
Compare
cheenamalhotra
force-pushed
the
dev/cheena/server-cert-fix
branch
from
July 14, 2026 01:04
59524a6 to
e5a2542
Compare
paulmedynski
previously requested changes
Jul 14, 2026
|
This pull request has been marked as stale due to inactivity for more than 30 days. If you would like to keep this pull request open, please provide an update or respond to any comments. Otherwise, it will be closed automatically in 7 days. |
- Perform ServerCertificate pin validation after chain/name policy error handling, making the additive semantics explicit in control flow. - Extract ValidateCertificatePin/LoadValidationCertificate helpers so the loaded pin certificate lives in a narrow 'using' scope (no try/finally). - Guard against a null server certificate in the pin path. - Clarify method docs on the policyErrors relationship and reword the no-pin fast-path trace message. - Replace ambiguous 'platform trust' wording in docs with chain-and-name validation, and note that pinning does not itself confer trust. - Add TempCertFile disposable test helper and a null-server-cert regression test for the policyErrors == None case. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Sep 15, 2026
Closed
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Refines the managed SNI certificate-validation helper so that the
ServerCertificateconnection-string keyword behaves consistently with its documented "exact match" semantic.Address internal item AB#46371
Two small refinements in
SniCommon.ValidateSslServerCertificate. The existing design is unchanged: an exactServerCertificatematch still satisfies certificate validation.policyErrors == SslPolicyErrors.Nonenow also requiresvalidationCertFileNameto be null/empty. When the caller has supplied aServerCertificate, the helper always compares it against the presented server certificate — previously it was skipped entirely whenever the platform reported no policy errors. The no-pin fast path is unchanged.SSLCertificateAuthenticationExceptionnaming the configured path, instead of silently discarding the option and falling back to host-name validation — matching the caller's explicit intent.Additionally, two defects surfaced in review:
X509Certificateis now disposed via a narrowusingscope (it owns unmanaged resources).AuthenticationExceptionrather than aNullReferenceExceptionfrom the raw-bytes comparison.The
TrustServerCertificate=trueshort-circuit on the transport handles is unchanged — when validation is disabled at that layer,ServerCertificateremains unconsulted, matching the existing semantic.Backwards compatibility
ServerCertificatesupplied → identical behavior.ServerCertificatesupplied, well-formed, and matches → identical behavior, including when the presented certificate would otherwise fail chain validation (for example a self-signed or private-CA certificate). This scenario deliberately continues to work.ServerCertificatesupplied and the file is missing/unreadable, or it doesn't match the server cert → now throwsSSLCertificateAuthenticationExceptionat handshake, aligning runtime with the documented "exact match" contract. Both cases previously risked accepting a connection the caller intended to restrict.Testing
Added
SniCommonValidateSslServerCertificateTest, which exercisesSniCommon.ValidateSslServerCertificatedirectly. Both the TCP and Named Pipes transports call into this same helper, so no transport-specific parameterization is needed.PolicyErrors.NonetruePolicyErrors.NonetruePolicyErrors.RemoteCertificateChainErrorstrue(exact match satisfies validation)PolicyErrors.NoneAuthenticationExceptionPolicyErrors.RemoteCertificateChainErrorsAuthenticationExceptionPolicyErrors.RemoteCertificateNotAvailableAuthenticationExceptionPolicyErrors.NoneAuthenticationExceptionPolicyErrors.NoneAuthenticationExceptionLocal run on
net9.0: 8 passed / 0 failed.Guidelines
Reviewed: