public async Task ImportPfxCertificateAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string name = $"cert-{Guid.NewGuid()}";

            //@@ byte[] pfx = File.ReadAllBytes("certificate.pfx");
            /*@@*/ byte[]            pfx           = Convert.FromBase64String(s_pfxBase64);
            ImportCertificateOptions importOptions = new ImportCertificateOptions(name, pfx)
            {
                Policy = new CertificatePolicy(WellKnownIssuerNames.Self, "CN=contoso.com")
                {
                    // Required when setting a policy; if no policy required, Pfx is assumed.
                    ContentType = CertificateContentType.Pkcs12,

                    // Optionally mark the private key exportable.
                    Exportable = true
                }
            };

            await client.ImportCertificateAsync(importOptions);

            DeleteCertificateOperation operation = await client.StartDeleteCertificateAsync(name);

            // To ensure certificates are deleted on server side.
            // You only need to wait for completion if you want to purge or recover the certificate.
            await operation.WaitForCompletionAsync();

            client.PurgeDeletedCertificate(name);
        }
        public async Task ImportPemCertificateAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string name = $"cert-{Guid.NewGuid()}";

            //@@ byte[] pem = File.ReadAllBytes("certificate.cer");
            /*@@*/ byte[]            pem           = Encoding.ASCII.GetBytes(s_pem);
            ImportCertificateOptions importOptions = new ImportCertificateOptions(name, pem)
            {
                Policy = new CertificatePolicy(WellKnownIssuerNames.Self, "CN=contoso.com")
                {
                    // Required when the certificate bytes are a PEM-formatted certificate.
                    ContentType = CertificateContentType.Pem,

                    // Optionally mark the private key exportable.
                    Exportable = true
                }
            };

            await client.ImportCertificateAsync(importOptions);

            DeleteCertificateOperation operation = await client.StartDeleteCertificateAsync(name);

            // To ensure certificates are deleted on server side.
            // You only need to wait for completion if you want to purge or recover the certificate.
            await operation.WaitForCompletionAsync();

            client.PurgeDeletedCertificate(name);
        }
Example #3
0
        public void HelloWorldSync(string keyVaultUrl)
        {
            #region Snippet:CertificatesSample1CertificateClient
            var client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
            #endregion

            #region Snippet:CertificatesSample1CreateCertificate
            string certName             = $"defaultCert-{Guid.NewGuid()}";
            CertificateOperation certOp = client.StartCreateCertificate(certName, CertificatePolicy.Default);

            while (!certOp.HasCompleted)
            {
                certOp.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            #endregion

            #region Snippet:CertificatesSample1GetCertificateWithPolicy
            KeyVaultCertificateWithPolicy certificate = client.GetCertificate(certName);

            Debug.WriteLine($"Certificate was returned with name {certificate.Name} which expires {certificate.Properties.ExpiresOn}");
            #endregion

            #region Snippet:CertificatesSample1UpdateCertificate
            CertificateProperties certificateProperties = certificate.Properties;
            certificateProperties.Enabled = false;

            KeyVaultCertificate updatedCert = client.UpdateCertificateProperties(certificateProperties);
            Debug.WriteLine($"Certificate enabled set to '{updatedCert.Properties.Enabled}'");
            #endregion

            #region Snippet:CertificatesSample1CreateCertificateWithNewVersion
            CertificateOperation newCertOp = client.StartCreateCertificate(certificate.Name, certificate.Policy);

            while (!newCertOp.HasCompleted)
            {
                newCertOp.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            #endregion

            #region Snippet:CertificatesSample1DeleteCertificate
            DeleteCertificateOperation operation = client.StartDeleteCertificate(certName);

            // To ensure certificate is deleted on server side.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }
            #endregion

            // If the keyvault is soft-delete enabled, then for permanent deletion, the deleted certificate needs to be purged.
            client.PurgeDeletedCertificate(certName);
        }
        public async Task HelloWorldAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            // Instantiate a certificate client that will be used to call the service. Notice that the client is using
            // default Azure credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create a self-signed certificate using the default policy. If the certificate
            // already exists in the Key Vault, then a new version of the key is created.
            string certName = $"defaultCert-{Guid.NewGuid()}";

            CertificateOperation certOp = await client.StartCreateCertificateAsync(certName, CertificatePolicy.Default);

            // Next, let's wait on the certificate operation to complete. Note that certificate creation can last an indeterministic
            // amount of time, so applications should only wait on the operation to complete in the case the issuance time is well
            // known and within the scope of the application lifetime. In this case we are creating a self-signed certificate which
            // should be issued in a relatively short amount of time.
            Response <KeyVaultCertificateWithPolicy> certificateResponse = await certOp.WaitForCompletionAsync();

            KeyVaultCertificateWithPolicy certificate = certificateResponse.Value;

            // At some time later we could get the created certificate along with its policy from the Key Vault.
            certificate = await client.GetCertificateAsync(certName);

            Debug.WriteLine($"Certificate was returned with name {certificate.Name} which expires {certificate.Properties.ExpiresOn}");

            // We find that the certificate has been compromised and we want to disable it so applications will no longer be able
            // to access the compromised version of the certificate.
            CertificateProperties certificateProperties = certificate.Properties;

            certificateProperties.Enabled = false;

            Response <KeyVaultCertificate> updatedCertResponse = await client.UpdateCertificatePropertiesAsync(certificateProperties);

            Debug.WriteLine($"Certificate enabled set to '{updatedCertResponse.Value.Properties.Enabled}'");

            // We need to create a new version of the certificate that applications can use to replace the compromised certificate.
            // Creating a certificate with the same name and policy as the compromised certificate will create another version of the
            // certificate with similar properties to the original certificate
            CertificateOperation newCertOp = await client.StartCreateCertificateAsync(certificate.Name, certificate.Policy);

            KeyVaultCertificateWithPolicy newCert = await newCertOp.WaitForCompletionAsync();

            // The certificate is no longer needed, need to delete it from the Key Vault.
            DeleteCertificateOperation operation = await client.StartDeleteCertificateAsync(certName);

            // You only need to wait for completion if you want to purge or recover the certificate.
            await operation.WaitForCompletionAsync();

            // If the keyvault is soft-delete enabled, then for permanent deletion, the deleted key needs to be purged.
            await client.PurgeDeletedCertificateAsync(certName);
        }
Example #5
0
        public async Task DownloadCertificateAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string certificateName         = $"rsa-{Guid.NewGuid()}";
            CertificateOperation operation = await client.StartCreateCertificateAsync(certificateName, CertificatePolicy.Default);

            await operation.WaitForCompletionAsync();

            using SHA256 sha = SHA256.Create();
            byte[] data = Encoding.UTF8.GetBytes("test");
            byte[] hash = sha.ComputeHash(data);

            #region Snippet:CertificatesSample4DownloadCertificateAsync
            X509KeyStorageFlags keyStorageFlags = X509KeyStorageFlags.MachineKeySet;
            if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                keyStorageFlags |= X509KeyStorageFlags.EphemeralKeySet;
            }

            DownloadCertificateOptions options = new DownloadCertificateOptions
            {
                KeyStorageFlags = keyStorageFlags
            };

            using X509Certificate2 certificate = await client.DownloadCertificateAsync(certificateName, options : options);

            using RSA key = certificate.GetRSAPrivateKey();

            byte[] signature = key.SignHash(hash, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            Debug.WriteLine($"Signature: {Convert.ToBase64String(signature)}");
            #endregion

            Response <KeyVaultCertificateWithPolicy> certificateResponse = await client.GetCertificateAsync(certificateName);

            using X509Certificate2 publicCertificate = new X509Certificate2(certificateResponse.Value.Cer);
            using RSA publicKey = publicCertificate.GetRSAPublicKey();

            bool verified = publicKey.VerifyHash(hash, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
            Debug.WriteLine($"Signature verified: {verified}");

            Assert.IsTrue(verified);

            DeleteCertificateOperation deleteOperation = await client.StartDeleteCertificateAsync(certificateName);

            await deleteOperation.WaitForCompletionAsync();

            client.PurgeDeletedCertificate(certificateName);
        }
Example #6
0
        public async Task DeleteAndPurgeCertificateAsync()
        {
            #region Snippet:DeleteAndPurgeCertificateAsync
            DeleteCertificateOperation operation = await client.StartDeleteCertificateAsync("MyCertificate");

            // You only need to wait for completion if you want to purge or recover the certificate.
            await operation.WaitForCompletionAsync();

            DeletedCertificate secret = operation.Value;
            await client.PurgeDeletedCertificateAsync(secret.Name);

            #endregion
        }
Example #7
0
        public void DeleteAndPurgeCertificate()
        {
            #region Snippet:DeleteAndPurgeCertificate
            DeleteCertificateOperation operation = client.StartDeleteCertificate("MyCertificate");

            // You only need to wait for completion if you want to purge or recover the certificate.
            // You should call `UpdateStatus` in another thread or after doing additional work like pumping messages.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }

            DeletedCertificate secret = operation.Value;
            client.PurgeDeletedCertificate(secret.Name);
            #endregion
        }
Example #8
0
        public void ImportPfxCertificateSync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            #region Snippet:CertificatesSample3CertificateClient
            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
            #endregion

            #region Snippet:CertificatesSample3ImportPfxCertificate
            string name = $"cert-{Guid.NewGuid()}";
#if SNIPPET
            byte[] pfx = File.ReadAllBytes("certificate.pfx");
#else
            byte[] pfx = Convert.FromBase64String(s_pfxBase64);
#endif
            ImportCertificateOptions importOptions = new ImportCertificateOptions(name, pfx)
            {
                Policy = new CertificatePolicy(WellKnownIssuerNames.Self, "CN=contoso.com")
                {
                    // Required when setting a policy; if no policy required, Pfx is assumed.
                    ContentType = CertificateContentType.Pkcs12,

                    // Optionally mark the private key exportable.
                    Exportable = true
                }
            };

            client.ImportCertificate(importOptions);
            #endregion

            DeleteCertificateOperation operation = client.StartDeleteCertificate(name);

            // To ensure certificates are deleted on server side.
            // You only need to wait for completion if you want to purge or recover the certificate.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }

            client.PurgeDeletedCertificate(name);
        }
        public async Task VerifyDeleteRecoverPurge()
        {
            string certName = Recording.GenerateId();

            CertificateOperation operation = await Client.StartCreateCertificateAsync(certName, DefaultPolicy);

            KeyVaultCertificateWithPolicy original = await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);

            Assert.NotNull(original);

            DeleteCertificateOperation deleteOperation = await Client.StartDeleteCertificateAsync(certName);

            DeletedCertificate deletedCert = deleteOperation.Value;

            Assert.IsNotNull(deletedCert);

            Assert.IsNotNull(deletedCert.RecoveryId);

            await WaitForDeletedCertificate(certName);

            _ = await Client.StartRecoverDeletedCertificateAsync(certName);

            Assert.NotNull(original);

            await PollForCertificate(certName);

            deleteOperation = await Client.StartDeleteCertificateAsync(certName);

            deletedCert = deleteOperation.Value;

            Assert.IsNotNull(deletedCert);

            Assert.IsNotNull(deletedCert.RecoveryId);

            await WaitForDeletedCertificate(certName);

            await Client.PurgeDeletedCertificateAsync(certName);

            await WaitForPurgedCertificate(certName);
        }
Example #10
0
        protected async Task DeleteCertificatesAsync(params string[] names)
        {
            List <Task> tasks = new(names.Length);

            for (int i = 0; i < names.Length; i++)
            {
                string name = names[i];
                Task   t    = Task.Run(async() =>
                {
                    DeleteCertificateOperation operation = null;
                    try
                    {
                        operation = await Client.StartDeleteCertificateAsync(name);
                        await operation.WaitForCompletionAsync();
                    }
                    catch (RequestFailedException ex) when(ex.Status == 404)
                    {
                    }

                    // Purge deleted Certificates if soft delete is enabled.
                    if (operation.Value.RecoveryId != null)
                    {
                        try
                        {
                            await Client.PurgeDeletedCertificateAsync(name);
                        }
                        catch (RequestFailedException ex) when(ex.Status == 404)
                        {
                        }
                    }
                });

                tasks.Add(t);
            }

            await Task.WhenAll(tasks);
        }
        public async Task GetCertificatesAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            // Instantiate a certificate client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create two self-signed certificates using the default policy
            string certName1 = $"defaultCert-{Guid.NewGuid()}";

            CertificateOperation certOp1 = await client.StartCreateCertificateAsync(certName1, CertificatePolicy.Default);

            string certName2 = $"defaultCert-{Guid.NewGuid()}";

            CertificateOperation certOp2 = await client.StartCreateCertificateAsync(certName1, CertificatePolicy.Default);

            // Next, let's wait on the certificate operation to complete. Note that certificate creation can last an indeterministic
            // amount of time, so applications should only wait on the operation to complete in the case the issuance time is well
            // known and within the scope of the application lifetime. In this case we are creating a self-signed certificate which
            // should be issued in a relatively short amount of time.
            await certOp1.WaitForCompletionAsync();

            await certOp2.WaitForCompletionAsync();

            // Let's list the certificates which exist in the vault along with their thumbprints
            await foreach (CertificateProperties cert in client.GetPropertiesOfCertificatesAsync())
            {
                Debug.WriteLine($"Certificate is returned with name {cert.Name} and thumbprint {BitConverter.ToString(cert.X509Thumbprint)}");
            }

            // We need to create a new version of a certificate. Creating a certificate with the same name will create another version of the certificate
            CertificateOperation newCertOp = await client.StartCreateCertificateAsync(certName1, CertificatePolicy.Default);

            await newCertOp.WaitForCompletionAsync();

            // Let's print all the versions of this certificate
            await foreach (CertificateProperties cert in client.GetPropertiesOfCertificateVersionsAsync(certName1))
            {
                Debug.WriteLine($"Certificate {cert.Name} with name {cert.Version}");
            }

            // The certificates are no longer needed.
            // You need to delete them from the Key Vault.
            DeleteCertificateOperation operation1 = await client.StartDeleteCertificateAsync(certName1);

            DeleteCertificateOperation operation2 = await client.StartDeleteCertificateAsync(certName2);

            // To ensure certificates are deleted on server side.
            Task.WaitAll(
                operation1.WaitForCompletionAsync().AsTask(),
                operation2.WaitForCompletionAsync().AsTask());

            // You can list all the deleted and non-purged certificates, assuming Key Vault is soft-delete enabled.
            await foreach (DeletedCertificate deletedCert in client.GetDeletedCertificatesAsync())
            {
                Debug.WriteLine($"Deleted certificate's recovery Id {deletedCert.RecoveryId}");
            }

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted keys needs to be purged.
            Task.WaitAll(
                client.PurgeDeletedCertificateAsync(certName1),
                client.PurgeDeletedCertificateAsync(certName2));
        }
Example #12
0
        private async Task MigrationGuide()
        {
            #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_Create
            CertificateClient client = new CertificateClient(
                new Uri("https://myvault.vault.azure.net"),
                new DefaultAzureCredential());
            #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_Create

            #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateWithOptions
            using (HttpClient httpClient = new HttpClient())
            {
                CertificateClientOptions options = new CertificateClientOptions
                {
                    Transport = new HttpClientTransport(httpClient)
                };

                //@@CertificateClient client = new CertificateClient(
                /*@@*/ CertificateClient _ = new CertificateClient(
                    new Uri("https://myvault.vault.azure.net"),
                    new DefaultAzureCredential(),
                    options);
            }
            #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateWithOptions

            #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateCustomPolicy
            CertificatePolicy policy = new CertificatePolicy("issuer-name", "CN=customdomain.com")
            {
                ContentType = CertificateContentType.Pkcs12,
                KeyType     = CertificateKeyType.Rsa,
                ReuseKey    = true,
                KeyUsage    =
                {
                    CertificateKeyUsage.CrlSign,
                    CertificateKeyUsage.DataEncipherment,
                    CertificateKeyUsage.DigitalSignature,
                    CertificateKeyUsage.KeyEncipherment,
                    CertificateKeyUsage.KeyAgreement,
                    CertificateKeyUsage.KeyCertSign
                },
                ValidityInMonths = 12,
                LifetimeActions  =
                {
                    new LifetimeAction(CertificatePolicyAction.AutoRenew)
                    {
                        DaysBeforeExpiry = 90,
                    }
                }
            };
            #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateSelfSignedPolicy

            #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateSelfSignedPolicy
            //@@CertificatePolicy policy = CertificatePolicy.Default;
            /*@@*/ policy = CertificatePolicy.Default;
            #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateSelfSignedPolicy

            {
                #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateCertificate
                // Start certificate creation.
                // Depending on the policy and your business process, this could even take days for manual signing.
                CertificateOperation createOperation = await client.StartCreateCertificateAsync("certificate-name", policy);

                KeyVaultCertificateWithPolicy certificate = await createOperation.WaitForCompletionAsync(TimeSpan.FromSeconds(20), CancellationToken.None);

                // If you need to restart the application you can recreate the operation and continue awaiting.
                createOperation = new CertificateOperation(client, "certificate-name");
                certificate     = await createOperation.WaitForCompletionAsync(TimeSpan.FromSeconds(20), CancellationToken.None);

                #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_CreateCertificate
            }

            {
                #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_ImportCertificate
                byte[] cer = File.ReadAllBytes("certificate.pfx");
                ImportCertificateOptions importCertificateOptions = new ImportCertificateOptions("certificate-name", cer)
                {
                    Policy = policy
                };

                KeyVaultCertificateWithPolicy certificate = await client.ImportCertificateAsync(importCertificateOptions);

                #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_ImportCertificate
            }

            {
                #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_ListCertificates
                // List all certificates asynchronously.
                await foreach (CertificateProperties item in client.GetPropertiesOfCertificatesAsync())
                {
                    KeyVaultCertificateWithPolicy certificate = await client.GetCertificateAsync(item.Name);
                }

                // List all certificates synchronously.
                foreach (CertificateProperties item in client.GetPropertiesOfCertificates())
                {
                    KeyVaultCertificateWithPolicy certificate = client.GetCertificate(item.Name);
                }
                #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_ListCertificates
            }

            {
                #region Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_DeleteCertificate
                // Delete the certificate.
                DeleteCertificateOperation deleteOperation = await client.StartDeleteCertificateAsync("certificate-name");

                // Purge or recover the deleted certificate if soft delete is enabled.
                if (deleteOperation.Value.RecoveryId != null)
                {
                    // Deleting a certificate does not happen immediately. Wait for the certificate to be deleted.
                    DeletedCertificate deletedCertificate = await deleteOperation.WaitForCompletionAsync();

                    // Purge the deleted certificate.
                    await client.PurgeDeletedCertificateAsync(deletedCertificate.Name);

                    // You can also recover the deleted certificate using StartRecoverDeletedCertificateAsync,
                    // which returns RecoverDeletedCertificateOperation you can await like DeleteCertificateOperation above.
                }
                #endregion Snippet:Azure_Security_KeyVault_Certificates_Snippets_MigrationGuide_DeleteCertificate
            }
        }
        public void GetCertificatesSync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            #region Snippet:CertificatesSample2CertificateClient
            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
            #endregion

            #region Snippet:CertificatesSample2CreateCertificate
            string certName1             = $"defaultCert-{Guid.NewGuid()}";
            CertificateOperation certOp1 = client.StartCreateCertificate(certName1, CertificatePolicy.Default);

            string certName2             = $"defaultCert-{Guid.NewGuid()}";
            CertificateOperation certOp2 = client.StartCreateCertificate(certName2, CertificatePolicy.Default);

            while (!certOp1.HasCompleted)
            {
                certOp1.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }

            while (!certOp2.HasCompleted)
            {
                certOp2.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            #endregion

            #region Snippet:CertificatesSample2ListCertificates
            foreach (CertificateProperties cert in client.GetPropertiesOfCertificates())
            {
                Debug.WriteLine($"Certificate is returned with name {cert.Name} and thumbprint {BitConverter.ToString(cert.X509Thumbprint)}");
            }
            #endregion

            #region Snippet:CertificatesSample2CreateCertificateWithNewVersion
            CertificateOperation newCertOp = client.StartCreateCertificate(certName1, CertificatePolicy.Default);

            while (!newCertOp.HasCompleted)
            {
                newCertOp.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            #endregion

            #region Snippet:CertificatesSample2ListCertificateVersions
            foreach (CertificateProperties cert in client.GetPropertiesOfCertificateVersions(certName1))
            {
                Debug.WriteLine($"Certificate {cert.Name} with name {cert.Version}");
            }
            #endregion

            #region Snippet:CertificatesSample2DeleteCertificates
            DeleteCertificateOperation operation1 = client.StartDeleteCertificate(certName1);
            DeleteCertificateOperation operation2 = client.StartDeleteCertificate(certName2);

            // To ensure certificates are deleted on server side.
            // You only need to wait for completion if you want to purge or recover the certificate.
            while (!operation1.HasCompleted || !operation2.HasCompleted)
            {
                Thread.Sleep(2000);

                operation1.UpdateStatus();
                operation2.UpdateStatus();
            }
            #endregion

            #region Snippet:CertificatesSample2ListDeletedCertificates
            foreach (DeletedCertificate deletedCert in client.GetDeletedCertificates())
            {
                Debug.WriteLine($"Deleted certificate's recovery Id {deletedCert.RecoveryId}");
            }
            #endregion

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted keys needs to be purged.
            client.PurgeDeletedCertificate(certName1);
            client.PurgeDeletedCertificate(certName2);
        }
        public void HelloWorldSync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = TestEnvironment.KeyVaultUrl;

            #region Snippet:CertificatesSample1CertificateClient
            CertificateClient client = new CertificateClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
            #endregion

            #region Snippet:CertificatesSample1CreateCertificate
            string certName             = $"defaultCert-{Guid.NewGuid()}";
            CertificateOperation certOp = client.StartCreateCertificate(certName, CertificatePolicy.Default);

            while (!certOp.HasCompleted)
            {
                certOp.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            #endregion

            #region Snippet:CertificatesSample1GetCertificateWithPolicy
            Response <KeyVaultCertificateWithPolicy> certificateResponse = client.GetCertificate(certName);
            KeyVaultCertificateWithPolicy            certificate         = certificateResponse.Value;

            Debug.WriteLine($"Certificate was returned with name {certificate.Name} which expires {certificate.Properties.ExpiresOn}");
            #endregion

            #region Snippet:CertificatesSample1UpdateCertificate
            CertificateProperties certificateProperties = certificate.Properties;
            certificateProperties.Enabled = false;

            Response <KeyVaultCertificate> updatedCertResponse = client.UpdateCertificateProperties(certificateProperties);
            Debug.WriteLine($"Certificate enabled set to '{updatedCertResponse.Value.Properties.Enabled}'");
            #endregion

            #region Snippet:CertificatesSample1CreateCertificateWithNewVersion
            CertificateOperation newCertOp = client.StartCreateCertificate(certificate.Name, certificate.Policy);

            while (!newCertOp.HasCompleted)
            {
                newCertOp.UpdateStatus();

                Thread.Sleep(TimeSpan.FromSeconds(1));
            }
            #endregion

            #region Snippet:CertificatesSample1DeleteCertificate
            DeleteCertificateOperation operation = client.StartDeleteCertificate(certName);

            // You only need to wait for completion if you want to purge or recover the certificate.
            while (!operation.HasCompleted)
            {
                Thread.Sleep(2000);

                operation.UpdateStatus();
            }
            #endregion

            // If the keyvault is soft-delete enabled, then for permanent deletion, the deleted certificate needs to be purged.
            client.PurgeDeletedCertificate(certName);
        }