Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,7 @@ private OpenIdConnectConfiguration GetOpenIdConfigForSigningKeys(string url, boo
throw SQL.AttestationFailed(string.Format(Strings.GetAttestationTokenSigningKeysFailed, GetInnerMostExceptionMessage(exception)), exception);
}

MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
};
OpenIdConnectConfigurationCache.Set<OpenIdConnectConfiguration>(url, openIdConnectConfig, options);
OpenIdConnectConfigurationCache.Set<OpenIdConnectConfiguration>(url, openIdConnectConfig, absoluteExpirationRelativeToNow: TimeSpan.FromDays(1));
}

return openIdConnectConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,8 @@ protected void GetEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionPa
retryThreadID = Thread.CurrentThread.ManagedThreadId.ToString();
}

MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(ThreadRetryCacheTimeoutInMinutes)
};
ThreadRetryCache.Set<string>(Thread.CurrentThread.ManagedThreadId.ToString(), retryThreadID, options);
ThreadRetryCache.Set<string>(Thread.CurrentThread.ManagedThreadId.ToString(), retryThreadID,
absoluteExpirationRelativeToNow: TimeSpan.FromMinutes(ThreadRetryCacheTimeoutInMinutes));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ namespace Microsoft.Data.SqlClient
// Maintains a cache of SqlEnclaveSession instances
internal class EnclaveSessionCache
{
// Cache timeout of 8 hours to be consistent with JWT validity.
private const int EnclaveCacheTimeOutInHours = 8;

private readonly MemoryCache enclaveMemoryCache = new MemoryCache(new MemoryCacheOptions());
private readonly object enclaveCacheLock = new object();

// Nonce for each message sent by the client to the server to prevent replay attacks by the server,
// given that for Always Encrypted scenarios, the server is considered an "untrusted" man-in-the-middle.
private long _counter;

// Cache timeout of 8 hours to be consistent with jwt validity.
private static int enclaveCacheTimeOutInHours = 8;
Comment on lines -21 to -22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Continue using constant (convert it to const instead)


// Retrieves a SqlEnclaveSession from the cache
internal SqlEnclaveSession GetEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, out long counter)
{
Expand Down Expand Up @@ -62,11 +62,8 @@ internal SqlEnclaveSession CreateSession(EnclaveSessionParameters enclaveSession
lock (enclaveCacheLock)
{
enclaveSession = new SqlEnclaveSession(sharedSecret, sessionId);
MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(enclaveCacheTimeOutInHours)
};
enclaveMemoryCache.Set<SqlEnclaveSession>(cacheKey, enclaveSession, options);
enclaveMemoryCache.Set<SqlEnclaveSession>(cacheKey, enclaveSession,
absoluteExpirationRelativeToNow: TimeSpan.FromHours(EnclaveCacheTimeOutInHours));
counter = Interlocked.Increment(ref _counter);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ internal static class ValueUtilsSmi

// Constants
private const int DefaultBinaryBufferSize = 4096; // Size of the buffer used to read input parameter of type Stream
private const int DefaultTextBufferSize = 4096; // Size of the buffer (in chars) user to read input parameter of type TextReader
private const int DefaultTextBufferSize = 4096; // Size of the buffer (in chars) user to read input parameter of type TextReader

private static XmlWriterSettings s_writerSettings;

//
// User-visible semantics-laden Getter/Setter support methods
Expand Down Expand Up @@ -3457,7 +3459,7 @@ private static void SetSqlXml_Unchecked(ITypedSettersV3 setters, int ordinal, Sq
private static void SetXmlReader_Unchecked(ITypedSettersV3 setters, int ordinal, XmlReader xmlReader)
{
// set up writer
XmlWriterSettings WriterSettings = new XmlWriterSettings
s_writerSettings ??= new XmlWriterSettings
{
CloseOutput = false, // don't close the memory stream
ConformanceLevel = ConformanceLevel.Fragment,
Expand All @@ -3466,7 +3468,7 @@ private static void SetXmlReader_Unchecked(ITypedSettersV3 setters, int ordinal,
};

using (Stream target = new SmiSettersStream(setters, ordinal, SmiMetaData.DefaultXml))
using (XmlWriter xmlWriter = XmlWriter.Create(target, WriterSettings))
using (XmlWriter xmlWriter = XmlWriter.Create(target, s_writerSettings))
{
// now spool the data into the writer (WriteNode will call Read())
xmlReader.Read();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ namespace Microsoft.Data.SqlClient
/// </summary>
internal class ColumnMasterKeyMetadataSignatureVerificationCache
{
private const int _cacheSize = 2000; // Cache size in number of entries.
private const int _cacheTrimThreshold = 300; // Threshold above the cache size when we start trimming.
private const int CacheSize = 2000; // Cache size in number of entries.
private const int CacheTrimThreshold = 300; // Threshold above the cache size when we start trimming.
private const int VerificationCacheTimeOutInDays = 10;

private const string _className = "ColumnMasterKeyMetadataSignatureVerificationCache";
private const string _getSignatureVerificationResultMethodName = "GetSignatureVerificationResult";
Expand Down Expand Up @@ -76,11 +77,7 @@ internal void AddSignatureVerificationResult(string keyStoreName, string masterK
TrimCacheIfNeeded();

// By default evict after 10 days.
MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(10)
};
_cache.Set<bool>(cacheLookupKey, result, options);
_cache.Set<bool>(cacheLookupKey, result, absoluteExpirationRelativeToNow: TimeSpan.FromDays(VerificationCacheTimeOutInDays));
}

private void ValidateSignatureNotNullOrEmpty(byte[] signature, string methodName)
Expand Down Expand Up @@ -117,12 +114,12 @@ private void TrimCacheIfNeeded()
{
// If the size of the cache exceeds the threshold, set that we are in trimming and trim the cache accordingly.
long currentCacheSize = _cache.Count;
if ((currentCacheSize > _cacheSize + _cacheTrimThreshold) && (0 == Interlocked.CompareExchange(ref _inTrim, 1, 0)))
if ((currentCacheSize > CacheSize + CacheTrimThreshold) && (0 == Interlocked.CompareExchange(ref _inTrim, 1, 0)))
{
try
{
// Example: 2301 - 2000 = 301; 301 / 2301 = 0.1308 * 100 = 13% compacting
_cache.Compact((((double)(currentCacheSize - _cacheSize) / (double)currentCacheSize) * 100));
_cache.Compact((((double)(currentCacheSize - CacheSize) / (double)currentCacheSize) * 100));
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ namespace Microsoft.Data.SqlClient
/// </summary>
sealed internal class SqlQueryMetadataCache
{
const int CacheSize = 2000; // Cache size in number of entries.
const int CacheTrimThreshold = 300; // Threshold above the cache size when we start trimming.
private const int CacheSize = 2000; // Cache size in number of entries.
private const int CacheTrimThreshold = 300; // Threshold above the cache size when we start trimming.
private const int MetadataCacheTimeOutInHours = 10;

private readonly MemoryCache _cache;
private static readonly SqlQueryMetadataCache s_singletonInstance = new();
Expand Down Expand Up @@ -235,16 +236,13 @@ internal void AddQueryMetadata(SqlCommand sqlCommand, bool ignoreQueriesWithRetu
}
}

// By default evict after 10 hours.
MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(10)
};
_cache.Set<Dictionary<string, SqlCipherMetadata>>(cacheLookupKey, cipherMetadataDictionary, options);
TimeSpan expirationPeriod = TimeSpan.FromHours(MetadataCacheTimeOutInHours);

_cache.Set<Dictionary<string, SqlCipherMetadata>>(cacheLookupKey, cipherMetadataDictionary, absoluteExpirationRelativeToNow: expirationPeriod);
if (sqlCommand.requiresEnclaveComputations)
{
ConcurrentDictionary<int, SqlTceCipherInfoEntry> keysToBeCached = CreateCopyOfEnclaveKeys(sqlCommand.keysToBeSentToEnclave);
_cache.Set<ConcurrentDictionary<int, SqlTceCipherInfoEntry>>(enclaveLookupKey, keysToBeCached, options);
_cache.Set<ConcurrentDictionary<int, SqlTceCipherInfoEntry>>(enclaveLookupKey, keysToBeCached, absoluteExpirationRelativeToNow: expirationPeriod);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,8 @@ private long TotalLength

sealed internal class SqlStreamingXml
{
private static readonly XmlWriterSettings s_writerSettings = new() { CloseOutput = true, ConformanceLevel = ConformanceLevel.Fragment };

private readonly int _columnOrdinal;
private SqlDataReader _reader;
private XmlReader _xmlReader;
Expand Down Expand Up @@ -509,10 +511,7 @@ public long GetChars(long dataIndex, char[] buffer, int bufferIndex, int length)
SqlStream sqlStream = new(_columnOrdinal, _reader, addByteOrderMark: true, processAllRows:false, advanceReader:false);
_xmlReader = sqlStream.ToXmlReader();
_strWriter = new StringWriter((System.IFormatProvider)null);
XmlWriterSettings writerSettings = new();
writerSettings.CloseOutput = true; // close the memory stream when done
writerSettings.ConformanceLevel = ConformanceLevel.Fragment;
_xmlWriter = XmlWriter.Create(_strWriter, writerSettings);
_xmlWriter = XmlWriter.Create(_strWriter, s_writerSettings);
}

int charsToSkip = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,7 @@ internal SqlClientSymmetricKey GetKey(SqlEncryptionKeyInfo keyInfo, SqlConnectio
{
// In case multiple threads reach here at the same time, the first one wins.
// The allocated memory will be reclaimed by Garbage Collector.
MemoryCacheEntryOptions options = new()
{
AbsoluteExpirationRelativeToNow = SqlConnection.ColumnEncryptionKeyCacheTtl
};
_cache.Set(cacheLookupKey, encryptionKey, options);
_cache.Set(cacheLookupKey, encryptionKey, absoluteExpirationRelativeToNow: SqlConnection.ColumnEncryptionKeyCacheTtl);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ namespace Microsoft.Data.SqlClient
internal sealed partial class TdsParser
{
private static int _objectTypeCount; // EventSource counter
private static XmlWriterSettings s_asyncWriterSettings;
private static XmlWriterSettings s_syncWriterSettings;

private readonly SqlClientLogger _logger = new SqlClientLogger();

private SspiContextProvider _authenticationProvider;
Expand Down Expand Up @@ -12768,13 +12771,9 @@ private async Task WriteXmlFeed(XmlDataFeed feed, TdsParserStateObject stateObj,
preambleToSkip = encoding.GetPreamble();
}

XmlWriterSettings writerSettings = new XmlWriterSettings();
writerSettings.CloseOutput = false; // don't close the memory stream
writerSettings.ConformanceLevel = ConformanceLevel.Fragment;
if (_asyncWrite)
{
writerSettings.Async = true;
}
XmlWriterSettings writerSettings = _asyncWrite
? (s_asyncWriterSettings ??= new() { CloseOutput = false, ConformanceLevel = ConformanceLevel.Fragment, Async = true })
: (s_syncWriterSettings ??= new() { CloseOutput = false, ConformanceLevel = ConformanceLevel.Fragment });

using ConstrainedTextWriter writer = new ConstrainedTextWriter(new StreamWriter(new TdsOutputStream(this, stateObj, preambleToSkip), encoding), size);
using XmlWriter ww = XmlWriter.Create(writer, writerSettings);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal abstract class VirtualizationBasedSecurityEnclaveProviderBase : Enclave

private const int DiffieHellmanKeySize = 384;
private const int VsmHGSProtocolId = (int)SqlConnectionAttestationProtocol.HGS;
private const int RootSigningCertificateCacheTimeOutInDays = 1;

// ENCLAVE_IDENTITY related constants
private static readonly EnclaveIdentity ExpectedPolicy = new EnclaveIdentity()
Expand Down Expand Up @@ -211,11 +212,8 @@ private X509Certificate2Collection GetSigningCertificate(string attestationUrl,
throw SQL.AttestationFailed(string.Format(Strings.GetAttestationSigningCertificateFailedInvalidCertificate, attestationUrl), exception);
}

MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
};
rootSigningCertificateCache.Set<X509Certificate2Collection>(attestationUrl, certificateCollection, options);
rootSigningCertificateCache.Set<X509Certificate2Collection>(attestationUrl, certificateCollection,
absoluteExpirationRelativeToNow: TimeSpan.FromDays(RootSigningCertificateCacheTimeOutInDays));
}

return rootSigningCertificateCache.Get<X509Certificate2Collection>(attestationUrl);
Expand Down
Loading