public async Task DownloadVersionedCertificate(string contentType)
        {
            string            name   = Recording.GenerateId();
            CertificatePolicy policy = new CertificatePolicy
            {
                IssuerName = WellKnownIssuerNames.Self,
                Subject    = "CN=default",
                KeyType    = CertificateKeyType.Rsa,
                Exportable = true,
                ReuseKey   = false,
                KeyUsage   =
                {
                    CertificateKeyUsage.DataEncipherment,
                },
                CertificateTransparency = false,
                ContentType             = contentType,
            };

            CertificateOperation operation = await Client.StartCreateCertificateAsync(name, policy);

            RegisterForCleanup(name);

            await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);

            KeyVaultCertificate certificate = await Client.GetCertificateAsync(name);

            string version = certificate.Properties.Version;

            using X509Certificate2 pub = new X509Certificate2(certificate.Cer);
#if NET6_0_OR_GREATER
            using RSA pubkey = (RSA)pub.PublicKey.GetRSAPublicKey();
#else
            using RSA pubkey = (RSA)pub.PublicKey.Key;
#endif

            byte[] plaintext  = Encoding.UTF8.GetBytes("Hello, world!");
            byte[] ciphertext = pubkey.Encrypt(plaintext, RSAEncryptionPadding.Pkcs1);

            // Create a new certificate version that is not exportable just to further prove we are not downloading it.
            policy.Exportable = false;
            operation         = await Client.StartCreateCertificateAsync(name, policy);

            await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);

            certificate = await Client.GetCertificateAsync(name);

            Assert.AreNotEqual(version, certificate.Properties.Version);

            // Now download the certificate and test decryption.
            using X509Certificate2 x509certificate = await Client.DownloadCertificateAsync(name, version);

            Assert.IsTrue(x509certificate.HasPrivateKey);

            using RSA rsa = (RSA)x509certificate.GetRSAPrivateKey();
            byte[] decrypted = rsa.Decrypt(ciphertext, RSAEncryptionPadding.Pkcs1);

            CollectionAssert.AreEqual(plaintext, decrypted);
        }
        public async Task VerifyGetCertificateCompletedSubsequently()
        {
            string certName = Recording.GenerateId();

            await Client.StartCreateCertificateAsync(certName, DefaultPolicy);

            RegisterForCleanup(certName);

            // Pretend a separate process was started subsequently and we need to get the operation again.
            CertificateOperation operation = new CertificateOperation(Client, certName);

            // Need to call the real async wait method or the sync version of this test fails because it's using the instrumented Client directly.
            using CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
            TimeSpan pollingInterval = TimeSpan.FromSeconds((Mode == RecordedTestMode.Playback) ? 0 : 1);

            await operation.WaitForCompletionAsync(pollingInterval, cts.Token);

            Assert.IsTrue(operation.HasCompleted);
            Assert.IsTrue(operation.HasValue);

            KeyVaultCertificateWithPolicy certificateWithPolicy = operation.Value;

            Assert.NotNull(certificateWithPolicy);
            Assert.AreEqual(certName, certificateWithPolicy.Name);
            Assert.NotNull(certificateWithPolicy.Properties.Version);
        }
        public async Task VerifyUnexpectedDeleteCertificateOperation()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

            certificatePolicy.IssuerName = WellKnownIssuerNames.Unknown;

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

            RegisterForCleanup(certName);

            try
            {
                // Calling through the CertificateClient directly won't affect the CertificateOperation, so subsequent status updates should throw.
                await Client.DeleteCertificateOperationAsync(certName);
            }
            catch (RequestFailedException e) when(e.Status == 403)
            {
                Assert.Inconclusive("The create operation completed before it could be canceled.");
            }

            InvalidOperationException ex = Assert.ThrowsAsync <InvalidOperationException>(
                async() => await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default));

            Assert.AreEqual("The operation was deleted so no value is available.", ex.Message);

            Assert.IsTrue(operation.HasCompleted);
            Assert.IsFalse(operation.HasValue);
            Assert.AreEqual(404, operation.GetRawResponse().Status);
        }
        public async Task VerifyUpdateCertificate()
        {
            string certName = Recording.GenerateId();

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

            RegisterForCleanup(certName);

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

            CertificateProperties originalProperties = original.Properties;

            Assert.IsTrue(originalProperties.Enabled);
            Assert.IsEmpty(originalProperties.Tags);

            IDictionary <string, string> expTags = new Dictionary <string, string>()
            {
                { "key1", "value1" }
            };

            originalProperties.Tags.Add("key1", "value1");

            KeyVaultCertificate updated = await Client.UpdateCertificatePropertiesAsync(originalProperties);

            Assert.IsTrue(updated.Properties.Enabled);
            CollectionAssert.AreEqual(expTags, updated.Properties.Tags);

            originalProperties.Enabled = false;
            originalProperties.Tags.Clear();
            updated = await Client.UpdateCertificatePropertiesAsync(originalProperties);

            Assert.IsFalse(updated.Properties.Enabled);
            CollectionAssert.AreEqual(expTags, updated.Properties.Tags);
        }
        public async Task VerifyUpdateCertificatePolicy()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

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

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

            Assert.NotNull(original);

            RegisterForCleanup(certName);

            certificatePolicy = new CertificatePolicy(WellKnownIssuerNames.Self, "CN=Azure SDK")
            {
                ReuseKey = true,
                CertificateTransparency = true,
                Exportable  = false,
                ContentType = CertificateContentType.Pem,
                KeySize     = 3072
            };

            CertificatePolicy updatePolicy = await Client.UpdateCertificatePolicyAsync(certName, certificatePolicy);

            Assert.NotNull(updatePolicy);
            Assert.NotNull(updatePolicy.UpdatedOn);
            Assert.AreEqual(certificatePolicy.Subject, updatePolicy.Subject);
            Assert.AreEqual(certificatePolicy.ReuseKey, updatePolicy.ReuseKey);
            Assert.AreEqual(certificatePolicy.Exportable, updatePolicy.Exportable);
            Assert.AreEqual(certificatePolicy.CertificateTransparency, updatePolicy.CertificateTransparency);
            Assert.AreEqual(certificatePolicy.ContentType, updatePolicy.ContentType);
            Assert.AreEqual(certificatePolicy.KeySize, updatePolicy.KeySize);
        }
        public async Task VerifyUnexpectedCancelCertificateOperation()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

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

            RegisterForCleanup(certName);

            try
            {
                // Calling through the CertificateClient directly won't affect the CertificateOperation, so subsequent status updates should throw.
                await Client.CancelCertificateOperationAsync(certName);
            }
            catch (RequestFailedException e) when(e.Status == 403)
            {
                Assert.Inconclusive("The create operation completed before it could be canceled.");
            }

            OperationCanceledException ex = Assert.ThrowsAsync <OperationCanceledException>(
                async() => await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default),
                $"Expected exception {nameof(OperationCanceledException)} not thrown. Operation status: {operation?.Properties?.Status}, error: {operation?.Properties?.Error?.Message}");

            Assert.AreEqual("The operation was canceled so no value is available.", ex.Message);

            Assert.IsTrue(operation.HasCompleted);
            Assert.IsFalse(operation.HasValue);
            Assert.AreEqual(200, operation.GetRawResponse().Status);
        }
        public async Task DownloadNonExportableCertificate(string contentType)
        {
            string            name   = Recording.GenerateId();
            CertificatePolicy policy = new CertificatePolicy
            {
                IssuerName = WellKnownIssuerNames.Self,
                Subject    = "CN=default",
                KeyType    = CertificateKeyType.Rsa,
                Exportable = false,
                ReuseKey   = false,
                KeyUsage   =
                {
                    CertificateKeyUsage.DataEncipherment,
                },
                CertificateTransparency = false,
                ContentType             = contentType,
            };

            CertificateOperation operation = await Client.StartCreateCertificateAsync(name, policy);

            RegisterForCleanup(name);

            await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);

            using X509Certificate2 x509certificate = await Client.DownloadCertificateAsync(name);

            Assert.IsFalse(x509certificate.HasPrivateKey);
        }
        protected async Task <KeyVaultCertificateWithPolicy> WaitForCompletion(CertificateOperation operation)
        {
            using CancellationTokenSource cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
            TimeSpan pollingInterval = TimeSpan.FromSeconds((Mode == RecordedTestMode.Playback) ? 0 : 1);

            try
            {
                if (IsAsync)
                {
                    await operation.WaitForCompletionAsync(pollingInterval, cts.Token);
                }
                else
                {
                    while (!operation.HasCompleted)
                    {
                        operation.UpdateStatus(cts.Token);

                        await Task.Delay(pollingInterval, cts.Token);
                    }
                }
            }
            catch (TaskCanceledException)
            {
                Assert.Inconclusive("Timed out while waiting for operation {0}", operation.Id);
            }

            return(operation.Value);
        }
        public async Task DownloadECDsaCertificateSignLocalVerifyRemote([EnumValues] CertificateContentType contentType, [EnumValues] CertificateKeyCurveName keyCurveName)
        {
#if NET461
            Assert.Ignore("ECC is not supported before .NET Framework 4.7");
#endif
            if (keyCurveName == CertificateKeyCurveName.P256K && RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                Assert.Ignore("https://github.com/Azure/azure-sdk-for-net/issues/25472");
            }

            string name = Recording.GenerateId();

            CertificatePolicy policy = new CertificatePolicy
            {
                IssuerName   = WellKnownIssuerNames.Self,
                Subject      = "CN=default",
                KeyType      = CertificateKeyType.Ec,
                KeyCurveName = keyCurveName,
                Exportable   = true,
                KeyUsage     =
                {
                    CertificateKeyUsage.DigitalSignature,
                },
                ContentType = contentType,
            };

            CertificateOperation operation = await Client.StartCreateCertificateAsync(name, policy);

            RegisterForCleanup(name);

            await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);

            // Download the certificate and sign data locally.
            byte[] plaintext = Encoding.UTF8.GetBytes(nameof(DownloadECDsaCertificateSignRemoteVerifyLocal));

            X509Certificate2 certificate = null;
            try
            {
                certificate = await Client.DownloadCertificateAsync(name, operation.Value.Properties.Version);

                using ECDsa privateKey = certificate.GetECDsaPrivateKey();

                byte[] signature = privateKey.SignData(plaintext, keyCurveName.GetHashAlgorithmName());

                // Verify data remotely.
                CryptographyClient cryptoClient = GetCryptographyClient(operation.Value.KeyId);
                VerifyResult       result       = await cryptoClient.VerifyDataAsync(keyCurveName.GetSignatureAlgorithm(), plaintext, signature);

                Assert.IsTrue(result.IsValid);
            }
            catch (Exception ex) when(IsExpectedP256KException(ex, keyCurveName))
            {
                Assert.Ignore("The curve is not supported by the current platform");
            }
            finally
            {
                certificate?.Dispose();
            }
        }
        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);
        }
Exemple #11
0
        public async Task CreateCertificateAsync()
        {
            #region Snippet:CreateCertificateAsync
            // Create a certificate. This starts a long running operation to create and sign the certificate.
            CertificateOperation operation = await client.StartCreateCertificateAsync("MyCertificate", CertificatePolicy.Default);

            // You can await the completion of the create certificate operation.
            KeyVaultCertificateWithPolicy certificate = await operation.WaitForCompletionAsync();

            #endregion
        }
Exemple #12
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);
        }
        public async Task VerifyUnexpectedCancelCertificateOperation()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

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

            RegisterForCleanup(certName);

            OperationCanceledException ex = null;

            try
            {
                // Calling through the CertificateClient directly won't affect the CertificateOperation, so subsequent status updates should throw.
                await Client.CancelCertificateOperationAsync(certName);

                await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);
            }
            catch (OperationCanceledException e)
            {
                ex = e;
            }
            catch (RequestFailedException e) when(e.Status == 403)
            {
                Assert.Inconclusive("The create operation completed before it could be canceled.");
            }
            catch (RequestFailedException e) when(e.Status == 409)
            {
                Assert.Inconclusive("There was a service timing issue when attempting to cancel the operation.");
            }

            if (operation.HasCompleted && !operation.Properties.CancellationRequested)
            {
                Assert.Inconclusive("The create operation completed before it could be canceled.");
            }

            Assert.AreEqual("The operation was canceled so no value is available.", ex?.Message);

            Assert.IsTrue(operation.HasCompleted);
            Assert.IsFalse(operation.HasValue);
            Assert.AreEqual(200, operation.GetRawResponse().Status);
        }
Exemple #14
0
        public async Task DownloadLatestCertificate()
        {
            string            name   = Recording.GenerateId();
            CertificatePolicy policy = new CertificatePolicy
            {
                IssuerName = WellKnownIssuerNames.Self,
                Subject    = "CN=default",
                KeyType    = CertificateKeyType.Rsa,
                Exportable = true,
                ReuseKey   = false,
                KeyUsage   =
                {
                    CertificateKeyUsage.DataEncipherment,
                    CertificateKeyUsage.DigitalSignature,
                },
                CertificateTransparency = false,
                ContentType             = CertificateContentType.Pkcs12,
            };

            CertificateOperation operation = await Client.StartCreateCertificateAsync(name, policy);

            RegisterForCleanup(name);

            await operation.WaitForCompletionAsync();

            KeyVaultCertificate certificate = await Client.GetCertificateAsync(name);

            using X509Certificate2 pub = new X509Certificate2(certificate.Cer);
            using RSA pubkey           = (RSA)pub.PublicKey.Key;

            byte[] plaintext  = Encoding.UTF8.GetBytes("Hello, world!");
            byte[] ciphertext = pubkey.Encrypt(plaintext, RSAEncryptionPadding.Pkcs1);

            using X509Certificate2 x509certificate = await Client.DownloadCertificateAsync(name);

            Assert.IsTrue(x509certificate.HasPrivateKey);

            using RSA rsa = (RSA)x509certificate.PrivateKey;
            byte[] decrypted = rsa.Decrypt(ciphertext, RSAEncryptionPadding.Pkcs1);

            CollectionAssert.AreEqual(plaintext, decrypted);
        }
Exemple #15
0
        protected async Task <CertificateWithPolicy> WaitForCompletion(CertificateOperation operation)
        {
            TimeSpan pollingInterval = TimeSpan.FromSeconds((Mode == RecordedTestMode.Playback) ? 0 : 1);

            if (IsAsync)
            {
                await operation.WaitForCompletionAsync();
            }
            else
            {
                while (!operation.HasValue)
                {
                    operation.UpdateStatus();

                    await Task.Delay(pollingInterval);
                }
            }

            return(operation.Value);
        }
        public async Task VerifyCancelCertificateOperation()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

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

            RegisterForCleanup(certName);

            // Give the service time to process the start request.
            await DelayAsync(TimeSpan.FromSeconds(2));

            OperationCanceledException ex = null;

            try
            {
                await operation.CancelAsync();

                await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);
            }
            catch (OperationCanceledException e)
            {
                ex = e;
            }
            catch (RequestFailedException e) when(e.Status == 403)
            {
                Assert.Inconclusive("The create operation completed before it could be canceled.");
            }

            if (operation.HasCompleted && !operation.Properties.CancellationRequested)
            {
                Assert.Inconclusive("The create operation completed before it could be canceled.");
            }

            Assert.AreEqual("The operation was canceled so no value is available.", ex?.Message);

            Assert.IsTrue(operation.HasCompleted);
            Assert.IsFalse(operation.HasValue);
            Assert.AreEqual(200, operation.GetRawResponse().Status);
        }
        private async ValueTask <KeyVaultCertificateWithPolicy> WaitForOperationAsync(CertificateOperation operation)
        {
            var rand = new Random();

            TimeSpan PollingInterval() => TimeSpan.FromMilliseconds(rand.Next(1, 50));

            if (IsAsync)
            {
                return(await operation.WaitForCompletionAsync(PollingInterval(), default));
            }
            else
            {
                while (!operation.HasCompleted)
                {
                    operation.UpdateStatus();
                    await Task.Delay(PollingInterval());
                }

                return(operation.Value);
            }
        }
        public async Task VerifyGetCertificatePolicy()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

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

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

            Assert.NotNull(original);

            RegisterForCleanup(certName);

            CertificatePolicy policy = await Client.GetCertificatePolicyAsync(certName);

            Assert.NotNull(policy);
            Assert.AreEqual(DefaultPolicy.KeyType, policy.KeyType);
            Assert.AreEqual(DefaultPolicy.IssuerName, policy.IssuerName);
            Assert.AreEqual(DefaultPolicy.ReuseKey, policy.ReuseKey);
        }
        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);
        }
        public async Task CreateClientAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            #region Snippet:CreateCertificateClient
            // Create a new certificate client using the default credential from Azure.Identity using environment variables previously set,
            // including AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID.
            var client = new CertificateClient(vaultUri: new Uri(keyVaultUrl), credential: new DefaultAzureCredential());
            #endregion

            #region Snippet:CreateCertificate
            // Create a certificate. This starts a long running operation to create and sign the certificate.
            CertificateOperation operation = await client.StartCreateCertificateAsync("MyCertificate");

            // You can await the completion of the create certificate operation.
            CertificateWithPolicy certificate = await operation.WaitForCompletionAsync();

            #endregion

            this.client = client;
        }
        public async Task VerifyDeleteCertificateOperation()
        {
            string certName = Recording.GenerateId();

            CertificatePolicy certificatePolicy = DefaultPolicy;

            certificatePolicy.IssuerName = WellKnownIssuerNames.Unknown;

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

            RegisterForCleanup(certName);

            await operation.DeleteAsync();

            InvalidOperationException ex = Assert.ThrowsAsync <InvalidOperationException>(
                async() => await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default));

            Assert.AreEqual("The operation was deleted so no value is available.", ex.Message);

            Assert.IsTrue(operation.HasCompleted);
            Assert.IsFalse(operation.HasValue);
            Assert.AreEqual(404, operation.GetRawResponse().Status);
        }
        public async Task VerifyGetCertificateCompleted()
        {
            string certName = Recording.GenerateId();

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

            RegisterForCleanup(certName);

            await operation.WaitForCompletionAsync(DefaultCertificateOperationPollingInterval, default);

            KeyVaultCertificateWithPolicy certificateWithPolicy = await Client.GetCertificateAsync(certName);

            Assert.NotNull(certificateWithPolicy);

            Assert.AreEqual(certificateWithPolicy.Name, certName);

            Assert.NotNull(certificateWithPolicy.Properties.Version);

            KeyVaultCertificate certificate = await Client.GetCertificateVersionAsync(certName, certificateWithPolicy.Properties.Version);

            Assert.NotNull(certificate);

            Assert.AreEqual(certificate.Name, certName);
        }
 protected async Task <KeyVaultCertificateWithPolicy> WaitForCompletion(CertificateOperation operation, TimeSpan?pollingInterval = null)
 {
     pollingInterval ??= TimeSpan.FromSeconds(1);
     return(await operation.WaitForCompletionAsync(pollingInterval.Value, default).TimeoutAfter(TimeSpan.FromMinutes(1)));
 }
Exemple #24
0
 private async ValueTask <KeyVaultCertificateWithPolicy> WaitForOperationAsync(CertificateOperation operation)
 {
     return(await operation.WaitForCompletionAsync(TimeSpan.Zero, default));
 }
        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));
        }
        public async Task ValidateMergeCertificate()
        {
            string serverCertificateName = Recording.GenerateId();

            // Generate the request.
            CertificatePolicy policy = new CertificatePolicy(WellKnownIssuerNames.Unknown, "CN=Azure SDK")
            {
                CertificateTransparency = false,
                ContentType             = CertificateContentType.Pkcs12,
            };

            CertificateOperation operation = await Client.StartCreateCertificateAsync(serverCertificateName, policy);

            RegisterForCleanup(serverCertificateName);
            await using IAsyncDisposable disposableOperation = EnsureDeleted(operation);

            // Read the CA.
            byte[]           caCertificateBytes = Convert.FromBase64String(CaPublicKeyBase64);
            X509Certificate2 caCertificate      = new X509Certificate2(caCertificateBytes);

            // Read CA private key since getting it from caCertificate above throws.
            AsymmetricCipherKeyPair caPrivateKey;

            using (StringReader caPrivateKeyReader = new StringReader(CaPrivateKeyPem))
            {
                Org.BouncyCastle.OpenSsl.PemReader reader = new Org.BouncyCastle.OpenSsl.PemReader(caPrivateKeyReader);
                caPrivateKey = (AsymmetricCipherKeyPair)reader.ReadObject();
            }

            // Read the CSR.
            Pkcs10CertificationRequest csr     = new Pkcs10CertificationRequest(operation.Properties.Csr);
            CertificationRequestInfo   csrInfo = csr.GetCertificationRequestInfo();

            // Parse the issuer subject name.
            Hashtable oidLookup = new Hashtable(X509Name.DefaultLookup)
            {
                { "s", new DerObjectIdentifier("2.5.4.8") },
            };

            X509Name issuerName = new X509Name(true, oidLookup, caCertificate.Subject);

            // Sign the request.
            X509V3CertificateGenerator generator = new X509V3CertificateGenerator();

            generator.SetIssuerDN(issuerName);
            generator.SetSerialNumber(BigInteger.One);
            generator.SetNotBefore(DateTime.Now);
            generator.SetNotAfter(DateTime.Now.AddDays(1));
            generator.SetSubjectDN(csrInfo.Subject);
            generator.SetPublicKey(csr.GetPublicKey());

            Asn1SignatureFactory signatureFactory      = new Asn1SignatureFactory("SHA256WITHRSA", caPrivateKey.Private);
            X509Certificate      serverSignedPublicKey = generator.Generate(signatureFactory);

            // Merge the certificate chain.
            MergeCertificateOptions       options = new MergeCertificateOptions(serverCertificateName, new[] { serverSignedPublicKey.GetEncoded(), caCertificateBytes });
            KeyVaultCertificateWithPolicy mergedServerCertificate = await Client.MergeCertificateAsync(options);

            X509Certificate2 serverCertificate = new X509Certificate2(mergedServerCertificate.Cer);

            Assert.AreEqual(csrInfo.Subject.ToString(), serverCertificate.Subject);
            Assert.AreEqual(serverCertificateName, mergedServerCertificate.Name);

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

            Assert.AreEqual(mergedServerCertificate.Name, completedServerCertificate.Name);
            CollectionAssert.AreEqual(mergedServerCertificate.Cer, completedServerCertificate.Cer);
        }
Exemple #27
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
            }
        }
Exemple #28
0
 private async ValueTask <KeyVaultCertificateWithPolicy> WaitForOperationAsync(CertificateOperation operation) =>
 await operation.WaitForCompletionAsync();