Skip to content

Commit dc5aba8

Browse files
authored
Merge pull request #2 from AppCoreNet/dev
Release 0.2.0
2 parents cf404c3 + 7326a7c commit dc5aba8

23 files changed

+368
-23
lines changed

AppCore.SigningTool.sln

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppCore.SigningTool", "src\
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppCore.SigningTool.Tests", "test\AppCore.SingingTool.Tests\AppCore.SigningTool.Tests.csproj", "{DE62F6BD-5942-4862-83DF-79C1EE50A940}"
99
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignedAssembly", "test\SignedAssembly\SignedAssembly.csproj", "{DEA19E22-7E9B-4BDC-B99D-47FC34DF5D9A}"
11+
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DelaySignedAssembly", "test\DelaySignedAssembly\DelaySignedAssembly.csproj", "{E8BCB2FA-EBF1-476B-BB6F-40E226C418B4}"
13+
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnsignedAssembly", "test\UnsignedAssembly\UnsignedAssembly.csproj", "{198A5852-EFF8-421E-8BC8-230810746123}"
15+
EndProject
1016
Global
1117
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1218
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +27,18 @@ Global
2127
{DE62F6BD-5942-4862-83DF-79C1EE50A940}.Debug|Any CPU.Build.0 = Debug|Any CPU
2228
{DE62F6BD-5942-4862-83DF-79C1EE50A940}.Release|Any CPU.ActiveCfg = Release|Any CPU
2329
{DE62F6BD-5942-4862-83DF-79C1EE50A940}.Release|Any CPU.Build.0 = Release|Any CPU
30+
{DEA19E22-7E9B-4BDC-B99D-47FC34DF5D9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31+
{DEA19E22-7E9B-4BDC-B99D-47FC34DF5D9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{DEA19E22-7E9B-4BDC-B99D-47FC34DF5D9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
33+
{DEA19E22-7E9B-4BDC-B99D-47FC34DF5D9A}.Release|Any CPU.Build.0 = Release|Any CPU
34+
{E8BCB2FA-EBF1-476B-BB6F-40E226C418B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35+
{E8BCB2FA-EBF1-476B-BB6F-40E226C418B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
36+
{E8BCB2FA-EBF1-476B-BB6F-40E226C418B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
37+
{E8BCB2FA-EBF1-476B-BB6F-40E226C418B4}.Release|Any CPU.Build.0 = Release|Any CPU
38+
{198A5852-EFF8-421E-8BC8-230810746123}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39+
{198A5852-EFF8-421E-8BC8-230810746123}.Debug|Any CPU.Build.0 = Debug|Any CPU
40+
{198A5852-EFF8-421E-8BC8-230810746123}.Release|Any CPU.ActiveCfg = Release|Any CPU
41+
{198A5852-EFF8-421E-8BC8-230810746123}.Release|Any CPU.Build.0 = Release|Any CPU
2442
EndGlobalSection
2543
GlobalSection(SolutionProperties) = preSolution
2644
HideSolutionNode = FALSE

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<Copyright>Copyright (c) 2020 the AppCore .NET project</Copyright>
77
<Version>1.0.0</Version>
88
<PackageLicenseExpression>MIT</PackageLicenseExpression>
9-
<RepositoryUrl>https://github.com/AppCoreNet/SingingTool</RepositoryUrl>
9+
<RepositoryUrl>https://github.com/AppCoreNet/SigningTool</RepositoryUrl>
1010
<RepositoryType>git</RepositoryType>
1111
<LangVersion>latest</LangVersion>
1212
<NoWarn>$(NoWarn);NU5105</NoWarn>

src/AppCore.SigningTool/AppCore.SigningTool.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
<TargetFrameworks>netcoreapp2.1;netcoreapp3.1</TargetFrameworks>
66
<PackAsTool>true</PackAsTool>
77
<ToolCommandName>dotnet-signtool</ToolCommandName>
8-
<Description>.NET Core command line tool for assembly signing.</Description>
8+
<Description>A .NET Core CLI tool for strong-name signing of assemblies.</Description>
9+
<PackageTags>$(PackageTags);Assembly;Signing;Strong-name;Strong-naming;SN;Tool</PackageTags>
910
</PropertyGroup>
1011

1112
<ItemGroup>

src/AppCore.SigningTool/Commands/Sn/SnCreateKeyCommand.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ public SnCreateKeyCommand(IStrongNameKeyGenerator keyGenerator)
2525

2626
public void Configure(CommandLineApplication cmd)
2727
{
28-
_force = cmd.Option<bool>("-f|--force", "Forces overwrite of an existing key file.",
28+
_force = cmd.Option<bool>(
29+
"-f|--force",
30+
"Forces overwrite of an existing key file.",
2931
CommandOptionType.NoValue);
3032

3133
_keySize = cmd.Option<int>(
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using AppCore.SigningTool.Extensions;
3+
using AppCore.SigningTool.StrongName;
4+
using dnlib.DotNet;
5+
using McMaster.Extensions.CommandLineUtils;
6+
7+
namespace AppCore.SigningTool.Commands.Sn
8+
{
9+
public class SnShowKeyCommand : ICommand<SnCommand>
10+
{
11+
private readonly IStrongNameKeyLoader _keyLoader;
12+
private CommandOption<bool> _showKey;
13+
private CommandArgument _keyFile;
14+
15+
public string Name => "show-key";
16+
17+
public string Description => "Displays the public key token.";
18+
19+
public SnShowKeyCommand(IStrongNameKeyLoader keyLoader)
20+
{
21+
_keyLoader = keyLoader;
22+
}
23+
24+
public void Configure(CommandLineApplication cmd)
25+
{
26+
_showKey = cmd.Option<bool>(
27+
"--with-key",
28+
"Output the public key in addition to the key token.",
29+
CommandOptionType.NoValue);
30+
31+
_keyFile = cmd.Argument("KEYFILE", "The path of the public key file.")
32+
.IsRequired(false, "The 'KEYFILE' argument is required.");
33+
}
34+
35+
public int Execute(CommandLineApplication cmd)
36+
{
37+
bool showKey = _showKey.HasValue();
38+
string keyFile = _keyFile.Value;
39+
40+
StrongNamePublicKey publicKey;
41+
try
42+
{
43+
publicKey = _keyLoader.LoadPublicKey(keyFile);
44+
}
45+
catch (Exception error)
46+
{
47+
cmd.Error.WriteLine("ERROR: {0}", error.Message);
48+
return ExitCodes.FromException(error);
49+
}
50+
51+
if (showKey)
52+
{
53+
cmd.Out.WriteLine("Public key (hash algorithm {0}) is:");
54+
cmd.Out.WriteLine(publicKey.CreatePublicKey().ToHexString());
55+
cmd.Out.WriteLine();
56+
}
57+
58+
cmd.Out.WriteLine("Public key token is:");
59+
cmd.Out.WriteLine(publicKey.CreatePublicKeyToken().ToHexString());
60+
61+
return ExitCodes.Success;
62+
}
63+
}
64+
}

src/AppCore.SigningTool/Commands/Sn/SnSignCommand.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.IO;
3+
using AppCore.SigningTool.Exceptions;
24
using AppCore.SigningTool.StrongName;
35
using dnlib.DotNet;
46
using McMaster.Extensions.CommandLineUtils;
@@ -9,9 +11,11 @@ public class SnSignCommand : ICommand<SnCommand>
911
{
1012
private readonly IStrongNameKeyLoader _keyLoader;
1113
private readonly IStrongNameSigner _signer;
14+
private CommandOption<bool> _delaySign;
15+
private CommandOption<bool> _force;
1216
private CommandArgument _keyFile;
1317
private CommandArgument _assemblyFile;
14-
private CommandOption<bool> _delaySign;
18+
private CommandArgument _outAssemblyFile;
1519

1620
public string Name => "sign";
1721

@@ -28,30 +32,44 @@ public void Configure(CommandLineApplication cmd)
2832
_delaySign = cmd.Option<bool>("-d|--delay-sign", "Delay signs the assembly.",
2933
CommandOptionType.NoValue);
3034

31-
_keyFile = cmd.Argument("KEYFILE", "The path of the strong name key file.")
35+
_force = cmd.Option<bool>("-f|--force", "Forces overwrite of an existing assembly.",
36+
CommandOptionType.NoValue);
37+
38+
_keyFile = cmd.Argument("KEYFILE", "The path of the key file. If the assembly is delay-signed this can be the public key.")
3239
.IsRequired(false, "The 'KEYFILE' argument is required.");
3340

3441
_assemblyFile = cmd.Argument("ASSEMBLY", "The path of the assembly file to sign.")
3542
.IsRequired(false, "The 'ASSEMBLY' argument is required.");
43+
44+
_outAssemblyFile = cmd.Argument(
45+
"OUTASSEMBLY",
46+
"The path of the signed assembly. If not specified the input assembly is overwritten.");
3647
}
3748

3849
public int Execute(CommandLineApplication cmd)
3950
{
4051
bool delaySign = _delaySign.HasValue();
52+
bool force = _force.HasValue();
4153
string keyFile = _keyFile.Value;
4254
string assemblyFile = _assemblyFile.Value;
55+
string outAssemblyFile = !string.IsNullOrEmpty(_outAssemblyFile.Value)
56+
? _outAssemblyFile.Value
57+
: null;
4358

4459
try
4560
{
61+
if (File.Exists(outAssemblyFile) && !force)
62+
throw new FileAreadyExistsException(outAssemblyFile);
63+
4664
if (delaySign)
4765
{
4866
StrongNamePublicKey publicKey = _keyLoader.LoadPublicKey(keyFile);
49-
_signer.DelaySignAssembly(assemblyFile, publicKey);
67+
_signer.DelaySignAssembly(assemblyFile, publicKey, outAssemblyFile);
5068
}
5169
else
5270
{
5371
StrongNameKey key = _keyLoader.LoadKey(keyFile);
54-
_signer.SignAssembly(assemblyFile, key);
72+
_signer.SignAssembly(assemblyFile, key, outAssemblyFile);
5573
}
5674
}
5775
catch (Exception error)
@@ -60,6 +78,7 @@ public int Execute(CommandLineApplication cmd)
6078
return ExitCodes.FromException(error);
6179
}
6280

81+
cmd.Out.WriteLine("Assembly '{0}' successfully signed.", outAssemblyFile);
6382
return ExitCodes.Success;
6483
}
6584
}

src/AppCore.SigningTool/ExitCodes.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ internal static class ExitCodes
1212
{
1313
public const int Success = 0;
1414

15-
public const int FileAreadyExists = 1;
15+
public const int UnrecognizedCommandOrArgument = 1;
1616

1717
public const int FileNotFound = 2;
1818

1919
public const int InvalidKey = 3;
2020

2121
public const int InvalidAssembly = 4;
2222

23+
public const int FileAreadyExists = 5;
24+
2325
public const int Unknown = -1;
2426

2527
public static int FromException(Exception error)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
3+
namespace AppCore.SigningTool.Extensions
4+
{
5+
internal static class ByteArrayExtensions
6+
{
7+
public static string ToHexString(this byte[] array)
8+
{
9+
return BitConverter.ToString(array)
10+
.Replace("-", "")
11+
.ToLowerInvariant();
12+
}
13+
}
14+
}

src/AppCore.SigningTool/Program.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ static int Main(string[] args)
1919
Name = "dotnet-signtool"
2020
};
2121

22+
app.MakeSuggestionsInErrorMessage = true;
2223
app.VersionOptionFromAssemblyAttributes(typeof(Program).Assembly);
2324
app.HelpOption("-h|--help", true);
2425
app.OnExecute(
@@ -30,7 +31,21 @@ static int Main(string[] args)
3031

3132
app.RegisterCommands(serviceProvider);
3233

33-
return app.Execute(args);
34+
try
35+
{
36+
return app.Execute(args);
37+
}
38+
catch (UnrecognizedCommandParsingException error)
39+
{
40+
app.Error.WriteLine(error.Message + ".");
41+
app.Out.WriteLine("Did you mean '{0}' ?", string.Join(' ', error.NearestMatches));
42+
}
43+
catch (CommandParsingException error)
44+
{
45+
app.Error.WriteLine(error.Message);
46+
}
47+
48+
return ExitCodes.UnrecognizedCommandOrArgument;
3449
}
3550

3651
private static ServiceProvider CreateServiceProvider()
@@ -49,6 +64,7 @@ private static void ConfigureServices(IServiceCollection services)
4964
services.AddSingleton<ICommand, SnCommand>();
5065
services.AddSingleton<ICommand<SnCommand>, SnCreateKeyCommand>();
5166
services.AddSingleton<ICommand<SnCommand>, SnExportPublicKeyCommand>();
67+
services.AddSingleton<ICommand<SnCommand>, SnShowKeyCommand>();
5268
services.AddSingleton<ICommand<SnCommand>, SnSignCommand>();
5369
}
5470
}

src/AppCore.SigningTool/StrongName/IStrongNameSigner.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ namespace AppCore.SigningTool.StrongName
44
{
55
public interface IStrongNameSigner
66
{
7-
void DelaySignAssembly(string assemblyPath, StrongNamePublicKey publicKey);
7+
void DelaySignAssembly(string assemblyPath, StrongNamePublicKey publicKey, string outAssemblyPath = null);
88

9-
void SignAssembly(string assemblyPath, StrongNameKey key);
9+
void SignAssembly(string assemblyPath, StrongNameKey key, string outAssemblyPath = null);
1010
}
1111
}

0 commit comments

Comments
 (0)