diff --git a/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs b/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs index 7db6184..18e2709 100644 --- a/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs +++ b/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs @@ -10,6 +10,7 @@ public sealed class AzureKeyVaultSignConfigurationSet public string AzureTenantId { get; init; } public Uri AzureKeyVaultUrl { get; init; } public string AzureKeyVaultCertificateName { get; init; } + public string AzureKeyVaultCertificateVersion { get; init; } public string AzureAccessToken { get; init; } public string AzureAuthority { get; init; } } diff --git a/src/AzureSignTool/KeyVaultConfigurationDiscoverer.cs b/src/AzureSignTool/KeyVaultConfigurationDiscoverer.cs index 7d1d3ca..ad95e62 100644 --- a/src/AzureSignTool/KeyVaultConfigurationDiscoverer.cs +++ b/src/AzureSignTool/KeyVaultConfigurationDiscoverer.cs @@ -47,14 +47,22 @@ public async Task> Materialize(A X509Certificate2 certificate; - KeyVaultCertificateWithPolicy azureCertificate; + KeyVaultCertificate azureCertificate; try { var certClient = new CertificateClient(configuration.AzureKeyVaultUrl, credential); - _logger.LogTrace($"Retrieving certificate {configuration.AzureKeyVaultCertificateName}."); - azureCertificate = (await certClient.GetCertificateAsync(configuration.AzureKeyVaultCertificateName).ConfigureAwait(false)).Value; - _logger.LogTrace($"Retrieved certificate {configuration.AzureKeyVaultCertificateName}."); + if (!string.IsNullOrWhiteSpace(configuration.AzureKeyVaultCertificateVersion)) + { + _logger.LogTrace($"Retrieving version [{configuration.AzureKeyVaultCertificateVersion}] of certificate {configuration.AzureKeyVaultCertificateName}."); + azureCertificate = (await certClient.GetCertificateVersionAsync(configuration.AzureKeyVaultCertificateName, configuration.AzureKeyVaultCertificateVersion).ConfigureAwait(false)).Value; + } + else + { + _logger.LogTrace($"Retrieving current version of certificate {configuration.AzureKeyVaultCertificateName}."); + azureCertificate = (await certClient.GetCertificateAsync(configuration.AzureKeyVaultCertificateName).ConfigureAwait(false)).Value; + } + _logger.LogTrace($"Retrieved certificate with Id {azureCertificate.Id}."); certificate = new X509Certificate2(azureCertificate.Cer); } diff --git a/src/AzureSignTool/Program.cs b/src/AzureSignTool/Program.cs index 0632153..f1b6879 100644 --- a/src/AzureSignTool/Program.cs +++ b/src/AzureSignTool/Program.cs @@ -65,6 +65,7 @@ internal sealed class SignCommand : Command internal string? KeyVaultClientSecret { get; set; } internal string? KeyVaultTenantId { get; set; } internal string? KeyVaultCertificate { get; set; } + internal string? KeyVaultCertificateVersion { get; set; } internal string? KeyVaultAccessToken { get; set; } internal bool UseManagedIdentity { get; set; } internal string? SignDescription { get; set; } @@ -150,8 +151,9 @@ public SignCommand() : base("sign", "Sign a file.", null) this.Add("kvs|azure-key-vault-client-secret=", "The Client Secret to authenticate to the Azure Key Vault.", v => KeyVaultClientSecret = v); this.Add("kvt|azure-key-vault-tenant-id=", "The Tenant Id to authenticate to the Azure Key Vault.", v => KeyVaultTenantId = v); this.Add("kvc|azure-key-vault-certificate=", "The name of the certificate in Azure Key Vault.", v => KeyVaultCertificate = v); + this.Add("kvcv|azure-key-vault-certificate-version=", "The version of the certificate in Azure Key Vault to use. The current version of the certificate is used by default.", v => KeyVaultCertificateVersion = v); this.Add("kva|azure-key-vault-accesstoken=", "The Access Token to authenticate to the Azure Key Vault.", v => KeyVaultAccessToken = v); - this.Add("kvm|azure-key-vault-managed-identity", "Use the current Azure mananaged identity.", v => UseManagedIdentity = v is not null); + this.Add("kvm|azure-key-vault-managed-identity", "Use the current Azure managed identity.", v => UseManagedIdentity = v is not null); this.Add("d|description=", "Provide a description of the signed content.", v => SignDescription = v); this.Add("du|description-url=", "Provide a URL with more information about the signed content.", v => SignDescriptionUrl = v); this.Add("tr|timestamp-rfc3161=", "Specifies the RFC 3161 timestamp server's URL. If this option (or -t) is not specified, the signed file will not be timestamped.", v => Rfc3161TimestampUrl = v); @@ -159,7 +161,7 @@ public SignCommand() : base("sign", "Sign a file.", null) this.Add("fd|file-digest=", "The digest algorithm to hash the file with.", v => FileDigestAlgorithm = v); this.Add("t|timestamp-authenticode=", "Specify the legacy timestamp server's URL. This option is generally not recommended. Use the --timestamp-rfc3161 option instead.", v => AuthenticodeTimestampUrl = v); this.Add("ac|additional-certificates=", "Specify one or more certificates to include in the public certificate chain.", AdditionalCertificates); - this.Add("v|verbose", "Specify one or more certificates to include in the public certificate chain.", v => Verbose = v is not null); + this.Add("v|verbose", "Include additional output in the log. This parameter does not accept a value and cannot be combine with the --quiet option.", v => Verbose = v is not null); this.Add("q|quiet", "Do not print any output to the console.", v => Quiet = v is not null); this.Add("ph|page-hashing", "Generate page hashes for executable files if supported.", v => PageHashing = v is not null); this.Add("nph|no-page-hashing", "Suppress page hashes for executable files if supported.", v => NoPageHashing = v is not null); @@ -212,6 +214,7 @@ private async ValueTask RunSign() { AzureKeyVaultUrl = new Uri(KeyVaultUrl!), AzureKeyVaultCertificateName = KeyVaultCertificate, + AzureKeyVaultCertificateVersion = KeyVaultCertificateVersion, AzureClientId = KeyVaultClientId, AzureTenantId = KeyVaultTenantId, AzureAccessToken = KeyVaultAccessToken,