Skip to content

Commit

Permalink
Merge pull request #13 from timheuer/master
Browse files Browse the repository at this point in the history
Fixes #12 by using NuGet LocalFolderUtility to parse out wildcard inp…
  • Loading branch information
Oren Novotny authored May 3, 2019
2 parents 5f1afcb + b949917 commit a786eda
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<PackageReference Include="Microsoft.Azure.KeyVault" Version="3.0.3" />
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="4.5.1" />
<PackageReference Include="NuGet.Packaging" Version="5.2.0-xprivate.60006" />
<PackageReference Include="NuGet.Protocol" Version="5.0.0" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
<PackageReference Include="RSAKeyVaultProvider" Version="1.1.22" />
</ItemGroup>
Expand Down
45 changes: 25 additions & 20 deletions NuGetKeyVaultSignTool.Core/SignCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using NuGet.Common;
using NuGet.Packaging.Signing;
using ILogger = Microsoft.Extensions.Logging.ILogger;
using NuGet.Protocol;

namespace NuGetKeyVaultSignTool
{
Expand Down Expand Up @@ -76,38 +77,42 @@ async Task<string> Authenticate(string authority, string resource, string scope)

public async Task<bool> SignAsync(string packagePath, string outputPath, string timestampUrl, HashAlgorithmName signatureHashAlgorithm, HashAlgorithmName timestampHashAlgorithm, bool overwrite, X509Certificate2 publicCertificate, System.Security.Cryptography.RSA rsa)
{
var fileName = Path.GetFileName(packagePath);
logger.LogInformation($"{nameof(SignAsync)} [{fileName}]: Begin Signing {packagePath}");
var packagesToSign = LocalFolderUtility.ResolvePackageFromPath(packagePath);

var signatureProvider = new KeyVaultSignatureProvider(rsa, new Rfc3161TimestampProvider(new Uri(timestampUrl)));

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

string originalPackageCopyPath = null;
try
foreach (var package in packagesToSign)
{
originalPackageCopyPath = CopyPackage(packagePath);

using (var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, outputPath, overwrite, signatureProvider, new NuGetLogger(logger, fileName)))
logger.LogInformation($"{nameof(SignAsync)} [{package}]: Begin Signing {Path.GetFileName(package)}");
try
{
await SigningUtility.SignAsync(options, request, CancellationToken.None);
originalPackageCopyPath = CopyPackage(package);

using (var options = SigningOptions.CreateFromFilePaths(originalPackageCopyPath, package, overwrite, signatureProvider, new NuGetLogger(logger, package)))
{
await SigningUtility.SignAsync(options, request, CancellationToken.None);
}
}
}
catch (Exception e)
{
logger.LogError(e, e.Message);
return false;
}
finally
{
try
catch (Exception e)
{
FileUtility.Delete(originalPackageCopyPath);
logger.LogError(e, e.Message);
return false;
}
catch
finally
{
try
{
FileUtility.Delete(originalPackageCopyPath);
}
catch
{
}

logger.LogInformation($"{nameof(SignAsync)} [{package}]: End Signing {Path.GetFileName(package)}");
}

logger.LogInformation($"{nameof(SignAsync)} [{fileName}]: End Signing {packagePath}");
}

return true;
Expand Down
51 changes: 30 additions & 21 deletions NuGetKeyVaultSignTool.Core/VerifyCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
using NuGet.Packaging.Signing;
using Microsoft.Extensions.Logging;
using ILogger = Microsoft.Extensions.Logging.ILogger;
using NuGet.Protocol;

namespace NuGetKeyVaultSignTool
{
public class VerifyCommand
{
readonly ILogger logger;

public VerifyCommand(ILogger logger)
{
this.logger = logger;
Expand All @@ -37,51 +38,59 @@ public async Task<bool> VerifyAsync(string file, StringBuilder buffer)
throw new ArgumentNullException(nameof(buffer));
}


var trustProviders = new ISignatureVerificationProvider[]
{
new IntegrityVerificationProvider(),
new SignatureTrustAndValidityVerificationProvider()
};
var verifier = new PackageSignatureVerifier(trustProviders);

var allPackagesVerified = true;

try
{
var result = 0;
using (var package = new PackageArchiveReader(file))
{
var verificationResult = await verifier.VerifySignaturesAsync(package, SignedPackageVerifierSettings.GetVerifyCommandDefaultPolicy(), CancellationToken.None);

var packagesToVerify = LocalFolderUtility.ResolvePackageFromPath(file);

if (verificationResult.IsValid)
{
return verificationResult.IsValid;
}
else
foreach (var packageFile in packagesToVerify)
{
using (var package = new PackageArchiveReader(packageFile))
{
var logMessages = verificationResult.Results.SelectMany(p => p.Issues).Select(p => p .AsRestoreLogMessage()).ToList();
foreach (var msg in logMessages)
var verificationResult = await verifier.VerifySignaturesAsync(package, SignedPackageVerifierSettings.GetVerifyCommandDefaultPolicy(), CancellationToken.None);

if (verificationResult.IsValid)
{
buffer.AppendLine(msg.Message);
allPackagesVerified = true;
}
if (logMessages.Any(m => m.Level >= NuGet.Common.LogLevel.Warning))
else
{
var errors = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Error).Count();
var warnings = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Warning).Count();
var logMessages = verificationResult.Results.SelectMany(p => p.Issues).Select(p => p.AsRestoreLogMessage()).ToList();
foreach (var msg in logMessages)
{
buffer.AppendLine(msg.Message);
}
if (logMessages.Any(m => m.Level >= NuGet.Common.LogLevel.Warning))
{
var errors = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Error).Count();
var warnings = logMessages.Where(m => m.Level == NuGet.Common.LogLevel.Warning).Count();

buffer.AppendLine($"Finished with {errors} errors and {warnings} warnings.");
buffer.AppendLine($"Finished with {errors} errors and {warnings} warnings.");

result = errors;
result = errors;
}
allPackagesVerified = false;
}
return false;
}

}
}
catch (Exception e)
{
logger.LogError(e, e.Message);
return false;
}

return allPackagesVerified;
}
}
}
12 changes: 3 additions & 9 deletions NuGetKeyVaultSignTool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ internal static int Main(string[] args)
var packagePath = signConfiguration.Argument("packagePath", "Package to sign.");
var outputPath = signConfiguration.Option("-o | --output", "The output file. If omitted, overwrites input.", CommandOptionType.SingleValue);
var force = signConfiguration.Option("-f | --force", "Overwrites a sigature if it exists.", CommandOptionType.NoValue);
var fileDigestAlgorithm = signConfiguration.Option("-fd | --file-digest", "The digest algorithm to hash the file with.", CommandOptionType.SingleValue);
var fileDigestAlgorithm = signConfiguration.Option("-fd | --file-digest", "The digest algorithm to hash the file with. Default option is sha256", CommandOptionType.SingleValue);
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);
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);
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);
var signatureType = signConfiguration.Option("-st | --signature-type", "The signature type (omit for author, default. Only author is supported currently).", CommandOptionType.SingleValue);
var azureKeyVaultUrl = signConfiguration.Option("-kvu | --azure-key-vault-url", "The URL to an Azure Key Vault.", CommandOptionType.SingleValue);
var azureKeyVaultClientId = signConfiguration.Option("-kvi | --azure-key-vault-client-id", "The Client ID to authenticate to the Azure Key Vault.", CommandOptionType.SingleValue);
Expand All @@ -46,7 +46,7 @@ internal static int Main(string[] args)
{
if (string.IsNullOrWhiteSpace(packagePath.Value))
{
logger.LogError("All arguments are required");
logger.LogError("Path to file(s) to sign are requried");
return -1;
}

Expand Down Expand Up @@ -122,12 +122,6 @@ internal static int Main(string[] args)
return -1;
}

if (!File.Exists(file.Value))
{
application.Error.WriteLine("File does not exist");
return -1;
}

var cmd = new VerifyCommand(logger);
var buffer = new StringBuilder();
var result = await cmd.VerifyAsync(file.Value, buffer);
Expand Down

0 comments on commit a786eda

Please sign in to comment.