Exemple #1
0
        public void SqlClientEncryptionKeyTest()
        {
            using (var context = MockContext.Start(this.GetType()))
            {
                fixture.Init(context);
                var client = this.fixture.CosmosDBManagementClient.SqlResources;

                var databaseAccountName = this.fixture.GetDatabaseAccountName(TestFixture.AccountType.Sql);

                var databaseName = TestUtilities.GenerateName("database");
                SqlDatabaseCreateUpdateParameters sqlDatabaseCreateUpdateParameters = new SqlDatabaseCreateUpdateParameters
                {
                    Resource = new SqlDatabaseResource {
                        Id = databaseName
                    },
                    Options = new CreateUpdateOptions()
                };

                SqlDatabaseGetResults sqlDatabaseGetResults = client.CreateUpdateSqlDatabaseWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName,
                    sqlDatabaseCreateUpdateParameters
                    ).GetAwaiter().GetResult().Body;
                Assert.NotNull(sqlDatabaseGetResults);
                Assert.Equal(databaseName, sqlDatabaseGetResults.Name);

                var clientEncryptionKeyName = TestUtilities.GenerateName("clientEncryptionKey");
                ClientEncryptionKeyResource clientEncryptionKeyResource = new ClientEncryptionKeyResource()
                {
                    Id = clientEncryptionKeyName,
                    EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256",
                    KeyWrapMetadata     = new KeyWrapMetadata
                    {
                        Type      = "akv",
                        Value     = "akvPath",
                        Name      = "cmk",
                        Algorithm = "algo"
                    },
                    WrappedDataEncryptionKey = new byte[] { 0xab, 0x57, 0x05, 0xe9, 0x9f, 0xe2 }
                };

                ClientEncryptionKeyCreateUpdateParameters clientEncryptionKeyCreateUpdateParameters = new ClientEncryptionKeyCreateUpdateParameters
                {
                    Resource = clientEncryptionKeyResource
                };

                client.CreateUpdateClientEncryptionKeyWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName,
                    clientEncryptionKeyName,
                    clientEncryptionKeyCreateUpdateParameters);

                Thread.Sleep(10000);

                ClientEncryptionKeyGetResults clientEncryptionKeyRetrieved = client.GetClientEncryptionKeyWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName,
                    clientEncryptionKeyName).GetAwaiter().GetResult().Body;
                Assert.NotNull(clientEncryptionKeyRetrieved);
                Assert.Equal(clientEncryptionKeyResource.Id, clientEncryptionKeyRetrieved.Resource.Id);
                Assert.Equal(clientEncryptionKeyResource.EncryptionAlgorithm, clientEncryptionKeyRetrieved.Resource.EncryptionAlgorithm);
                Assert.Equal(clientEncryptionKeyResource.KeyWrapMetadata.Name, clientEncryptionKeyRetrieved.Resource.KeyWrapMetadata.Name);
                Assert.Equal(clientEncryptionKeyResource.KeyWrapMetadata.Algorithm, clientEncryptionKeyRetrieved.Resource.KeyWrapMetadata.Algorithm);

                clientEncryptionKeyResource.WrappedDataEncryptionKey = new byte[] { 0xac, 0x15 };
                clientEncryptionKeyCreateUpdateParameters            = new ClientEncryptionKeyCreateUpdateParameters
                {
                    Resource = clientEncryptionKeyResource
                };

                client.CreateUpdateClientEncryptionKeyWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName,
                    clientEncryptionKeyName,
                    clientEncryptionKeyCreateUpdateParameters);

                Thread.Sleep(10000);
                clientEncryptionKeyRetrieved = client.GetClientEncryptionKeyWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName,
                    clientEncryptionKeyName).GetAwaiter().GetResult().Body;
                Assert.NotNull(clientEncryptionKeyRetrieved);
                Assert.Equal(clientEncryptionKeyResource.Id, clientEncryptionKeyRetrieved.Resource.Id);
                Assert.Equal(clientEncryptionKeyName, clientEncryptionKeyRetrieved.Name);
                Assert.Equal(clientEncryptionKeyResource.WrappedDataEncryptionKey.Length, clientEncryptionKeyRetrieved.Resource.WrappedDataEncryptionKey.Length);

                var clientEncryptionKeyName2 = TestUtilities.GenerateName("clientEncryptionKey");
                ClientEncryptionKeyResource clientEncryptionKeyResource2 = new ClientEncryptionKeyResource()
                {
                    Id = clientEncryptionKeyName2,
                    EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256",
                    KeyWrapMetadata     = new KeyWrapMetadata
                    {
                        Type      = "akv",
                        Value     = "akvPath2",
                        Name      = "cmk",
                        Algorithm = "algo"
                    },
                    WrappedDataEncryptionKey = new byte[] { 0x11, 0x54, 0x10, 0xa9, 0x1f, 0x24 }
                };

                clientEncryptionKeyCreateUpdateParameters = new ClientEncryptionKeyCreateUpdateParameters
                {
                    Resource = clientEncryptionKeyResource2
                };

                client.CreateUpdateClientEncryptionKeyWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName,
                    clientEncryptionKeyName2,
                    clientEncryptionKeyCreateUpdateParameters);

                Thread.Sleep(10000);

                IEnumerable <ClientEncryptionKeyGetResults> clientEncryptionKeyList = client.ListClientEncryptionKeysWithHttpMessagesAsync(
                    this.fixture.ResourceGroupName,
                    databaseAccountName,
                    databaseName).GetAwaiter().GetResult().Body;
                Assert.NotNull(clientEncryptionKeyList);
                int count = 0;
                foreach (ClientEncryptionKeyGetResults clientEncryptionKeyListElement in clientEncryptionKeyList)
                {
                    count++;
                    Assert.True(clientEncryptionKeyListElement.Name == clientEncryptionKeyName || clientEncryptionKeyListElement.Name == clientEncryptionKeyName2);
                }

                Assert.Equal(2, count);

                client.DeleteSqlDatabaseWithHttpMessagesAsync(this.fixture.ResourceGroupName, databaseAccountName, sqlDatabaseGetResults.Name);
            }
        }
        public override void ExecuteCmdlet()
        {
            if (ParameterSetName.Equals(ParentObjectParameterSet, StringComparison.Ordinal))
            {
                ResourceIdentifier resourceIdentifier = new ResourceIdentifier(SqlDatabaseObject.Id);
                ResourceGroupName = resourceIdentifier.ResourceGroupName;
                DatabaseName      = resourceIdentifier.ResourceName;
                AccountName       = ResourceIdentifierExtensions.GetDatabaseAccountName(resourceIdentifier);
            }

            KeyWrapMetadata encryptionKeyWrapMetadata;

            if (KeyWrapMetadata != null)
            {
                encryptionKeyWrapMetadata = PSSqlKeyWrapMetadata.ToSDKModel(KeyWrapMetadata);
            }
            else
            {
                throw new ArgumentException("KeyWrapMetadata cannot be null");
            }

            if (!string.Equals(EncryptionAlgorithmName, "AEAD_AES_256_CBC_HMAC_SHA256"))
            {
                throw new ArgumentException($"Invalid encryption algorithm '{EncryptionAlgorithmName}' passed. Please refer to https://aka.ms/CosmosClientEncryption for more details.");
            }

            if (!string.Equals(encryptionKeyWrapMetadata.Algorithm, "RSA-OAEP"))
            {
                throw new ArgumentException($"Invalid key wrap algorithm '{encryptionKeyWrapMetadata.Algorithm}' passed. Please refer to https://aka.ms/CosmosClientEncryption for more details.");
            }

            if (string.Equals(encryptionKeyWrapMetadata.Type, "AZURE_KEY_VAULT") && KeyEncryptionKeyResolver == null)
            {
                // get the token credential for key vault audience.
                TokenCredential tokenCredential = new CosmosDBSessionCredential(DefaultContext, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId);

                KeyEncryptionKeyResolver = new KeyResolver(tokenCredential);
            }
            else
            {
                if (KeyEncryptionKeyResolver == null)
                {
                    throw new ArgumentException("KeyEncryptionKeyResolver cannot be null.");
                }
            }

            byte[] plainTextDataEncryptionKey = new byte[32];
            RandomNumberGenerator rng         = RandomNumberGenerator.Create();

            rng.GetBytes(plainTextDataEncryptionKey);


            byte[] wrappedDataEncryptionKey = KeyEncryptionKeyResolver.Resolve(encryptionKeyWrapMetadata.Value)
                                              .WrapKey(encryptionKeyWrapMetadata.Algorithm, plainTextDataEncryptionKey);

            ClientEncryptionKeyResource clientEncryptionKeyResource = new ClientEncryptionKeyResource
            {
                Id = Name,
                EncryptionAlgorithm      = EncryptionAlgorithmName,
                KeyWrapMetadata          = encryptionKeyWrapMetadata,
                WrappedDataEncryptionKey = wrappedDataEncryptionKey
            };

            ClientEncryptionKeyCreateUpdateParameters clientEncryptionKeyCreateUpdateParameters = new ClientEncryptionKeyCreateUpdateParameters
            {
                Resource = clientEncryptionKeyResource
            };

            if (ShouldProcess(Name, "Creating a new CosmosDB Client Encryption Key"))
            {
                // FIXME : This requires a backend fix since its not honoring If-None-Match header with a *. This is required to prevent a race which might result in
                // accidental replace of a key. This is a best effort approach to check for resource conflict.
                ClientEncryptionKeyGetResults readClientEncryptionKeyGetResults = null;
                try
                {
                    readClientEncryptionKeyGetResults = CosmosDBManagementClient.SqlResources.GetClientEncryptionKey(ResourceGroupName, AccountName, DatabaseName, Name);
                }
                catch (CloudException e)
                {
                    if (e.Response.StatusCode != System.Net.HttpStatusCode.NotFound)
                    {
                        throw;
                    }
                }

                if (readClientEncryptionKeyGetResults != null)
                {
                    throw new ConflictingResourceException(message: string.Format(ExceptionMessage.Conflict, Name));
                }

                ClientEncryptionKeyGetResults clientEncryptionKeyGetResults = CosmosDBManagementClient.SqlResources.CreateUpdateClientEncryptionKeyWithHttpMessagesAsync(ResourceGroupName, AccountName, DatabaseName, Name, clientEncryptionKeyCreateUpdateParameters).GetAwaiter().GetResult().Body;
                WriteObject(new PSSqlClientEncryptionKeyGetResults(clientEncryptionKeyGetResults));
            }
        }
Exemple #3
0
        public override void ExecuteCmdlet()
        {
            if (ParameterSetName.Equals(ParentObjectParameterSet, StringComparison.Ordinal))
            {
                ResourceIdentifier resourceIdentifier = new ResourceIdentifier(SqlDatabaseObject.Id);
                ResourceGroupName = resourceIdentifier.ResourceGroupName;
                DatabaseName      = resourceIdentifier.ResourceName;
                AccountName       = ResourceIdentifierExtensions.GetDatabaseAccountName(resourceIdentifier);
            }
            else if (ParameterSetName.Equals(ObjectParameterSet, StringComparison.Ordinal))
            {
                ResourceIdentifier resourceIdentifier = new ResourceIdentifier(InputObject.Id);
                ResourceGroupName = resourceIdentifier.ResourceGroupName;
                DatabaseName      = ResourceIdentifierExtensions.GetSqlDatabaseName(resourceIdentifier);
                AccountName       = ResourceIdentifierExtensions.GetDatabaseAccountName(resourceIdentifier);
                Name = InputObject.Name;
            }

            KeyWrapMetadata newEncryptionKeyWrapMetadata;

            if (KeyWrapMetadata != null)
            {
                newEncryptionKeyWrapMetadata = PSSqlKeyWrapMetadata.ToSDKModel(KeyWrapMetadata);
            }
            else
            {
                throw new ArgumentException("KeyWrapMetadata cannot be null");
            }

            ClientEncryptionKeyGetResults readClientEncryptionKeyGetResults = null;

            try
            {
                readClientEncryptionKeyGetResults = CosmosDBManagementClient.SqlResources.GetClientEncryptionKey(ResourceGroupName, AccountName, DatabaseName, Name);
            }
            catch (CloudException e)
            {
                if (e.Response.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    throw new ResourceNotFoundException(message: string.Format(ExceptionMessage.NotFound, Name), innerException: e);
                }
            }

            ClientEncryptionKeyResource clientEncryptionKeyResource = UpdateAzCosmosDbClientEncryptionKey.PopulateSqlClientEncryptionKeyResource(readClientEncryptionKeyGetResults.Resource);

            if (!string.Equals(newEncryptionKeyWrapMetadata.Algorithm, "RSA-OAEP"))
            {
                throw new ArgumentException($"Invalid key wrap algorithm '{newEncryptionKeyWrapMetadata.Algorithm}' passed. Please refer to https://aka.ms/CosmosClientEncryption for more details.");
            }

            byte[] rewrappedKey;

            if (string.Equals(clientEncryptionKeyResource.KeyWrapMetadata.Type, "AZURE_KEY_VAULT") && KeyEncryptionKeyResolver == null)
            {
                if (!string.Equals(newEncryptionKeyWrapMetadata.Type, "AZURE_KEY_VAULT"))
                {
                    throw new ArgumentException("KeyEncryptionKeyResolver type cannot be changed during rewrap operations. Please refer to https://aka.ms/CosmosClientEncryption for more details.");
                }

                // get the token credential for key vault audience.
                TokenCredential tokenCredential = new CosmosDBSessionCredential(DefaultContext, AzureEnvironment.Endpoint.AzureKeyVaultServiceEndpointResourceId);

                KeyEncryptionKeyResolver = new KeyResolver(tokenCredential);
            }
            else
            {
                if (KeyEncryptionKeyResolver == null)
                {
                    throw new ArgumentException("KeyEncryptionKeyResolver cannot be null.");
                }
            }

            byte[] unwrappedKey = KeyEncryptionKeyResolver.Resolve(clientEncryptionKeyResource.KeyWrapMetadata.Value)
                                  .UnwrapKey(clientEncryptionKeyResource.KeyWrapMetadata.Algorithm, clientEncryptionKeyResource.WrappedDataEncryptionKey);

            rewrappedKey = KeyEncryptionKeyResolver.Resolve(newEncryptionKeyWrapMetadata.Value)
                           .WrapKey(newEncryptionKeyWrapMetadata.Algorithm, unwrappedKey);

            clientEncryptionKeyResource = new ClientEncryptionKeyResource
            {
                Id = Name,
                EncryptionAlgorithm      = clientEncryptionKeyResource.EncryptionAlgorithm,
                KeyWrapMetadata          = newEncryptionKeyWrapMetadata,
                WrappedDataEncryptionKey = rewrappedKey
            };

            ClientEncryptionKeyCreateUpdateParameters clientEncryptionKeyCreateUpdateParameters = new ClientEncryptionKeyCreateUpdateParameters
            {
                Resource = clientEncryptionKeyResource
            };

            if (ShouldProcess(Name, "Updating an existing CosmosDB Client Encryption Key"))
            {
                ClientEncryptionKeyGetResults clientEncryptionKeyGetResults = CosmosDBManagementClient.SqlResources.CreateUpdateClientEncryptionKeyWithHttpMessagesAsync(ResourceGroupName, AccountName, DatabaseName, Name, clientEncryptionKeyCreateUpdateParameters).GetAwaiter().GetResult().Body;
                WriteObject(new PSSqlClientEncryptionKeyGetResults(clientEncryptionKeyGetResults));
            }
        }