From 38936f6d80a587a8a32decc7aa328f4bfa81f4df Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 13 Dec 2023 12:25:17 -0500 Subject: [PATCH] Update to .NET 8 --- .github/workflows/pr.yml | 6 +-- Directory.Build.props | 6 +-- src/AzureSign.Core/AlgorithmTranslator.cs | 38 ++++++++----------- .../AuthenticodeKeyVaultSigner.cs | 4 +- src/AzureSign.Core/AzureSign.Core.csproj | 6 +-- src/AzureSign.Core/Interop/crypt32.cs | 18 +++------ src/AzureSignTool/AccessTokenCredential.cs | 2 - .../AzureKeyVaultMaterializedConfiguration.cs | 14 +------ .../AzureKeyVaultSignConfigurationSet.cs | 17 ++++----- src/AzureSignTool/AzureSignTool.csproj | 19 +++++----- src/AzureSignTool/SignCommand.cs | 24 ++++++------ .../AzureSign.Core.Tests.csproj | 8 ++-- .../AzureSignTool.Tests.csproj | 8 ++-- 13 files changed, 70 insertions(+), 100 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index aa33a0a..8e9714d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -7,9 +7,9 @@ jobs: build: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 name: Checkout - - uses: actions/setup-dotnet@v1 + - uses: actions/setup-dotnet@v4 with: - dotnet-version: '6.0' + dotnet-version: '8.0' - run: dotnet test diff --git a/Directory.Build.props b/Directory.Build.props index 180b017..8b7f1ae 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -11,12 +11,8 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb true - + true - - - - diff --git a/src/AzureSign.Core/AlgorithmTranslator.cs b/src/AzureSign.Core/AlgorithmTranslator.cs index 0ff06d9..f008e5c 100644 --- a/src/AzureSign.Core/AlgorithmTranslator.cs +++ b/src/AzureSign.Core/AlgorithmTranslator.cs @@ -7,32 +7,26 @@ internal static class AlgorithmTranslator { public static uint HashAlgorithmToAlgId(HashAlgorithmName hashAlgorithmName) { - if (hashAlgorithmName.Name == HashAlgorithmName.SHA1.Name) - return 0x00008004; - if (hashAlgorithmName.Name == HashAlgorithmName.SHA256.Name) - return 0x0000800c; - if (hashAlgorithmName.Name == HashAlgorithmName.SHA384.Name) - return 0x0000800d; - if (hashAlgorithmName.Name == HashAlgorithmName.SHA512.Name) - return 0x0000800e; - throw new NotSupportedException("The algorithm specified is not supported."); + return hashAlgorithmName.Name switch + { + nameof(HashAlgorithmName.SHA1) => 0x00008004, + nameof(HashAlgorithmName.SHA256) => 0x0000800c, + nameof(HashAlgorithmName.SHA384) => 0x0000800d, + nameof(HashAlgorithmName.SHA512) => 0x0000800e, + _ => throw new NotSupportedException("The algorithm specified is not supported."), + }; } public static ReadOnlySpan HashAlgorithmToOidAsciiTerminated(HashAlgorithmName hashAlgorithmName) { - if (hashAlgorithmName.Name == HashAlgorithmName.SHA1.Name) - //1.3.14.3.2.26 - return new byte[] { 0x31, 0x2e, 0x33, 0x2e, 0x31, 0x34, 0x2e, 0x33, 0x2e, 0x32, 0x2e, 0x32, 0x36, 0x00 }; - if (hashAlgorithmName.Name == HashAlgorithmName.SHA256.Name) - //2.16.840.1.101.3.4.2.1 - return new byte[] { 0x32, 0x2e, 0x31, 0x36, 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x2e, 0x31, 0x30, 0x31, 0x2e, 0x33, 0x2e, 0x34, 0x2e, 0x32, 0x2e, 0x31, 0x00 }; - if (hashAlgorithmName.Name == HashAlgorithmName.SHA384.Name) - //2.16.840.1.101.3.4.2.2 - return new byte[] { 0x32, 0x2e, 0x31, 0x36, 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x2e, 0x31, 0x30, 0x31, 0x2e, 0x33, 0x2e, 0x34, 0x2e, 0x32, 0x2e, 0x32, 0x00 }; - if (hashAlgorithmName.Name == HashAlgorithmName.SHA512.Name) - //2.16.840.1.101.3.4.2.3 - return new byte[] { 0x32, 0x2e, 0x31, 0x36, 0x2e, 0x38, 0x34, 0x30, 0x2e, 0x31, 0x2e, 0x31, 0x30, 0x31, 0x2e, 0x33, 0x2e, 0x34, 0x2e, 0x32, 0x2e, 0x33, 0x00 }; - throw new NotSupportedException("The algorithm specified is not supported."); + return hashAlgorithmName.Name switch + { + nameof(HashAlgorithmName.SHA1) => "1.3.14.3.2.26\0"u8, + nameof(HashAlgorithmName.SHA256) => "2.16.840.1.101.3.4.2.1\0"u8, + nameof(HashAlgorithmName.SHA384) => "2.16.840.1.101.3.4.2.2\0"u8, + nameof(HashAlgorithmName.SHA512) => "2.16.840.1.101.3.4.2.3\0"u8, + _ => throw new NotSupportedException("The algorithm specified is not supported."), + }; } } } diff --git a/src/AzureSign.Core/AuthenticodeKeyVaultSigner.cs b/src/AzureSign.Core/AuthenticodeKeyVaultSigner.cs index 686aa52..0a2b0a5 100644 --- a/src/AzureSign.Core/AuthenticodeKeyVaultSigner.cs +++ b/src/AzureSign.Core/AuthenticodeKeyVaultSigner.cs @@ -20,7 +20,7 @@ public class AuthenticodeKeyVaultSigner : IDisposable private readonly MemoryCertificateStore _certificateStore; private readonly X509Chain _chain; private readonly SignCallback _signCallback; - private static readonly Version _win11Version = new Version(10, 0, 22000); + private static readonly Version _win11Version = new(10, 0, 22000); /// @@ -103,7 +103,7 @@ static char[] NullTerminate(ReadOnlySpan str) { if (Environment.OSVersion.Version < _win11Version) { - // must throw, if continued SignerSignEx3 might return no error, but fail with the task, we must prevent this silent corruption. + // SignerSignEx3 silently succeeds with append on Windows 10 but does not actually append, so throw an error if we are not on Windows 11 or later. throw new PlatformNotSupportedException("Appending signatures requires Windows 11 or later."); } if (_timeStampConfiguration.Type == TimeStampType.Authenticode) diff --git a/src/AzureSign.Core/AzureSign.Core.csproj b/src/AzureSign.Core/AzureSign.Core.csproj index 841af99..f5977a8 100644 --- a/src/AzureSign.Core/AzureSign.Core.csproj +++ b/src/AzureSign.Core/AzureSign.Core.csproj @@ -4,15 +4,15 @@ netstandard2.0 Authenticode signing library. true - win10-x64;win10-x86 + win-x64;win-x86;win-arm64 true v enable - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/AzureSign.Core/Interop/crypt32.cs b/src/AzureSign.Core/Interop/crypt32.cs index 08e68f3..d28a00b 100644 --- a/src/AzureSign.Core/Interop/crypt32.cs +++ b/src/AzureSign.Core/Interop/crypt32.cs @@ -26,20 +26,12 @@ public static extern IntPtr CertOpenStore } [type: StructLayout(LayoutKind.Sequential)] - internal struct SIGNER_CERT_STORE_INFO + internal struct SIGNER_CERT_STORE_INFO(IntPtr pSigningCert, SignerCertStoreInfoFlags dwCertPolicy, IntPtr hCertStore) { - public uint cbSize; - public IntPtr pSigningCert; - public SignerCertStoreInfoFlags dwCertPolicy; - public IntPtr hCertStore; - - public SIGNER_CERT_STORE_INFO(IntPtr pSigningCert, SignerCertStoreInfoFlags dwCertPolicy, IntPtr hCertStore) - { - this.cbSize = (uint)Marshal.SizeOf(); - this.pSigningCert = pSigningCert; - this.dwCertPolicy = dwCertPolicy; - this.hCertStore = hCertStore; - } + public uint cbSize = (uint)Marshal.SizeOf(); + public IntPtr pSigningCert = pSigningCert; + public SignerCertStoreInfoFlags dwCertPolicy = dwCertPolicy; + public IntPtr hCertStore = hCertStore; } [type: Flags] diff --git a/src/AzureSignTool/AccessTokenCredential.cs b/src/AzureSignTool/AccessTokenCredential.cs index 1eb640e..a5250d0 100644 --- a/src/AzureSignTool/AccessTokenCredential.cs +++ b/src/AzureSignTool/AccessTokenCredential.cs @@ -1,8 +1,6 @@ using Azure.Core; using System; -using System.Collections.Generic; -using System.Text; using System.Threading; using System.Threading.Tasks; diff --git a/src/AzureSignTool/AzureKeyVaultMaterializedConfiguration.cs b/src/AzureSignTool/AzureKeyVaultMaterializedConfiguration.cs index 06585d1..0cfc3de 100644 --- a/src/AzureSignTool/AzureKeyVaultMaterializedConfiguration.cs +++ b/src/AzureSignTool/AzureKeyVaultMaterializedConfiguration.cs @@ -6,17 +6,5 @@ namespace AzureSignTool { - public class AzureKeyVaultMaterializedConfiguration - { - public AzureKeyVaultMaterializedConfiguration(TokenCredential credential, X509Certificate2 publicCertificate, Uri keyId) - { - TokenCredential = credential; - KeyId = keyId; - PublicCertificate = publicCertificate; - } - - public X509Certificate2 PublicCertificate { get; } - public TokenCredential TokenCredential { get; } - public Uri KeyId { get; } - } + public sealed record AzureKeyVaultMaterializedConfiguration(TokenCredential TokenCredential, X509Certificate2 PublicCertificate, Uri KeyId); } diff --git a/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs b/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs index 9970d23..245a299 100644 --- a/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs +++ b/src/AzureSignTool/AzureKeyVaultSignConfigurationSet.cs @@ -1,16 +1,15 @@ - -using System; +using System; namespace AzureSignTool { public sealed class AzureKeyVaultSignConfigurationSet { - public bool ManagedIdentity { get; set; } - public string AzureClientId { get; set; } - public string AzureClientSecret { get; set; } - public string AzureTenantId { get; set; } - public Uri AzureKeyVaultUrl { get; set; } - public string AzureKeyVaultCertificateName { get; set; } - public string AzureAccessToken { get; set; } + public bool ManagedIdentity { get; init; } + public string AzureClientId { get; init; } + public string AzureClientSecret { get; init; } + public string AzureTenantId { get; init; } + public Uri AzureKeyVaultUrl { get; init; } + public string AzureKeyVaultCertificateName { get; init; } + public string AzureAccessToken { get; init; } } } diff --git a/src/AzureSignTool/AzureSignTool.csproj b/src/AzureSignTool/AzureSignTool.csproj index 52e5f1b..a90c5f2 100644 --- a/src/AzureSignTool/AzureSignTool.csproj +++ b/src/AzureSignTool/AzureSignTool.csproj @@ -1,22 +1,23 @@ - + Exe - net6.0 + net8.0 true azuresigntool Azure Sign Tool is similar to signtool in the Windows SDK, with the major difference being that it uses Azure Key Vault for performing the signing process. The usage is like signtool, except with a limited set of options for signing and options for authenticating to Azure Key Vault. - win10-x64;win10-x86;win10-arm;win10-arm64 + win-x64;win-x86;win-arm64 v + true - - - - - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/AzureSignTool/SignCommand.cs b/src/AzureSignTool/SignCommand.cs index ca20385..841408e 100644 --- a/src/AzureSignTool/SignCommand.cs +++ b/src/AzureSignTool/SignCommand.cs @@ -16,6 +16,7 @@ using System.Threading.Tasks; using static AzureSignTool.HRESULT; +using AllowedValuesAttribute = McMaster.Extensions.CommandLineUtils.AllowedValuesAttribute; namespace AzureSignTool { @@ -63,7 +64,7 @@ internal sealed class SignCommand public (bool Present, string Uri) AuthenticodeTimestamp { get; set; } [Option("-ac | --additional-certificates", "Specify one or more certificates to include in the public certificate chain.", CommandOptionType.MultipleValue), FileExists] - public string[] AdditionalCertificates { get; set; } = Array.Empty(); + public string[] AdditionalCertificates { get; set; } = []; [Option("-v | --verbose", "Include additional output.", CommandOptionType.NoValue)] public bool Verbose { get; set; } @@ -97,7 +98,7 @@ internal sealed class SignCommand // We manually validate the file's existance with the --input-file-list. Don't validate here. [Argument(0, "file", "The path to the file.")] - public string[] Files { get; set; } = Array.Empty(); + public string[] Files { get; set; } = []; private HashSet _allFiles; public HashSet AllFiles @@ -135,7 +136,7 @@ public LogLevel LogLevel } } - private ValidationResult OnValidate(ValidationContext context, CommandLineContext appContext) + private ValidationResult OnValidate() { if (PageHashing && NoPageHashing) { @@ -191,7 +192,7 @@ private ValidationResult OnValidate(ValidationContext context, CommandLineContex return ValidationResult.Success; } - public int OnValidationError(ValidationResult result, CommandLineApplication command, IConsole console) + public static int OnValidationError(ValidationResult result, CommandLineApplication command, IConsole console) { console.ForegroundColor = ConsoleColor.Red; console.Error.WriteLine(result.ErrorMessage); @@ -210,7 +211,7 @@ private void ConfigureLogging(ILoggingBuilder builder) builder.SetMinimumLevel(LogLevel); } - public async Task OnExecuteAsync(CommandLineApplication app, IConsole console) + public async Task OnExecuteAsync(IConsole console) { using (var loggerFactory = LoggerFactory.Create(ConfigureLogging)) { @@ -335,7 +336,7 @@ public async Task OnExecuteAsync(CommandLineApplication app, IConsole conso } else { - logger.LogError($"Signing failed with error {result:X2}."); + logger.LogError("Signing failed with error {result}.", $"{result:X2}"); if (!ContinueOnError || AllFiles.Count == 1) { logger.LogInformation("Stopping file signing."); @@ -351,8 +352,9 @@ public async Task OnExecuteAsync(CommandLineApplication app, IConsole conso Interlocked.Add(ref succeeded, result.succeeded); }); } - logger.LogInformation($"Successful operations: {succeeded}"); - logger.LogInformation($"Failed operations: {failed}"); + logger.LogInformation("Successful operations: {succeeded}", succeeded); + logger.LogInformation("Failed operations: {failed}", failed); + if (failed > 0 && succeeded == 0) { return E_ALL_FAILED; @@ -369,14 +371,14 @@ public async Task OnExecuteAsync(CommandLineApplication app, IConsole conso } private static readonly string CodeSigningOid = "1.3.6.1.5.5.7.3.3"; - + public static bool IsSigned(string filePath) { try { var certificate = new X509Certificate2(X509Certificate.CreateFromSignedFile(filePath)); - // check if file contains a code signing cert. + // check if file contains a code signing cert. // Note that this does not check validity of the signature return certificate.Extensions .Select(extension => extension as X509EnhancedKeyUsageExtension) @@ -404,7 +406,7 @@ private static ErrorOr GetAdditionalCertificates(IEn case X509ContentType.Authenticode: case X509ContentType.SerializedCert: var certificate = new X509Certificate2(path); - logger.LogTrace($"Including additional certificate {certificate.Thumbprint}."); + logger.LogTrace("Including additional certificate {thumbprint}.", certificate.Thumbprint); collection.Add(certificate); break; default: diff --git a/test/AzureSign.Core.Tests/AzureSign.Core.Tests.csproj b/test/AzureSign.Core.Tests/AzureSign.Core.Tests.csproj index d7a8f45..8cf3ff1 100644 --- a/test/AzureSign.Core.Tests/AzureSign.Core.Tests.csproj +++ b/test/AzureSign.Core.Tests/AzureSign.Core.Tests.csproj @@ -1,15 +1,15 @@  - net6.0 + net8.0 false - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/AzureSignTool.Tests/AzureSignTool.Tests.csproj b/test/AzureSignTool.Tests/AzureSignTool.Tests.csproj index f880ba0..fe8dc41 100644 --- a/test/AzureSignTool.Tests/AzureSignTool.Tests.csproj +++ b/test/AzureSignTool.Tests/AzureSignTool.Tests.csproj @@ -1,15 +1,15 @@ - net6.0 + net8.0 false - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive