Skip to content

Commit 131e907

Browse files
Update Encrypt property default value to true (#1210)
1 parent 554fe16 commit 131e907

File tree

11 files changed

+124
-99
lines changed

11 files changed

+124
-99
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ End Module
537537
|Current Language<br /><br /> -or-<br /><br /> Language|N/A|Sets the language used for database server warning or error messages.<br /><br /> The language name can be 128 characters or less.|
538538
|Data Source<br /><br /> -or-<br /><br /> Server<br /><br /> -or-<br /><br /> Address<br /><br /> -or-<br /><br /> Addr<br /><br /> -or-<br /><br /> Network Address|N/A|The name or network address of the instance of SQL Server to which to connect. The port number can be specified after the server name:<br /><br /> `server=tcp:servername, portnumber`<br /><br /> When specifying a local instance, always use (local). To force a protocol, add one of the following prefixes:<br /><br /> `np:(local), tcp:(local), lpc:(local)`<br /><br /> You can also connect to a LocalDB database as follows:<br /><br /> `server=(localdb)\\myInstance`<br /><br /> For more information about LocalDB, see [SqlClient Support for LocalDB](/sql/connect/ado-net/sql/sqlclient-support-localdb).<br /><br /> **Data Source** must use the TCP format or the Named Pipes format.<br /><br /> TCP format is as follows:<br /><br /> - tcp:\<host name>\\<instance name\><br />- tcp:\<host name>,\<TCP/IP port number><br /><br /> The TCP format must start with the prefix "tcp:" and is followed by the database instance, as specified by a host name and an instance name. This format is not applicable when connecting to Azure SQL Database. TCP is automatically selected for connections to Azure SQL Database when no protocol is specified.<br /><br /> The host name MUST be specified in one of the following ways:<br /><br /> - NetBIOSName<br />- IPv4Address<br />- IPv6Address<br /><br /> The instance name is used to resolve to a particular TCP/IP port number on which a database instance is hosted. Alternatively, specifying a TCP/IP port number directly is also allowed. If both instance name and port number are not present, the default database instance is used.<br /><br /> The Named Pipes format is as follows:<br /><br /> - np:\\\\<host name\>\pipe\\<pipe name\><br /><br /> The Named Pipes format MUST start with the prefix "np:" and is followed by a named pipe name.<br /><br /> The host name MUST be specified in one of the following ways:<br /><br /> - NetBIOSName<br />- IPv4Address<br />- IPv6Address<br /><br /> The pipe name is used to identify the database instance to which the .NET application will connect.<br /><br /> If the value of the **Network** key is specified, the prefixes "tcp:" and "np:" should not be specified. **Note:** You can force the use of TCP instead of shared memory, either by prefixing **tcp:** to the server name in the connection string, or by using **localhost**.|
539539
|Enclave Attestation Url|N/A|Gets or sets the enclave attestation URL to be used with enclave based Always Encrypted.|
540-
|Encrypt|'false'|When `true`, SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed. Recognized values are `true`, `false`, `yes`, and `no`. For more information, see [Connection String Syntax](/sql/connect/ado-net/connection-string-syntax).<br /><br /> When `TrustServerCertificate` is false and `Encrypt` is true, the server name (or IP address) in a SQL Server SSL certificate must exactly match the server name (or IP address) specified in the connection string. Otherwise, the connection attempt will fail. For information about support for certificates whose subject starts with a wildcard character (*), see [Accepted wildcards used by server certificates for server authentication](https://support.microsoft.com/kb/258858).|
540+
|Encrypt|'true'|When `true`, SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed. Recognized values are `true`, `false`, `yes`, and `no`. For more information, see [Connection String Syntax](/sql/connect/ado-net/connection-string-syntax).<br /><br /> When `TrustServerCertificate` is false and `Encrypt` is true, the server name (or IP address) in a SQL Server SSL certificate must exactly match the server name (or IP address) specified in the connection string. Otherwise, the connection attempt will fail. For information about support for certificates whose subject starts with a wildcard character (*), see [Accepted wildcards used by server certificates for server authentication](https://support.microsoft.com/kb/258858).|
541541
|Enlist|'true'|`true` indicates that the SQL Server connection pooler automatically enlists the connection in the creation thread's current transaction context.|
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
|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.|

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,11 @@ public EncryptionOptions Options
5555
return _encryptionOption;
5656
}
5757
}
58+
59+
/// <summary>
60+
/// Verify client encryption possibility
61+
/// </summary>
62+
// TODO: by adding support ENCRYPT_NOT_SUP, it could be calculated.
63+
public bool ClientOSEncryptionSupport => true;
5864
}
5965
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ internal static partial class DEFAULT
2828
internal const int Connect_Timeout = ADP.DefaultConnectionTimeout;
2929
internal const string Current_Language = _emptyString;
3030
internal const string Data_Source = _emptyString;
31-
internal const bool Encrypt = false;
31+
internal const bool Encrypt = true;
3232
internal const bool Enlist = true;
3333
internal const string FailoverPartner = _emptyString;
3434
internal const string Initial_Catalog = _emptyString;

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

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ internal sealed partial class TdsParser
4747
internal readonly int _objectID = Interlocked.Increment(ref _objectTypeCount);
4848
internal int ObjectID => _objectID;
4949

50+
/// <summary>
51+
/// Verify client encryption possibility.
52+
/// </summary>
53+
private bool ClientOSEncryptionSupport => TdsParserStateObjectFactory.Singleton.ClientOSEncryptionSupport;
54+
5055
// Default state object for parser
5156
internal TdsParserStateObject _physicalStateObj = null; // Default stateObj and connection for Dbnetlib and non-MARS SNI.
5257

@@ -464,6 +469,18 @@ internal void Connect(
464469
_physicalStateObj.AssignPendingDNSInfo(serverInfo.UserProtocol, FQDNforDNSCahce, ref _connHandler.pendingSQLDNSObject);
465470
}
466471

472+
if (!ClientOSEncryptionSupport)
473+
{
474+
//If encryption is required, an error will be thrown.
475+
if (encrypt)
476+
{
477+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByClient(), "", 0));
478+
_physicalStateObj.Dispose();
479+
ThrowExceptionAndWarning(_physicalStateObj);
480+
}
481+
_encryptionOption = EncryptionOptions.NOT_SUP;
482+
}
483+
467484
SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.Connect|SEC> Sending prelogin handshake");
468485
SendPreLoginHandshake(instanceName, encrypt);
469486

@@ -674,7 +691,7 @@ private void SendPreLoginHandshake(byte[] instanceName, bool encrypt)
674691
case (int)PreLoginOptions.ENCRYPT:
675692
if (_encryptionOption == EncryptionOptions.NOT_SUP)
676693
{
677-
// If OS doesn't support encryption, inform server not supported.
694+
//If OS doesn't support encryption and encryption is not required, inform server "not supported" by client.
678695
payload[payloadLength] = (byte)EncryptionOptions.NOT_SUP;
679696
}
680697
else
@@ -885,7 +902,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
885902
// Encrypt all.
886903
_encryptionOption = EncryptionOptions.ON;
887904
}
888-
905+
// NOT_SUP: No encryption.
889906
break;
890907

891908
case (EncryptionOptions.NOT_SUP):

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

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ internal sealed partial class SNILoadHandle : SafeHandle
1818
internal readonly SNINativeMethodWrapper.SqlAsyncCallbackDelegate WriteAsyncCallbackDispatcher = new SNINativeMethodWrapper.SqlAsyncCallbackDelegate(WriteDispatcher);
1919

2020
private readonly uint _sniStatus = TdsEnums.SNI_UNINITIALIZED;
21-
private readonly EncryptionOptions _encryptionOption;
21+
private readonly EncryptionOptions _encryptionOption = EncryptionOptions.OFF;
22+
private bool? _clientOSEncryptionSupport = null;
2223

2324
private SNILoadHandle() : base(IntPtr.Zero, true)
2425
{
@@ -30,30 +31,41 @@ private SNILoadHandle() : base(IntPtr.Zero, true)
3031
finally
3132
{
3233
_sniStatus = SNINativeMethodWrapper.SNIInitialize();
33-
34-
uint value = 0;
35-
36-
// VSDevDiv 479597: If initialize fails, don't call QueryInfo.
37-
if (TdsEnums.SNI_SUCCESS == _sniStatus)
38-
{
39-
// Query OS to find out whether encryption is supported.
40-
SNINativeMethodWrapper.SNIQueryInfo(SNINativeMethodWrapper.QTypes.SNI_QUERY_CLIENT_ENCRYPT_POSSIBLE, ref value);
41-
}
42-
43-
_encryptionOption = (value == 0) ? EncryptionOptions.NOT_SUP : EncryptionOptions.OFF;
44-
4534
base.handle = (IntPtr)1; // Initialize to non-zero dummy variable.
4635
}
4736
}
4837

49-
public override bool IsInvalid
38+
/// <summary>
39+
/// Verify client encryption possibility.
40+
/// </summary>
41+
public bool ClientOSEncryptionSupport
5042
{
5143
get
5244
{
53-
return (IntPtr.Zero == base.handle);
45+
if (_clientOSEncryptionSupport is null)
46+
{
47+
// VSDevDiv 479597: If initialize fails, don't call QueryInfo.
48+
if (TdsEnums.SNI_SUCCESS == _sniStatus)
49+
{
50+
try
51+
{
52+
UInt32 value = 0;
53+
// Query OS to find out whether encryption is supported.
54+
SNINativeMethodWrapper.SNIQueryInfo(SNINativeMethodWrapper.QTypes.SNI_QUERY_CLIENT_ENCRYPT_POSSIBLE, ref value);
55+
_clientOSEncryptionSupport = value != 0;
56+
}
57+
catch (Exception e)
58+
{
59+
SqlClientEventSource.Log.TryTraceEvent("<sc.SNILoadHandle.EncryptClientPossible|SEC> Exception occurs during resolving encryption possibility: {0}", e.Message);
60+
}
61+
}
62+
}
63+
return _clientOSEncryptionSupport.Value;
5464
}
5565
}
5666

67+
public override bool IsInvalid => (IntPtr.Zero == base.handle);
68+
5769
override protected bool ReleaseHandle()
5870
{
5971
if (base.handle != IntPtr.Zero)
@@ -69,21 +81,9 @@ override protected bool ReleaseHandle()
6981
return true;
7082
}
7183

72-
public uint Status
73-
{
74-
get
75-
{
76-
return _sniStatus;
77-
}
78-
}
84+
public uint Status => _sniStatus;
7985

80-
public EncryptionOptions Options
81-
{
82-
get
83-
{
84-
return _encryptionOption;
85-
}
86-
}
86+
public EncryptionOptions Options => _encryptionOption;
8787

8888
private static void ReadDispatcher(IntPtr key, IntPtr packet, uint error)
8989
{

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Managed.cs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,14 @@ internal sealed class TdsParserStateObjectFactory
1313

1414
public static readonly TdsParserStateObjectFactory Singleton = new TdsParserStateObjectFactory();
1515

16-
public EncryptionOptions EncryptionOptions
17-
{
18-
get
19-
{
20-
return SNI.SNILoadHandle.SingletonInstance.Options;
21-
}
22-
}
16+
public EncryptionOptions EncryptionOptions => SNI.SNILoadHandle.SingletonInstance.Options;
2317

24-
public uint SNIStatus
25-
{
26-
get
27-
{
28-
return SNI.SNILoadHandle.SingletonInstance.Status;
29-
}
30-
}
18+
public uint SNIStatus => SNI.SNILoadHandle.SingletonInstance.Status;
19+
20+
/// <summary>
21+
/// Verify client encryption possibility.
22+
/// </summary>
23+
public bool ClientOSEncryptionSupport => SNI.SNILoadHandle.SingletonInstance.ClientOSEncryptionSupport;
3124

3225
public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser)
3326
{

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,17 @@ internal sealed class TdsParserStateObjectFactory
1616
private static bool shouldUseManagedSNI;
1717

1818
// If the appcontext switch is set then Use Managed SNI based on the value. Otherwise Native SNI.dll will be used by default.
19-
public static bool UseManagedSNI { get; } =
19+
public static bool UseManagedSNI =>
2020
AppContext.TryGetSwitch(UseManagedNetworkingOnWindows, out shouldUseManagedSNI) ? shouldUseManagedSNI : false;
2121

22-
public EncryptionOptions EncryptionOptions
23-
{
24-
get
25-
{
26-
return UseManagedSNI ? SNI.SNILoadHandle.SingletonInstance.Options : SNILoadHandle.SingletonInstance.Options;
27-
}
28-
}
22+
public EncryptionOptions EncryptionOptions => UseManagedSNI ? SNI.SNILoadHandle.SingletonInstance.Options : SNILoadHandle.SingletonInstance.Options;
2923

30-
public uint SNIStatus
31-
{
32-
get
33-
{
34-
return UseManagedSNI ? SNI.SNILoadHandle.SingletonInstance.Status : SNILoadHandle.SingletonInstance.Status;
35-
}
36-
}
24+
public uint SNIStatus => UseManagedSNI ? SNI.SNILoadHandle.SingletonInstance.Status : SNILoadHandle.SingletonInstance.Status;
25+
26+
/// <summary>
27+
/// Verify client encryption possibility.
28+
/// </summary>
29+
public bool ClientOSEncryptionSupport => UseManagedSNI ? SNI.SNILoadHandle.SingletonInstance.ClientOSEncryptionSupport : SNILoadHandle.SingletonInstance.ClientOSEncryptionSupport;
3730

3831
public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser)
3932
{

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionString.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ internal static class DEFAULT
3131
internal const bool Context_Connection = false;
3232
internal const string Current_Language = _emptyString;
3333
internal const string Data_Source = _emptyString;
34-
internal const bool Encrypt = false;
34+
internal const bool Encrypt = true;
3535
internal const bool Enlist = true;
3636
internal const string FailoverPartner = _emptyString;
3737
internal const string Initial_Catalog = _emptyString;

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

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ internal int ObjectID
5858
}
5959
}
6060

61+
/// <summary>
62+
/// Verify client encryption possibility.
63+
/// </summary>
64+
private bool ClientOSEncryptionSupport => SNILoadHandle.SingletonInstance.ClientOSEncryptionSupport;
6165

6266
// ReliabilitySection Usage:
6367
//
@@ -644,6 +648,18 @@ internal void Connect(ServerInfo serverInfo,
644648
// for DNS Caching phase 1
645649
AssignPendingDNSInfo(serverInfo.UserProtocol, FQDNforDNSCahce);
646650

651+
if(!ClientOSEncryptionSupport)
652+
{
653+
//If encryption is required, an error will be thrown.
654+
if (encrypt)
655+
{
656+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByClient(), "", 0));
657+
_physicalStateObj.Dispose();
658+
ThrowExceptionAndWarning(_physicalStateObj);
659+
}
660+
_encryptionOption = EncryptionOptions.NOT_SUP;
661+
}
662+
647663
// UNDONE - send "" for instance now, need to fix later
648664
SqlClientEventSource.Log.TryTraceEvent("<sc.TdsParser.Connect|SEC> Sending prelogin handshake");
649665
SendPreLoginHandshake(instanceName, encrypt, !string.IsNullOrEmpty(certificate), useOriginalAddressInfo);
@@ -683,8 +699,8 @@ internal void Connect(ServerInfo serverInfo,
683699
AssignPendingDNSInfo(serverInfo.UserProtocol, FQDNforDNSCahce);
684700

685701
SendPreLoginHandshake(instanceName, encrypt, !string.IsNullOrEmpty(certificate), useOriginalAddressInfo);
686-
status = ConsumePreLoginHandshake(authType, encrypt, trustServerCert, integratedSecurity, serverCallback, clientCallback, out marsCapable,
687-
out _connHandler._fedAuthRequired);
702+
status = ConsumePreLoginHandshake(authType, encrypt, trustServerCert, integratedSecurity, serverCallback, clientCallback,
703+
out marsCapable, out _connHandler._fedAuthRequired);
688704

689705
// Don't need to check for Sphinx failure, since we've already consumed
690706
// one pre-login packet and know we are connecting to Shiloh.
@@ -983,7 +999,7 @@ private void SendPreLoginHandshake(byte[] instanceName, bool encrypt, bool clien
983999
case (int)PreLoginOptions.ENCRYPT:
9841000
if (_encryptionOption == EncryptionOptions.NOT_SUP)
9851001
{
986-
// If OS doesn't support encryption, inform server not supported.
1002+
//If OS doesn't support encryption and encryption is not required, inform server "not supported" by client.
9871003
payload[payloadLength] = (byte)EncryptionOptions.NOT_SUP;
9881004
}
9891005
else
@@ -1189,7 +1205,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod
11891205
switch (_encryptionOption & EncryptionOptions.OPTIONS_MASK)
11901206
{
11911207
case (EncryptionOptions.ON):
1192-
if (serverOption == EncryptionOptions.NOT_SUP)
1208+
if ((serverOption & EncryptionOptions.OPTIONS_MASK) == EncryptionOptions.NOT_SUP)
11931209
{
11941210
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
11951211
_physicalStateObj.Dispose();
@@ -1209,7 +1225,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(SqlAuthenticationMethod
12091225
// Encrypt all.
12101226
_encryptionOption = EncryptionOptions.ON | (_encryptionOption & ~EncryptionOptions.OPTIONS_MASK);
12111227
}
1212-
1228+
// NOT_SUP: No encryption.
12131229
break;
12141230

12151231
case (EncryptionOptions.NOT_SUP):

0 commit comments

Comments
 (0)