Skip to content

Commit

Permalink
Support signing key
Browse files Browse the repository at this point in the history
  • Loading branch information
feast107 committed Nov 24, 2024
1 parent f81c91a commit 2fc44a8
Show file tree
Hide file tree
Showing 12 changed files with 190 additions and 32 deletions.
2 changes: 1 addition & 1 deletion extern/cecil
28 changes: 24 additions & 4 deletions src/Antelcat.AutoGen.AssemblyWeavers.Tests/UnitTest1.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Antelcat.AutoGen.AssemblyWeavers.Tests;

Expand All @@ -14,6 +15,24 @@ public class Tests

private static readonly string Standard = Root / "netstandard2.0" / "Antelcat.AutoGen.Native.dll";

private class TestLogger : TaskLogger
{
public override void LogDebug(string message)
{
Console.WriteLine($"DEBUG: {message}");
}

public override void LogWarning(string message)
{
Console.WriteLine($"WARNING: {message}");
}

public override void LogError(string message)
{
Debugger.Break();
Console.Error.WriteLine($"ERROR: {message}");
}
}

[SetUp]
public void Setup()
Expand All @@ -27,21 +46,21 @@ public void TestCore() =>
WeaveTaskInternal.Execute(new TestWaveArgument
{
AssemblyFile = Core,
}, x => throw new Exception(x));
}, new TestLogger());

[Test]
public void TestStandard() =>
WeaveTaskInternal.Execute(new TestWaveArgument
{
AssemblyFile = Standard,
}, x => throw new Exception(x));
}, new TestLogger());
#else
[Test]
public void TestFramework() =>
WeaveTaskInternal.Execute(new TestWaveArgument
{
AssemblyFile = Framework,
}, x => throw new Exception(x));
}, new TestLogger());
#endif
}

Expand All @@ -52,4 +71,5 @@ public class TestWaveArgument : IWaveArguments
public bool SignAssembly { get; set; }
public bool DelaySign { get; set; }
public bool ReadWritePdb { get; set; }
public string? IntermediateDirectory { get; set; }
}

This file was deleted.

1 change: 1 addition & 0 deletions src/Antelcat.AutoGen.AssemblyWeavers/IWaveArguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public interface IWaveArguments
public bool SignAssembly { get; set; }
public bool DelaySign { get; set; }
public bool ReadWritePdb { get; set; }
public string? IntermediateDirectory { get; set; }
}
84 changes: 84 additions & 0 deletions src/Antelcat.AutoGen.AssemblyWeavers/StrongKeyFinder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using Mono.Cecil;

#if NETSTANDARD
using StrongNameKeyPair = Mono.Cecil.StrongNameKeyPair;
#else
using StrongNameKeyPair = System.Reflection.StrongNameKeyPair;
#endif

namespace Antelcat.AutoGen.AssemblyWeavers;

public class StrongKeyFinder(IWaveArguments waveArguments, ModuleDefinition module, TaskLogger logger)
{
public StrongNameKeyPair? StrongNameKeyPair;
public byte[]? PublicKey;

public void FindStrongNameKey()
{
var path = GetKeyFilePath();
if (path == null) return;
if (!File.Exists(path))
{
throw new FileNotFoundException($"KeyFilePath was defined but file does not exist. '{path}'.");
}

var fileBytes = File.ReadAllBytes(path);

if (!waveArguments.DelaySign)
{
try
{
logger.LogDebug("Extract public key from key file for signing.");

StrongNameKeyPair = new(fileBytes);
// Ensure that we can generate the public key from the key file. This requires the private key to
// work. If we cannot generate the public key, an ArgumentException will be thrown. In this case,
// the assembly is delay-signed with a public only key-file.
// Note: The NETSTANDARD implementation of StrongNameKeyPair.PublicKey does never throw here.
PublicKey = StrongNameKeyPair.PublicKey;
return;
}
catch (ArgumentException)
{
logger.LogWarning("Failed to extract public key from key file, fall back to delay-signing.");
}
}

// Fall back to delay signing, this was the original behavior, however that does not work in NETSTANDARD (s.a.)
logger.LogDebug("Prepare public key for delay-signing.");

// We know that we cannot sign the assembly with this key-file. Let's assume that it is a public
// only key-file and pass along all the bytes.
StrongNameKeyPair = null;
PublicKey = fileBytes;
}

private string? GetKeyFilePath()
{
if (waveArguments.AssemblyOriginatorKeyFile != null)
{
var keyFilePath = Path.GetFullPath(waveArguments.AssemblyOriginatorKeyFile);
logger.LogDebug($"Using strong name key from KeyFilePath '{keyFilePath}'.");
return keyFilePath;
}

var assemblyKeyFileAttribute = module
.Assembly
.CustomAttributes
.FirstOrDefault(static attribute => attribute.AttributeType.Name == nameof(AssemblyKeyFileAttribute));
if (assemblyKeyFileAttribute != null)
{
var keyFileSuffix = (string)assemblyKeyFileAttribute.ConstructorArguments.First().Value;
var path = Path.Combine(waveArguments.IntermediateDirectory!, keyFileSuffix);
logger.LogDebug($"Using strong name key from [AssemblyKeyFileAttribute(\"{keyFileSuffix}\")] '{path}'");
return path;
}

logger.LogDebug("No strong name key found");
return null;
}
}
10 changes: 10 additions & 0 deletions src/Antelcat.AutoGen.AssemblyWeavers/TaskLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Antelcat.AutoGen.AssemblyWeavers;

public abstract class TaskLogger
{
public abstract void LogDebug(string message);

public abstract void LogWarning(string message);

public abstract void LogError(string message);
}
27 changes: 23 additions & 4 deletions src/Antelcat.AutoGen.AssemblyWeavers/WeaveTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,40 @@ namespace Antelcat.AutoGen.AssemblyWeavers;
[Serializable]
public class WeaveTask : Task, IWaveArguments
{
private static string Category = typeof(WeaveTask).FullName!;
private static string category = typeof(WeaveTask).FullName!;

[Required] public required string AssemblyFile { get; set; }
public string? AssemblyOriginatorKeyFile { get; set; }
public bool SignAssembly { get; set; }
public bool DelaySign { get; set; }
public bool ReadWritePdb { get; set; } = true;
public string? IntermediateDirectory { get; set; }

[Output] public string? Output { get; set; }

public override bool Execute()
{
Log.LogMessage(MessageImportance.High, $"[{Category}] Weaving start");
if (!WeaveTaskInternal.Execute(this, x => Log.LogError($"[{Category}] {x}"))) return false;
Log.LogMessage(MessageImportance.High, $"[{Category}] Weaving complete");
Log.LogMessage(MessageImportance.High, $"[{category}] Weaving start");
if (!WeaveTaskInternal.Execute(this, new Logger(Log))) return false;
Log.LogMessage(MessageImportance.High, $"[{category}] Weaving complete");
return true;
}

private class Logger(TaskLoggingHelper logger) : AssemblyWeavers.TaskLogger
{
public override void LogDebug(string message)
{
logger.LogMessage(MessageImportance.Low, $"[{category}] {message}");
}

public override void LogWarning(string message)
{
logger.LogWarning($"[{category}] {message}");
}

public override void LogError(string message)
{
logger.LogError($"[{category}] {message}");
}
}
}
15 changes: 12 additions & 3 deletions src/Antelcat.AutoGen.AssemblyWeavers/WeaveTaskInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Antelcat.AutoGen.AssemblyWeavers;

internal static class WeaveTaskInternal
{
public static bool Execute(IWaveArguments arguments, Action<string>? errorLog = null)
public static bool Execute(IWaveArguments arguments, TaskLogger logger)
{
var resolver = new DefaultAssemblyResolver();
resolver.AddSearchDirectory(Path.GetDirectoryName(arguments.AssemblyFile)!);
Expand Down Expand Up @@ -40,7 +40,7 @@ public static bool Execute(IWaveArguments arguments, Action<string>? errorLog =
#if DEBUG
Debugger.Break();
#endif
errorLog?.Invoke(exception.ToString());
logger.LogError(exception.ToString());
}

return false;
Expand All @@ -49,10 +49,17 @@ public static bool Execute(IWaveArguments arguments, Action<string>? errorLog =
var temp = Path.GetTempFileName();
try
{
var strongKeyFinder = arguments.SignAssembly ? new StrongKeyFinder(arguments, assembly.MainModule,logger) : null;
strongKeyFinder?.FindStrongNameKey();
if (strongKeyFinder?.PublicKey is not null)
{
assembly.Name.PublicKey = strongKeyFinder.PublicKey;
}
assembly.Write(temp, new WriterParameters
{
SymbolWriterProvider = arguments.ReadWritePdb ? new PortablePdbWriterProvider() : default!,
WriteSymbols = arguments.ReadWritePdb,
StrongNameKeyPair = strongKeyFinder?.StrongNameKeyPair!
});
File.Copy(temp, arguments.AssemblyFile, true);
return true;
Expand All @@ -62,7 +69,7 @@ public static bool Execute(IWaveArguments arguments, Action<string>? errorLog =
#if DEBUG
throw;
#endif
errorLog?.Invoke(exception.ToString());
logger.LogError(exception.ToString());
return false;
}
}
Expand All @@ -71,4 +78,6 @@ private static IEnumerable<IWeaver> Weavers()
{
yield return new RecordPlaceboWeaver();
}


}
11 changes: 10 additions & 1 deletion src/Antelcat.AutoGen.Native/Antelcat.AutoGen.Native.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>

<AutoGenTasksPath>../Antelcat.AutoGen.AssemblyWeavers/bin/$(Configuration)</AutoGenTasksPath>

<UserSecretsId>956d9030-8b78-4578-a776-2bba91b29543</UserSecretsId>

<SignAssembly>true</SignAssembly>

<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>

</PropertyGroup>

<Import Project="../Antelcat.AutoGen.AssemblyWeavers/Antelcat.AutoGen.AssemblyWeavers.targets"/>
<Import Project="../Antelcat.AutoGen/Antelcat.AutoGen.targets"/>

<PropertyGroup Condition="$(TargetFramework) == 'net8.0'">
<PublishAot>true</PublishAot>
Expand Down
Binary file added src/Antelcat.AutoGen.Native/Key.snk
Binary file not shown.
5 changes: 4 additions & 1 deletion src/Antelcat.AutoGen/Antelcat.AutoGen.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<IsPackable>true</IsPackable>
<LangVersion>preview</LangVersion>

<Version>3.0.0-preview-241121-1</Version>
<Version>3.0.0-preview-241125-1</Version>
<FileVersion>3.0.0</FileVersion>
<AssemblyVersion>3.0.0</AssemblyVersion>

Expand Down Expand Up @@ -44,5 +44,8 @@
</None>
<None Include="..\..\README.md" PackagePath="\" Pack="true" />
<None Include="..\Antelcat.AutoGen.SourceGenerators\bin\$(Configuration)\netstandard2.0\Antelcat.AutoGen.SourceGenerators.dll" PackagePath="analyzers\dotnet\cs" Pack="true" />
<None Include="..\Antelcat.AutoGen.AssemblyWeavers\bin\$(Configuration)\netstandard2.0\Antelcat.AutoGen.AssemblyWeavers.dll" PackagePath="tasks\netstandard2.0" Pack="true" />
<None Include="..\Antelcat.AutoGen.AssemblyWeavers\bin\$(Configuration)\net472\Antelcat.AutoGen.AssemblyWeavers.dll" PackagePath="tasks\net472" Pack="true" />
<None Include="Antelcat.AutoGen.targets" PackagePath="build" Pack="true" />
</ItemGroup>
</Project>
21 changes: 21 additions & 0 deletions src/Antelcat.AutoGen/Antelcat.AutoGen.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project>
<PropertyGroup>
<AutoGenTasksPath Condition="$(AutoGenTasksPath) == ''">$(MSBuildThisFileDirectory)../tasks</AutoGenTasksPath>
<AutoGenAssemblyWeaverDirectory Condition="$(MSBuildRuntimeType) == 'Core'">$(AutoGenTasksPath)/netstandard2.0</AutoGenAssemblyWeaverDirectory>
<AutoGenAssemblyWeaverDirectory Condition="$(MSBuildRuntimeType) != 'Core'">$(AutoGenTasksPath)/net472</AutoGenAssemblyWeaverDirectory>
</PropertyGroup>

<UsingTask AssemblyFile="$(AutoGenAssemblyWeaverDirectory)/Antelcat.AutoGen.AssemblyWeavers.dll"
TaskName="Antelcat.AutoGen.AssemblyWeavers.WeaveTask"/>

<Target Name="WeaveAssembly" AfterTargets="PostBuildEvent">
<Antelcat.AutoGen.AssemblyWeavers.WeaveTask
AssemblyFile="$(TargetPath)"
AssemblyOriginatorKeyFile="$(AssemblyOriginatorKeyFile)"
IntermediateDirectory="$(ProjectDir)$(IntermediateOutputPath)"
SignAssembly="$(SignAssembly)"
DelaySign="$(DelaySign)">
<Output PropertyName="OutputPath" TaskParameter="Output"/>
</Antelcat.AutoGen.AssemblyWeavers.WeaveTask>
</Target>
</Project>

0 comments on commit 2fc44a8

Please sign in to comment.