Skip to content

Commit 8596bf9

Browse files
committed
Merged PR 4075: [3.1.5]
1 parent f368547 commit 8596bf9

File tree

9 files changed

+271
-188
lines changed

9 files changed

+271
-188
lines changed

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

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
843843
int payloadOffset = 0;
844844
int payloadLength = 0;
845845
int option = payload[offset++];
846+
bool serverSupportsEncryption = false;
846847

847848
while (option != (byte)PreLoginOptions.LASTOPT)
848849
{
@@ -879,18 +880,11 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
879880
LOGIN
880881
} */
881882

883+
// Any response other than NOT_SUP means the server supports encryption.
884+
serverSupportsEncryption = serverOption != EncryptionOptions.NOT_SUP;
885+
882886
switch (_encryptionOption)
883887
{
884-
case (EncryptionOptions.ON):
885-
if (serverOption == EncryptionOptions.NOT_SUP)
886-
{
887-
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
888-
_physicalStateObj.Dispose();
889-
ThrowExceptionAndWarning(_physicalStateObj);
890-
}
891-
892-
break;
893-
894888
case (EncryptionOptions.OFF):
895889
if (serverOption == EncryptionOptions.OFF)
896890
{
@@ -908,6 +902,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
908902
case (EncryptionOptions.NOT_SUP):
909903
if (serverOption == EncryptionOptions.REQ)
910904
{
905+
// Server requires encryption, but client does not support it.
911906
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByClient(), "", 0));
912907
_physicalStateObj.Dispose();
913908
ThrowExceptionAndWarning(_physicalStateObj);
@@ -916,49 +911,15 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
916911
break;
917912

918913
default:
919-
Debug.Fail("Invalid client encryption option detected");
920-
break;
921-
}
922-
923-
if (_encryptionOption == EncryptionOptions.ON ||
924-
_encryptionOption == EncryptionOptions.LOGIN)
925-
{
926-
uint error = 0;
927-
928-
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
929-
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert);
930-
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
931-
| (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0);
932-
933-
if (encrypt && !integratedSecurity)
934-
{
935-
// optimization: in case of SQL Authentication and encryption, set SNI_SSL_IGNORE_CHANNEL_BINDINGS to let SNI
936-
// know that it does not need to allocate/retrieve the Channel Bindings from the SSL context.
937-
// This applies to Native SNI
938-
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
939-
}
940-
941-
error = _physicalStateObj.EnableSsl(ref info);
942-
943-
if (error != TdsEnums.SNI_SUCCESS)
944-
{
945-
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
946-
ThrowExceptionAndWarning(_physicalStateObj);
947-
}
948-
949-
int protocolVersion = 0;
950-
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
951-
952-
SslProtocols protocol = (SslProtocols)protocolVersion;
953-
string warningMessage = protocol.GetProtocolWarning();
954-
if (!string.IsNullOrEmpty(warningMessage))
955-
{
956-
// This logs console warning of insecure protocol in use.
957-
_logger.LogWarning(_typeName, MethodBase.GetCurrentMethod().Name, warningMessage);
958-
}
914+
// Any other client option needs encryption
915+
if (serverOption == EncryptionOptions.NOT_SUP)
916+
{
917+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
918+
_physicalStateObj.Dispose();
919+
ThrowExceptionAndWarning(_physicalStateObj);
920+
}
959921

960-
// create a new packet encryption changes the internal packet size
961-
_physicalStateObj.ClearAllWritePackets();
922+
break;
962923
}
963924

964925
break;
@@ -1041,6 +1002,54 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
10411002
}
10421003
}
10431004

1005+
if (_encryptionOption == EncryptionOptions.ON ||
1006+
_encryptionOption == EncryptionOptions.LOGIN)
1007+
{
1008+
if (!serverSupportsEncryption)
1009+
{
1010+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
1011+
_physicalStateObj.Dispose();
1012+
ThrowExceptionAndWarning(_physicalStateObj);
1013+
}
1014+
1015+
uint error = 0;
1016+
1017+
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
1018+
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert);
1019+
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
1020+
| (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0);
1021+
1022+
if (encrypt && !integratedSecurity)
1023+
{
1024+
// optimization: in case of SQL Authentication and encryption, set SNI_SSL_IGNORE_CHANNEL_BINDINGS to let SNI
1025+
// know that it does not need to allocate/retrieve the Channel Bindings from the SSL context.
1026+
// This applies to Native SNI
1027+
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
1028+
}
1029+
1030+
error = _physicalStateObj.EnableSsl(ref info);
1031+
1032+
if (error != TdsEnums.SNI_SUCCESS)
1033+
{
1034+
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
1035+
ThrowExceptionAndWarning(_physicalStateObj);
1036+
}
1037+
1038+
int protocolVersion = 0;
1039+
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
1040+
1041+
SslProtocols protocol = (SslProtocols)protocolVersion;
1042+
string warningMessage = protocol.GetProtocolWarning();
1043+
if (!string.IsNullOrEmpty(warningMessage))
1044+
{
1045+
// This logs console warning of insecure protocol in use.
1046+
_logger.LogWarning(_typeName, MethodBase.GetCurrentMethod().Name, warningMessage);
1047+
}
1048+
1049+
// create a new packet encryption changes the internal packet size
1050+
_physicalStateObj.ClearAllWritePackets();
1051+
}
1052+
10441053
return PreLoginHandshakeStatus.Successful;
10451054
}
10461055

0 commit comments

Comments
 (0)