From f278394f7a2b526d3aadf5ae03d6b61385b099ea Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Wed, 19 Aug 2020 12:59:29 -0700 Subject: [PATCH 1/2] [Cleanup] Remove unused algorithm classes. --- .../src/Microsoft.Data.SqlClient.csproj | 6 -- .../Data/SqlClient/SqlSecurityUtility.cs | 8 +- .../netfx/src/Microsoft.Data.SqlClient.csproj | 6 -- .../Data/SqlClient/SqlSecurityUtility.cs | 4 - .../SqlAeadAes256CbcHmac256EncryptionKey.cs | 2 +- .../Data/SqlClient/SqlAes256CbcAlgorithm.cs | 56 ------------- .../Data/SqlClient/SqlAes256CbcFactory.cs | 81 ------------------- ...SqlClientEncryptionAlgorithmFactoryList.cs | 3 +- .../Data/SqlClient/SqlClientSymmetricKey.cs | 7 -- 9 files changed, 4 insertions(+), 169 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcAlgorithm.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcFactory.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 9232078830..c0dbdf45e1 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -144,12 +144,6 @@ Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Factory.cs - - Microsoft\Data\SqlClient\SqlAes256CbcAlgorithm.cs - - - Microsoft\Data\SqlClient\SqlAes256CbcFactory.cs - Microsoft\Data\SqlClient\SqlAuthenticationParameters.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs index a17a2dea1e..6df67b9b98 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs @@ -150,10 +150,6 @@ private static string ValidateAndGetEncryptionAlgorithmName(byte cipherAlgorithm { return SqlAeadAes256CbcHmac256Algorithm.AlgorithmName; } - else if (TdsEnums.AES_256_CBC == cipherAlgorithmId) - { - return SqlAes256CbcAlgorithm.AlgorithmName; - } else { throw SQL.UnknownColumnEncryptionAlgorithmId(cipherAlgorithmId, GetRegisteredCipherAlgorithmIds()); @@ -241,7 +237,7 @@ internal static byte[] DecryptWithKey(byte[] cipherText, SqlCipherMetadata md, s } /// - /// Decrypts the symmetric key and saves it in metadata. In addition, initializes + /// Decrypts the symmetric key and saves it in metadata. In addition, initializes /// the SqlClientEncryptionAlgorithm for rapid decryption. /// internal static void DecryptSymmetricKey(SqlCipherMetadata md, string serverName) @@ -253,7 +249,7 @@ internal static void DecryptSymmetricKey(SqlCipherMetadata md, string serverName DecryptSymmetricKey(md.EncryptionInfo, serverName, out symKey, out encryptionkeyInfoChosen); - // Given the symmetric key instantiate a SqlClientEncryptionAlgorithm object and cache it in metadata + // Given the symmetric key instantiate a SqlClientEncryptionAlgorithm object and cache it in metadata md.CipherAlgorithm = null; SqlClientEncryptionAlgorithm cipherAlgorithm = null; string algorithmName = ValidateAndGetEncryptionAlgorithmName(md.CipherAlgorithmId, md.CipherAlgorithmName); // may throw diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 042ba6de5e..f3fc7d279b 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -199,12 +199,6 @@ Microsoft\Data\SqlClient\SqlAeadAes256CbcHmac256Factory.cs - - Microsoft\Data\SqlClient\SqlAes256CbcAlgorithm.cs - - - Microsoft\Data\SqlClient\SqlAes256CbcFactory.cs - Microsoft\Data\SqlClient\SqlAuthenticationParameters.cs diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs index a20a506b52..a86ae7100e 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlSecurityUtility.cs @@ -149,10 +149,6 @@ private static string ValidateAndGetEncryptionAlgorithmName(byte cipherAlgorithm { return SqlAeadAes256CbcHmac256Algorithm.AlgorithmName; } - else if (TdsEnums.AES_256_CBC == cipherAlgorithmId) - { - return SqlAes256CbcAlgorithm.AlgorithmName; - } else { throw SQL.UnknownColumnEncryptionAlgorithmId(cipherAlgorithmId, GetRegisteredCipherAlgorithmIds()); diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAeadAes256CbcHmac256EncryptionKey.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAeadAes256CbcHmac256EncryptionKey.cs index a02247834e..b0109902c6 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAeadAes256CbcHmac256EncryptionKey.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAeadAes256CbcHmac256EncryptionKey.cs @@ -7,7 +7,7 @@ namespace Microsoft.Data.SqlClient { /// - /// Encryption key class containing 4 keys. This class is used by SqlAeadAes256CbcHmac256Algorithm and SqlAes256CbcAlgorithm + /// Encryption key class containing 4 keys. This class is used by SqlAeadAes256CbcHmac256Algorithm /// 1) root key - Main key that is used to derive the keys used in the encryption algorithm /// 2) encryption key - A derived key that is used to encrypt the plain text and generate cipher text /// 3) mac_key - A derived key that is used to compute HMAC of the cipher text diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcAlgorithm.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcAlgorithm.cs deleted file mode 100644 index 6e8f34172f..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcAlgorithm.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Data.SqlClient -{ - /// - /// This class implements AES_256_CBC algorithm. - /// - internal class SqlAes256CbcAlgorithm : SqlAeadAes256CbcHmac256Algorithm - { - /// - /// Algorithm Name - /// - internal new const string AlgorithmName = @"AES_256_CBC"; - - /// - /// Initializes a new instance of SqlAes256CbcAlgorithm algorithm with a given key and encryption type - /// - /// - /// Root encryption key from which three other keys will be derived - /// - /// Encryption Type, accepted values are Deterministic and Randomized. - /// For Deterministic encryption, a synthetic IV will be generated during encryption - /// For Randomized encryption, a random IV will be generated during encryption. - /// - /// - /// Algorithm version - /// - internal SqlAes256CbcAlgorithm(SqlAeadAes256CbcHmac256EncryptionKey encryptionKey, SqlClientEncryptionType encryptionType, byte algorithmVersion) - : base(encryptionKey, encryptionType, algorithmVersion) - { } - - /// - /// Encryption Algorithm - /// Simply call the base class, indicating we don't need an authentication tag. - /// - /// Plaintext data to be encrypted - /// Returns the ciphertext corresponding to the plaintext. - internal override byte[] EncryptData(byte[] plainText) - { - return EncryptData(plainText, hasAuthenticationTag: false); - } - - /// - /// Decryption Algorithm - /// Simply call the base class, indicating we don't have an authentication tag. - /// - /// - /// - internal override byte[] DecryptData(byte[] cipherText) - { - return base.DecryptData(cipherText, hasAuthenticationTag: false); - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcFactory.cs deleted file mode 100644 index 1b6c7ef9bf..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlAes256CbcFactory.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Text; - -namespace Microsoft.Data.SqlClient -{ - /// - /// This is a factory class for AES_256_CBC. - /// - internal class SqlAes256CbcFactory : SqlAeadAes256CbcHmac256Factory - { - /// - /// Factory classes caches the SqlAeadAes256CbcHmac256EncryptionKey objects to avoid computation of the derived keys - /// - private readonly ConcurrentDictionary _encryptionAlgorithms = - new ConcurrentDictionary(concurrencyLevel: 4 * Environment.ProcessorCount /* default value in ConcurrentDictionary*/, capacity: 2); - - /// - /// Creates an instance of SqlAes256CbcAlgorithm class with a given key - /// - /// Root key - /// Encryption Type. Expected values are either Deterministic or Randomized. - /// Encryption Algorithm. - /// - internal override SqlClientEncryptionAlgorithm Create(SqlClientSymmetricKey encryptionKey, SqlClientEncryptionType encryptionType, string encryptionAlgorithm) - { - // Callers should have validated the encryption algorithm and the encryption key - Debug.Assert(encryptionKey != null); - Debug.Assert(string.Equals(encryptionAlgorithm, SqlAes256CbcAlgorithm.AlgorithmName, StringComparison.OrdinalIgnoreCase) == true); - - // Validate encryption type - if (!((encryptionType == SqlClientEncryptionType.Deterministic) || (encryptionType == SqlClientEncryptionType.Randomized))) - { - throw SQL.InvalidEncryptionType(SqlAes256CbcAlgorithm.AlgorithmName, - encryptionType, - SqlClientEncryptionType.Deterministic, - SqlClientEncryptionType.Randomized); - } - - // Get the cached encryption algorithm if one exists or create a new one, add it to cache and use it - // - // For now, we only have one version. In future, we may need to parse the algorithm names to derive the version byte. - const byte algorithmVersion = 0x1; - - StringBuilder algorithmKeyBuilder = new StringBuilder(Convert.ToBase64String(encryptionKey.RootKey), SqlSecurityUtility.GetBase64LengthFromByteLength(encryptionKey.RootKey.Length) + 4/*separators, type and version*/); - -#if DEBUG - int capacity = algorithmKeyBuilder.Capacity; -#endif //DEBUG - - algorithmKeyBuilder.Append(":"); - algorithmKeyBuilder.Append((int)encryptionType); - algorithmKeyBuilder.Append(":"); - algorithmKeyBuilder.Append(algorithmVersion); - - string algorithmKey = algorithmKeyBuilder.ToString(); - -#if DEBUG - Debug.Assert(algorithmKey.Length <= capacity, "We needed to allocate a larger array"); -#endif //DEBUG - - SqlAes256CbcAlgorithm aesAlgorithm; - if (!_encryptionAlgorithms.TryGetValue(algorithmKey, out aesAlgorithm)) - { - SqlAeadAes256CbcHmac256EncryptionKey encryptedKey = new SqlAeadAes256CbcHmac256EncryptionKey(encryptionKey.RootKey, SqlAes256CbcAlgorithm.AlgorithmName); - aesAlgorithm = new SqlAes256CbcAlgorithm(encryptedKey, encryptionType, algorithmVersion); - - // In case multiple threads reach here at the same time, the first one adds the value - // the second one will be a no-op, the allocated memory will be claimed by Garbage Collector. - _encryptionAlgorithms.TryAdd(algorithmKey, aesAlgorithm); - } - - return aesAlgorithm; - } - } -} diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEncryptionAlgorithmFactoryList.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEncryptionAlgorithmFactoryList.cs index b6ebf913ed..78c3c2f698 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEncryptionAlgorithmFactoryList.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientEncryptionAlgorithmFactoryList.cs @@ -21,9 +21,8 @@ private SqlClientEncryptionAlgorithmFactoryList() { _encryptionAlgoFactoryList = new ConcurrentDictionary(concurrencyLevel: 4 * Environment.ProcessorCount /* default value in ConcurrentDictionary*/, capacity: 2); - // Add wellknown algorithms + // Add wellknown algorithm _encryptionAlgoFactoryList.TryAdd(SqlAeadAes256CbcHmac256Algorithm.AlgorithmName, new SqlAeadAes256CbcHmac256Factory()); - _encryptionAlgoFactoryList.TryAdd(SqlAes256CbcAlgorithm.AlgorithmName, new SqlAes256CbcFactory()); } internal static SqlClientEncryptionAlgorithmFactoryList GetInstance() diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientSymmetricKey.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientSymmetricKey.cs index cb9ab65471..af96d947f0 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientSymmetricKey.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlClientSymmetricKey.cs @@ -30,13 +30,6 @@ internal SqlClientSymmetricKey(byte[] rootKey) _rootKey = rootKey; } - /// - /// Empty destructor for binary back compat. - /// - ~SqlClientSymmetricKey() - { - } - /// /// Returns a copy of the plain text key /// This is needed for actual encryption/decryption. From 96cfee8cdcc1ade147234f79c188b2e04d2fd9a8 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Mon, 24 Aug 2020 09:55:58 -0700 Subject: [PATCH 2/2] Remove unused constants --- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 9 ++++----- .../src/Microsoft/Data/SqlClient/TdsEnums.cs | 19 +++++++++---------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs index 83005d7a03..7325755d26 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -134,7 +134,7 @@ internal static class TdsEnums public const byte SQLDEBUG_CMD = 0x60; public const byte SQLLOGINACK = 0xad; public const byte SQLFEATUREEXTACK = 0xae; // TDS 7.4 - feature ack - public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state + public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state public const byte SQLENVCHANGE = 0xe3; // Environment change notification public const byte SQLSECLEVEL = 0xed; // Security level token ??? public const byte SQLROWCRC = 0x39; // ROWCRC datastream??? @@ -210,8 +210,8 @@ public enum EnvChangeType : byte public const byte FEATUREEXT_FEDAUTH = 0x02; public const byte FEATUREEXT_TCE = 0x04; public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; - // 0x06 is for x_eFeatureExtensionId_LoginToken - // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry + // 0x06 is for x_eFeatureExtensionId_LoginToken + // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry public const byte FEATUREEXT_AZURESQLSUPPORT = 0x08; public const byte FEATUREEXT_DATACLASSIFICATION = 0x09; public const byte FEATUREEXT_UTF8SUPPORT = 0x0A; @@ -272,7 +272,7 @@ public enum ActiveDirectoryWorkflow : byte public const byte MAX_NIC_SIZE = 6; // The size of a MAC or client address public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) - public const int CLIENT_PROG_VER = 0x06000000; // Client interface version + public const int CLIENT_PROG_VER = 0x06000000; // Client interface version public const int YUKON_LOG_REC_FIXED_LEN = 0x5e; // misc public const int TEXT_TIME_STAMP_LEN = 8; @@ -987,7 +987,6 @@ internal static string GetSniContextEnumName(SniContext sniContext) internal const long MAX_TCE_CIPHERTEXT_SIZE = 2147483648; // max size of encrypted blob- currently 2GB. internal const byte CustomCipherAlgorithmId = 0; // Id used for custom encryption algorithm. - internal const int AES_256_CBC = 1; internal const int AEAD_AES_256_CBC_HMAC_SHA256 = 2; internal const string ENCLAVE_TYPE_VBS = "VBS"; internal const string ENCLAVE_TYPE_SGX = "SGX"; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs index c6ad7fea14..2ea1ce25c7 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsEnums.cs @@ -148,7 +148,7 @@ internal static class TdsEnums public const byte SQLDEBUG_CMD = 0x60; public const byte SQLLOGINACK = 0xad; public const byte SQLFEATUREEXTACK = 0xae; // TDS 7.4 - feature ack - public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state + public const byte SQLSESSIONSTATE = 0xe4; // TDS 7.4 - connection resiliency session state public const byte SQLENVCHANGE = 0xe3; // Environment change notification public const byte SQLSECLEVEL = 0xed; // Security level token ??? public const byte SQLROWCRC = 0x39; // ROWCRC datastream??? @@ -199,11 +199,11 @@ internal static class TdsEnums public const byte FEATUREEXT_TERMINATOR = 0xFF; public const byte FEATUREEXT_SRECOVERY = 0x01; public const byte FEATUREEXT_FEDAUTH = 0x02; - // 0x03 is for x_eFeatureExtensionId_Rcs + // 0x03 is for x_eFeatureExtensionId_Rcs public const byte FEATUREEXT_TCE = 0x04; public const byte FEATUREEXT_GLOBALTRANSACTIONS = 0x05; - // 0x06 is for x_eFeatureExtensionId_LoginToken - // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry + // 0x06 is for x_eFeatureExtensionId_LoginToken + // 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry public const byte FEATUREEXT_AZURESQLSUPPORT = 0x08; public const byte FEATUREEXT_DATACLASSIFICATION = 0x09; public const byte FEATUREEXT_UTF8SUPPORT = 0x0A; @@ -219,7 +219,7 @@ public enum FeatureExtension : uint GlobalTransactions = 1 << (TdsEnums.FEATUREEXT_GLOBALTRANSACTIONS - 1), AzureSQLSupport = 1 << (TdsEnums.FEATUREEXT_AZURESQLSUPPORT - 1), DataClassification = 1 << (TdsEnums.FEATUREEXT_DATACLASSIFICATION - 1), - UTF8Support = 1 << (TdsEnums.FEATUREEXT_UTF8SUPPORT - 1), + UTF8Support = 1 << (TdsEnums.FEATUREEXT_UTF8SUPPORT - 1), SQLDNSCaching = 1 << (TdsEnums.FEATUREEXT_SQLDNSCACHING - 1) } @@ -264,7 +264,7 @@ public enum ActiveDirectoryWorkflow : byte public const byte MAX_NIC_SIZE = 6; // The size of a MAC or client address public const byte SQLVARIANT_SIZE = 2; // size of the fixed portion of a sql variant (type, cbPropBytes) public const byte VERSION_SIZE = 4; // size of the tds version (4 unsigned bytes) - public const int CLIENT_PROG_VER = 0x06000000; // Client interface version + public const int CLIENT_PROG_VER = 0x06000000; // Client interface version public const int YUKON_LOG_REC_FIXED_LEN = 0x5e; // misc public const int TEXT_TIME_STAMP_LEN = 8; @@ -610,8 +610,8 @@ public enum ActiveDirectoryWorkflow : byte // Login data validation Rules // internal const ushort MAXLEN_HOSTNAME = 128; // the client machine name - internal const ushort MAXLEN_CLIENTID = 128; - internal const ushort MAXLEN_CLIENTSECRET = 128; + internal const ushort MAXLEN_CLIENTID = 128; + internal const ushort MAXLEN_CLIENTSECRET = 128; internal const ushort MAXLEN_APPNAME = 128; // the client application name internal const ushort MAXLEN_SERVERNAME = 128; // the server name internal const ushort MAXLEN_CLIENTINTERFACE = 128; // the interface library name @@ -951,7 +951,6 @@ internal enum FedAuthInfoId : byte internal const long MAX_TCE_CIPHERTEXT_SIZE = 2147483648; // max size of encrypted blob- currently 2GB. internal const byte CustomCipherAlgorithmId = 0; // Id used for custom encryption algorithm. - internal const int AES_256_CBC = 1; internal const int AEAD_AES_256_CBC_HMAC_SHA256 = 2; internal const string ENCLAVE_TYPE_VBS = "VBS"; internal const string ENCLAVE_TYPE_SGX = "SGX"; @@ -1100,7 +1099,7 @@ public enum SqlAuthenticationMethod ActiveDirectoryDeviceCodeFlow, #if ADONET_CERT_AUTH SqlCertificate -#endif +#endif } // This enum indicates the state of TransparentNetworkIPResolution // The first attempt when TNIR is on should be sequential. If the first attempt failes next attempts should be parallel.