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); }
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 }
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); }
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); }
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))); }
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); }
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 } }
private async ValueTask <KeyVaultCertificateWithPolicy> WaitForOperationAsync(CertificateOperation operation) => await operation.WaitForCompletionAsync();