Beispiel #1
0
        public void ValidateClientEncryptionPolicyDeserialization()
        {
            ClientEncryptionPolicy policy = MockCosmosUtil.Serializer.FromStream <ClientEncryptionPolicy>(new MemoryStream(
                                                                                                              Encoding.UTF8.GetBytes("{ 'policyFormatVersion': 2, 'newproperty': 'value'  }")));

            Assert.AreEqual(2, policy.PolicyFormatVersion);
        }
Beispiel #2
0
        private async Task <EncryptionSettingForProperty> FetchEncryptionSettingForPropertyAsync(
            string propertyName,
            CancellationToken cancellationToken)
        {
            ClientEncryptionPolicy clientEncryptionPolicy = await this.EncryptionProcessor.EncryptionCosmosClient.GetClientEncryptionPolicyAsync(
                this.EncryptionProcessor.Container,
                cancellationToken : cancellationToken,
                shouldForceRefresh : false);

            if (clientEncryptionPolicy != null)
            {
                foreach (ClientEncryptionIncludedPath propertyToEncrypt in clientEncryptionPolicy.IncludedPaths)
                {
                    if (string.Equals(propertyToEncrypt.Path.Substring(1), propertyName))
                    {
                        EncryptionType encryptionType = this.GetEncryptionTypeForProperty(propertyToEncrypt);

                        return(new EncryptionSettingForProperty(
                                   propertyToEncrypt.ClientEncryptionKeyId,
                                   encryptionType,
                                   this.EncryptionProcessor));
                    }
                }
            }

            return(null);
        }
        /// <summary>
        /// Gets or Adds ClientEncryptionPolicy. The Cache gets seeded initially either via InitializeEncryptionAsync call on the container,
        /// or during the the first request to create an item.
        /// </summary>
        /// <param name="container"> The container handler to read the policies from.</param>
        /// <param name="cancellationToken"> cancellation token </param>
        /// <param name="shouldForceRefresh"> force refresh the cache </param>
        /// <returns> task result </returns>
        internal async Task <ClientEncryptionPolicy> GetClientEncryptionPolicyAsync(
            Container container,
            CancellationToken cancellationToken = default,
            bool shouldForceRefresh             = false)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            // container Id is unique within a Database.
            string cacheKey = container.Database.Id + "/" + container.Id;

            // cache it against Database and Container ID key.
            return(await this.clientEncryptionPolicyCacheByContainerId.GetAsync(
                       cacheKey,
                       obsoleteValue : null,
                       async() =>
            {
                ContainerResponse containerResponse = await container.ReadContainerAsync();
                ClientEncryptionPolicy clientEncryptionPolicy = containerResponse.Resource.ClientEncryptionPolicy;
                return clientEncryptionPolicy;
            },
                       cancellationToken,
                       forceRefresh : shouldForceRefresh));
        }
Beispiel #4
0
        public PSClientEncryptionPolicy(ClientEncryptionPolicy clientEncryptionPolicy)
        {
            if (clientEncryptionPolicy == null)
            {
                return;
            }

            if (ModelHelper.IsNotNullOrEmpty(clientEncryptionPolicy.IncludedPaths))
            {
                PSClientEncryptionPolicy.ValidateIncludedPaths(clientEncryptionPolicy.IncludedPaths);

                IncludedPaths = new List <PSClientEncryptionIncludedPath>();
                foreach (ClientEncryptionIncludedPath key in clientEncryptionPolicy.IncludedPaths)
                {
                    IncludedPaths.Add(new PSClientEncryptionIncludedPath(key));
                }
            }

            this.PolicyFormatVersion = (int)clientEncryptionPolicy.PolicyFormatVersion;
        }
Beispiel #5
0
        public static ClientEncryptionPolicy ToSDKModel(PSClientEncryptionPolicy pSClientEncryptionPolicy, List <string> partitionKeyPathTokens)
        {
            if (pSClientEncryptionPolicy == null)
            {
                return(null);
            }

            ClientEncryptionPolicy clientEncryptionPolicy = new ClientEncryptionPolicy
            {
                IncludedPaths       = new List <ClientEncryptionIncludedPath>(),
                PolicyFormatVersion = pSClientEncryptionPolicy.PolicyFormatVersion
            };

            if (ModelHelper.IsNotNullOrEmpty(pSClientEncryptionPolicy.IncludedPaths))
            {
                foreach (PSClientEncryptionIncludedPath includedPath in pSClientEncryptionPolicy.IncludedPaths)
                {
                    ClientEncryptionIncludedPath clientEncryptionIncludedPath = new ClientEncryptionIncludedPath
                    {
                        Path = includedPath.Path,
                        ClientEncryptionKeyId = includedPath.ClientEncryptionKeyId,
                        EncryptionAlgorithm   = includedPath.EncryptionAlgorithm,
                        EncryptionType        = includedPath.EncryptionType
                    };

                    clientEncryptionPolicy.IncludedPaths.Add(clientEncryptionIncludedPath);
                }
            }

            PSClientEncryptionPolicy.ValidatePartitionKeyPathsAreNotEncrypted(clientEncryptionPolicy.IncludedPaths, partitionKeyPathTokens);

            if (clientEncryptionPolicy.PolicyFormatVersion != 1)
            {
                throw new InvalidOperationException($"Invalid PolicyFormatVersion:{clientEncryptionPolicy.PolicyFormatVersion} used in Client Encryption Policy. ");
            }

            return(clientEncryptionPolicy);
        }
Beispiel #6
0
        internal async Task InitContainerCacheAsync(
            CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            EncryptionCosmosClient encryptionCosmosClient = this.EncryptionCosmosClient;
            ClientEncryptionPolicy clientEncryptionPolicy = await encryptionCosmosClient.GetClientEncryptionPolicyAsync(
                container : this,
                cancellationToken : cancellationToken,
                shouldForceRefresh : false);

            if (clientEncryptionPolicy != null)
            {
                foreach (string clientEncryptionKeyId in clientEncryptionPolicy.IncludedPaths.Select(p => p.ClientEncryptionKeyId).Distinct())
                {
                    await this.EncryptionCosmosClient.GetClientEncryptionKeyPropertiesAsync(
                        clientEncryptionKeyId : clientEncryptionKeyId,
                        container : this,
                        cancellationToken : cancellationToken,
                        shouldForceRefresh : false);
                }
            }
        }
 private void AddClientEncryptionPolicy(ClientEncryptionPolicy clientEncryptionPolicy)
 {
     this.clientEncryptionPolicy = clientEncryptionPolicy;
 }
 private static ClientEncryptionPolicy SetSupportedPolicyVersionOnClientEncryptionPolicy(ClientEncryptionPolicy clientEncryptionPolicy)
 {
     clientEncryptionPolicy.PolicyFormatVersion = 1;
     return(clientEncryptionPolicy);
 }
 public PSSqlClientEncryptionPolicy(ClientEncryptionPolicy clientEncryptionPolicy) : base(PSSqlClientEncryptionPolicy.SetSupportedPolicyVersionOnClientEncryptionPolicy(clientEncryptionPolicy))
 {
 }
Beispiel #10
0
        private async Task <CachedEncryptionSettings> FetchCachedEncryptionSettingsAsync(
            string propertyName,
            EncryptionProcessor encryptionProcessor,
            CancellationToken cancellationToken)
        {
            ClientEncryptionPolicy clientEncryptionPolicy = await encryptionProcessor.EncryptionCosmosClient.GetClientEncryptionPolicyAsync(
                encryptionProcessor.Container,
                cancellationToken,
                false);

            if (clientEncryptionPolicy != null)
            {
                foreach (ClientEncryptionIncludedPath propertyToEncrypt in clientEncryptionPolicy.IncludedPaths)
                {
                    if (string.Equals(propertyToEncrypt.Path.Substring(1), propertyName))
                    {
                        ClientEncryptionKeyProperties clientEncryptionKeyProperties = await encryptionProcessor.EncryptionCosmosClient.GetClientEncryptionKeyPropertiesAsync(
                            clientEncryptionKeyId : propertyToEncrypt.ClientEncryptionKeyId,
                            container : encryptionProcessor.Container,
                            cancellationToken : cancellationToken,
                            shouldForceRefresh : false);

                        ProtectedDataEncryptionKey protectedDataEncryptionKey = null;

                        try
                        {
                            protectedDataEncryptionKey = this.BuildProtectedDataEncryptionKey(
                                clientEncryptionKeyProperties,
                                encryptionProcessor.EncryptionKeyStoreProvider,
                                propertyToEncrypt.ClientEncryptionKeyId);
                        }
                        catch (RequestFailedException ex)
                        {
                            // the key was revoked. Try to fetch the latest EncryptionKeyProperties from the backend.
                            // This should succeed provided the user has rewraped the key with right set of meta data.
                            if (ex.Status == (int)HttpStatusCode.Forbidden)
                            {
                                clientEncryptionKeyProperties = await encryptionProcessor.EncryptionCosmosClient.GetClientEncryptionKeyPropertiesAsync(
                                    clientEncryptionKeyId : propertyToEncrypt.ClientEncryptionKeyId,
                                    container : encryptionProcessor.Container,
                                    cancellationToken : cancellationToken,
                                    shouldForceRefresh : true);

                                protectedDataEncryptionKey = this.BuildProtectedDataEncryptionKey(
                                    clientEncryptionKeyProperties,
                                    encryptionProcessor.EncryptionKeyStoreProvider,
                                    propertyToEncrypt.ClientEncryptionKeyId);
                            }
                            else
                            {
                                throw;
                            }
                        }

                        EncryptionSettings encryptionSettings = new EncryptionSettings
                        {
                            EncryptionSettingTimeToLive = DateTime.UtcNow + TimeSpan.FromMinutes(Constants.CachedEncryptionSettingsDefaultTTLInMinutes),
                            ClientEncryptionKeyId       = propertyToEncrypt.ClientEncryptionKeyId,
                            DataEncryptionKey           = protectedDataEncryptionKey,
                        };

                        EncryptionType encryptionType = EncryptionType.Plaintext;
                        switch (propertyToEncrypt.EncryptionType)
                        {
                        case CosmosEncryptionType.Deterministic:
                            encryptionType = EncryptionType.Deterministic;
                            break;

                        case CosmosEncryptionType.Randomized:
                            encryptionType = EncryptionType.Randomized;
                            break;

                        case CosmosEncryptionType.Plaintext:
                            encryptionType = EncryptionType.Plaintext;
                            break;

                        default:
                            throw new ArgumentException($"Invalid encryption type {propertyToEncrypt.EncryptionType}. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
                        }

                        encryptionSettings = EncryptionSettings.Create(encryptionSettings, encryptionType);
                        return(new CachedEncryptionSettings(encryptionSettings, encryptionSettings.EncryptionSettingTimeToLive));
                    }
                }
            }

            return(null);
        }