From a99b1349327eb9be9980333af74e374d230ebe36 Mon Sep 17 00:00:00 2001 From: Cinder Biscuits Date: Thu, 5 Dec 2019 06:40:30 -0600 Subject: [PATCH 1/3] Add nuget package signing --- src/SecureSign.Core/Models/PathConfig.cs | 5 ++ .../Signers/AuthenticodeSigner.cs | 49 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/SecureSign.Core/Models/PathConfig.cs b/src/SecureSign.Core/Models/PathConfig.cs index d661cf6..6c9d0e0 100644 --- a/src/SecureSign.Core/Models/PathConfig.cs +++ b/src/SecureSign.Core/Models/PathConfig.cs @@ -49,5 +49,10 @@ public class PathConfig /// public string SignTool { get; set; } = @"C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86\signtool.exe"; + /// + /// Gets or sets the path to nuget.exe + /// + public string Nuget { get; set; } = @"nuget"; + } } diff --git a/src/SecureSign.Core/Signers/AuthenticodeSigner.cs b/src/SecureSign.Core/Signers/AuthenticodeSigner.cs index aaf73a2..290841d 100644 --- a/src/SecureSign.Core/Signers/AuthenticodeSigner.cs +++ b/src/SecureSign.Core/Signers/AuthenticodeSigner.cs @@ -66,6 +66,11 @@ public async Task SignAsync(Stream input, X509Certificate2 cert, string File.WriteAllBytes(certFile, exportedCert); await input.CopyToFileAsync(inputFile); + if (fileExtention.Contains("nupkg")) + { + return await SignUsingNugetAsync(inputFile, certFile, password); + } + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (fileExtention.Contains("ps")) @@ -145,6 +150,50 @@ await RunProcessAsync( return File.OpenRead(inputFile); } + /// + /// Signs the specified file using nuget.exe. Needs to be a nupkg + /// + /// File to sign + /// Path to the certificate to use for signing + /// Password for the certificate + /// A signed copy of the file + private async Task 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", + new[] + { + _pathConfig.Nuget, + "sign", + $"-CertificatePath \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"", + $"-CertificatePassword \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"", + "-Timestamper http://timestamp.digicert.com", + $"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"", + } + ); + } + else + { + await RunProcessAsync( + _pathConfig.Nuget, + new[] + { + "sign", + $"-CertificatePath \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"", + $"-CertificatePassword \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"", + "-Timestamper http://timestamp.digicert.com", + $"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"", + } + ); + } + + // SignTool signs in-place, so just return the file we were given. + return File.OpenRead(inputFile); + } + /// /// Signs the specified file using osslsigncode /// From 9f9b632e8aa394093d6d717d3e7a0e7b7ed8dfe0 Mon Sep 17 00:00:00 2001 From: Cinder Biscuits Date: Thu, 5 Dec 2019 06:43:50 -0600 Subject: [PATCH 2/3] Make timestamp service url configurable --- src/SecureSign.Core/Models/PathConfig.cs | 5 +++++ src/SecureSign.Core/Signers/AuthenticodeSigner.cs | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/SecureSign.Core/Models/PathConfig.cs b/src/SecureSign.Core/Models/PathConfig.cs index 6c9d0e0..942446e 100644 --- a/src/SecureSign.Core/Models/PathConfig.cs +++ b/src/SecureSign.Core/Models/PathConfig.cs @@ -54,5 +54,10 @@ public class PathConfig /// public string Nuget { get; set; } = @"nuget"; + /// + /// Gets or sets the timestamp service url for Authenticode signing + /// + public string Timestamper { get; set; } = @"http://timestamp.digicert.com"; + } } diff --git a/src/SecureSign.Core/Signers/AuthenticodeSigner.cs b/src/SecureSign.Core/Signers/AuthenticodeSigner.cs index 290841d..89e20f5 100644 --- a/src/SecureSign.Core/Signers/AuthenticodeSigner.cs +++ b/src/SecureSign.Core/Signers/AuthenticodeSigner.cs @@ -115,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)}\"", @@ -142,7 +142,7 @@ 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}\"", } ); @@ -170,7 +170,7 @@ await RunProcessAsync( "sign", $"-CertificatePath \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"", $"-CertificatePassword \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"", - "-Timestamper http://timestamp.digicert.com", + $"-Timestamper {_pathConfig.Timestamper}", $"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"", } ); @@ -184,7 +184,7 @@ await RunProcessAsync( "sign", $"-CertificatePath \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"", $"-CertificatePassword \"{CommandLineEncoder.Utils.EncodeArgText(certPassword)}\"", - "-Timestamper http://timestamp.digicert.com", + $"-Timestamper {_pathConfig.Timestamper}", $"\"{CommandLineEncoder.Utils.EncodeArgText(inputFile)}\"", } ); @@ -253,7 +253,7 @@ private async Task RunOsslSignCodeAsync(string certFile, string certPasswordFile var args = new List { "sign", - "-ts http://timestamp.digicert.com", + $"-ts {_pathConfig.Timestamper}", $"-n \"{CommandLineEncoder.Utils.EncodeArgText(description)}\"", $"-i \"{CommandLineEncoder.Utils.EncodeArgText(url)}\"", $"-pkcs12 \"{CommandLineEncoder.Utils.EncodeArgText(certFile)}\"", From c1d2d6cfa9026d47dc9f88d7e69dddb02a566338 Mon Sep 17 00:00:00 2001 From: Cinder Biscuits Date: Thu, 5 Dec 2019 06:53:22 -0600 Subject: [PATCH 3/3] Match exact file extension for nupkg --- src/SecureSign.Core/Signers/AuthenticodeSigner.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SecureSign.Core/Signers/AuthenticodeSigner.cs b/src/SecureSign.Core/Signers/AuthenticodeSigner.cs index 89e20f5..6641504 100644 --- a/src/SecureSign.Core/Signers/AuthenticodeSigner.cs +++ b/src/SecureSign.Core/Signers/AuthenticodeSigner.cs @@ -66,7 +66,7 @@ public async Task SignAsync(Stream input, X509Certificate2 cert, string File.WriteAllBytes(certFile, exportedCert); await input.CopyToFileAsync(inputFile); - if (fileExtention.Contains("nupkg")) + if (fileExtention == "nupkg") { return await SignUsingNugetAsync(inputFile, certFile, password); } @@ -190,7 +190,7 @@ await RunProcessAsync( ); } - // SignTool signs in-place, so just return the file we were given. + // nuget signs in-place, so just return the file we were given. return File.OpenRead(inputFile); }