Skip to content

Commit a786eda

Browse files
author
Oren Novotny
authored
Merge pull request #13 from timheuer/master
Fixes #12 by using NuGet LocalFolderUtility to parse out wildcard inp…
2 parents 5f1afcb + b949917 commit a786eda

File tree

4 files changed

+59
-50
lines changed

4 files changed

+59
-50
lines changed

NuGetKeyVaultSignTool.Core/NuGetKeyVaultSignTool.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.3" />
1010
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="4.5.1" />
1111
<PackageReference Include="NuGet.Packaging" Version="5.2.0-xprivate.60006" />
12+
<PackageReference Include="NuGet.Protocol" Version="5.0.0" />
1213
<PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
1314
<PackageReference Include="RSAKeyVaultProvider" Version="1.1.22" />
1415
</ItemGroup>

NuGetKeyVaultSignTool.Core/SignCommand.cs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using NuGet.Common;
1111
using NuGet.Packaging.Signing;
1212
using ILogger = Microsoft.Extensions.Logging.ILogger;
13+
using NuGet.Protocol;
1314

1415
namespace NuGetKeyVaultSignTool
1516
{
@@ -76,38 +77,42 @@ async Task<string> Authenticate(string authority, string resource, string scope)
7677

7778
public async Task<bool> SignAsync(string packagePath, string outputPath, string timestampUrl, HashAlgorithmName signatureHashAlgorithm, HashAlgorithmName timestampHashAlgorithm, bool overwrite, X509Certificate2 publicCertificate, System.Security.Cryptography.RSA rsa)
7879
{
79-
var fileName = Path.GetFileName(packagePath);
80-
logger.LogInformation($"{nameof(SignAsync)} [{fileName}]: Begin Signing {packagePath}");
80+
var packagesToSign = LocalFolderUtility.ResolvePackageFromPath(packagePath);
81+
8182
var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl)));
8283

8384
var request = new AuthorSignPackageRequest(publicCertificate, signatureHashAlgorithm, timestampHashAlgorithm);
8485

8586
string originalPackageCopyPath = null;
86-
try
87+
foreach (var package in packagesToSign)
8788
{
88-
originalPackageCopyPath = CopyPackage(packagePath);
89-
90-
using (var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, outputPath, overwrite, signatureProvider, new NuGetLogger(logger, fileName)))
89+
logger.LogInformation($"{nameof(SignAsync)} [{package}]: Begin Signing {Path.GetFileName(package)}");
90+
try
9191
{
92-
await SigningUtility.SignAsync(options, request, CancellationToken.None);
92+
originalPackageCopyPath = CopyPackage(package);
93+
94+
using (var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, package, overwrite, signatureProvider, new NuGetLogger(logger, package)))
95+
{
96+
await SigningUtility.SignAsync(options, request, CancellationToken.None);
97+
}
9398
}
94-
}
95-
catch (Exception e)
96-
{
97-
logger.LogError(e, e.Message);
98-
return false;
99-
}
100-
finally
101-
{
102-
try
99+
catch (Exception e)
103100
{
104-
FileUtility.Delete(originalPackageCopyPath);
101+
logger.LogError(e, e.Message);
102+
return false;
105103
}
106-
catch
104+
finally
107105
{
106+
try
107+
{
108+
FileUtility.Delete(originalPackageCopyPath);
109+
}
110+
catch
111+
{
112+
}
113+
114+
logger.LogInformation($"{nameof(SignAsync)} [{package}]: End Signing {Path.GetFileName(package)}");
108115
}
109-
110-
logger.LogInformation($"{nameof(SignAsync)} [{fileName}]: End Signing {packagePath}");
111116
}
112117

113118
return true;

NuGetKeyVaultSignTool.Core/VerifyCommand.cs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
using NuGet.Packaging.Signing;
1414
using Microsoft.Extensions.Logging;
1515
using ILogger = Microsoft.Extensions.Logging.ILogger;
16+
using NuGet.Protocol;
1617

1718
namespace NuGetKeyVaultSignTool
1819
{
1920
public class VerifyCommand
2021
{
2122
readonly ILogger logger;
22-
23+
2324
public VerifyCommand(ILogger logger)
2425
{
2526
this.logger = logger;
@@ -37,51 +38,59 @@ public async Task<bool> VerifyAsync(string file, StringBuilder buffer)
3738
throw new ArgumentNullException(nameof(buffer));
3839
}
3940

40-
41+
4142
var trustProviders = new ISignatureVerificationProvider[]
4243
{
4344
new IntegrityVerificationProvider(),
4445
new SignatureTrustAndValidityVerificationProvider()
4546
};
4647
var verifier = new PackageSignatureVerifier(trustProviders);
48+
49+
var allPackagesVerified = true;
50+
4751
try
4852
{
4953
var result = 0;
50-
using (var package = new PackageArchiveReader(file))
51-
{
52-
var verificationResult = await verifier.VerifySignaturesAsync(package, SignedPackageVerifierSettings.GetVerifyCommandDefaultPolicy(), CancellationToken.None);
53-
54+
var packagesToVerify = LocalFolderUtility.ResolvePackageFromPath(file);
5455

55-
if (verificationResult.IsValid)
56-
{
57-
return verificationResult.IsValid;
58-
}
59-
else
56+
foreach (var packageFile in packagesToVerify)
57+
{
58+
using (var package = new PackageArchiveReader(packageFile))
6059
{
61-
var logMessages = verificationResult.Results.SelectMany(p => p.Issues).Select(p => p .AsRestoreLogMessage()).ToList();
62-
foreach (var msg in logMessages)
60+
var verificationResult = await verifier.VerifySignaturesAsync(package, SignedPackageVerifierSettings.GetVerifyCommandDefaultPolicy(), CancellationToken.None);
61+
62+
if (verificationResult.IsValid)
6363
{
64-
buffer.AppendLine(msg.Message);
64+
allPackagesVerified = true;
6565
}
66-
if (logMessages.Any(m => m.Level >= NuGet.Common.LogLevel.Warning))
66+
else
6767
{
68-
var errors = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Error).Count();
69-
var warnings = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Warning).Count();
68+
var logMessages = verificationResult.Results.SelectMany(p => p.Issues).Select(p => p.AsRestoreLogMessage()).ToList();
69+
foreach (var msg in logMessages)
70+
{
71+
buffer.AppendLine(msg.Message);
72+
}
73+
if (logMessages.Any(m => m.Level >= NuGet.Common.LogLevel.Warning))
74+
{
75+
var errors = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Error).Count();
76+
var warnings = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Warning).Count();
7077

71-
buffer.AppendLine($"Finished with {errors} errors and {warnings} warnings.");
78+
buffer.AppendLine($"Finished with {errors} errors and {warnings} warnings.");
7279

73-
result = errors;
80+
result = errors;
81+
}
82+
allPackagesVerified = false;
7483
}
75-
return false;
7684
}
77-
7885
}
7986
}
8087
catch (Exception e)
8188
{
8289
logger.LogError(e, e.Message);
8390
return false;
8491
}
92+
93+
return allPackagesVerified;
8594
}
8695
}
8796
}

NuGetKeyVaultSignTool/Program.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ internal static int Main(string[] args)
3232
var packagePath = signConfiguration.Argument("packagePath", "Package to sign.");
3333
var outputPath = signConfiguration.Option("-o | --output", "The output file. If omitted, overwrites input.", CommandOptionType.SingleValue);
3434
var force = signConfiguration.Option("-f | --force", "Overwrites a sigature if it exists.", CommandOptionType.NoValue);
35-
var fileDigestAlgorithm = signConfiguration.Option("-fd | --file-digest", "The digest algorithm to hash the file with.", CommandOptionType.SingleValue);
35+
var fileDigestAlgorithm = signConfiguration.Option("-fd | --file-digest", "The digest algorithm to hash the file with. Default option is sha256", CommandOptionType.SingleValue);
3636
var rfc3161TimeStamp = signConfiguration.Option("-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.", CommandOptionType.SingleValue);
37-
var rfc3161Digest = signConfiguration.Option("-td | --timestamp-digest", "Used with the -tr switch to request a digest algorithm used by the RFC 3161 timestamp server.", CommandOptionType.SingleValue);
37+
var rfc3161Digest = signConfiguration.Option("-td | --timestamp-digest", "Used with the -tr switch to request a digest algorithm used by the RFC 3161 timestamp server. Default option is sha256", CommandOptionType.SingleValue);
3838
var signatureType = signConfiguration.Option("-st | --signature-type", "The signature type (omit for author, default. Only author is supported currently).", CommandOptionType.SingleValue);
3939
var azureKeyVaultUrl = signConfiguration.Option("-kvu | --azure-key-vault-url", "The URL to an Azure Key Vault.", CommandOptionType.SingleValue);
4040
var azureKeyVaultClientId = signConfiguration.Option("-kvi | --azure-key-vault-client-id", "The Client ID to authenticate to the Azure Key Vault.", CommandOptionType.SingleValue);
@@ -46,7 +46,7 @@ internal static int Main(string[] args)
4646
{
4747
if (string.IsNullOrWhiteSpace(packagePath.Value))
4848
{
49-
logger.LogError("All arguments are required");
49+
logger.LogError("Path to file(s) to sign are requried");
5050
return -1;
5151
}
5252

@@ -122,12 +122,6 @@ internal static int Main(string[] args)
122122
return -1;
123123
}
124124

125-
if (!File.Exists(file.Value))
126-
{
127-
application.Error.WriteLine("File does not exist");
128-
return -1;
129-
}
130-
131125
var cmd = new VerifyCommand(logger);
132126
var buffer = new StringBuilder();
133127
var result = await cmd.VerifyAsync(file.Value, buffer);

0 commit comments

Comments
 (0)