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));
            }
        }
Esempio n. 2
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));
            }
        }