@@ -5,15 +5,14 @@ namespace VirtualClient
55{
66 using System ;
77 using System . Net ;
8- using System . Runtime . ConstrainedExecution ;
8+ using System . Security . Cryptography . X509Certificates ;
99 using System . Threading ;
1010 using System . Threading . Tasks ;
1111 using Azure ;
1212 using Azure . Core ;
1313 using Azure . Security . KeyVault . Certificates ;
1414 using Azure . Security . KeyVault . Keys ;
1515 using Azure . Security . KeyVault . Secrets ;
16- using Microsoft . CodeAnalysis . CSharp . Syntax ;
1716 using Polly ;
1817 using VirtualClient . Common . Extensions ;
1918 using VirtualClient . Contracts ;
@@ -59,12 +58,12 @@ public KeyVaultManager(DependencyKeyVaultStore storeDescription)
5958 /// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
6059 /// <param name="retryPolicy">A policy to use for handling retries when transient errors/failures happen.</param>
6160 /// <returns>
62- /// A <see cref="KeyVaultDescriptor "/> containing the secret value and metadata .
61+ /// A <see cref="string "/> containing the secret value.
6362 /// </returns>
6463 /// <exception cref="DependencyException">
6564 /// Thrown if the secret is not found, access is denied, or another error occurs.
6665 /// </exception>
67- public async Task < KeyVaultDescriptor > GetSecretAsync (
66+ public async Task < string > GetSecretAsync (
6867 KeyVaultDescriptor descriptor ,
6968 CancellationToken cancellationToken ,
7069 IAsyncPolicy retryPolicy = null )
@@ -87,16 +86,7 @@ public async Task<KeyVaultDescriptor> GetSecretAsync(
8786 return await ( retryPolicy ?? KeyVaultManager . DefaultRetryPolicy ) . ExecuteAsync ( async ( ) =>
8887 {
8988 KeyVaultSecret secret = await client . GetSecretAsync ( secretName , cancellationToken : cancellationToken ) ;
90- KeyVaultDescriptor result = new KeyVaultDescriptor ( descriptor )
91- {
92- Value = secret . Value ,
93- Version = secret . Properties . Version ,
94- Name = secretName ,
95- VaultUri = vaultUri . ToString ( ) ,
96- ObjectId = secret . Id ? . ToString ( ) ,
97- ObjectType = KeyVaultObjectType . Secret
98- } ;
99- return result ;
89+ return secret . Value ;
10090 } ) . ConfigureAwait ( false ) ;
10191 }
10292 catch ( RequestFailedException ex ) when ( ex . Status == ( int ) HttpStatusCode . Forbidden )
@@ -136,12 +126,12 @@ public async Task<KeyVaultDescriptor> GetSecretAsync(
136126 /// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
137127 /// <param name="retryPolicy">A policy to use for handling retries when transient errors/failures happen.</param>
138128 /// <returns>
139- /// A <see cref="KeyVaultDescriptor "/> containing the key metadata .
129+ /// A <see cref="KeyVaultKey "/> containing the key.
140130 /// </returns>
141131 /// <exception cref="DependencyException">
142132 /// Thrown if the key is not found, access is denied, or another error occurs.
143133 /// </exception>
144- public async Task < KeyVaultDescriptor > GetKeyAsync (
134+ public async Task < KeyVaultKey > GetKeyAsync (
145135 KeyVaultDescriptor descriptor ,
146136 CancellationToken cancellationToken ,
147137 IAsyncPolicy retryPolicy = null )
@@ -162,15 +152,7 @@ public async Task<KeyVaultDescriptor> GetKeyAsync(
162152 return await ( retryPolicy ?? KeyVaultManager . DefaultRetryPolicy ) . ExecuteAsync ( async ( ) =>
163153 {
164154 KeyVaultKey key = await client . GetKeyAsync ( keyName , cancellationToken : cancellationToken ) ;
165- KeyVaultDescriptor result = new KeyVaultDescriptor ( descriptor )
166- {
167- ObjectType = KeyVaultObjectType . Key ,
168- Name = keyName ,
169- VaultUri = vaultUri . ToString ( ) ,
170- Version = key . Properties . Version ,
171- ObjectId = key . Id . ToString ( )
172- } ;
173- return result ;
155+ return key ;
174156 } ) . ConfigureAwait ( false ) ;
175157 }
176158 catch ( RequestFailedException ex ) when ( ex . Status == ( int ) HttpStatusCode . Forbidden )
@@ -208,16 +190,18 @@ public async Task<KeyVaultDescriptor> GetKeyAsync(
208190 /// </summary>
209191 /// <param name="descriptor">Provides the details for the certificate to retrieve (requires "CertificateName" and "VaultUri").</param>
210192 /// <param name="cancellationToken">A token that can be used to cancel the operation.</param>
193+ /// <param name="retrieveWithPrivateKey">flag to decode whether to retrieve certificate with private key</param>
211194 /// <param name="retryPolicy">A policy to use for handling retries when transient errors/failures happen.</param>
212195 /// <returns>
213- /// A <see cref="KeyVaultDescriptor "/> containing the certificate metadata.
196+ /// A <see cref="X509Certificate2 "/> containing the certificate
214197 /// </returns>
215198 /// <exception cref="DependencyException">
216199 /// Thrown if the certificate is not found, access is denied, or another error occurs.
217200 /// </exception>
218- public async Task < KeyVaultDescriptor > GetCertificateAsync (
201+ public async Task < X509Certificate2 > GetCertificateAsync (
219202 KeyVaultDescriptor descriptor ,
220203 CancellationToken cancellationToken ,
204+ bool retrieveWithPrivateKey = false ,
221205 IAsyncPolicy retryPolicy = null )
222206 {
223207 this . ValidateKeyVaultStore ( ) ;
@@ -235,17 +219,26 @@ public async Task<KeyVaultDescriptor> GetCertificateAsync(
235219 {
236220 return await ( retryPolicy ?? KeyVaultManager . DefaultRetryPolicy ) . ExecuteAsync ( async ( ) =>
237221 {
238- KeyVaultCertificateWithPolicy cert = await client . GetCertificateAsync ( certName , cancellationToken : cancellationToken ) ;
239- KeyVaultDescriptor result = new KeyVaultDescriptor ( descriptor )
222+ // Get the full certificate with private key (PFX) if requested
223+ if ( retrieveWithPrivateKey )
224+ {
225+ X509Certificate2 privateKeyCert = await client
226+ . DownloadCertificateAsync ( certName , cancellationToken : cancellationToken )
227+ . ConfigureAwait ( false ) ;
228+
229+ if ( privateKeyCert is null || ! privateKeyCert . HasPrivateKey )
230+ {
231+ throw new DependencyException ( "Failed to retrieve certificate content with private key." ) ;
232+ }
233+
234+ return privateKeyCert ;
235+ }
236+ else
240237 {
241- ObjectType = KeyVaultObjectType . Certificate ,
242- Name = certName ,
243- VaultUri = vaultUri . ToString ( ) ,
244- Version = cert . Properties . Version ,
245- ObjectId = cert . Id . ToString ( ) ,
246- Policy = cert . Policy ? . ToString ( )
247- } ;
248- return result ;
238+ // If private key not needed, load cert from PublicBytes
239+ KeyVaultCertificateWithPolicy cert = await client . GetCertificateAsync ( certName , cancellationToken : cancellationToken ) ;
240+ return X509CertificateLoader . LoadCertificate ( cert . Cer ) ;
241+ }
249242 } ) . ConfigureAwait ( false ) ;
250243 }
251244 catch ( RequestFailedException ex ) when ( ex . Status == ( int ) HttpStatusCode . Forbidden )
0 commit comments