diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionEnclaveProvider.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionEnclaveProvider.xml
index 4276c98b9f..4b4762439a 100644
--- a/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionEnclaveProvider.xml
+++ b/doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionEnclaveProvider.xml
@@ -17,8 +17,8 @@
The information the provider uses to attest the enclave and generate a symmetric key for the session. The format of this information is specific to the enclave attestation protocol.
-
- A Diffie-Hellman algorithm object that encapsulates a client-side key pair.
+
+ A set of parameters for the attestation process, including the client's Diffie-Hellman key pair.
The set of parameters required for an enclave session.
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs
index 6d26429122..446ec03032 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AzureAttestationBasedEnclaveProvider.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -79,56 +79,35 @@ internal override SqlEnclaveAttestationParameters GetAttestationParameters(strin
return new SqlEnclaveAttestationParameters(AzureBasedAttestationProtocolId, attestationParam, clientDHKey);
}
- // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache.
- internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter)
+ protected override SqlEnclaveSession CreateEnclaveSessionCore(
+ byte[] enclaveAttestationInfo,
+ SqlEnclaveAttestationParameters attestationParameters,
+ EnclaveSessionParameters enclaveSessionParameters,
+ byte[] customData,
+ int customDataLength)
{
- sqlEnclaveSession = null;
- counter = 0;
- try
+ if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl) && customData != null && customDataLength > 0)
{
- ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString());
- sqlEnclaveSession = GetEnclaveSessionFromCache(enclaveSessionParameters, out counter);
- if (sqlEnclaveSession == null)
- {
- if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl) && customData != null && customDataLength > 0)
- {
- byte[] nonce = customData;
+ byte[] nonce = customData;
- IdentityModelEventSource.ShowPII = true;
+ IdentityModelEventSource.ShowPII = true;
- // Deserialize the payload
- AzureAttestationInfo attestInfo = new AzureAttestationInfo(attestationInfo);
+ // Deserialize the payload
+ AzureAttestationInfo attestInfo = new AzureAttestationInfo(enclaveAttestationInfo);
- // Validate the attestation info
- VerifyAzureAttestationInfo(enclaveSessionParameters.AttestationUrl, attestInfo.EnclaveType, attestInfo.AttestationToken.AttestationToken, attestInfo.Identity, nonce);
+ // Validate the attestation info
+ VerifyAzureAttestationInfo(enclaveSessionParameters.AttestationUrl, attestInfo.EnclaveType, attestInfo.AttestationToken.AttestationToken, attestInfo.Identity, nonce);
- // Set up shared secret and validate signature
- byte[] sharedSecret = GetSharedSecret(attestInfo.Identity, nonce, attestInfo.EnclaveType, attestInfo.EnclaveDHInfo, clientDHKey);
+ // Set up shared secret and validate signature
+ byte[] sharedSecret = GetSharedSecret(attestInfo.Identity, nonce, attestInfo.EnclaveType, attestInfo.EnclaveDHInfo, attestationParameters.ClientDiffieHellmanKey);
- // add session to cache
- sqlEnclaveSession = AddEnclaveSessionToCache(enclaveSessionParameters, sharedSecret, attestInfo.SessionId, out counter);
- }
- else
- {
- throw SQL.AttestationFailed(Strings.FailToCreateEnclaveSession);
- }
- }
+ return new SqlEnclaveSession(sharedSecret, attestInfo.SessionId);
}
- finally
+ else
{
- // As per current design, we want to minimize the number of create session calls. To achieve this we block all the GetEnclaveSession calls until the first call to
- // GetEnclaveSession -> GetAttestationParameters -> CreateEnclaveSession completes or the event timeout happen.
- // Case 1: When the first request successfully creates the session, then all outstanding GetEnclaveSession will use the current session.
- // Case 2: When the first request unable to create the enclave session (may be due to some error or the first request doesn't require enclave computation) then in those case we set the event timeout to 0.
- UpdateEnclaveSessionLockStatus(sqlEnclaveSession);
+ throw SQL.AttestationFailed(Strings.FailToCreateEnclaveSession);
}
}
-
- // When overridden in a derived class, looks up and evicts an enclave session from the enclave session cache, if the provider implements session caching.
- internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSessionToInvalidate)
- {
- InvalidateEnclaveSessionHelper(enclaveSessionParameters, enclaveSessionToInvalidate);
- }
#endregion
#region Internal Class
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs
index 8b461087bd..8b3c5b5360 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveDelegate.Crypto.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -47,7 +47,7 @@ internal void CreateEnclaveSession(SqlConnectionAttestationProtocol attestationP
sqlColumnEncryptionEnclaveProvider.CreateEnclaveSession(
attestationInfo,
- attestationParameters.ClientDiffieHellmanKey,
+ attestationParameters,
enclaveSessionParameters,
customData,
customDataLength,
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs
index c81f04471c..be5ecd743c 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveProviderBase.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -88,6 +88,9 @@ internal abstract class EnclaveProviderBase : SqlColumnEncryptionEnclaveProvider
#endregion
#region protected methods
+ // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session and creates an enclave session.
+ protected abstract SqlEnclaveSession CreateEnclaveSessionCore(byte[] enclaveAttestationInfo, SqlEnclaveAttestationParameters attestationParameters, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength);
+
// Helper method to get the enclave session from the cache if present
protected void GetEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionParameters, bool shouldGenerateNonce, bool isRetry, out SqlEnclaveSession sqlEnclaveSession, out long counter, out byte[] customData, out int customDataLength)
{
@@ -173,8 +176,39 @@ protected void GetEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionPa
}
}
+ // Calls CreateEnclaveSessionCore to create an enclave session and stores the session information in the cache.
+ internal override void CreateEnclaveSession(byte[] attestationInfo, SqlEnclaveAttestationParameters attestationParameters, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter)
+ {
+ sqlEnclaveSession = null;
+ counter = 0;
+ try
+ {
+ ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString());
+ sqlEnclaveSession = SessionCache.GetEnclaveSession(enclaveSessionParameters, out counter);
+ if (sqlEnclaveSession == null)
+ {
+ // Add session to cache
+ sqlEnclaveSession = CreateEnclaveSessionCore(attestationInfo, attestationParameters, enclaveSessionParameters, customData, customDataLength);
+ SessionCache.CreateSession(enclaveSessionParameters, sqlEnclaveSession, out counter);
+ }
+ }
+ finally
+ {
+ // As per current design, we want to minimize the number of create session calls. To achieve this we block all the GetEnclaveSession calls until the first call to
+ // GetEnclaveSession -> GetAttestationParameters -> CreateEnclaveSession completes or the event timeout happen.
+ // Case 1: When the first request successfully creates the session, then all outstanding GetEnclaveSession will use the current session.
+ // Case 2: When the first request unable to create the enclave session (may be due to some error or the first request doesn't require enclave computation) then in those case we set the event timeout to 0.
+ UpdateEnclaveSessionLockStatus(sqlEnclaveSession);
+ }
+ }
+
+ internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSessionToInvalidate)
+ {
+ SessionCache.InvalidateSession(enclaveSessionParameters, enclaveSessionToInvalidate);
+ }
+
// Reset the session lock status
- protected void UpdateEnclaveSessionLockStatus(SqlEnclaveSession sqlEnclaveSession)
+ private void UpdateEnclaveSessionLockStatus(SqlEnclaveSession sqlEnclaveSession)
{
// As per current design, we want to minimize the number of create session calls. To achieve this we block all the GetEnclaveSession calls until the first call to
// GetEnclaveSession -> GetAttestationParameters -> CreateEnclaveSession completes or the event timeout happens.
@@ -193,24 +227,6 @@ protected void UpdateEnclaveSessionLockStatus(SqlEnclaveSession sqlEnclaveSessio
}
}
}
-
- // Helper method to remove the enclave session from the cache
- protected void InvalidateEnclaveSessionHelper(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSessionToInvalidate)
- {
- SessionCache.InvalidateSession(enclaveSessionParameters, enclaveSessionToInvalidate);
- }
-
- // Helper method for getting the enclave session from the session cache
- protected SqlEnclaveSession GetEnclaveSessionFromCache(EnclaveSessionParameters enclaveSessionParameters, out long counter)
- {
- return SessionCache.GetEnclaveSession(enclaveSessionParameters, out counter);
- }
-
- // Helper method for adding the enclave session to the session cache
- protected SqlEnclaveSession AddEnclaveSessionToCache(EnclaveSessionParameters enclaveSessionParameters, byte[] sharedSecret, long sessionId, out long counter)
- {
- return SessionCache.CreateSession(enclaveSessionParameters, sharedSecret, sessionId, out counter);
- }
}
#endregion
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs
index c3845244f3..6dfeee8ba7 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -54,20 +54,16 @@ internal void InvalidateSession(EnclaveSessionParameters enclaveSessionParameter
}
}
- // Creates a new SqlEnclaveSession and adds it to the cache
- internal SqlEnclaveSession CreateSession(EnclaveSessionParameters enclaveSessionParameters, byte[] sharedSecret, long sessionId, out long counter)
+ // Adds a new SqlEnclaveSession to the cache
+ internal void CreateSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSession, out long counter)
{
string cacheKey = GenerateCacheKey(enclaveSessionParameters);
- SqlEnclaveSession enclaveSession = null;
lock (enclaveCacheLock)
{
- enclaveSession = new SqlEnclaveSession(sharedSecret, sessionId);
enclaveMemoryCache.Set(cacheKey, enclaveSession,
absoluteExpirationRelativeToNow: s_enclaveCacheTimeout);
counter = Interlocked.Increment(ref _counter);
}
-
- return enclaveSession;
}
// Generates the cache key for the enclave session cache
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs
index fabd69c976..aebb160fd9 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/NoneAttestationEnclaveProvider.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -30,77 +30,52 @@ internal override SqlEnclaveAttestationParameters GetAttestationParameters(strin
return new SqlEnclaveAttestationParameters(NoneAttestationProtocolId, Array.Empty(), clientDHKey);
}
- // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates an enclave session and stores the session information in the cache.
- internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter)
+ protected override SqlEnclaveSession CreateEnclaveSessionCore(
+ byte[] enclaveAttestationInfo,
+ SqlEnclaveAttestationParameters attestationParameters,
+ EnclaveSessionParameters enclaveSessionParameters,
+ byte[] customData,
+ int customDataLength)
{
- // for None attestation: enclave does not send public key, and sends an empty attestation info
- // The only non-trivial content it sends is the session setup info (DH pubkey of enclave)
-
- sqlEnclaveSession = null;
- counter = 0;
- try
- {
- ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString());
- sqlEnclaveSession = GetEnclaveSessionFromCache(enclaveSessionParameters, out counter);
-
- if (sqlEnclaveSession == null)
- {
- // Read AttestationInfo
- int attestationInfoOffset = 0;
- uint sizeOfTrustedModuleAttestationInfoBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
- attestationInfoOffset += sizeof(UInt32);
- int sizeOfTrustedModuleAttestationInfoBufferInt = checked((int)sizeOfTrustedModuleAttestationInfoBuffer);
- Debug.Assert(sizeOfTrustedModuleAttestationInfoBuffer == 0);
-
- // read secure session info
- uint sizeOfSecureSessionInfoResponse = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
- attestationInfoOffset += sizeof(UInt32);
-
- byte[] enclaveSessionHandle = new byte[EnclaveSessionHandleSize];
- Buffer.BlockCopy(attestationInfo, attestationInfoOffset, enclaveSessionHandle, 0, EnclaveSessionHandleSize);
- attestationInfoOffset += EnclaveSessionHandleSize;
-
- uint sizeOfTrustedModuleDHPublicKeyBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
- attestationInfoOffset += sizeof(UInt32);
- uint sizeOfTrustedModuleDHPublicKeySignatureBuffer = BitConverter.ToUInt32(attestationInfo, attestationInfoOffset);
- attestationInfoOffset += sizeof(UInt32);
- int sizeOfTrustedModuleDHPublicKeyBufferInt = checked((int)sizeOfTrustedModuleDHPublicKeyBuffer);
-
- byte[] trustedModuleDHPublicKey = new byte[sizeOfTrustedModuleDHPublicKeyBuffer];
- Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKey, 0,
- sizeOfTrustedModuleDHPublicKeyBufferInt);
- attestationInfoOffset += sizeOfTrustedModuleDHPublicKeyBufferInt;
-
- byte[] trustedModuleDHPublicKeySignature = new byte[sizeOfTrustedModuleDHPublicKeySignatureBuffer];
- Buffer.BlockCopy(attestationInfo, attestationInfoOffset, trustedModuleDHPublicKeySignature, 0,
- checked((int)sizeOfTrustedModuleDHPublicKeySignatureBuffer));
-
- byte[] sharedSecret;
- using ECDiffieHellman ecdh = KeyConverter.CreateECDiffieHellmanFromPublicKeyBlob(trustedModuleDHPublicKey);
- sharedSecret = KeyConverter.DeriveKey(clientDHKey, ecdh.PublicKey);
- long sessionId = BitConverter.ToInt64(enclaveSessionHandle, 0);
- sqlEnclaveSession = AddEnclaveSessionToCache(enclaveSessionParameters, sharedSecret, sessionId, out counter);
-
- if (sqlEnclaveSession is null)
- {
- throw SQL.AttestationFailed(Strings.FailToCreateEnclaveSession);
- }
- }
- }
- finally
- {
- UpdateEnclaveSessionLockStatus(sqlEnclaveSession);
- }
- }
-
- ///
- /// When overridden in a derived class, looks up and evicts an enclave session from the enclave session cache, if the provider implements session caching.
- ///
- /// The set of parameters required for enclave session.
- /// The session to be invalidated.
- internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSessionToInvalidate)
- {
- InvalidateEnclaveSessionHelper(enclaveSessionParameters, enclaveSessionToInvalidate);
+ // For None attestation: enclave does not send public key, and sends an empty attestation info.
+ // The only non-trivial content it sends is the session setup info (DH pubkey of enclave.)
+
+ // Read AttestationInfo
+ int attestationInfoOffset = 0;
+ uint sizeOfTrustedModuleAttestationInfoBuffer = BitConverter.ToUInt32(enclaveAttestationInfo, attestationInfoOffset);
+ attestationInfoOffset += sizeof(UInt32);
+ int sizeOfTrustedModuleAttestationInfoBufferInt = checked((int)sizeOfTrustedModuleAttestationInfoBuffer);
+ Debug.Assert(sizeOfTrustedModuleAttestationInfoBuffer == 0);
+
+ // read secure session info
+ uint sizeOfSecureSessionInfoResponse = BitConverter.ToUInt32(enclaveAttestationInfo, attestationInfoOffset);
+ attestationInfoOffset += sizeof(UInt32);
+
+ byte[] enclaveSessionHandle = new byte[EnclaveSessionHandleSize];
+ Buffer.BlockCopy(enclaveAttestationInfo, attestationInfoOffset, enclaveSessionHandle, 0, EnclaveSessionHandleSize);
+ attestationInfoOffset += EnclaveSessionHandleSize;
+
+ uint sizeOfTrustedModuleDHPublicKeyBuffer = BitConverter.ToUInt32(enclaveAttestationInfo, attestationInfoOffset);
+ attestationInfoOffset += sizeof(UInt32);
+ uint sizeOfTrustedModuleDHPublicKeySignatureBuffer = BitConverter.ToUInt32(enclaveAttestationInfo, attestationInfoOffset);
+ attestationInfoOffset += sizeof(UInt32);
+ int sizeOfTrustedModuleDHPublicKeyBufferInt = checked((int)sizeOfTrustedModuleDHPublicKeyBuffer);
+
+ byte[] trustedModuleDHPublicKey = new byte[sizeOfTrustedModuleDHPublicKeyBuffer];
+ Buffer.BlockCopy(enclaveAttestationInfo, attestationInfoOffset, trustedModuleDHPublicKey, 0,
+ sizeOfTrustedModuleDHPublicKeyBufferInt);
+ attestationInfoOffset += sizeOfTrustedModuleDHPublicKeyBufferInt;
+
+ byte[] trustedModuleDHPublicKeySignature = new byte[sizeOfTrustedModuleDHPublicKeySignatureBuffer];
+ Buffer.BlockCopy(enclaveAttestationInfo, attestationInfoOffset, trustedModuleDHPublicKeySignature, 0,
+ checked((int)sizeOfTrustedModuleDHPublicKeySignatureBuffer));
+
+ byte[] sharedSecret;
+ using ECDiffieHellman ecdh = KeyConverter.CreateECDiffieHellmanFromPublicKeyBlob(trustedModuleDHPublicKey);
+ sharedSecret = KeyConverter.DeriveKey(attestationParameters.ClientDiffieHellmanKey, ecdh.PublicKey);
+ long sessionId = BitConverter.ToInt64(enclaveSessionHandle, 0);
+
+ return new SqlEnclaveSession(sharedSecret, sessionId);
}
}
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.cs
index 21a62a80c3..265d262193 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionEnclaveProvider.cs
@@ -1,9 +1,7 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.Security.Cryptography;
-
namespace Microsoft.Data.SqlClient
{
///
@@ -16,7 +14,7 @@ internal abstract class SqlColumnEncryptionEnclaveProvider
internal abstract SqlEnclaveAttestationParameters GetAttestationParameters(string attestationUrl, byte[] customData, int customDataLength);
///
- internal abstract void CreateEnclaveSession(byte[] enclaveAttestationInfo, ECDiffieHellman clientDiffieHellmanKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter);
+ internal abstract void CreateEnclaveSession(byte[] enclaveAttestationInfo, SqlEnclaveAttestationParameters attestationParameters, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter);
///
internal abstract void InvalidateEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSession);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs
index a3b4545d03..03ad23c83a 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -100,52 +100,34 @@ internal override SqlEnclaveAttestationParameters GetAttestationParameters(strin
return new SqlEnclaveAttestationParameters(VsmHGSProtocolId, Array.Empty(), clientDHKey);
}
- // When overridden in a derived class, performs enclave attestation, generates a symmetric key for the session, creates a an enclave session and stores the session information in the cache.
- internal override void CreateEnclaveSession(byte[] attestationInfo, ECDiffieHellman clientDHKey, EnclaveSessionParameters enclaveSessionParameters, byte[] customData, int customDataLength, out SqlEnclaveSession sqlEnclaveSession, out long counter)
+ protected override SqlEnclaveSession CreateEnclaveSessionCore(
+ byte[] enclaveAttestationInfo,
+ SqlEnclaveAttestationParameters attestationParameters,
+ EnclaveSessionParameters enclaveSessionParameters,
+ byte[] customData,
+ int customDataLength)
{
- sqlEnclaveSession = null;
- counter = 0;
- try
+ if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl))
{
- ThreadRetryCache.Remove(Thread.CurrentThread.ManagedThreadId.ToString());
- sqlEnclaveSession = GetEnclaveSessionFromCache(enclaveSessionParameters, out counter);
- if (sqlEnclaveSession == null)
- {
- if (!string.IsNullOrEmpty(enclaveSessionParameters.AttestationUrl))
- {
- // Deserialize the payload
- AttestationInfo info = new AttestationInfo(attestationInfo);
+ // Deserialize the payload
+ AttestationInfo info = new AttestationInfo(enclaveAttestationInfo);
- // Verify enclave policy matches expected policy
- VerifyEnclavePolicy(info.EnclaveReportPackage);
+ // Verify enclave policy matches expected policy
+ VerifyEnclavePolicy(info.EnclaveReportPackage);
- // Perform Attestation per VSM protocol
- VerifyAttestationInfo(enclaveSessionParameters.AttestationUrl, info.HealthReport, info.EnclaveReportPackage);
+ // Perform Attestation per VSM protocol
+ VerifyAttestationInfo(enclaveSessionParameters.AttestationUrl, info.HealthReport, info.EnclaveReportPackage);
- // Set up shared secret and validate signature
- byte[] sharedSecret = GetSharedSecret(info.Identity, info.EnclaveDHInfo, clientDHKey);
+ // Set up shared secret and validate signature
+ byte[] sharedSecret = GetSharedSecret(info.Identity, info.EnclaveDHInfo, attestationParameters.ClientDiffieHellmanKey);
- // add session to cache
- sqlEnclaveSession = AddEnclaveSessionToCache(enclaveSessionParameters, sharedSecret, info.SessionId, out counter);
- }
- else
- {
- throw SQL.AttestationFailed(Strings.FailToCreateEnclaveSession);
- }
- }
+ return new SqlEnclaveSession(sharedSecret, info.SessionId);
}
- finally
+ else
{
- UpdateEnclaveSessionLockStatus(sqlEnclaveSession);
+ throw SQL.AttestationFailed(Strings.FailToCreateEnclaveSession);
}
}
-
- // When overridden in a derived class, looks up and evicts an enclave session from the enclave session cache, if the provider implements session caching.
- internal override void InvalidateEnclaveSession(EnclaveSessionParameters enclaveSessionParameters, SqlEnclaveSession enclaveSessionToInvalidate)
- {
- InvalidateEnclaveSessionHelper(enclaveSessionParameters, enclaveSessionToInvalidate);
- }
-
#endregion
#region Private helpers