Sign tool update

WIP writing tests for Azure Code Signing

Fix issue to make sure we sign at least one file at a time

"Working" test with manually providing dependencies

Work on download dependencies.

Revert signtool.exe change
This commit is contained in:
Kevin Bost
2024-11-02 15:13:37 -07:00
committed by Caelan
parent 4eb319efc6
commit 3c61874cef
16 changed files with 181 additions and 97 deletions

View File

@@ -1,4 +1,5 @@
using System.Diagnostics;
#nullable enable
using System.Diagnostics;
using Velopack.Packaging.Unix.Commands;
using Velopack.Packaging.Windows.Commands;
using Velopack.Util;
@@ -10,7 +11,7 @@ namespace Velopack.Packaging.Tests;
public static class TestApp
{
public static void PackTestApp(string id, string version, string testString, string releaseDir, ILogger logger,
string releaseNotes = null, string channel = null, RID targetRid = null, string packTitle = null)
string? releaseNotes = null, string? channel = null, RID? targetRid = null, string? packTitle = null, string? azureTrustedSignFile = null)
{
targetRid ??= RID.Parse(VelopackRuntimeInfo.SystemRid);
@@ -30,7 +31,7 @@ public static class TestApp
logger.Info($"TEST: Running {psi.FileName} {debug}");
using var p = Process.Start(psi);
p.WaitForExit();
p!.WaitForExit();
if (p.ExitCode != 0)
throw new Exception($"dotnet publish failed with exit code {p.ExitCode}");
@@ -48,6 +49,7 @@ public static class TestApp
PackDirectory = Path.Combine(projDir, "publish"),
ReleaseNotes = releaseNotes,
Channel = channel,
AzureTrustedSignFile = azureTrustedSignFile
};
var runner = new WindowsPackCommandRunner(logger, console);
runner.Run(options).GetAwaiterResult();
@@ -79,7 +81,7 @@ public static class TestApp
PackVersion = version,
PackDirectory = Path.Combine(projDir, "publish"),
ReleaseNotes = releaseNotes,
Channel = channel,
Channel = channel
};
var runner = new LinuxPackCommandRunner(logger, console);
runner.Run(options).GetAwaiterResult();

View File

@@ -0,0 +1,74 @@
using System.Security.Cryptography.X509Certificates;
using Azure.Core;
using Azure.Identity;
using Velopack.Packaging.Windows;
using Velopack.Util;
namespace Velopack.Packaging.Tests;
public class TrustedSigningTests
{
private const string CodeSigningEndpoint = "https://eus.codesigning.azure.net";
private readonly ITestOutputHelper _output;
public TrustedSigningTests(ITestOutputHelper output)
{
_output = output;
}
private static async Task<bool> IsAuthenticatedForCodeSigningAsync()
{
//SingTool.exe will use DefaultAzureCredentials to authenticate.
//We preemptively check if there are valid creds to use and skip the test if not.
//This allows the test to be skipped for everyone who does not have the "Trusted Signing Certificate Profile Signer" role.
// We are more restrictive than the DefaultAzureCredentials, and only check for the AzureCliCredential and EnvironmentCredential.
// To appropriately run this test, you will need to first run `az login` and authenticate with an account that has the "Trusted Signing Certificate Profile Signer" role within the Velopack Azure subscription.
var creds = new ChainedTokenCredential(
new AzureCliCredential(),
new EnvironmentCredential());
try {
var token = await creds.GetTokenAsync(new TokenRequestContext([$"{CodeSigningEndpoint}/.default"]));
return token.Token != null;
} catch (Exception) {
return false;
}
}
[SkippableFact]
public async void CanSignWithTrustedSigning()
{
Skip.If(!VelopackRuntimeInfo.IsWindows);
Skip.If(await IsAuthenticatedForCodeSigningAsync());
using var logger = _output.BuildLoggerFor<TrustedSigningTests>();
using var _ = TempUtil.GetTempDirectory(out var releaseDir);
string channel = string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("CI"))
? VelopackRuntimeInfo.SystemOs.GetOsShortName()
: "ci-" + VelopackRuntimeInfo.SystemOs.GetOsShortName();
string metadataFile = Path.Combine(releaseDir, "metadata.json");
File.WriteAllText(metadataFile, $$"""
{
"Endpoint": "{{CodeSigningEndpoint}}",
"CodeSigningAccountName": "velopack-signing-account",
"CertificateProfileName": "VelopackPublic"
}
""");
var id = "AZTrustedSigningApp";
TestApp.PackTestApp(id, "1.0.0", $"aztrusted-{DateTime.UtcNow.ToLongDateString()}", releaseDir, logger, channel: channel, azureTrustedSignFile: metadataFile);
var files = Directory.EnumerateFiles(releaseDir)
.Where(x => PathUtil.FileIsLikelyPEImage(x))
.ToList();
Assert.NotEmpty(files);
#pragma warning disable CA1416 // Validate platform compatibility, this test only executes on Windows
Assert.All(files, x => Assert.True(AuthenticodeTools.IsTrusted(x)));
#pragma warning restore CA1416 // Validate platform compatibility
}
}

View File

@@ -9,6 +9,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.12.1" />
<PackageReference Include="Octokit" Version="13.0.1" />
<PackageReference Include="NuGet.Packaging" Version="6.12.1" />
<PackageReference Include="System.Formats.Asn1" Version="8.0.1" />