diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainerExtensions.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainerExtensions.cs
index b20758d1bc..c0852f9be5 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainerExtensions.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionContainerExtensions.cs
@@ -29,7 +29,7 @@ public static class EncryptionContainerExtensions
///
///
///
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClient.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClient.cs
index 8779f61a93..89dfc4b7bd 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClient.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClient.cs
@@ -8,25 +8,26 @@ namespace Microsoft.Azure.Cosmos.Encryption
using System.Net;
using System.Threading;
using System.Threading.Tasks;
- using Microsoft.Data.Encryption.Cryptography;
///
/// CosmosClient with Encryption support.
///
internal sealed class EncryptionCosmosClient : CosmosClient
{
+ internal static readonly SemaphoreSlim EncryptionKeyCacheSemaphore = new SemaphoreSlim(1, 1);
+
private readonly CosmosClient cosmosClient;
private readonly AsyncCache clientEncryptionKeyPropertiesCacheByKeyId;
- public EncryptionCosmosClient(CosmosClient cosmosClient, EncryptionKeyStoreProvider encryptionKeyStoreProvider)
+ public EncryptionCosmosClient(CosmosClient cosmosClient, EncryptionKeyWrapProvider encryptionKeyWrapProvider)
{
this.cosmosClient = cosmosClient ?? throw new ArgumentNullException(nameof(cosmosClient));
- this.EncryptionKeyStoreProvider = encryptionKeyStoreProvider ?? throw new ArgumentNullException(nameof(encryptionKeyStoreProvider));
+ this.EncryptionKeyWrapProvider = encryptionKeyWrapProvider ?? throw new ArgumentNullException(nameof(encryptionKeyWrapProvider));
this.clientEncryptionKeyPropertiesCacheByKeyId = new AsyncCache();
}
- public EncryptionKeyStoreProvider EncryptionKeyStoreProvider { get; }
+ public EncryptionKeyWrapProvider EncryptionKeyWrapProvider { get; }
public override CosmosClientOptions ClientOptions => this.cosmosClient.ClientOptions;
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClientExtensions.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClientExtensions.cs
index 2419e78676..ad2077f3dc 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClientExtensions.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionCosmosClientExtensions.cs
@@ -16,15 +16,15 @@ public static class EncryptionCosmosClientExtensions
/// Get Cosmos Client with Encryption support for performing operations using client-side encryption.
///
/// Regular Cosmos Client.
- /// EncryptionKeyStoreProvider, provider that allows interaction with the master keys.
+ /// EncryptionKeyWrapProvider, provider that allows interaction with the master keys.
/// CosmosClient to perform operations supporting client-side encryption / decryption.
public static CosmosClient WithEncryption(
this CosmosClient cosmosClient,
- EncryptionKeyStoreProvider encryptionKeyStoreProvider)
+ EncryptionKeyWrapProvider encryptionKeyWrapProvider)
{
- if (encryptionKeyStoreProvider == null)
+ if (encryptionKeyWrapProvider == null)
{
- throw new ArgumentNullException(nameof(encryptionKeyStoreProvider));
+ throw new ArgumentNullException(nameof(encryptionKeyWrapProvider));
}
if (cosmosClient == null)
@@ -32,19 +32,7 @@ public static CosmosClient WithEncryption(
throw new ArgumentNullException(nameof(cosmosClient));
}
- // set the TTL for ProtectedDataEncryption at the Encryption CosmosClient Init so that we have a uniform expiry of the KeyStoreProvider and ProtectedDataEncryption cache items.
- if (encryptionKeyStoreProvider.DataEncryptionKeyCacheTimeToLive.HasValue)
- {
- ProtectedDataEncryptionKey.TimeToLive = encryptionKeyStoreProvider.DataEncryptionKeyCacheTimeToLive.Value;
- }
- else
- {
- // If null is passed to DataEncryptionKeyCacheTimeToLive it results in forever caching hence setting
- // arbitrarily large caching period. ProtectedDataEncryptionKey does not seem to handle TimeSpan.MaxValue.
- ProtectedDataEncryptionKey.TimeToLive = TimeSpan.FromDays(36500);
- }
-
- return new EncryptionCosmosClient(cosmosClient, encryptionKeyStoreProvider);
+ return new EncryptionCosmosClient(cosmosClient, encryptionKeyWrapProvider);
}
}
}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionDatabaseExtensions.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionDatabaseExtensions.cs
index 1a323f6d89..417c9f3856 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionDatabaseExtensions.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionDatabaseExtensions.cs
@@ -38,7 +38,7 @@ public static class EncryptionDatabaseExtensions
public static async Task CreateClientEncryptionKeyAsync(
this Database database,
string clientEncryptionKeyId,
- DataEncryptionKeyAlgorithm dataEncryptionKeyAlgorithm,
+ string dataEncryptionKeyAlgorithm,
EncryptionKeyWrapMetadata encryptionKeyWrapMetadata,
CancellationToken cancellationToken = default)
{
@@ -49,11 +49,9 @@ public static async Task CreateClientEncryptionKeyA
throw new ArgumentNullException(nameof(clientEncryptionKeyId));
}
- string encryptionAlgorithm = dataEncryptionKeyAlgorithm.ToString();
-
- if (!string.Equals(encryptionAlgorithm, DataEncryptionKeyAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256.ToString()))
+ if (!string.Equals(dataEncryptionKeyAlgorithm, DataEncryptionKeyAlgorithm.AeadAes256CbcHmacSha256))
{
- throw new ArgumentException($"Invalid Encryption Algorithm '{encryptionAlgorithm}' passed. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
+ throw new ArgumentException($"Invalid Encryption Algorithm '{dataEncryptionKeyAlgorithm}' passed. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
}
if (encryptionKeyWrapMetadata == null)
@@ -65,17 +63,17 @@ public static async Task CreateClientEncryptionKeyA
? encryptionDatabase.EncryptionCosmosClient
: throw new ArgumentException("Creating a ClientEncryptionKey resource requires the use of an encryption - enabled client. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
- EncryptionKeyStoreProvider encryptionKeyStoreProvider = encryptionCosmosClient.EncryptionKeyStoreProvider;
+ EncryptionKeyWrapProvider encryptionKeyWrapProvider = encryptionCosmosClient.EncryptionKeyWrapProvider;
- if (!string.Equals(encryptionKeyWrapMetadata.Type, encryptionKeyStoreProvider.ProviderName))
+ if (!string.Equals(encryptionKeyWrapMetadata.Type, encryptionKeyWrapProvider.ProviderName))
{
- throw new ArgumentException("The EncryptionKeyWrapMetadata Type value does not match with the ProviderName of EncryptionKeyStoreProvider configured on the Client. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
+ throw new ArgumentException("The EncryptionKeyWrapMetadata Type value does not match with the ProviderName of EncryptionKeyWrapProvider configured on the Client. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
}
KeyEncryptionKey keyEncryptionKey = KeyEncryptionKey.GetOrCreate(
encryptionKeyWrapMetadata.Name,
encryptionKeyWrapMetadata.Value,
- encryptionKeyStoreProvider);
+ encryptionKeyWrapProvider.EncryptionKeyStoreProviderImpl);
ProtectedDataEncryptionKey protectedDataEncryptionKey = new ProtectedDataEncryptionKey(
clientEncryptionKeyId,
@@ -91,7 +89,7 @@ public static async Task CreateClientEncryptionKeyA
ClientEncryptionKeyProperties clientEncryptionKeyProperties = new ClientEncryptionKeyProperties(
clientEncryptionKeyId,
- encryptionAlgorithm,
+ dataEncryptionKeyAlgorithm,
wrappedDataEncryptionKey,
encryptionKeyWrapMetadata);
@@ -145,11 +143,11 @@ public static async Task RewrapClientEncryptionKeyA
? encryptionDatabase.EncryptionCosmosClient
: throw new ArgumentException("Rewraping a ClientEncryptionKey requires the use of an encryption - enabled client. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
- EncryptionKeyStoreProvider encryptionKeyStoreProvider = encryptionCosmosClient.EncryptionKeyStoreProvider;
+ EncryptionKeyWrapProvider encryptionKeyWrapProvider = encryptionCosmosClient.EncryptionKeyWrapProvider;
- if (!string.Equals(newEncryptionKeyWrapMetadata.Type, encryptionKeyStoreProvider.ProviderName))
+ if (!string.Equals(newEncryptionKeyWrapMetadata.Type, encryptionKeyWrapProvider.ProviderName))
{
- throw new ArgumentException("The EncryptionKeyWrapMetadata Type value does not match with the ProviderName of EncryptionKeyStoreProvider configured on the Client. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
+ throw new ArgumentException("The EncryptionKeyWrapMetadata Type value does not match with the ProviderName of EncryptionKeyWrapProvider configured on the Client. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
}
ClientEncryptionKeyProperties clientEncryptionKeyProperties = await clientEncryptionKey.ReadAsync(cancellationToken: cancellationToken);
@@ -162,14 +160,14 @@ public static async Task RewrapClientEncryptionKeyA
KeyEncryptionKey keyEncryptionKey = KeyEncryptionKey.GetOrCreate(
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata.Name,
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata.Value,
- encryptionKeyStoreProvider);
+ encryptionKeyWrapProvider.EncryptionKeyStoreProviderImpl);
byte[] unwrappedKey = keyEncryptionKey.DecryptEncryptionKey(clientEncryptionKeyProperties.WrappedDataEncryptionKey);
keyEncryptionKey = KeyEncryptionKey.GetOrCreate(
newEncryptionKeyWrapMetadata.Name,
newEncryptionKeyWrapMetadata.Value,
- encryptionKeyStoreProvider);
+ encryptionKeyWrapProvider.EncryptionKeyStoreProviderImpl);
byte[] rewrappedKey = keyEncryptionKey.EncryptEncryptionKey(unwrappedKey);
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettingForProperty.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettingForProperty.cs
index 45b2a37c51..bf7103faa2 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettingForProperty.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettingForProperty.cs
@@ -13,15 +13,13 @@ namespace Microsoft.Azure.Cosmos.Encryption
internal sealed class EncryptionSettingForProperty
{
- private static readonly SemaphoreSlim EncryptionKeyCacheSemaphore = new SemaphoreSlim(1, 1);
-
private readonly string databaseRid;
private readonly EncryptionContainer encryptionContainer;
public EncryptionSettingForProperty(
string clientEncryptionKeyId,
- EncryptionType encryptionType,
+ Data.Encryption.Cryptography.EncryptionType encryptionType,
EncryptionContainer encryptionContainer,
string databaseRid)
{
@@ -33,7 +31,7 @@ public EncryptionSettingForProperty(
public string ClientEncryptionKeyId { get; }
- public EncryptionType EncryptionType { get; }
+ public Data.Encryption.Cryptography.EncryptionType EncryptionType { get; }
public async Task BuildEncryptionAlgorithmForSettingAsync(CancellationToken cancellationToken)
{
@@ -52,7 +50,7 @@ public async Task BuildEncryptionAlgori
// Here a request is sent out to unwrap using the Master Key configured via the Key Encryption Key.
protectedDataEncryptionKey = await this.BuildProtectedDataEncryptionKeyAsync(
clientEncryptionKeyProperties,
- this.encryptionContainer.EncryptionCosmosClient.EncryptionKeyStoreProvider,
+ this.encryptionContainer.EncryptionCosmosClient.EncryptionKeyWrapProvider,
this.ClientEncryptionKeyId,
cancellationToken);
}
@@ -75,7 +73,7 @@ public async Task BuildEncryptionAlgori
// try to build the ProtectedDataEncryptionKey. If it fails, try to force refresh the gateway cache and get the latest client encryption key.
protectedDataEncryptionKey = await this.BuildProtectedDataEncryptionKeyAsync(
clientEncryptionKeyProperties,
- this.encryptionContainer.EncryptionCosmosClient.EncryptionKeyStoreProvider,
+ this.encryptionContainer.EncryptionCosmosClient.EncryptionKeyWrapProvider,
this.ClientEncryptionKeyId,
cancellationToken);
}
@@ -143,7 +141,7 @@ private async Task ForceRefreshGatewayCacheAndBuildP
ProtectedDataEncryptionKey protectedDataEncryptionKey = await this.BuildProtectedDataEncryptionKeyAsync(
clientEncryptionKeyProperties,
- this.encryptionContainer.EncryptionCosmosClient.EncryptionKeyStoreProvider,
+ this.encryptionContainer.EncryptionCosmosClient.EncryptionKeyWrapProvider,
this.ClientEncryptionKeyId,
cancellationToken);
@@ -152,18 +150,18 @@ private async Task ForceRefreshGatewayCacheAndBuildP
private async Task BuildProtectedDataEncryptionKeyAsync(
ClientEncryptionKeyProperties clientEncryptionKeyProperties,
- EncryptionKeyStoreProvider encryptionKeyStoreProvider,
+ EncryptionKeyWrapProvider encryptionKeyWrapProvider,
string keyId,
CancellationToken cancellationToken)
{
- if (await EncryptionKeyCacheSemaphore.WaitAsync(-1, cancellationToken))
+ if (await EncryptionCosmosClient.EncryptionKeyCacheSemaphore.WaitAsync(-1, cancellationToken))
{
try
{
KeyEncryptionKey keyEncryptionKey = KeyEncryptionKey.GetOrCreate(
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata.Name,
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata.Value,
- encryptionKeyStoreProvider);
+ encryptionKeyWrapProvider.EncryptionKeyStoreProviderImpl);
ProtectedDataEncryptionKey protectedDataEncryptionKey = ProtectedDataEncryptionKey.GetOrCreate(
keyId,
@@ -174,7 +172,7 @@ private async Task BuildProtectedDataEncryptionKeyAs
}
finally
{
- EncryptionKeyCacheSemaphore.Release(1);
+ EncryptionCosmosClient.EncryptionKeyCacheSemaphore.Release(1);
}
}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettings.cs b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettings.cs
index 5078fa3eb2..074d8a5c1f 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettings.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/EncryptionSettings.cs
@@ -49,12 +49,12 @@ public void SetRequestHeaders(RequestOptions requestOptions)
};
}
- private static EncryptionType GetEncryptionTypeForProperty(ClientEncryptionIncludedPath clientEncryptionIncludedPath)
+ private static Data.Encryption.Cryptography.EncryptionType GetEncryptionTypeForProperty(ClientEncryptionIncludedPath clientEncryptionIncludedPath)
{
return clientEncryptionIncludedPath.EncryptionType switch
{
- CosmosEncryptionType.Deterministic => EncryptionType.Deterministic,
- CosmosEncryptionType.Randomized => EncryptionType.Randomized,
+ EncryptionType.Deterministic => Data.Encryption.Cryptography.EncryptionType.Deterministic,
+ EncryptionType.Randomized => Data.Encryption.Cryptography.EncryptionType.Randomized,
_ => throw new ArgumentException($"Invalid encryption type {clientEncryptionIncludedPath.EncryptionType}. Please refer to https://aka.ms/CosmosClientEncryption for more details. "),
};
}
@@ -102,7 +102,7 @@ await encryptionContainer.EncryptionCosmosClient.GetClientEncryptionKeyPropertie
// update the property level setting.
foreach (ClientEncryptionIncludedPath propertyToEncrypt in clientEncryptionPolicy.IncludedPaths)
{
- EncryptionType encryptionType = GetEncryptionTypeForProperty(propertyToEncrypt);
+ Data.Encryption.Cryptography.EncryptionType encryptionType = GetEncryptionTypeForProperty(propertyToEncrypt);
EncryptionSettingForProperty encryptionSettingsForProperty = new EncryptionSettingForProperty(
propertyToEncrypt.ClientEncryptionKeyId,
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/AzureKeyVaultKeyWrapProvider.cs b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/AzureKeyVaultKeyWrapProvider.cs
new file mode 100644
index 0000000000..3945d380c1
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/AzureKeyVaultKeyWrapProvider.cs
@@ -0,0 +1,77 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Encryption
+{
+ using System;
+ using System.Threading.Tasks;
+ using global::Azure.Core;
+ using Microsoft.Data.Encryption.AzureKeyVaultProvider;
+
+ ///
+ /// Implementation of key encryption key store provider that allows client applications to access data when a
+ /// key encryption key is stored in Microsoft Azure Key Vault.
+ ///
+ public sealed class AzureKeyVaultKeyWrapProvider : EncryptionKeyWrapProvider
+ {
+ private readonly AzureKeyVaultKeyStoreProvider azureKeyVaultKeyStoreProvider;
+
+ ///
+ /// Initializes a new instance of the class.
+ /// Constructor that takes an implementation of Token Credential that is capable of providing an OAuth Token.
+ ///
+ /// returns token credentials.
+ public AzureKeyVaultKeyWrapProvider(TokenCredential tokenCredential)
+ {
+ // just rely on cache managed via EncryptionKeyWrapProvider. Setting DataEncryptionKeyCacheTimeToLive to zero results in not using azureKeyVaultKeyWrapProvider cache.
+ this.azureKeyVaultKeyStoreProvider = new AzureKeyVaultKeyStoreProvider(tokenCredential)
+ {
+ DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero,
+ };
+ }
+
+ ///
+ /// Gets name of the Encryption Key Store Provider implementation.
+ ///
+ public override string ProviderName => this.azureKeyVaultKeyStoreProvider.ProviderName;
+
+ ///
+ /// This function uses the asymmetric key specified by the key path
+ /// and decrypts an encrypted data dencryption key with RSA encryption algorithm.
+ /// .
+ /// Identifier of an asymmetric key in Azure Key Vault.
+ /// The key encryption algorithm.
+ /// The ciphertext key.
+ /// Plain text data encryption key.
+ public override Task UnwrapKeyAsync(string encryptionKeyId, string cosmosKeyEncryptionKeyAlgorithm, byte[] encryptedKey)
+ {
+ Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm keyEncryptionKeyAlgorithm = cosmosKeyEncryptionKeyAlgorithm switch
+ {
+ KeyEncryptionKeyAlgorithm.RsaOaep => Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm.RSA_OAEP,
+ _ => throw new NotSupportedException("The specified KeyEncryptionAlgorithm is not supported. Please refer to https://aka.ms/CosmosClientEncryption for more details. "),
+ };
+
+ return Task.FromResult(this.azureKeyVaultKeyStoreProvider.UnwrapKey(encryptionKeyId, keyEncryptionKeyAlgorithm, encryptedKey));
+ }
+
+ ///
+ /// This function uses the asymmetric key specified by the key path
+ /// and encrypts an unencrypted data encryption key with RSA encryption algorithm.
+ ///
+ /// Identifier of an asymmetric key in Azure Key Vault.
+ /// The key encryption algorithm.
+ /// The plaintext key.
+ /// Encrypted data encryption key.
+ public override Task WrapKeyAsync(string encryptionKeyId, string cosmosKeyEncryptionKeyAlgorithm, byte[] key)
+ {
+ Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm keyEncryptionKeyAlgorithm = cosmosKeyEncryptionKeyAlgorithm switch
+ {
+ KeyEncryptionKeyAlgorithm.RsaOaep => Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm.RSA_OAEP,
+ _ => throw new NotSupportedException("This specified KeyEncryptionAlgorithm is not supported. Please refer to https://aka.ms/CosmosClientEncryption for more details. "),
+ };
+
+ return Task.FromResult(this.azureKeyVaultKeyStoreProvider.WrapKey(encryptionKeyId, keyEncryptionKeyAlgorithm, key));
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/DataEncryptionKeyAlgorithm.cs b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/DataEncryptionKeyAlgorithm.cs
new file mode 100644
index 0000000000..e5216c1eb9
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/DataEncryptionKeyAlgorithm.cs
@@ -0,0 +1,18 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Encryption
+{
+ ///
+ /// Represents the encryption algorithms supported for data encryption.
+ ///
+ public static class DataEncryptionKeyAlgorithm
+ {
+ ///
+ /// Represents the authenticated encryption algorithm with associated data as described in
+ /// http://tools.ietf.org/html/draft-mcgrew-aead-aes-cbc-hmac-sha2-05.
+ ///
+ public const string AeadAes256CbcHmacSha256 = "AEAD_AES_256_CBC_HMAC_SHA256";
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionKeyStoreProviderImpl.cs b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionKeyStoreProviderImpl.cs
new file mode 100644
index 0000000000..45fc041933
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionKeyStoreProviderImpl.cs
@@ -0,0 +1,74 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Encryption
+{
+ using System;
+ using Microsoft.Data.Encryption.Cryptography;
+
+ ///
+ /// The purpose/intention to introduce this class is to utilize the cache provide by the abstract class. This class basically
+ /// redirects all the corresponding calls to 's overridden methods and thus allowing us
+ /// to utilize the virtual method to access the cache.
+ ///
+ /// Note: Since and methods are not exposed, is not supported either.
+ ///
+ ///
+ /// The call hierarchy is as follows. Note, all core MDE API's used in internal cosmos encryption code are passed an EncryptionKeyStoreProviderImpl object.
+ /// ProtectedDataEncryptionKey -> KeyEncryptionKey(containing EncryptionKeyStoreProviderImpl object) -> EncryptionKeyStoreProviderImpl.WrapKey -> this.EncryptionKeyWrapProvider.WrapKeyAsync
+ /// ProtectedDataEncryptionKey -> KeyEncryptionKey(containing EncryptionKeyStoreProviderImpl object) -> EncryptionKeyStoreProviderImpl.UnWrapKey -> this.EncryptionKeyWrapProvider.UnwrapKeyAsync
+ ///
+ ///
+ internal class EncryptionKeyStoreProviderImpl : EncryptionKeyStoreProvider
+ {
+ private readonly EncryptionKeyWrapProvider encryptionKeyWrapProvider;
+
+ public EncryptionKeyStoreProviderImpl(EncryptionKeyWrapProvider encryptionKeyWrapProvider)
+ {
+ this.encryptionKeyWrapProvider = encryptionKeyWrapProvider;
+ }
+
+ public override string ProviderName => this.encryptionKeyWrapProvider.ProviderName;
+
+ public override byte[] UnwrapKey(string encryptionKeyId, Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm algorithm, byte[] encryptedKey)
+ {
+ // since we do not expose GetOrCreateDataEncryptionKey we first look up the cache.
+ // Cache miss results in call to UnWrapCore which updates the cache after UnwrapKeyAsync is called.
+ return this.GetOrCreateDataEncryptionKey(encryptedKey.ToHexString(), UnWrapKeyCore);
+
+ // delegate that is called by GetOrCreateDataEncryptionKey, which unwraps the key and updates the cache in case of cache miss.
+ byte[] UnWrapKeyCore()
+ {
+ return this.encryptionKeyWrapProvider.UnwrapKeyAsync(encryptionKeyId, algorithm.ToString(), encryptedKey)
+ .ConfigureAwait(false)
+ .GetAwaiter()
+ .GetResult();
+ }
+ }
+
+ public override byte[] WrapKey(string encryptionKeyId, Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm algorithm, byte[] key)
+ {
+ return this.encryptionKeyWrapProvider.WrapKeyAsync(encryptionKeyId, algorithm.ToString(), key)
+ .ConfigureAwait(false)
+ .GetAwaiter()
+ .GetResult();
+ }
+
+ ///
+ /// The public facing Cosmos Encryption library interface does not expose this method, hence not supported.
+ ///
+ public override byte[] Sign(string encryptionKeyId, bool allowEnclaveComputations)
+ {
+ throw new NotSupportedException("The Sign operation is not supported. ");
+ }
+
+ ///
+ /// The public facing Cosmos Encryption library interface does not expose this method, hence not supported.
+ ///
+ public override bool Verify(string encryptionKeyId, bool allowEnclaveComputations, byte[] signature)
+ {
+ throw new NotSupportedException("The Verify operation is not supported. ");
+ }
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionKeyWrapProvider.cs b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionKeyWrapProvider.cs
new file mode 100644
index 0000000000..408f060a7c
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionKeyWrapProvider.cs
@@ -0,0 +1,92 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Encryption
+{
+ using System;
+ using System.Threading.Tasks;
+ using Microsoft.Data.Encryption.Cryptography;
+
+ ///
+ /// Base class for all key store providers. A custom provider must derive from this
+ /// class and override its member functions.
+ ///
+ public abstract class EncryptionKeyWrapProvider
+ {
+ internal EncryptionKeyWrapProvider()
+ {
+ this.EncryptionKeyStoreProviderImpl = new EncryptionKeyStoreProviderImpl(this);
+ }
+
+ ///
+ /// Gets or sets the lifespan of the decrypted data encryption key in the cache.
+ /// Once the timespan has elapsed, the decrypted data encryption key is discarded
+ /// and must be revalidated.
+ ///
+ ///
+ /// Internally, there is a cache of key encryption keys (once they are unwrapped).
+ /// This is useful for rapidly decrypting multiple data values. The default value is 2 hours.
+ /// Setting the to zero disables caching.
+ ///
+ public TimeSpan? DataEncryptionKeyCacheTimeToLive
+ {
+ get => this.EncryptionKeyStoreProviderImpl.DataEncryptionKeyCacheTimeToLive;
+ set
+ {
+ this.EncryptionKeyStoreProviderImpl.DataEncryptionKeyCacheTimeToLive = value;
+
+ // set the TTL for ProtectedDataEncryption, so that we have a uniform expiry of the KeyStoreProvider and ProtectedDataEncryption cache items.
+ if (this.EncryptionKeyStoreProviderImpl.DataEncryptionKeyCacheTimeToLive.HasValue)
+ {
+ if (EncryptionCosmosClient.EncryptionKeyCacheSemaphore.Wait(-1))
+ {
+ try
+ {
+ // pick the min of the new value being set and ProtectedDataEncryptionKey's current TTL. Note ProtectedDataEncryptionKey TimeToLive is static
+ // and results in various instances to share this value. Hence we pick up whatever is the min value. If a TimeSpan.Zero is across any one instance
+ // it should be fine, since we look up the KeyStoreProvider cache. ProtectedDataEncryptionKey's own cache supersedes KeyStoreProvider cache, since it stores
+ // the RootKey which is derived from unwrapped key(Data Encryption Key).
+ // Note: DataEncryptionKeyCacheTimeToLive is nullable. When set to null this results in AbsoluteExpirationRelativeToNow to be set to null which caches forever.
+ // whatever is the current set value for ProtectedDataEncryptionKey TimeToLive(is not nullable) would be min if null value is passed.
+ if (TimeSpan.Compare(this.EncryptionKeyStoreProviderImpl.DataEncryptionKeyCacheTimeToLive.Value, ProtectedDataEncryptionKey.TimeToLive) < 0)
+ {
+ ProtectedDataEncryptionKey.TimeToLive = this.EncryptionKeyStoreProviderImpl.DataEncryptionKeyCacheTimeToLive.Value;
+ }
+ }
+ finally
+ {
+ EncryptionCosmosClient.EncryptionKeyCacheSemaphore.Release(1);
+ }
+ }
+ }
+ }
+ }
+
+ ///
+ /// Gets the unique name that identifies a particular implementation of the abstract .
+ ///
+ public abstract string ProviderName { get; }
+
+ internal EncryptionKeyStoreProviderImpl EncryptionKeyStoreProviderImpl { get; }
+
+ ///
+ /// Unwraps the specified of a data encryption key. The encrypted value is expected to be encrypted using
+ /// the key encryption key with the specified and using the specified .
+ ///
+ /// The key Id tells the provider where to find the key.
+ /// The key encryption algorithm.
+ /// The ciphertext key.
+ /// The unwrapped data encryption key.
+ public abstract Task UnwrapKeyAsync(string encryptionKeyId, string keyEncryptionKeyAlgorithm, byte[] encryptedKey);
+
+ ///
+ /// Wraps a data encryption key using the key encryption key with the specified and using the specified .
+ ///
+ /// The key Id tells the provider where to find the key.
+ /// The key encryption algorithm.
+ /// The plaintext key.
+ /// The wrapped data encryption key.
+ public abstract Task WrapKeyAsync(string encryptionKeyId, string keyEncryptionKeyAlgorithm, byte[] key);
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/CosmosEncryptionType.cs b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionType.cs
similarity index 58%
rename from Microsoft.Azure.Cosmos.Encryption/src/CosmosEncryptionType.cs
rename to Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionType.cs
index 111b54e3bf..f602f6e8b2 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/CosmosEncryptionType.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/EncryptionType.cs
@@ -5,9 +5,17 @@
namespace Microsoft.Azure.Cosmos.Encryption
{
///
- /// Algorithms for use with client-side encryption support in Azure Cosmos DB.
+ /// Represents the encryption algorithms supported for data encryption.
///
- internal static class CosmosEncryptionType
+ ///
+ /// The type of data encryption.
+ ///
+ ///
+ /// The two encryption types are Deterministic and Randomized.
+ /// Deterministic encryption always generates the same encrypted value for any given plain text value.
+ /// Randomized encryption uses a method that encrypts data in a less predictable manner. Randomized encryption is more secure.
+ ///
+ public static class EncryptionType
{
///
/// Deterministic encryption always generates the same encrypted value for any given plain text value.
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/KeyEncryptionKeyAlgorithm.cs b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/KeyEncryptionKeyAlgorithm.cs
new file mode 100644
index 0000000000..255000884f
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Encryption/src/MdeSupport/KeyEncryptionKeyAlgorithm.cs
@@ -0,0 +1,17 @@
+//------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------
+
+namespace Microsoft.Azure.Cosmos.Encryption
+{
+ ///
+ /// Represents the encryption algorithms supported for key encryption.
+ ///
+ public static class KeyEncryptionKeyAlgorithm
+ {
+ ///
+ /// RSA public key cryptography algorithm with Optimal Asymmetric Encryption Padding (OAEP) padding.
+ ///
+ public const string RsaOaep = "RSA_OAEP";
+ }
+}
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj b/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj
index 85bf7c8b48..b0a6d4465a 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj
+++ b/Microsoft.Azure.Cosmos.Encryption/src/Microsoft.Azure.Cosmos.Encryption.csproj
@@ -35,6 +35,7 @@
+
diff --git a/Microsoft.Azure.Cosmos.Encryption/src/QueryDefinitionExtensions.cs b/Microsoft.Azure.Cosmos.Encryption/src/QueryDefinitionExtensions.cs
index 808c8e8307..c9ee880032 100644
--- a/Microsoft.Azure.Cosmos.Encryption/src/QueryDefinitionExtensions.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/src/QueryDefinitionExtensions.cs
@@ -88,7 +88,7 @@ public static async Task AddParameterAsync(
return queryDefinitionwithEncryptedValues;
}
- if (settingsForProperty.EncryptionType == EncryptionType.Randomized)
+ if (settingsForProperty.EncryptionType == Data.Encryption.Cryptography.EncryptionType.Randomized)
{
throw new ArgumentException($"Unsupported argument with Path: {path} for query. For executing queries on encrypted path requires the use of deterministic encryption type. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
}
diff --git a/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs b/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs
index b44fe889e4..5eccc58c7a 100644
--- a/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs
+++ b/Microsoft.Azure.Cosmos.Encryption/tests/EmulatorTests/MdeEncryptionTests.cs
@@ -10,13 +10,13 @@ namespace Microsoft.Azure.Cosmos.Encryption.EmulatorTests
using System.IO;
using System.Linq;
using System.Net;
+ using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using global::Azure;
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Encryption;
- using Microsoft.Data.Encryption.Cryptography;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -33,22 +33,22 @@ public class MdeEncryptionTests
private static Database database;
private static Container encryptionContainer;
private static Container encryptionContainerForChangeFeed;
- private static TestEncryptionKeyStoreProvider testEncryptionKeyStoreProvider;
+ private static TestEncryptionKeyWrapProvider testEncryptionKeyWrapProvider;
[ClassInitialize]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "The ClassInitialize method takes a single parameter of type TestContext.")]
public static async Task ClassInitialize(TestContext context)
{
MdeEncryptionTests.client = TestCommon.CreateCosmosClient();
- testEncryptionKeyStoreProvider = new TestEncryptionKeyStoreProvider
+ testEncryptionKeyWrapProvider = new TestEncryptionKeyWrapProvider
{
DataEncryptionKeyCacheTimeToLive = null
};
- metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, "key1", "tempmetadata1");
- metadata2 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, "key2", "tempmetadata2");
+ metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, "key1", "tempmetadata1");
+ metadata2 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, "key2", "tempmetadata2");
- MdeEncryptionTests.encryptionCosmosClient = MdeEncryptionTests.client.WithEncryption(testEncryptionKeyStoreProvider);
+ MdeEncryptionTests.encryptionCosmosClient = MdeEncryptionTests.client.WithEncryption(testEncryptionKeyWrapProvider);
MdeEncryptionTests.database = await MdeEncryptionTests.encryptionCosmosClient.CreateDatabaseAsync(Guid.NewGuid().ToString());
await MdeEncryptionTests.CreateClientEncryptionKeyAsync(
@@ -60,10 +60,10 @@ await MdeEncryptionTests.CreateClientEncryptionKeyAsync(
metadata2);
- EncryptionKeyWrapMetadata revokedKekmetadata = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, "revokedKek", "revokedKek-metadata");
+ EncryptionKeyWrapMetadata revokedKekmetadata = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, "revokedKek", "revokedKek-metadata");
await database.CreateClientEncryptionKeyAsync(
"keywithRevokedKek",
- DataEncryptionKeyAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
+ DataEncryptionKeyAlgorithm.AeadAes256CbcHmacSha256,
revokedKekmetadata);
Collection paths = new Collection()
@@ -183,7 +183,7 @@ private static async Task CreateClientEncryptionKey
{
ClientEncryptionKeyResponse clientEncrytionKeyResponse = await database.CreateClientEncryptionKeyAsync(
cekId,
- DataEncryptionKeyAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
+ DataEncryptionKeyAlgorithm.AeadAes256CbcHmacSha256,
encryptionKeyWrapMetadata);
Assert.AreEqual(HttpStatusCode.Created, clientEncrytionKeyResponse.StatusCode);
@@ -235,7 +235,7 @@ public async Task EncryptionBulkCrud()
.WithBulkExecution(true)
.Build());
- CosmosClient encryptionCosmosClientWithBulk = clientWithBulk.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient encryptionCosmosClientWithBulk = clientWithBulk.WithEncryption(new TestEncryptionKeyWrapProvider());
Database databaseWithBulk = encryptionCosmosClientWithBulk.GetDatabase(MdeEncryptionTests.database.Id);
Container encryptionContainerWithBulk = databaseWithBulk.GetContainer(MdeEncryptionTests.encryptionContainer.Id);
@@ -257,18 +257,18 @@ public async Task EncryptionCreateClientEncryptionKey()
{
string cekId = "anotherCek";
- EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, cekId, "testmetadata1");
+ EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, cekId, "testmetadata1");
ClientEncryptionKeyProperties clientEncryptionKeyProperties = await MdeEncryptionTests.CreateClientEncryptionKeyAsync(
cekId,
metadata1);
Assert.AreEqual(
- new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, name: cekId, value: metadata1.Value),
+ new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, name: cekId, value: metadata1.Value),
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata);
// creating another key with same id should fail
- metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, cekId, "testmetadata2");
+ metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, cekId, "testmetadata2");
try
{
@@ -289,22 +289,22 @@ await MdeEncryptionTests.CreateClientEncryptionKeyAsync(
public async Task EncryptionRewrapClientEncryptionKey()
{
string cekId = "rewrapkeytest";
- EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, cekId, "testmetadata1");
+ EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, cekId, "testmetadata1");
ClientEncryptionKeyProperties clientEncryptionKeyProperties = await MdeEncryptionTests.CreateClientEncryptionKeyAsync(
cekId,
metadata1);
Assert.AreEqual(
- new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, name: cekId, value: metadata1.Value),
+ new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, name: cekId, value: metadata1.Value),
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata);
- EncryptionKeyWrapMetadata updatedMetaData = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, cekId, metadata1 + "updatedmetadata");
+ EncryptionKeyWrapMetadata updatedMetaData = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, cekId, metadata1 + "updatedmetadata");
clientEncryptionKeyProperties = await MdeEncryptionTests.RewarpClientEncryptionKeyAsync(
cekId,
updatedMetaData);
Assert.AreEqual(
- new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, name: cekId, value: updatedMetaData.Value),
+ new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, name: cekId, value: updatedMetaData.Value),
clientEncryptionKeyProperties.EncryptionKeyWrapMetadata);
}
@@ -332,12 +332,12 @@ public async Task EncryptionCreateItemWithNullProperty()
CosmosClient clientWithNoCaching = TestCommon.CreateCosmosClient(builder => builder
.Build());
- TestEncryptionKeyStoreProvider testEncryptionKeyStoreProvider = new TestEncryptionKeyStoreProvider
+ TestEncryptionKeyWrapProvider testEncryptionKeyWrapProvider = new TestEncryptionKeyWrapProvider
{
DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero
};
- CosmosClient encryptionCosmosClient = clientWithNoCaching.WithEncryption(testEncryptionKeyStoreProvider);
+ CosmosClient encryptionCosmosClient = clientWithNoCaching.WithEncryption(testEncryptionKeyWrapProvider);
Database database = encryptionCosmosClient.GetDatabase(MdeEncryptionTests.database.Id);
Container encryptionContainer = database.GetContainer(MdeEncryptionTests.encryptionContainer.Id);
@@ -395,7 +395,7 @@ await MdeEncryptionTests.ValidateQueryResultsAsync(
expectedDoc: expectedDoc);
// no access to key.
- testEncryptionKeyStoreProvider.RevokeAccessSet = true;
+ testEncryptionKeyWrapProvider.RevokeAccessSet = true;
testDoc = TestDoc.Create();
@@ -409,7 +409,7 @@ await MdeEncryptionTests.ValidateQueryResultsAsync(
Assert.AreEqual(HttpStatusCode.Created, createResponse.StatusCode);
VerifyExpectedDocResponse(testDoc, createResponse.Resource);
- testEncryptionKeyStoreProvider.RevokeAccessSet = false;
+ testEncryptionKeyWrapProvider.RevokeAccessSet = false;
}
@@ -428,18 +428,18 @@ public async Task EncryptionResourceTokenAuthRestricted()
restrictedUserPermission.Token);
- CosmosClient encryptedclientForRestrictedUser = clientForRestrictedUser.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient encryptedclientForRestrictedUser = clientForRestrictedUser.WithEncryption(new TestEncryptionKeyWrapProvider());
Database databaseForRestrictedUser = encryptedclientForRestrictedUser.GetDatabase(MdeEncryptionTests.database.Id);
try
{
string cekId = "testingcekID";
- EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, cekId, "testmetadata1");
+ EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, cekId, "testmetadata1");
ClientEncryptionKeyResponse clientEncrytionKeyResponse = await databaseForRestrictedUser.CreateClientEncryptionKeyAsync(
cekId,
- DataEncryptionKeyAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
+ DataEncryptionKeyAlgorithm.AeadAes256CbcHmacSha256,
metadata1);
Assert.Fail("CreateClientEncryptionKeyAsync should have failed due to restrictions");
}
@@ -450,7 +450,7 @@ public async Task EncryptionResourceTokenAuthRestricted()
try
{
string cekId = "testingcekID";
- EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, cekId, "testmetadata1" + "updated");
+ EncryptionKeyWrapMetadata metadata1 = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, cekId, "testmetadata1" + "updated");
ClientEncryptionKeyResponse clientEncrytionKeyResponse = await databaseForRestrictedUser.RewrapClientEncryptionKeyAsync(
cekId,
@@ -1001,7 +1001,7 @@ public async Task EncryptionValidatePolicyRefreshPostContainerDeleteWithBulk()
.WithBulkExecution(false)
.Build());
- CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyWrapProvider());
Database otherDatabase = otherEncryptionClient.GetDatabase(MdeEncryptionTests.database.Id);
Container otherEncryptionContainer = otherDatabase.GetContainer(encryptionContainerToDelete.Id);
@@ -1150,7 +1150,7 @@ public async Task EncryptionValidatePolicyRefreshPostContainerDeleteTransactionB
CosmosClient otherClient = TestCommon.CreateCosmosClient(builder => builder
.Build());
- CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyWrapProvider());
Database otherDatabase = otherEncryptionClient.GetDatabase(MdeEncryptionTests.database.Id);
Container otherEncryptionContainer = otherDatabase.GetContainer(encryptionContainerToDelete.Id);
@@ -1282,7 +1282,7 @@ public async Task EncryptionValidatePolicyRefreshPostContainerDeleteQuery()
CosmosClient otherClient = TestCommon.CreateCosmosClient(builder => builder
.Build());
- CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyWrapProvider());
Database otherDatabase = otherEncryptionClient.GetDatabase(MdeEncryptionTests.database.Id);
Container otherEncryptionContainer = otherDatabase.GetContainer(encryptionContainerToDelete.Id);
@@ -1397,7 +1397,7 @@ public async Task EncryptionValidatePolicyRefreshPostContainerDeletePatch()
CosmosClient otherClient = TestCommon.CreateCosmosClient(builder => builder
.Build());
- CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient otherEncryptionClient = otherClient.WithEncryption(new TestEncryptionKeyWrapProvider());
Database otherDatabase = otherEncryptionClient.GetDatabase(MdeEncryptionTests.database.Id);
Container otherEncryptionContainer = otherDatabase.GetContainer(encryptionContainerToDelete.Id);
@@ -1544,18 +1544,18 @@ public async Task EncryptionValidatePolicyRefreshPostDatabaseDelete()
CosmosClient mainClient = TestCommon.CreateCosmosClient(builder => builder
.Build());
- TestEncryptionKeyStoreProvider testEncryptionKeyStoreProvider = new TestEncryptionKeyStoreProvider
+ TestEncryptionKeyWrapProvider testEncryptionKeyWrapProvider = new TestEncryptionKeyWrapProvider
{
DataEncryptionKeyCacheTimeToLive = TimeSpan.FromMinutes(30),
};
- EncryptionKeyWrapMetadata keyWrapMetadata = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider.ProviderName, "myCek", "mymetadata1");
- CosmosClient encryptionCosmosClient = mainClient.WithEncryption(testEncryptionKeyStoreProvider);
+ EncryptionKeyWrapMetadata keyWrapMetadata = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider.ProviderName, "myCek", "mymetadata1");
+ CosmosClient encryptionCosmosClient = mainClient.WithEncryption(testEncryptionKeyWrapProvider);
Database mainDatabase = await encryptionCosmosClient.CreateDatabaseAsync("databaseToBeDeleted");
ClientEncryptionKeyResponse clientEncrytionKeyResponse = await mainDatabase.CreateClientEncryptionKeyAsync(
keyWrapMetadata.Name,
- DataEncryptionKeyAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
+ DataEncryptionKeyAlgorithm.AeadAes256CbcHmacSha256,
keyWrapMetadata);
Collection originalPaths = new Collection()
@@ -1597,12 +1597,12 @@ public async Task EncryptionValidatePolicyRefreshPostDatabaseDelete()
CosmosClient otherClient1 = TestCommon.CreateCosmosClient(builder => builder
.Build());
- TestEncryptionKeyStoreProvider testEncryptionKeyStoreProvider2 = new TestEncryptionKeyStoreProvider
+ TestEncryptionKeyWrapProvider testEncryptionKeyWrapProvider2 = new TestEncryptionKeyWrapProvider
{
DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero,
};
- CosmosClient otherEncryptionClient = otherClient1.WithEncryption(testEncryptionKeyStoreProvider2);
+ CosmosClient otherEncryptionClient = otherClient1.WithEncryption(testEncryptionKeyWrapProvider2);
Database otherDatabase = otherEncryptionClient.GetDatabase(mainDatabase.Id);
Container otherEncryptionContainer = otherDatabase.GetContainer(encryptionContainerToDelete.Id);
@@ -1615,10 +1615,10 @@ public async Task EncryptionValidatePolicyRefreshPostDatabaseDelete()
mainDatabase = await encryptionCosmosClient.CreateDatabaseAsync("databaseToBeDeleted");
- keyWrapMetadata = new EncryptionKeyWrapMetadata(testEncryptionKeyStoreProvider2.ProviderName, "myCek", "mymetadata2");
+ keyWrapMetadata = new EncryptionKeyWrapMetadata(testEncryptionKeyWrapProvider2.ProviderName, "myCek", "mymetadata2");
clientEncrytionKeyResponse = await mainDatabase.CreateClientEncryptionKeyAsync(
keyWrapMetadata.Name,
- DataEncryptionKeyAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256,
+ DataEncryptionKeyAlgorithm.AeadAes256CbcHmacSha256,
keyWrapMetadata);
using (await mainDatabase.GetContainer(encryptionContainerToDelete.Id).DeleteContainerStreamAsync())
@@ -1723,12 +1723,12 @@ public async Task EncryptionValidatePolicyRefreshPostDatabaseDelete()
.WithBulkExecution(true)
.Build());
- TestEncryptionKeyStoreProvider testEncryptionKeyStoreProvider3 = new TestEncryptionKeyStoreProvider
+ TestEncryptionKeyWrapProvider testEncryptionKeyWrapProvider3 = new TestEncryptionKeyWrapProvider
{
DataEncryptionKeyCacheTimeToLive = TimeSpan.FromMinutes(30),
};
- CosmosClient otherEncryptionClient2 = otherClient2.WithEncryption(testEncryptionKeyStoreProvider3);
+ CosmosClient otherEncryptionClient2 = otherClient2.WithEncryption(testEncryptionKeyWrapProvider3);
Database otherDatabase2 = otherEncryptionClient2.GetDatabase(mainDatabase.Id);
Container otherEncryptionContainer3 = otherDatabase2.GetContainer(otherEncryptionContainer2.Id);
@@ -1774,18 +1774,102 @@ public async Task EncryptionValidatePolicyRefreshPostDatabaseDelete()
await mainClient.GetDatabase("databaseToBeDeleted").DeleteStreamAsync();
}
+ [TestMethod]
+ public void MdeEncryptionTypesContractTest()
+ {
+ string[] cosmosSupportedEncryptionTypes = typeof(EncryptionType)
+ .GetMembers(BindingFlags.Static | BindingFlags.Public)
+ .Select(e => ((FieldInfo)e).GetValue(e).ToString())
+ .ToArray();
+
+ string[] mdeSupportedEncryptionTypes = typeof(Data.Encryption.Cryptography.EncryptionType)
+ .GetMembers(BindingFlags.Static | BindingFlags.Public)
+ .Select(e => e.Name)
+ .ToArray();
+
+ if (mdeSupportedEncryptionTypes.Length > cosmosSupportedEncryptionTypes.Length)
+ {
+ HashSet missingEncryptionTypes = new HashSet(mdeSupportedEncryptionTypes);
+ foreach (string encryptionTypes in cosmosSupportedEncryptionTypes)
+ {
+ missingEncryptionTypes.Remove(encryptionTypes);
+ }
+
+ // no Plaintext support.
+ missingEncryptionTypes.Remove("Plaintext");
+ mdeSupportedEncryptionTypes = mdeSupportedEncryptionTypes.Where(value => value != "Plaintext").ToArray();
+
+ if (missingEncryptionTypes.Count != 0)
+ {
+ Assert.Fail($"Missing EncryptionType support from CosmosEncryptionType: {string.Join(";", missingEncryptionTypes)}");
+ }
+ }
+
+ CollectionAssert.AreEquivalent(mdeSupportedEncryptionTypes, cosmosSupportedEncryptionTypes);
+ }
+
+ [TestMethod]
+ public void MdeEncryptionAlgorithmsTypesContractTest()
+ {
+ string[] cosmosKeyEncryptionAlgorithms = typeof(KeyEncryptionKeyAlgorithm)
+ .GetMembers(BindingFlags.Static | BindingFlags.Public)
+ .Select(e => ((FieldInfo)e).GetValue(e).ToString())
+ .ToArray();
+
+ string[] mdeKeyEncryptionAlgorithms = typeof(Data.Encryption.Cryptography.KeyEncryptionKeyAlgorithm)
+ .GetMembers(BindingFlags.Static | BindingFlags.Public)
+ .Select(e => e.Name)
+ .ToArray();
+
+ if (mdeKeyEncryptionAlgorithms.Length > cosmosKeyEncryptionAlgorithms.Length)
+ {
+ HashSet missingKeyEncryptionAlgorithms = new HashSet(mdeKeyEncryptionAlgorithms);
+ foreach (string algorithm in cosmosKeyEncryptionAlgorithms)
+ {
+ missingKeyEncryptionAlgorithms.Remove(algorithm);
+ }
+
+ Assert.Fail($"Missing key encryption algorithm support from CosmosKeyEncryptionKeyAlgorithm: {string.Join(";", missingKeyEncryptionAlgorithms)}");
+ }
+
+ CollectionAssert.AreEquivalent(mdeKeyEncryptionAlgorithms, cosmosKeyEncryptionAlgorithms);
+
+ string[] cosmosDataEncryptionAlgorithms = typeof(DataEncryptionKeyAlgorithm)
+ .GetMembers(BindingFlags.Static | BindingFlags.Public)
+ .Select(e => ((FieldInfo)e).GetValue(e).ToString())
+ .ToArray();
+
+ string[] mdeDataEncryptionAlgorithms = typeof(Data.Encryption.Cryptography.DataEncryptionKeyAlgorithm)
+ .GetMembers(BindingFlags.Static | BindingFlags.Public)
+ .Select(e => e.Name)
+ .ToArray();
+
+ if (mdeDataEncryptionAlgorithms.Length > cosmosDataEncryptionAlgorithms.Length)
+ {
+ HashSet missingDataEncryptionAlgorithms = new HashSet(mdeDataEncryptionAlgorithms);
+ foreach (string algorithm in cosmosDataEncryptionAlgorithms)
+ {
+ missingDataEncryptionAlgorithms.Remove(algorithm);
+ }
+
+ Assert.Fail($"Missing data encryption algorithm support from CosmosDataEncryptionKeyAlgorithm: {string.Join(";", missingDataEncryptionAlgorithms)}");
+ }
+
+ CollectionAssert.AreEquivalent(mdeDataEncryptionAlgorithms, cosmosDataEncryptionAlgorithms);
+ }
+
[TestMethod]
public async Task VerifyKekRevokeHandling()
{
CosmosClient clientWithNoCaching = TestCommon.CreateCosmosClient(builder => builder
.Build());
- TestEncryptionKeyStoreProvider testEncryptionKeyStoreProvider = new TestEncryptionKeyStoreProvider
+ TestEncryptionKeyWrapProvider testEncryptionKeyWrapProvider = new TestEncryptionKeyWrapProvider
{
DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero
};
- CosmosClient encryptionCosmosClient = clientWithNoCaching.WithEncryption(testEncryptionKeyStoreProvider);
+ CosmosClient encryptionCosmosClient = clientWithNoCaching.WithEncryption(testEncryptionKeyWrapProvider);
Database database = encryptionCosmosClient.GetDatabase(MdeEncryptionTests.database.Id);
// Once a Dek gets cached and the Kek is revoked, calls to unwrap/wrap keys would fail since KEK is revoked.
@@ -1809,7 +1893,7 @@ public async Task VerifyKekRevokeHandling()
TestDoc testDoc1 = await MdeEncryptionTests.MdeCreateItemAsync(encryptionContainer);
- testEncryptionKeyStoreProvider.RevokeAccessSet = true;
+ testEncryptionKeyWrapProvider.RevokeAccessSet = true;
// try creating it and it should fail as it has been revoked.
try
@@ -1837,16 +1921,16 @@ await MdeEncryptionTests.ValidateQueryResultsAsync(
}
// for unwrap to succeed
- testEncryptionKeyStoreProvider.RevokeAccessSet = false;
+ testEncryptionKeyWrapProvider.RevokeAccessSet = false;
// lets rewrap it.
await database.RewrapClientEncryptionKeyAsync("keywithRevokedKek", MdeEncryptionTests.metadata2);
- testEncryptionKeyStoreProvider.RevokeAccessSet = true;
+ testEncryptionKeyWrapProvider.RevokeAccessSet = true;
// Should fail but will try to fetch the lastest from the Backend and updates the cache.
await MdeEncryptionTests.MdeCreateItemAsync(encryptionContainer);
- testEncryptionKeyStoreProvider.RevokeAccessSet = false;
- testEncryptionKeyStoreProvider.DataEncryptionKeyCacheTimeToLive = TimeSpan.FromMinutes(120);
+ testEncryptionKeyWrapProvider.RevokeAccessSet = false;
+ testEncryptionKeyWrapProvider.DataEncryptionKeyCacheTimeToLive = TimeSpan.FromMinutes(120);
}
[TestMethod]
@@ -2126,7 +2210,7 @@ public async Task EncryptionTransactionalBatchWithCustomSerializer()
.WithCustomSerializer(customSerializer)
.Build());
- CosmosClient encryptionCosmosClientWithCustomSerializer = clientWithCustomSerializer.WithEncryption(new TestEncryptionKeyStoreProvider());
+ CosmosClient encryptionCosmosClientWithCustomSerializer = clientWithCustomSerializer.WithEncryption(new TestEncryptionKeyWrapProvider());
Database databaseWithCustomSerializer = encryptionCosmosClientWithCustomSerializer.GetDatabase(MdeEncryptionTests.database.Id);
Container encryptionContainerWithCustomSerializer = databaseWithCustomSerializer.GetContainer(MdeEncryptionTests.encryptionContainer.Id);
@@ -2184,8 +2268,8 @@ await MdeEncryptionTests.ValidateQueryResultsAsync(
public async Task ValidateCachingofProtectedDataEncryptionKey()
{
// Default cache TTL 2 hours.
- TestEncryptionKeyStoreProvider newtestEncryptionKeyStoreProvider = new TestEncryptionKeyStoreProvider();
- CosmosClient newEncryptionClient = MdeEncryptionTests.client.WithEncryption(newtestEncryptionKeyStoreProvider);
+ TestEncryptionKeyWrapProvider newtestEncryptionKeyWrapProvider = new TestEncryptionKeyWrapProvider();
+ CosmosClient newEncryptionClient = MdeEncryptionTests.client.WithEncryption(newtestEncryptionKeyWrapProvider);
Database database = newEncryptionClient.GetDatabase(MdeEncryptionTests.database.Id);
Container encryptionContainer = database.GetContainer(MdeEncryptionTests.encryptionContainer.Id);
@@ -2195,17 +2279,13 @@ public async Task ValidateCachingofProtectedDataEncryptionKey()
await MdeEncryptionTests.MdeCreateItemAsync(encryptionContainer);
}
- newtestEncryptionKeyStoreProvider.UnWrapKeyCallsCount.TryGetValue(metadata1.Value, out int unwrapcount);
+ newtestEncryptionKeyWrapProvider.UnWrapKeyCallsCount.TryGetValue(metadata1.Value, out int unwrapcount);
// expecting just one unwrap.
Assert.AreEqual(1, unwrapcount);
// no caching.
- newtestEncryptionKeyStoreProvider = new TestEncryptionKeyStoreProvider()
- {
- DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero,
- };
+ newtestEncryptionKeyWrapProvider.DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero;
- newEncryptionClient = MdeEncryptionTests.client.WithEncryption(newtestEncryptionKeyStoreProvider);
database = newEncryptionClient.GetDatabase(MdeEncryptionTests.database.Id);
encryptionContainer = database.GetContainer(MdeEncryptionTests.encryptionContainer.Id);
@@ -2215,7 +2295,7 @@ public async Task ValidateCachingofProtectedDataEncryptionKey()
await MdeEncryptionTests.MdeCreateItemAsync(encryptionContainer);
}
- newtestEncryptionKeyStoreProvider.UnWrapKeyCallsCount.TryGetValue(metadata1.Value, out unwrapcount);
+ newtestEncryptionKeyWrapProvider.UnWrapKeyCallsCount.TryGetValue(metadata1.Value, out unwrapcount);
Assert.IsTrue(unwrapcount > 1, "The actual unwrap count was not greater than 1");
}
@@ -3214,7 +3294,7 @@ public Stream ToStream()
}
}
- internal class TestEncryptionKeyStoreProvider : EncryptionKeyStoreProvider
+ internal class TestEncryptionKeyWrapProvider : EncryptionKeyWrapProvider
{
readonly Dictionary keyinfo = new Dictionary
{
@@ -3223,9 +3303,12 @@ internal class TestEncryptionKeyStoreProvider : EncryptionKeyStoreProvider
};
public bool RevokeAccessSet { get; set; }
+
public Dictionary WrapKeyCallsCount { get; set; }
+
public Dictionary UnWrapKeyCallsCount { get; set; }
- public TestEncryptionKeyStoreProvider()
+
+ public TestEncryptionKeyWrapProvider()
{
this.WrapKeyCallsCount = new Dictionary();
this.UnWrapKeyCallsCount = new Dictionary();
@@ -3234,33 +3317,28 @@ public TestEncryptionKeyStoreProvider()
public override string ProviderName => "TESTKEYSTORE_VAULT";
- public override byte[] UnwrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm encryptionAlgorithm, byte[] encryptedKey)
+ public override Task UnwrapKeyAsync(string masterKeyPath, string keyEncryptionKeyAlgorithm, byte[] encryptedKey)
{
if (masterKeyPath.Equals("revokedKek-metadata") && this.RevokeAccessSet)
{
throw new RequestFailedException((int)HttpStatusCode.Forbidden, "Forbidden");
}
- return this.GetOrCreateDataEncryptionKey(encryptedKey.ToHexString(), DecryptEncryptionKey);
-
- byte[] DecryptEncryptionKey()
+ if (!this.UnWrapKeyCallsCount.ContainsKey(masterKeyPath))
{
- if (!this.UnWrapKeyCallsCount.ContainsKey(masterKeyPath))
- {
- this.UnWrapKeyCallsCount[masterKeyPath] = 1;
- }
- else
- {
- this.UnWrapKeyCallsCount[masterKeyPath]++;
- }
-
- this.keyinfo.TryGetValue(masterKeyPath, out int moveBy);
- byte[] plainkey = encryptedKey.Select(b => (byte)(b - moveBy)).ToArray();
- return plainkey;
+ this.UnWrapKeyCallsCount[masterKeyPath] = 1;
}
+ else
+ {
+ this.UnWrapKeyCallsCount[masterKeyPath]++;
+ }
+
+ this.keyinfo.TryGetValue(masterKeyPath, out int moveBy);
+ byte[] plainkey = encryptedKey.Select(b => (byte)(b - moveBy)).ToArray();
+ return Task.FromResult(plainkey);
}
- public override byte[] WrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm encryptionAlgorithm, byte[] key)
+ public override Task WrapKeyAsync(string masterKeyPath, string keyEncryptionKeyAlgorithm, byte[] key)
{
if (!this.WrapKeyCallsCount.ContainsKey(masterKeyPath))
{
@@ -3273,17 +3351,7 @@ public override byte[] WrapKey(string masterKeyPath, KeyEncryptionKeyAlgorithm e
this.keyinfo.TryGetValue(masterKeyPath, out int moveBy);
byte[] encryptedkey = key.Select(b => (byte)(b + moveBy)).ToArray();
- return encryptedkey;
- }
-
- public override byte[] Sign(string masterKeyPath, bool allowEnclaveComputations)
- {
- return null;
- }
-
- public override bool Verify(string masterKeyPath, bool allowEnclaveComputations, byte[] signature)
- {
- return true;
+ return Task.FromResult(encryptedkey);
}
}
diff --git a/Microsoft.Azure.Cosmos.Encryption/tests/Microsoft.Azure.Cosmos.Encryption.Tests/Contracts/DotNetSDKEncryptionAPI.json b/Microsoft.Azure.Cosmos.Encryption/tests/Microsoft.Azure.Cosmos.Encryption.Tests/Contracts/DotNetSDKEncryptionAPI.json
index 14887781c5..1f53d62344 100644
--- a/Microsoft.Azure.Cosmos.Encryption/tests/Microsoft.Azure.Cosmos.Encryption.Tests/Contracts/DotNetSDKEncryptionAPI.json
+++ b/Microsoft.Azure.Cosmos.Encryption/tests/Microsoft.Azure.Cosmos.Encryption.Tests/Contracts/DotNetSDKEncryptionAPI.json
@@ -1,5 +1,47 @@
{
"Subclasses": {
+ "Microsoft.Azure.Cosmos.Encryption.AzureKeyVaultKeyWrapProvider;Microsoft.Azure.Cosmos.Encryption.EncryptionKeyWrapProvider;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "System.String get_ProviderName()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.String get_ProviderName();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.String ProviderName": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.String ProviderName;CanRead:True;CanWrite:False;System.String get_ProviderName();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Threading.Tasks.Task`1[System.Byte[]] UnwrapKeyAsync(System.String, System.String, Byte[])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Threading.Tasks.Task`1[System.Byte[]] UnwrapKeyAsync(System.String, System.String, Byte[]);IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Threading.Tasks.Task`1[System.Byte[]] WrapKeyAsync(System.String, System.String, Byte[])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Threading.Tasks.Task`1[System.Byte[]] WrapKeyAsync(System.String, System.String, Byte[]);IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Void .ctor(Azure.Core.TokenCredential)": {
+ "Type": "Constructor",
+ "Attributes": [],
+ "MethodInfo": "[Void .ctor(Azure.Core.TokenCredential), Void .ctor(Azure.Core.TokenCredential)]"
+ }
+ },
+ "NestedTypes": {}
+ },
+ "Microsoft.Azure.Cosmos.Encryption.DataEncryptionKeyAlgorithm;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "System.String AeadAes256CbcHmacSha256": {
+ "Type": "Field",
+ "Attributes": [],
+ "MethodInfo": "System.String AeadAes256CbcHmacSha256;IsInitOnly:False;IsStatic:True;"
+ }
+ },
+ "NestedTypes": {}
+ },
"Microsoft.Azure.Cosmos.Encryption.EncryptionContainerExtensions;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
"Subclasses": {},
"Members": {
@@ -38,12 +80,12 @@
"Microsoft.Azure.Cosmos.Encryption.EncryptionCosmosClientExtensions;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
"Subclasses": {},
"Members": {
- "Microsoft.Azure.Cosmos.CosmosClient WithEncryption(Microsoft.Azure.Cosmos.CosmosClient, Microsoft.Data.Encryption.Cryptography.EncryptionKeyStoreProvider)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
+ "Microsoft.Azure.Cosmos.CosmosClient WithEncryption(Microsoft.Azure.Cosmos.CosmosClient, Microsoft.Azure.Cosmos.Encryption.EncryptionKeyWrapProvider)[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"ExtensionAttribute"
],
- "MethodInfo": "Microsoft.Azure.Cosmos.CosmosClient WithEncryption(Microsoft.Azure.Cosmos.CosmosClient, Microsoft.Data.Encryption.Cryptography.EncryptionKeyStoreProvider);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ "MethodInfo": "Microsoft.Azure.Cosmos.CosmosClient WithEncryption(Microsoft.Azure.Cosmos.CosmosClient, Microsoft.Azure.Cosmos.Encryption.EncryptionKeyWrapProvider);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
}
},
"NestedTypes": {}
@@ -51,13 +93,13 @@
"Microsoft.Azure.Cosmos.Encryption.EncryptionDatabaseExtensions;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
"Subclasses": {},
"Members": {
- "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ClientEncryptionKeyResponse] CreateClientEncryptionKeyAsync(Microsoft.Azure.Cosmos.Database, System.String, Microsoft.Data.Encryption.Cryptography.DataEncryptionKeyAlgorithm, Microsoft.Azure.Cosmos.EncryptionKeyWrapMetadata, System.Threading.CancellationToken)[System.Runtime.CompilerServices.AsyncStateMachineAttribute(typeof(Microsoft.Azure.Cosmos.Encryption.EncryptionDatabaseExtensions+))]-[System.Runtime.CompilerServices.ExtensionAttribute()]": {
+ "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ClientEncryptionKeyResponse] CreateClientEncryptionKeyAsync(Microsoft.Azure.Cosmos.Database, System.String, System.String, Microsoft.Azure.Cosmos.EncryptionKeyWrapMetadata, System.Threading.CancellationToken)[System.Runtime.CompilerServices.AsyncStateMachineAttribute(typeof(Microsoft.Azure.Cosmos.Encryption.EncryptionDatabaseExtensions+))]-[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
"Attributes": [
"AsyncStateMachineAttribute",
"ExtensionAttribute"
],
- "MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ClientEncryptionKeyResponse] CreateClientEncryptionKeyAsync(Microsoft.Azure.Cosmos.Database, System.String, Microsoft.Data.Encryption.Cryptography.DataEncryptionKeyAlgorithm, Microsoft.Azure.Cosmos.EncryptionKeyWrapMetadata, System.Threading.CancellationToken);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ "MethodInfo": "System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ClientEncryptionKeyResponse] CreateClientEncryptionKeyAsync(Microsoft.Azure.Cosmos.Database, System.String, System.String, Microsoft.Azure.Cosmos.EncryptionKeyWrapMetadata, System.Threading.CancellationToken);IsAbstract:False;IsStatic:True;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
},
"System.Threading.Tasks.Task`1[Microsoft.Azure.Cosmos.ClientEncryptionKeyResponse] RewrapClientEncryptionKeyAsync(Microsoft.Azure.Cosmos.Database, System.String, Microsoft.Azure.Cosmos.EncryptionKeyWrapMetadata, System.Threading.CancellationToken)[System.Runtime.CompilerServices.AsyncStateMachineAttribute(typeof(Microsoft.Azure.Cosmos.Encryption.EncryptionDatabaseExtensions+))]-[System.Runtime.CompilerServices.ExtensionAttribute()]": {
"Type": "Method",
@@ -70,6 +112,106 @@
},
"NestedTypes": {}
},
+ "Microsoft.Azure.Cosmos.Encryption.EncryptionKeyWrapProvider;System.Object;IsAbstract:True;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {
+ "Microsoft.Azure.Cosmos.Encryption.AzureKeyVaultKeyWrapProvider;Microsoft.Azure.Cosmos.Encryption.EncryptionKeyWrapProvider;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "System.String get_ProviderName()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.String get_ProviderName();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.String ProviderName": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.String ProviderName;CanRead:True;CanWrite:False;System.String get_ProviderName();IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Threading.Tasks.Task`1[System.Byte[]] UnwrapKeyAsync(System.String, System.String, Byte[])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Threading.Tasks.Task`1[System.Byte[]] UnwrapKeyAsync(System.String, System.String, Byte[]);IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Threading.Tasks.Task`1[System.Byte[]] WrapKeyAsync(System.String, System.String, Byte[])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Threading.Tasks.Task`1[System.Byte[]] WrapKeyAsync(System.String, System.String, Byte[]);IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Void .ctor(Azure.Core.TokenCredential)": {
+ "Type": "Constructor",
+ "Attributes": [],
+ "MethodInfo": "[Void .ctor(Azure.Core.TokenCredential), Void .ctor(Azure.Core.TokenCredential)]"
+ }
+ },
+ "NestedTypes": {}
+ }
+ },
+ "Members": {
+ "System.Nullable`1[System.TimeSpan] DataEncryptionKeyCacheTimeToLive": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.Nullable`1[System.TimeSpan] DataEncryptionKeyCacheTimeToLive;CanRead:True;CanWrite:True;System.Nullable`1[System.TimeSpan] get_DataEncryptionKeyCacheTimeToLive();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_DataEncryptionKeyCacheTimeToLive(System.Nullable`1[System.TimeSpan]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Nullable`1[System.TimeSpan] get_DataEncryptionKeyCacheTimeToLive()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Nullable`1[System.TimeSpan] get_DataEncryptionKeyCacheTimeToLive();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.String get_ProviderName()": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.String get_ProviderName();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.String ProviderName": {
+ "Type": "Property",
+ "Attributes": [],
+ "MethodInfo": "System.String ProviderName;CanRead:True;CanWrite:False;System.String get_ProviderName();IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Threading.Tasks.Task`1[System.Byte[]] UnwrapKeyAsync(System.String, System.String, Byte[])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Threading.Tasks.Task`1[System.Byte[]] UnwrapKeyAsync(System.String, System.String, Byte[]);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "System.Threading.Tasks.Task`1[System.Byte[]] WrapKeyAsync(System.String, System.String, Byte[])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "System.Threading.Tasks.Task`1[System.Byte[]] WrapKeyAsync(System.String, System.String, Byte[]);IsAbstract:True;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ },
+ "Void set_DataEncryptionKeyCacheTimeToLive(System.Nullable`1[System.TimeSpan])": {
+ "Type": "Method",
+ "Attributes": [],
+ "MethodInfo": "Void set_DataEncryptionKeyCacheTimeToLive(System.Nullable`1[System.TimeSpan]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;"
+ }
+ },
+ "NestedTypes": {}
+ },
+ "Microsoft.Azure.Cosmos.Encryption.EncryptionType;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "System.String Deterministic": {
+ "Type": "Field",
+ "Attributes": [],
+ "MethodInfo": "System.String Deterministic;IsInitOnly:False;IsStatic:True;"
+ },
+ "System.String Randomized": {
+ "Type": "Field",
+ "Attributes": [],
+ "MethodInfo": "System.String Randomized;IsInitOnly:False;IsStatic:True;"
+ }
+ },
+ "NestedTypes": {}
+ },
+ "Microsoft.Azure.Cosmos.Encryption.KeyEncryptionKeyAlgorithm;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
+ "Subclasses": {},
+ "Members": {
+ "System.String RsaOaep": {
+ "Type": "Field",
+ "Attributes": [],
+ "MethodInfo": "System.String RsaOaep;IsInitOnly:False;IsStatic:True;"
+ }
+ },
+ "NestedTypes": {}
+ },
"Microsoft.Azure.Cosmos.Encryption.QueryDefinitionExtensions;System.Object;IsAbstract:True;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": {
"Subclasses": {},
"Members": {