Skip to content

Commit 198b906

Browse files
authored
Fix down-level SSL/TLS version warnings (#3126)
* Added test for downlevel connectivity warning * Correctly test bit flags for legacy SSL protocol warning * Corrected warning disablement/restore.
1 parent 89f5dcb commit 198b906

File tree

11 files changed

+64
-34
lines changed

11 files changed

+64
-34
lines changed

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -765,30 +765,30 @@ private static string ToFriendlyName(this SslProtocols protocol)
765765
}*/
766766
#pragma warning disable CA5397 // Do not use deprecated SslProtocols values
767767
#pragma warning disable CA5398 // Avoid hardcoded SslProtocols values
768-
if ((protocol & SslProtocols.Tls12) == SslProtocols.Tls12)
768+
if ((protocol & SslProtocols.Tls12) != SslProtocols.None)
769769
{
770770
name = "TLS 1.2";
771771
}
772772
#if NET8_0_OR_GREATER
773773
#pragma warning disable SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated
774774
#endif
775-
else if ((protocol & SslProtocols.Tls11) == SslProtocols.Tls11)
775+
else if ((protocol & SslProtocols.Tls11) != SslProtocols.None)
776776
{
777777
name = "TLS 1.1";
778778
}
779-
else if ((protocol & SslProtocols.Tls) == SslProtocols.Tls)
779+
else if ((protocol & SslProtocols.Tls) != SslProtocols.None)
780780
{
781781
name = "TLS 1.0";
782782
}
783783
#if NET8_0_OR_GREATER
784784
#pragma warning restore SYSLIB0039 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated
785785
#endif
786786
#pragma warning disable CS0618 // Type or member is obsolete: SSL is deprecated
787-
else if ((protocol & SslProtocols.Ssl3) == SslProtocols.Ssl3)
787+
else if ((protocol & SslProtocols.Ssl3) != SslProtocols.None)
788788
{
789789
name = "SSL 3.0";
790790
}
791-
else if ((protocol & SslProtocols.Ssl2) == SslProtocols.Ssl2)
791+
else if ((protocol & SslProtocols.Ssl2) != SslProtocols.None)
792792
#pragma warning restore CS0618 // Type or member is obsolete: SSL and TLS 1.0 & 1.1 is deprecated
793793
{
794794
name = "SSL 2.0";

src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParameters.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Linq;
8+
using System.Security.Authentication;
89
using System.Text;
910
using System.Threading.Tasks;
1011
using Microsoft.SqlServer.TDS.PreLogin;
@@ -26,15 +27,21 @@ public class ConnectionTestParameters
2627
public string HostNameInCertificate => _hnic;
2728
public bool TestResult => _result;
2829
public TDSPreLoginTokenEncryptionType TdsEncryptionType => _encryptionType;
30+
public SslProtocols EncryptionProtocols { get; }
2931

3032
public ConnectionTestParameters(TDSPreLoginTokenEncryptionType tdsEncryptionType, SqlConnectionEncryptOption encryptOption, bool trustServerCert, string cert, string hnic, bool result)
33+
: this(tdsEncryptionType, encryptOption, trustServerCert, cert, hnic, SslProtocols.Tls12, result)
34+
{ }
35+
36+
public ConnectionTestParameters(TDSPreLoginTokenEncryptionType tdsEncryptionType, SqlConnectionEncryptOption encryptOption, bool trustServerCert, string cert, string hnic, SslProtocols sslProtocols, bool result)
3137
{
3238
_encryptionOption = encryptOption;
3339
_trustServerCert = trustServerCert;
3440
_cert = cert;
3541
_hnic = hnic;
3642
_result = result;
3743
_encryptionType = tdsEncryptionType;
44+
EncryptionProtocols = sslProtocols;
3845
}
3946
}
4047
}

src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ConnectionTestParametersData.cs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
using System.Collections.Generic;
66
using System.IO;
7+
using System.Security.Authentication;
78
using Microsoft.SqlServer.TDS.PreLogin;
89

910
namespace Microsoft.Data.SqlClient.ManualTesting.Tests.DataCommon
1011
{
1112
public class ConnectionTestParametersData
1213
{
13-
private const int CASES = 30;
1414
private string _empty = string.Empty;
1515
// It was advised to store the client certificate in its own folder.
1616
private static readonly string s_fullPathToCer = Path.Combine(Directory.GetCurrentDirectory(), "clientcert", "localhostcert.cer");
@@ -22,7 +22,7 @@ public class ConnectionTestParametersData
2222

2323
public static IEnumerable<object[]> GetConnectionTestParameters()
2424
{
25-
for (int i = 0; i < CASES; i++)
25+
for (int i = 0; i < Data.ConnectionTestParametersList.Count; i++)
2626
{
2727
yield return new object[] { Data.ConnectionTestParametersList[i] };
2828
}
@@ -33,11 +33,11 @@ public ConnectionTestParametersData()
3333
// Test cases possible field values for connection parameters:
3434
// These combinations are based on the possible values of Encrypt, TrustServerCertificate, Certificate, HostNameInCertificate
3535
/*
36-
* TDSEncryption | Encrypt | TrustServerCertificate | Certificate | HNIC | TestResults
37-
* ----------------------------------------------------------------------------------------------
38-
* Off | Optional | true | valid | valid name | true
39-
* On | Mandatory | false | mismatched | empty | false
40-
* Required | | x | ChainError? | wrong name? |
36+
* TDSEncryption | Encrypt | TrustServerCertificate | Certificate | HNIC | SSL Protocols | TestResults
37+
* ---------------------------------------------------------------------------------------------------------------
38+
* Off | Optional | true | valid | valid name | TLS 1.2 | true
39+
* On | Mandatory | false | mismatched | empty | TLS 1.0, TLS 1.1 | false
40+
* Required | | x | ChainError? | wrong name? | |
4141
*/
4242
ConnectionTestParametersList = new List<ConnectionTestParameters>
4343
{
@@ -79,6 +79,21 @@ public ConnectionTestParametersData()
7979
new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true),
8080
new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, s_mismatchedcert, _empty, false),
8181
new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, true, s_mismatchedcert, _empty, true),
82+
83+
// Multiple SSL protocols test
84+
#pragma warning disable CA5397 // Do not use deprecated SslProtocols values
85+
#pragma warning disable CA5398 // Avoid hardcoded SslProtocols values
86+
#if NET
87+
#pragma warning disable SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated
88+
#endif
89+
new(TDSPreLoginTokenEncryptionType.Off, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, SslProtocols.Tls | SslProtocols.Tls11, true),
90+
new(TDSPreLoginTokenEncryptionType.On, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, SslProtocols.Tls | SslProtocols.Tls11, true),
91+
new(TDSPreLoginTokenEncryptionType.Required, SqlConnectionEncryptOption.Mandatory, false, s_fullPathToCer, _empty, SslProtocols.Tls | SslProtocols.Tls11, true),
92+
#if NET
93+
#pragma warning restore SYSLIB0039 // Type or member is obsolete: TLS 1.0 & 1.1 are deprecated
94+
#endif
95+
#pragma warning restore CA5397 // Do not use deprecated SslProtocols values
96+
#pragma warning restore CA5398 // Avoid hardcoded SslProtocols values
8297
};
8398
}
8499
}

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionTestWithSSLCert/CertificateTestWithTdsServer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ private void ConnectionTest(ConnectionTestParameters connectionTestParameters)
127127
#else
128128
new X509Certificate2(s_fullPathToPfx, "nopassword", X509KeyStorageFlags.UserKeySet),
129129
#endif
130+
encryptionProtocols: connectionTestParameters.EncryptionProtocols,
130131
encryptionType: connectionTestParameters.TdsEncryptionType);
131132

132133
builder = new(server.ConnectionString)

src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/TestTdsServer.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Net;
88
using System.Net.Sockets;
99
using System.Runtime.CompilerServices;
10+
using System.Security.Authentication;
1011
using System.Security.Cryptography.X509Certificates;
1112
using Microsoft.SqlServer.TDS.EndPoint;
1213
using Microsoft.SqlServer.TDS.PreLogin;
@@ -31,7 +32,7 @@ public TestTdsServer(QueryEngine engine, TDSServerArguments args) : base(args)
3132

3233
public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool enableFedAuth = false, bool enableLog = false,
3334
int connectionTimeout = DefaultConnectionTimeout, [CallerMemberName] string methodName = "",
34-
X509Certificate2 encryptionCertificate = null, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported)
35+
X509Certificate2 encryptionCertificate = null, SslProtocols encryptionProtocols = SslProtocols.Tls12, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported)
3536
{
3637
TDSServerArguments args = new TDSServerArguments()
3738
{
@@ -44,6 +45,7 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool
4445
}
4546

4647
args.EncryptionCertificate = encryptionCertificate;
48+
args.EncryptionProtocols = encryptionProtocols;
4749
args.Encryption = encryptionType;
4850

4951
TestTdsServer server = engine == null ? new TestTdsServer(args) : new TestTdsServer(engine, args);
@@ -79,9 +81,9 @@ public static TestTdsServer StartServerWithQueryEngine(QueryEngine engine, bool
7981

8082
public static TestTdsServer StartTestServer(bool enableFedAuth = false, bool enableLog = false,
8183
int connectionTimeout = DefaultConnectionTimeout, [CallerMemberName] string methodName = "",
82-
X509Certificate2 encryptionCertificate = null, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported)
84+
X509Certificate2 encryptionCertificate = null, SslProtocols encryptionProtocols = SslProtocols.Tls12, TDSPreLoginTokenEncryptionType encryptionType = TDSPreLoginTokenEncryptionType.NotSupported)
8385
{
84-
return StartServerWithQueryEngine(null, enableFedAuth, enableLog, connectionTimeout, methodName, encryptionCertificate, encryptionType);
86+
return StartServerWithQueryEngine(null, enableFedAuth, enableLog, connectionTimeout, methodName, encryptionCertificate, encryptionProtocols, encryptionType);
8587
}
8688

8789
public void Dispose() => _endpoint?.Stop();

src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.EndPoint/ITDSServerSession.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Security.Authentication;
67
using System.Security.Cryptography.X509Certificates;
78
using Microsoft.SqlServer.TDS.EndPoint.SSPI;
89

@@ -68,6 +69,11 @@ public interface ITDSServerSession
6869
/// </summary>
6970
X509Certificate EncryptionCertificate { get; }
7071

72+
/// <summary>
73+
/// SSL/TLS protocols to use for transport encryption
74+
/// </summary>
75+
SslProtocols EncryptionProtocols { get; }
76+
7177
/// <summary>
7278
/// Counter of connection reset requests for this session
7379
/// </summary>

src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.EndPoint/TDSParser.cs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@ public class TDSParser
2525
/// </summary>
2626
public TextWriter EventLog { get; set; }
2727

28-
/// <summary>
29-
/// Encryption protocol for server to use with AuthenticateAsServer
30-
/// </summary>
31-
public static SslProtocols ServerSslProtocol { get; set; }
32-
3328
/// <summary>
3429
/// Protocol stream between the client and the server
3530
/// </summary>
@@ -43,8 +38,6 @@ public TDSParser(Stream transport)
4338
// Save original transport
4439
_originalTransport = transport;
4540

46-
ServerSslProtocol = SslProtocols.Tls12;
47-
4841
// Wrap transport layer with TDS
4942
Transport = new TDSStream(transport, false);
5043
}
@@ -57,14 +50,6 @@ public void SetTDSStreamPreWriteCallback(Func<byte[], int, int, ushort> funcTDSS
5750
Transport.PreWriteCallBack = funcTDSStreamPreWriteCallBack;
5851
}
5952

60-
/// <summary>
61-
/// Resets the targeted encryption protocol for the server.
62-
/// </summary>
63-
public static void ResetTargetProtocol()
64-
{
65-
ServerSslProtocol = SslProtocols.Tls12;
66-
}
67-
6853
/// <summary>
6954
/// Enable transport encryption
7055
/// </summary>
@@ -105,7 +90,7 @@ protected void EnableClientTransportEncryption(string server)
10590
/// <summary>
10691
/// Enable transport encryption
10792
/// </summary>
108-
protected void EnableServerTransportEncryption(X509Certificate certificate)
93+
protected void EnableServerTransportEncryption(X509Certificate certificate, SslProtocols encryptionProtocols)
10994
{
11095
// Check if transport encryption is applied
11196
if (Transport.InnerStream is SslStream)
@@ -134,7 +119,7 @@ protected void EnableServerTransportEncryption(X509Certificate certificate)
134119
SslStream ssl = new SslStream(multiplexer, true);
135120

136121
// Secure the channel
137-
ssl.AuthenticateAsServer(certificate, false, ServerSslProtocol, false);
122+
ssl.AuthenticateAsServer(certificate, false, encryptionProtocols, false);
138123

139124
// Replace TDS stream with raw transport stream in multiplexer
140125
multiplexer.InnerStream = Transport.InnerStream;

src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.EndPoint/TDSServerParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public void Run()
146146
if (Session.Encryption == TDSEncryptionType.LoginOnly || Session.Encryption == TDSEncryptionType.Full)
147147
{
148148
// Enable server side encryption
149-
EnableServerTransportEncryption(Session.EncryptionCertificate);
149+
EnableServerTransportEncryption(Session.EncryptionCertificate, Session.EncryptionProtocols);
150150
}
151151
}
152152

src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ public virtual ITDSServerSession OpenSession()
8585
// Create a new session
8686
GenericTDSServerSession session = new GenericTDSServerSession(this, (uint)_sessionCount);
8787

88-
// Use configured encryption certificate
88+
// Use configured encryption certificate and protocols
8989
session.EncryptionCertificate = Arguments.EncryptionCertificate;
90+
session.EncryptionProtocols = Arguments.EncryptionProtocols;
9091

9192
return session;
9293
}

src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/GenericTDSServerSession.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using System.Collections.Generic;
7+
using System.Security.Authentication;
78
using System.Security.Cryptography.X509Certificates;
89
using Microsoft.SqlServer.TDS.EndPoint;
910
using Microsoft.SqlServer.TDS.EndPoint.SSPI;
@@ -78,6 +79,11 @@ public class GenericTDSServerSession : ITDSServerSession
7879
/// </summary>
7980
public X509Certificate EncryptionCertificate { get; set; }
8081

82+
/// <summary>
83+
/// SSL/TLS protocols to use for transport encryption
84+
/// </summary>
85+
public SslProtocols EncryptionProtocols { get; set; }
86+
8187
/// <summary>
8288
/// Nonce option sent by client
8389
/// </summary>

0 commit comments

Comments
 (0)