public EncryptionCosmosClient(
            CosmosClient cosmosClient,
            IKeyEncryptionKeyResolver keyEncryptionKeyResolver,
            string keyEncryptionKeyResolverName,
            TimeSpan?keyCacheTimeToLive)
        {
            this.cosmosClient                 = cosmosClient ?? throw new ArgumentNullException(nameof(cosmosClient));
            this.KeyEncryptionKeyResolver     = keyEncryptionKeyResolver ?? throw new ArgumentNullException(nameof(keyEncryptionKeyResolver));
            this.KeyEncryptionKeyResolverName = keyEncryptionKeyResolverName ?? throw new ArgumentNullException(nameof(keyEncryptionKeyResolverName));
            this.clientEncryptionKeyPropertiesCacheByKeyId = new AsyncCache <string, ClientEncryptionKeyProperties>();
            this.EncryptionKeyStoreProviderImpl            = new EncryptionKeyStoreProviderImpl(keyEncryptionKeyResolver, keyEncryptionKeyResolverName);

            keyCacheTimeToLive ??= TimeSpan.FromHours(1);

            if (EncryptionCosmosClient.EncryptionKeyCacheSemaphore.Wait(-1))
            {
                try
                {
                    // We pick the minimum between the existing and passed in value given this is a static cache.
                    // This also means that the maximum cache duration is the originally initialized value for ProtectedDataEncryptionKey.TimeToLive which is 2 hours.
                    if (keyCacheTimeToLive < ProtectedDataEncryptionKey.TimeToLive)
                    {
                        ProtectedDataEncryptionKey.TimeToLive = keyCacheTimeToLive.Value;
                    }
                }
                finally
                {
                    EncryptionCosmosClient.EncryptionKeyCacheSemaphore.Release(1);
                }
            }
        }
 internal AzureKeyVaultXmlEncryptor(IKeyEncryptionKeyResolver client, string keyId,
                                    RandomNumberGenerator randomNumberGenerator)
 {
     _client = client;
     _keyId  = keyId;
     _randomNumberGenerator = randomNumberGenerator;
 }
Ejemplo n.º 3
0
        // </Main>

        private static CosmosClient CreateClientInstance(
            IConfigurationRoot configuration,
            IKeyEncryptionKeyResolver keyResolver)
        {
            string endpoint = configuration["EndPointUrl"];

            if (string.IsNullOrEmpty(endpoint))
            {
                throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
            }

            string authKey = configuration["AuthorizationKey"];

            if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
            {
                throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
            }

            CosmosClientOptions options = new CosmosClientOptions
            {
                AllowBulkExecution = true,
            };
            CosmosClient encryptionCosmosClient = new CosmosClient(endpoint, authKey, options);

            // enable encryption support on the cosmos client.
            return(encryptionCosmosClient.WithEncryption(keyResolver, KeyEncryptionKeyResolverName.AzureKeyVault));
        }
        /// <summary>
        /// Provides an instance of CosmosClient with support for performing operations involving client-side encryption.
        /// </summary>
        /// <param name="cosmosClient">CosmosClient instance on which encryption support is needed.</param>
        /// <param name="keyEncryptionKeyResolver">Resolver that allows interaction with key encryption keys.</param>
        /// <param name="keyEncryptionKeyResolverName">Name of the resolver, for example <see cref="KeyEncryptionKeyResolverName.AzureKeyVault" />.</param>
        /// <param name="keyCacheTimeToLive">Time for which raw data encryption keys are cached in-memory. Defaults to 1 hour.</param>
        /// <returns>CosmosClient instance with support for performing operations involving client-side encryption.</returns>
        /// <example>
        /// This example shows how to get instance of CosmosClient with support for performing operations involving client-side encryption.
        ///
        /// <code language="c#">
        /// <![CDATA[
        /// Azure.Core.TokenCredential tokenCredential = new Azure.Identity.DefaultAzureCredential();
        /// Azure.Core.Cryptography.IKeyEncryptionKeyResolver keyResolver = new Azure.Security.KeyVault.Keys.Cryptography.KeyResolver(tokenCredential);
        /// CosmosClient client = (new CosmosClient(endpoint, authKey)).WithEncryption(keyResolver, KeyEncryptionKeyResolverName.AzureKeyVault);
        /// Container container = client.GetDatabase("databaseId").GetContainer("containerId");
        /// ]]>
        /// </code>
        /// </example>
        /// <remarks>
        /// See <see href="https://aka.ms/CosmosClientEncryption">client-side encryption documentation</see> for more details.
        /// </remarks>
        public static CosmosClient WithEncryption(
            this CosmosClient cosmosClient,
            IKeyEncryptionKeyResolver keyEncryptionKeyResolver,
            string keyEncryptionKeyResolverName,
            TimeSpan?keyCacheTimeToLive = null)
        {
            if (keyEncryptionKeyResolver == null)
            {
                throw new ArgumentNullException(nameof(keyEncryptionKeyResolver));
            }

            if (keyEncryptionKeyResolverName == null)
            {
                throw new ArgumentNullException(nameof(keyEncryptionKeyResolverName));
            }

            if (cosmosClient == null)
            {
                throw new ArgumentNullException(nameof(cosmosClient));
            }

            return(new EncryptionCosmosClient(cosmosClient, keyEncryptionKeyResolver, keyEncryptionKeyResolverName, keyCacheTimeToLive));
        }
Ejemplo n.º 5
0
 public EncryptionKeyStoreProviderImpl(IKeyEncryptionKeyResolver keyEncryptionKeyResolver, string providerName)
 {
     this.keyEncryptionKeyResolver         = keyEncryptionKeyResolver;
     this.ProviderName                     = providerName;
     this.DataEncryptionKeyCacheTimeToLive = TimeSpan.Zero;
 }
 public AzureKeyVaultXmlDecryptor(IServiceProvider serviceProvider)
 {
     _client = serviceProvider.GetService <IKeyEncryptionKeyResolver>();
 }
Ejemplo n.º 7
0
        private static async Task <byte[]> UnwrapKeyInternal(EncryptionData encryptionData, IKeyEncryptionKeyResolver keyResolver, bool async, CancellationToken cancellationToken)
        {
            IKeyEncryptionKey oldKey = async
                    ? await keyResolver.ResolveAsync(encryptionData.WrappedContentKey.KeyId, cancellationToken).ConfigureAwait(false)
                    : keyResolver.Resolve(encryptionData.WrappedContentKey.KeyId, cancellationToken);

            if (oldKey == default)
            {
                throw Errors.ClientSideEncryption.KeyNotFound(encryptionData.WrappedContentKey.KeyId);
            }

            return(async
                ? await oldKey.UnwrapKeyAsync(
                       encryptionData.WrappedContentKey.Algorithm,
                       encryptionData.WrappedContentKey.EncryptedKey,
                       cancellationToken).ConfigureAwait(false)
                : oldKey.UnwrapKey(
                       encryptionData.WrappedContentKey.Algorithm,
                       encryptionData.WrappedContentKey.EncryptedKey,
                       cancellationToken));
        }
        /// <summary>
        /// Configures the data protection system to protect keys with specified key in Azure KeyVault.
        /// </summary>
        /// <param name="builder">The builder instance to modify.</param>
        /// <param name="keyResolver">The <see cref="IKeyEncryptionKeyResolver"/> to use for Key Vault access.</param>
        /// <param name="keyIdentifier">The Azure Key Vault key identifier used for key encryption.</param>
        /// <returns>The value <paramref name="builder"/>.</returns>
        public static IDataProtectionBuilder ProtectKeysWithAzureKeyVault(this IDataProtectionBuilder builder, string keyIdentifier, IKeyEncryptionKeyResolver keyResolver)
        {
            Argument.AssertNotNull(builder, nameof(builder));
            Argument.AssertNotNull(keyResolver, nameof(keyResolver));
            Argument.AssertNotNullOrEmpty(keyIdentifier, nameof(keyIdentifier));

            builder.Services.AddSingleton <IKeyEncryptionKeyResolver>(keyResolver);
            builder.Services.Configure <KeyManagementOptions>(options =>
            {
                options.XmlEncryptor = new AzureKeyVaultXmlEncryptor(keyResolver, keyIdentifier);
            });

            return(builder);
        }
 public AzureKeyVaultXmlEncryptor(IKeyEncryptionKeyResolver client, string keyId)
     : this(client, keyId, RandomNumberGenerator.Create())
 {
 }
 public ClientSideDecryptor(ClientSideEncryptionOptions options)
 {
     _potentialCachedIKeyEncryptionKey = options.KeyEncryptionKey;
     _keyResolver = options.KeyResolver;
 }