From 740f24de486816905920dd29d75252b306af8be5 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Thu, 21 Sep 2023 08:51:28 +0200 Subject: [PATCH 1/2] PICARD-2760: Timestamp the Windows binaries when codesigning This ensures the final binaries are still accepted by the OS even after the certificates have expired. --- scripts/package/win-common.ps1 | 5 ++++- scripts/package/win-package-appx.ps1 | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/package/win-common.ps1 b/scripts/package/win-common.ps1 index 1c8cc2b2e6..f096af65f9 100644 --- a/scripts/package/win-common.ps1 +++ b/scripts/package/win-common.ps1 @@ -5,6 +5,9 @@ Param( $Certificate ) +# RFC 3161 timestamp server for code signing +$TimeStampServer = 'http://ts.ssl.com' + Function CodeSignBinary { Param( [ValidateScript({Test-Path $_ -PathType Leaf})] @@ -13,7 +16,7 @@ Function CodeSignBinary { ) If ($Certificate) { Set-AuthenticodeSignature -FilePath $BinaryPath -Certificate $Certificate ` - -ErrorAction Stop + -TimestampServer $TimeStampServer -ErrorAction Stop } Else { Write-Output "Skip signing $BinaryPath" } diff --git a/scripts/package/win-package-appx.ps1 b/scripts/package/win-package-appx.ps1 index 7bf0d9d591..628c701187 100644 --- a/scripts/package/win-package-appx.ps1 +++ b/scripts/package/win-package-appx.ps1 @@ -12,6 +12,9 @@ Param( $BuildNumber ) +# RFC 3161 timestamp server for code signing +$TimeStampServer = 'http://ts.ssl.com' + # Errors are handled explicitly. Otherwise any output to stderr when # calling classic Windows exes causes a script error. $ErrorActionPreference = 'Continue' @@ -72,9 +75,9 @@ ThrowOnExeError "MakeAppx failed" # Sign package If ($CertificateFile) { - SignTool sign /fd SHA256 /f "$CertificateFile" /p (ConvertFrom-SecureString -AsPlainText $CertificatePassword) $PackageFile + SignTool sign /v /fd SHA256 /tr "$TimeStampServer" /td sha256 /f "$CertificateFile" /p (ConvertFrom-SecureString -AsPlainText $CertificatePassword) $PackageFile ThrowOnExeError "SignTool failed" } ElseIf ($Certificate) { - SignTool sign /fd SHA256 /sha1 $Certificate.Thumbprint $PackageFile + SignTool sign /v /fd SHA256 /tr "$TimeStampServer" /td sha256 /sha1 $Certificate.Thumbprint $PackageFile ThrowOnExeError "SignTool failed" } From 7556986a54dd5f5fb034017fe43d41c7f0e84217 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Thu, 21 Sep 2023 09:08:33 +0200 Subject: [PATCH 2/2] PICARD-2760: Use SignTool for all Windows code signing This tool is more flexible then the than the Powershell commandlet and unifies code signing between .exe and .appx packages. --- .github/workflows/package.yml | 26 ++++++++++++++--------- scripts/package/win-common.ps1 | 15 ++++++++----- scripts/package/win-package-appx.ps1 | 18 +++------------- scripts/package/win-package-installer.ps1 | 9 +++++--- scripts/package/win-package-portable.ps1 | 9 +++++--- 5 files changed, 41 insertions(+), 36 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 68951b0178..ce0102219c 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -188,8 +188,10 @@ jobs: - name: Build Windows 10 signed app package if: matrix.type == 'signed-app' && env.CODESIGN == '1' run: | - $CertPassword = ConvertTo-SecureString -String $Env:CODESIGN_P12_PASSWORD -Force -AsPlainText - & .\scripts\package\win-package-appx.ps1 -BuildNumber $Env:BUILD_NUMBER -CertificateFile .\codesign.pfx -CertificatePassword $CertPassword + $CertificateFile = ".\codesign.pfx" + $CertificatePassword = ConvertTo-SecureString -String $Env:CODESIGN_P12_PASSWORD -Force -AsPlainText + & .\scripts\package\win-package-appx.ps1 -BuildNumber $Env:BUILD_NUMBER ` + -CertificateFile $CertificateFile -CertificatePassword $CertificatePassword Move-Item .\dist\*.msix .\artifacts env: CODESIGN_P12_PASSWORD: ${{ secrets.CODESIGN_P12_PASSWORD }} @@ -198,12 +200,14 @@ jobs: run: | # choco install nsis If ($Env:CODESIGN -eq "1") { - $CertPassword = ConvertTo-SecureString -String $Env:CODESIGN_P12_PASSWORD -Force -AsPlainText - $Certificate = Get-PfxCertificate -FilePath .\codesign.pfx -Password $CertPassword + $CertificateFile = ".\codesign.pfx" + $CertificatePassword = ConvertTo-SecureString -String $Env:CODESIGN_P12_PASSWORD -Force -AsPlainText } Else { - $Certificate = $null + $CertificateFile = $null + $CertificatePassword = $null } - & .\scripts\package\win-package-installer.ps1 -BuildNumber $Env:BUILD_NUMBER -Certificate $Certificate + & .\scripts\package\win-package-installer.ps1 -BuildNumber $Env:BUILD_NUMBER ` + -CertificateFile $CertificateFile -CertificatePassword $CertificatePassword Move-Item .\installer\*.exe .\artifacts dist\picard\fpcalc -version env: @@ -212,12 +216,14 @@ jobs: if: matrix.type == 'portable' run: | If ($Env:CODESIGN -eq "1") { - $CertPassword = ConvertTo-SecureString -String $Env:CODESIGN_P12_PASSWORD -Force -AsPlainText - $Certificate = Get-PfxCertificate -FilePath .\codesign.pfx -Password $CertPassword + $CertificateFile = ".\codesign.pfx" + $CertificatePassword = ConvertTo-SecureString -String $Env:CODESIGN_P12_PASSWORD -Force -AsPlainText } Else { - $Certificate = $null + $CertificateFile = $null + $CertificatePassword = $null } - & .\scripts\package\win-package-portable.ps1 -BuildNumber $Env:BUILD_NUMBER -Certificate $Certificate + & .\scripts\package\win-package-portable.ps1 -BuildNumber $Env:BUILD_NUMBER ` + -CertificateFile $CertificateFile -CertificatePassword $CertificatePassword Move-Item .\dist\*.exe .\artifacts env: CODESIGN_P12_PASSWORD: ${{ secrets.CODESIGN_P12_PASSWORD }} diff --git a/scripts/package/win-common.ps1 b/scripts/package/win-common.ps1 index f096af65f9..5add6e69c3 100644 --- a/scripts/package/win-common.ps1 +++ b/scripts/package/win-common.ps1 @@ -1,8 +1,11 @@ # Common functions for Windows packaging scripts Param( - [System.Security.Cryptography.X509Certificates.X509Certificate] - $Certificate + [ValidateScript({ (Test-Path $_ -PathType Leaf) -or (-not $_) })] + [String] + $CertificateFile, + [SecureString] + $CertificatePassword ) # RFC 3161 timestamp server for code signing @@ -14,9 +17,11 @@ Function CodeSignBinary { [String] $BinaryPath ) - If ($Certificate) { - Set-AuthenticodeSignature -FilePath $BinaryPath -Certificate $Certificate ` - -TimestampServer $TimeStampServer -ErrorAction Stop + If ($CertificateFile) { + SignTool sign /v /fd SHA256 /tr "$TimeStampServer" /td sha256 ` + /f "$CertificateFile" /p (ConvertFrom-SecureString -AsPlainText $CertificatePassword) ` + $BinaryPath + ThrowOnExeError "SignTool failed" } Else { Write-Output "Skip signing $BinaryPath" } diff --git a/scripts/package/win-package-appx.ps1 b/scripts/package/win-package-appx.ps1 index 628c701187..a381223257 100644 --- a/scripts/package/win-package-appx.ps1 +++ b/scripts/package/win-package-appx.ps1 @@ -1,9 +1,7 @@ # Build a MSIX app package for Windows 10 Param( - [System.Security.Cryptography.X509Certificates.X509Certificate] - $Certificate, - [ValidateScript({Test-Path $_ -PathType Leaf})] + [ValidateScript({ (Test-Path $_ -PathType Leaf) -or (-not $_) })] [String] $CertificateFile, [SecureString] @@ -12,9 +10,6 @@ Param( $BuildNumber ) -# RFC 3161 timestamp server for code signing -$TimeStampServer = 'http://ts.ssl.com' - # Errors are handled explicitly. Otherwise any output to stderr when # calling classic Windows exes causes a script error. $ErrorActionPreference = 'Continue' @@ -28,7 +23,7 @@ If (-Not $Certificate -And $CertificateFile) { } $ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -. $ScriptDirectory\win-common.ps1 -Certificate $Certificate +. $ScriptDirectory\win-common.ps1 -CertificateFile $CertificateFile -CertificatePassword $CertificatePassword Write-Output "Building Windows 10 app package..." @@ -73,11 +68,4 @@ If ($CertificateFile -or $Certificate) { MakeAppx pack /o /h SHA256 /d $PackageDir /p $PackageFile ThrowOnExeError "MakeAppx failed" -# Sign package -If ($CertificateFile) { - SignTool sign /v /fd SHA256 /tr "$TimeStampServer" /td sha256 /f "$CertificateFile" /p (ConvertFrom-SecureString -AsPlainText $CertificatePassword) $PackageFile - ThrowOnExeError "SignTool failed" -} ElseIf ($Certificate) { - SignTool sign /v /fd SHA256 /tr "$TimeStampServer" /td sha256 /sha1 $Certificate.Thumbprint $PackageFile - ThrowOnExeError "SignTool failed" -} +CodeSignBinary $PackageFile diff --git a/scripts/package/win-package-installer.ps1 b/scripts/package/win-package-installer.ps1 index 5a075bb971..aa1d989cad 100644 --- a/scripts/package/win-package-installer.ps1 +++ b/scripts/package/win-package-installer.ps1 @@ -1,8 +1,11 @@ # Build a Windows installer Param( - [System.Security.Cryptography.X509Certificates.X509Certificate] - $Certificate, + [ValidateScript({ (Test-Path $_ -PathType Leaf) -or (-not $_) })] + [String] + $CertificateFile, + [SecureString] + $CertificatePassword, [Int] $BuildNumber ) @@ -16,7 +19,7 @@ If (-Not $BuildNumber) { } $ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -. $ScriptDirectory\win-common.ps1 -Certificate $Certificate +. $ScriptDirectory\win-common.ps1 -CertificateFile $CertificateFile -CertificatePassword $CertificatePassword Write-Output "Building Windows installer..." diff --git a/scripts/package/win-package-portable.ps1 b/scripts/package/win-package-portable.ps1 index 06345fbfe6..da5dc022ea 100644 --- a/scripts/package/win-package-portable.ps1 +++ b/scripts/package/win-package-portable.ps1 @@ -1,8 +1,11 @@ # Build a portable app Param( - [System.Security.Cryptography.X509Certificates.X509Certificate] - $Certificate, + [ValidateScript({ (Test-Path $_ -PathType Leaf) -or (-not $_) })] + [String] + $CertificateFile, + [SecureString] + $CertificatePassword, [Int] $BuildNumber ) @@ -16,7 +19,7 @@ If (-Not $BuildNumber) { } $ScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent -. $ScriptDirectory\win-common.ps1 -Certificate $Certificate +. $ScriptDirectory\win-common.ps1 -CertificateFile $CertificateFile -CertificatePassword $CertificatePassword Write-Output "Building portable exe..."