Skip to content

Commit 5e18eb1

Browse files
committed
Address comments and renamed serverCert to serverCertificateFilename
1 parent c4512d3 commit 5e18eb1

File tree

10 files changed

+162
-66
lines changed

10 files changed

+162
-66
lines changed

doc/snippets/Microsoft.Data.SqlClient/SqlConnection.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ End Module
542542
|Failover Partner|N/A|The name of the failover partner server where database mirroring is configured.<br /><br /> If the value of this key is "", then **Initial Catalog** must be present, and its value must not be "".<br /><br /> The server name can be 128 characters or less.<br /><br /> If you specify a failover partner but the failover partner server is not configured for database mirroring and the primary server (specified with the Server keyword) is not available, then the connection will fail.<br /><br /> If you specify a failover partner and the primary server is not configured for database mirroring, the connection to the primary server (specified with the Server keyword) will succeed if the primary server is available.|
543543
|Failover Partner SPN<br /><br /> -or-<br /><br /> FailoverPartnerSPN|N/A|The SPN for the failover partner. The default value is an empty string, which causes SqlClient to use the default, driver-generated SPN.<br /><br /> (Only available in v5.0+)|
544544
|Host Name In Certificate<br /><br /> -or-<br /><br />HostNameInCertificate|N/A|The host name to use when validating the server certificate. When not specified, the server name from the Data Source is used for certificate validation.<br /><br /> (Only available in v5.0+)|
545-
|Server Certificate<br /><br /> -or-<br /><br />ServerCertificate|N/A|The path to a certificate file to match against the SQL Server TLS/SSL certificate. The accepted certificate formats are PEM, DER, and CER. If specified, the SQL Server certificate is checked by seeing if the ServerCertificate provided is an exact match.<br /><br /> (Only available in v5.0+)|
545+
|Server Certificate<br /><br /> -or-<br /><br />ServerCertificate|N/A|The path to a certificate file to match against the SQL Server TLS/SSL certificate. The accepted certificate formats are PEM, DER, and CER. If specified, the SQL Server certificate is checked by verifying if the ServerCertificate provided is an exact match.<br /><br /> (Only available in v5.0+)|
546546
|Initial Catalog<br /><br /> -or-<br /><br /> Database|N/A|The name of the database.<br /><br /> The database name can be 128 characters or less.|
547547
|Integrated Security<br /><br /> -or-<br /><br /> Trusted_Connection|'false'|When `false`, User ID and Password are specified in the connection. When `true`, the current Windows account credentials are used for authentication.<br /><br /> Recognized values are `true`, `false`, `yes`, `no`, and `sspi` (strongly recommended), which is equivalent to `true`.<br /><br /> If User ID and Password are specified and Integrated Security is set to true, the User ID and Password will be ignored and Integrated Security will be used.<br /><br /> <xref:Microsoft.Data.SqlClient.SqlCredential> is a more secure way to specify credentials for a connection that uses SQL Server Authentication (`Integrated Security=false`).|
548548
|IP Address Preference<br /><br /> -or-<br /><br /> IPAddressPreference|IPv4First|The IP address family preference when establishing TCP connections. If `Transparent Network IP Resolution` (in .NET Framework) or `Multi Subnet Failover` is set to true, this setting has no effect. Supported values include:<br /><br /> `IPAddressPreference=IPv4First`<br /><br />`IPAddressPreference=IPv6First`<br /><br />`IPAddressPreference=UsePlatformDefault`|

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ internal static bool ValidateSslServerCertificate(string targetServerName, X509C
200200
/// Certificate validation and chain trust validations are done by SSLStream class [System.Net.Security.SecureChannel.VerifyRemoteCertificate method]
201201
/// This method is called as a result of callback for SSL Stream Certificate validation.
202202
/// </summary>
203-
/// <param name="clientCert">X.509 server certificate provided by the client</param>
204-
/// <param name="serverCert">X.509 certificate provuded by the server</param>
203+
/// <param name="clientCert">X.509 certificate provided by the client</param>
204+
/// <param name="serverCert">X.509 certificate provided by the server</param>
205205
/// <param name="policyErrors">Policy errors</param>
206206
/// <returns>True if certificate is valid</returns>
207207
internal static bool ValidateSslServerCertificate(X509Certificate clientCert, X509Certificate serverCert, SslPolicyErrors policyErrors)

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode)
144144
/// <param name="pendingDNSInfo">Used for DNS Cache</param>
145145
/// <param name="tlsFirst">Support TDS8.0</param>
146146
/// <param name="hostNameInCertificate">Used for the HostName in certificate</param>
147-
/// <param name="serverCert">Used for the path to the Server Certificate</param>
147+
/// <param name="serverCertificateFilename">Used for the path to the Server Certificate</param>
148148
/// <returns>SNI handle</returns>
149149
internal static SNIHandle CreateConnectionHandle(
150150
string fullServerName,
@@ -162,7 +162,7 @@ internal static SNIHandle CreateConnectionHandle(
162162
ref SQLDNSInfo pendingDNSInfo,
163163
bool tlsFirst,
164164
string hostNameInCertificate,
165-
string serverCert)
165+
string serverCertificateFilename)
166166
{
167167
instanceName = new byte[1];
168168

@@ -189,7 +189,7 @@ internal static SNIHandle CreateConnectionHandle(
189189
case DataSource.Protocol.None: // default to using tcp if no protocol is provided
190190
case DataSource.Protocol.TCP:
191191
sniHandle = CreateTcpHandle(details, timerExpire, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo,
192-
tlsFirst, hostNameInCertificate, serverCert);
192+
tlsFirst, hostNameInCertificate, serverCertificateFilename);
193193
break;
194194
case DataSource.Protocol.NP:
195195
sniHandle = CreateNpHandle(details, timerExpire, parallel, tlsFirst);
@@ -288,7 +288,7 @@ private static byte[][] GetSqlServerSPNs(string hostNameOrAddress, string portOr
288288
/// <param name="pendingDNSInfo">Used for DNS Cache</param>
289289
/// <param name="tlsFirst">Support TDS8.0</param>
290290
/// <param name="hostNameInCertificate">Host name in certificate</param>
291-
/// <param name="serverCert">Used for the path to the Server Certificate</param>
291+
/// <param name="serverCertificateFilename">Used for the path to the Server Certificate</param>
292292
/// <returns>SNITCPHandle</returns>
293293
private static SNITCPHandle CreateTcpHandle(
294294
DataSource details,
@@ -299,7 +299,7 @@ private static SNITCPHandle CreateTcpHandle(
299299
ref SQLDNSInfo pendingDNSInfo,
300300
bool tlsFirst,
301301
string hostNameInCertificate,
302-
string serverCert)
302+
string serverCertificateFilename)
303303
{
304304
// TCP Format:
305305
// tcp:<host name>\<instance name>
@@ -338,7 +338,7 @@ private static SNITCPHandle CreateTcpHandle(
338338
}
339339

340340
return new SNITCPHandle(hostName, port, timerExpire, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo,
341-
tlsFirst, hostNameInCertificate, serverCert);
341+
tlsFirst, hostNameInCertificate, serverCertificateFilename);
342342
}
343343

344344
/// <summary>

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs

+11-11
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ internal sealed class SNITCPHandle : SNIPhysicalHandle
2727
private readonly Socket _socket;
2828
private NetworkStream _tcpStream;
2929
private readonly string _hostNameInCertificate;
30-
private readonly string _serverCertificate;
30+
private readonly string _serverCertificateFilename;
3131
private readonly bool _tlsFirst;
3232

3333
private Stream _stream;
@@ -123,7 +123,7 @@ public override int ProtocolVersion
123123
/// <param name="pendingDNSInfo">Used for DNS Cache</param>
124124
/// <param name="tlsFirst">Support TDS8.0</param>
125125
/// <param name="hostNameInCertificate">Host Name in Certificate</param>
126-
/// <param name="serverCert">Used for the path to the Server Certificate</param>
126+
/// <param name="serverCertifiateFilename">Used for the path to the Server Certificate</param>
127127
public SNITCPHandle(
128128
string serverName,
129129
int port,
@@ -134,7 +134,7 @@ public SNITCPHandle(
134134
ref SQLDNSInfo pendingDNSInfo,
135135
bool tlsFirst,
136136
string hostNameInCertificate,
137-
string serverCert)
137+
string serverCertifiateFilename)
138138
{
139139
using (TrySNIEventScope.Create(nameof(SNITCPHandle)))
140140
{
@@ -143,7 +143,7 @@ public SNITCPHandle(
143143
_targetServer = serverName;
144144
_tlsFirst = tlsFirst;
145145
_hostNameInCertificate = hostNameInCertificate;
146-
_serverCertificate = serverCert;
146+
_serverCertificateFilename = serverCertifiateFilename;
147147
_sendSync = new object();
148148

149149
SQLDNSInfo cachedDNSInfo;
@@ -653,11 +653,11 @@ public override void DisableSsl()
653653
/// Validate server certificate callback
654654
/// </summary>
655655
/// <param name="sender">Sender object</param>
656-
/// <param name="cert">X.509 certificate</param>
656+
/// <param name="serverCertificate">X.509 certificate provided from the server</param>
657657
/// <param name="chain">X.509 chain</param>
658658
/// <param name="policyErrors">Policy errors</param>
659659
/// <returns>True if certificate is valid</returns>
660-
private bool ValidateServerCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
660+
private bool ValidateServerCertificate(object sender, X509Certificate serverCertificate, X509Chain chain, SslPolicyErrors policyErrors)
661661
{
662662
if (!_validateCert)
663663
{
@@ -675,13 +675,13 @@ private bool ValidateServerCertificate(object sender, X509Certificate cert, X509
675675
serverNameToValidate = _targetServer;
676676
}
677677

678-
if (!string.IsNullOrEmpty(_serverCertificate))
678+
if (!string.IsNullOrEmpty(_serverCertificateFilename))
679679
{
680-
X509Certificate serverCert = null;
680+
X509Certificate clientCertificate = null;
681681
try
682682
{
683-
serverCert = new X509Certificate(_serverCertificate);
684-
return SNICommon.ValidateSslServerCertificate(serverCert, cert, policyErrors);
683+
clientCertificate = new X509Certificate(_serverCertificateFilename);
684+
return SNICommon.ValidateSslServerCertificate(clientCertificate, serverCertificate, policyErrors);
685685
}
686686
catch (Exception e)
687687
{
@@ -691,7 +691,7 @@ private bool ValidateServerCertificate(object sender, X509Certificate cert, X509
691691
}
692692

693693
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNITCPHandle), EventType.INFO, "Connection Id {0}, Certificate will be validated for Target Server name", args0: _connectionId);
694-
return SNICommon.ValidateSslServerCertificate(serverNameToValidate, cert, policyErrors);
694+
return SNICommon.ValidateSslServerCertificate(serverNameToValidate, serverCertificate, policyErrors);
695695
}
696696

697697
/// <summary>

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

+59-19
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,12 @@ internal void Connect(
365365
bool withFailover)
366366
{
367367
SqlConnectionEncryptOption encrypt = connectionOptions.Encrypt;
368+
bool isTlsFirst = (encrypt == SqlConnectionEncryptOption.Strict);
368369
bool trustServerCert = connectionOptions.TrustServerCertificate;
369370
bool integratedSecurity = connectionOptions.IntegratedSecurity;
370371
SqlAuthenticationMethod authType = connectionOptions.Authentication;
371372
string hostNameInCertificate = connectionOptions.HostNameInCertificate;
372-
string serverCert = connectionOptions.ServerCertificate;
373+
string serverCertificateFilename = connectionOptions.ServerCertificate;
373374

374375
if (_state != TdsParserState.Closed)
375376
{
@@ -415,8 +416,8 @@ internal void Connect(
415416
SqlClientEventSource.Log.TryTraceEvent("TdsParser.Connect | SEC | SSPI or Active Directory Authentication Library loaded for SQL Server based integrated authentication");
416417
}
417418

418-
// if Strict encryption is chosen trust server certificate should always be false.
419-
if (encrypt == SqlConnectionEncryptOption.Strict)
419+
// if Strict encryption (i.e. isTlsFirst) is chosen trust server certificate should always be false.
420+
if (isTlsFirst)
420421
{
421422
trustServerCert = false;
422423
}
@@ -440,10 +441,23 @@ internal void Connect(
440441
_connHandler.pendingSQLDNSObject = null;
441442

442443
// AD Integrated behaves like Windows integrated when connecting to a non-fedAuth server
443-
_physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref _sniSpnBuffer,
444-
false, true, fParallel, _connHandler.ConnectionOptions.IPAddressPreference, FQDNforDNSCache, ref _connHandler.pendingSQLDNSObject, serverInfo.ServerSPN,
445-
integratedSecurity || authType == SqlAuthenticationMethod.ActiveDirectoryIntegrated, encrypt == SqlConnectionEncryptOption.Strict,
446-
hostNameInCertificate, serverCert);
444+
_physicalStateObj.CreatePhysicalSNIHandle(
445+
serverInfo.ExtendedServerName,
446+
ignoreSniOpenTimeout,
447+
timerExpire,
448+
out instanceName,
449+
ref _sniSpnBuffer,
450+
false,
451+
true,
452+
fParallel,
453+
_connHandler.ConnectionOptions.IPAddressPreference,
454+
FQDNforDNSCache,
455+
ref _connHandler.pendingSQLDNSObject,
456+
serverInfo.ServerSPN,
457+
integratedSecurity || authType == SqlAuthenticationMethod.ActiveDirectoryIntegrated,
458+
isTlsFirst,
459+
hostNameInCertificate,
460+
serverCertificateFilename);
447461

448462
if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status)
449463
{
@@ -502,15 +516,21 @@ internal void Connect(
502516
}
503517

504518
SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.Connect|SEC> Sending prelogin handshake");
505-
SendPreLoginHandshake(instanceName, encrypt, integratedSecurity, serverCert);
519+
SendPreLoginHandshake(instanceName, encrypt, integratedSecurity, serverCertificateFilename);
506520

507521
_connHandler.TimeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.SendPreLoginHandshake);
508522
_connHandler.TimeoutErrorInternal.SetAndBeginPhase(SqlConnectionTimeoutErrorPhase.ConsumePreLoginHandshake);
509523

510524
_physicalStateObj.SniContext = SniContext.Snix_PreLogin;
511525
SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.Connect|SEC> Consuming prelogin handshake");
512-
PreLoginHandshakeStatus status = ConsumePreLoginHandshake(encrypt, trustServerCert, integratedSecurity, out marsCapable,
513-
out _connHandler._fedAuthRequired, encrypt == SqlConnectionEncryptOption.Strict, serverCert);
526+
PreLoginHandshakeStatus status = ConsumePreLoginHandshake(
527+
encrypt,
528+
trustServerCert,
529+
integratedSecurity,
530+
out marsCapable,
531+
out _connHandler._fedAuthRequired,
532+
isTlsFirst,
533+
serverCertificateFilename);
514534

515535
if (status == PreLoginHandshakeStatus.InstanceFailure)
516536
{
@@ -520,8 +540,22 @@ internal void Connect(
520540
// On Instance failure re-connect and flush SNI named instance cache.
521541
_physicalStateObj.SniContext = SniContext.Snix_Connect;
522542

523-
_physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref _sniSpnBuffer, true, true, fParallel,
524-
_connHandler.ConnectionOptions.IPAddressPreference, FQDNforDNSCache, ref _connHandler.pendingSQLDNSObject, serverInfo.ServerSPN, integratedSecurity);
543+
_physicalStateObj.CreatePhysicalSNIHandle(
544+
serverInfo.ExtendedServerName,
545+
ignoreSniOpenTimeout,
546+
timerExpire, out instanceName,
547+
ref _sniSpnBuffer,
548+
true,
549+
true,
550+
fParallel,
551+
_connHandler.ConnectionOptions.IPAddressPreference,
552+
FQDNforDNSCache,
553+
ref _connHandler.pendingSQLDNSObject,
554+
serverInfo.ServerSPN,
555+
integratedSecurity,
556+
isTlsFirst,
557+
hostNameInCertificate,
558+
serverCertificateFilename);
525559

526560
if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status)
527561
{
@@ -541,9 +575,15 @@ internal void Connect(
541575
_physicalStateObj.AssignPendingDNSInfo(serverInfo.UserProtocol, FQDNforDNSCache, ref _connHandler.pendingSQLDNSObject);
542576
}
543577

544-
SendPreLoginHandshake(instanceName, encrypt, integratedSecurity, serverCert);
545-
status = ConsumePreLoginHandshake(encrypt, trustServerCert, integratedSecurity, out marsCapable, out _connHandler._fedAuthRequired,
546-
encrypt == SqlConnectionEncryptOption.Strict, serverCert);
578+
SendPreLoginHandshake(instanceName, encrypt, integratedSecurity, serverCertificateFilename);
579+
status = ConsumePreLoginHandshake(
580+
encrypt,
581+
trustServerCert,
582+
integratedSecurity,
583+
out marsCapable,
584+
out _connHandler._fedAuthRequired,
585+
isTlsFirst,
586+
serverCertificateFilename);
547587

548588
// Don't need to check for 7.0 failure, since we've already consumed
549589
// one pre-login packet and know we are connecting to 2000.
@@ -663,14 +703,14 @@ private void SendPreLoginHandshake(
663703
byte[] instanceName,
664704
SqlConnectionEncryptOption encrypt,
665705
bool integratedSecurity,
666-
string serverCert)
706+
string serverCertificateFilename)
667707
{
668708
if (encrypt == SqlConnectionEncryptOption.Strict)
669709
{
670710
//Always validate the certificate when in strict encryption mode
671711
uint info = TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE | TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE | TdsEnums.SNI_SSL_SEND_ALPN_EXTENSION;
672712

673-
EnableSsl(info, encrypt, integratedSecurity, serverCert);
713+
EnableSsl(info, encrypt, integratedSecurity, serverCertificateFilename);
674714

675715
// Since encryption has already been negotiated, we need to set encryption not supported in
676716
// prelogin so that we don't try to negotiate encryption again during ConsumePreLoginHandshake.
@@ -831,7 +871,7 @@ private void SendPreLoginHandshake(
831871
_physicalStateObj.WritePacket(TdsEnums.HARDFLUSH);
832872
}
833873

834-
private void EnableSsl(uint info, SqlConnectionEncryptOption encrypt, bool integratedSecurity, string serverCert)
874+
private void EnableSsl(uint info, SqlConnectionEncryptOption encrypt, bool integratedSecurity, string serverCertificateFilename)
835875
{
836876
uint error = 0;
837877

@@ -843,7 +883,7 @@ private void EnableSsl(uint info, SqlConnectionEncryptOption encrypt, bool integ
843883
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
844884
}
845885

846-
error = _physicalStateObj.EnableSsl(ref info, encrypt == SqlConnectionEncryptOption.Strict, serverCert);
886+
error = _physicalStateObj.EnableSsl(ref info, encrypt == SqlConnectionEncryptOption.Strict, serverCertificateFilename);
847887

848888
if (error != TdsEnums.SNI_SUCCESS)
849889
{

0 commit comments

Comments
 (0)