Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/SecureSign.Core/Models/PathConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,15 @@ public class PathConfig
/// </summary>
public string SignTool { get; set; } = @"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\signtool.exe";

/// <summary>
/// Gets or sets the path to nuget.exe
/// </summary>
public string Nuget { get; set; } = @"nuget";

/// <summary>
/// Gets or sets the timestamp service url for Authenticode signing
/// </summary>
public string Timestamper { get; set; } = @"http://timestamp.digicert.com";

}
}
55 changes: 52 additions & 3 deletions src/SecureSign.Core/Signers/AuthenticodeSigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ public async Task<Stream> SignAsync(Stream input, X509Certificate2 cert, string
File.WriteAllBytes(certFile, exportedCert);
await input.CopyToFileAsync(inputFile);

if (fileExtention == "nupkg")
{
return await SignUsingNugetAsync(inputFile, certFile, password);
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (fileExtention.Contains("ps"))
Expand Down Expand Up @@ -110,7 +115,7 @@ await RunProcessAsync(
$"/p \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"",
$"/d \"{CommandLineEncoder.Utils.EncodeArgText(description)}\"",
$"/du \"{CommandLineEncoder.Utils.EncodeArgText(url)}\"",
"/tr http://timestamp.digicert.com",
$"/tr {_pathConfig.Timestamper}",
"/td sha256",
"/fd sha256",
$"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"",
Expand All @@ -137,14 +142,58 @@ await RunProcessAsync(
"-command",
"\"$Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2;",
$"$Cert.Import('{CommandLineEncoder.Utils.EncodeArgText(certFile)}','{CommandLineEncoder.Utils.EncodeArgText(certPassword)}',[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::DefaultKeySet);",
$"Set-AuthenticodeSignature '{CommandLineEncoder.Utils.EncodeArgText(inputFile)}' $Cert -Timestamp http://timestamp.digicert.com\"",
$"Set-AuthenticodeSignature '{CommandLineEncoder.Utils.EncodeArgText(inputFile)}' $Cert -Timestamp {_pathConfig.Timestamper}\"",
}
);

// PowerShell signs in-place, so just return the file we were given.
return File.OpenRead(inputFile);
}

/// <summary>
/// Signs the specified file using nuget.exe. Needs to be a nupkg
/// </summary>
/// <param name="inputFile">File to sign</param>
/// <param name="certFile">Path to the certificate to use for signing</param>
/// <param name="certPassword">Password for the certificate</param>
/// <returns>A signed copy of the file</returns>
private async Task<Stream> SignUsingNugetAsync(string inputFile, string certFile, string certPassword)
{
// if we aren't windows, we need to call nuget from mono
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
await RunProcessAsync(
"mono",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is Mono really needed here? Could it use .NET Core instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, it doesn't work in .NET Core yet. NuGet/NuGet.Client#2545

new[]
{
_pathConfig.Nuget,
"sign",
$"-CertificatePath \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"",
$"-CertificatePassword \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"",
$"-Timestamper {_pathConfig.Timestamper}",
$"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"",
}
);
}
else
{
await RunProcessAsync(
_pathConfig.Nuget,
new[]
{
"sign",
$"-CertificatePath \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"",
$"-CertificatePassword \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"",
$"-Timestamper {_pathConfig.Timestamper}",
$"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These arguments are all identical across both - Can you please remove the duplication (eg. pull them out into a separate array)?

}
);
}

// nuget signs in-place, so just return the file we were given.
return File.OpenRead(inputFile);
}

/// <summary>
/// Signs the specified file using osslsigncode
/// </summary>
Expand Down Expand Up @@ -204,7 +253,7 @@ private async Task RunOsslSignCodeAsync(string certFile, string certPasswordFile
var args = new List<string>
{
"sign",
"-ts http://timestamp.digicert.com",
$"-ts {_pathConfig.Timestamper}",
$"-n \"{CommandLineEncoder.Utils.EncodeArgText(description)}\"",
$"-i \"{CommandLineEncoder.Utils.EncodeArgText(url)}\"",
$"-pkcs12 \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"",
Expand Down