Skip to content

Commit

Permalink
Migrate to new code signing (#863)
Browse files Browse the repository at this point in the history
  • Loading branch information
erri120 authored Jan 29, 2024
1 parent 57852bc commit 4c3a106
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 39 deletions.
52 changes: 28 additions & 24 deletions .github/workflows/build-windows-pupnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ on:
required: false
default: false
secrets:
PFX_BASE64:
description: "Base64 encoded string of the PFX file for signing"
ES_USERNAME:
description: "The SSL.com account username."
required: false
PFX_KEY:
description: "Key for the PFX file used for signing"
ES_PASSWORD:
description: "The SSL.com account password."
required: false
ES_CREDENTIAL_ID:
description: "The Credential ID for signing certificate."
required: false
ES_TOTP_SECRET:
description: "The OAuth TOTP secret."
required: false
outputs:
ArtifactNameWindowsArchive:
Expand All @@ -52,10 +58,6 @@ on:
description: "Name of the Artifact that contains the Windows Inno Setup"
value: ${{ jobs.build.outputs.artifactNameWindowsInnoSetup }}

env:
SigningCertificate: "GitHubActionsWorkflow.pfx"
TimestampServer: "http://timestamp.digicert.com"

jobs:
build:
runs-on: windows-latest
Expand Down Expand Up @@ -85,44 +87,46 @@ jobs:
- name: Get PupNet
run: dotnet tool install -g KuiperZone.PupNet --version ${{ inputs.PupNetVersion }}

- name: Decode PFX
if: inputs.SignExecutable == true
- name: Download CodeSignTool
id: downloadCodeSignTool
shell: pwsh
run: |
$certBytes = [System.Convert]::FromBase64String("${{ secrets.PFX_BASE64 }}")
$certPath = Join-Path -Path ${{ steps.transformInputs.outputs.projectDir }} -ChildPath $env:SigningCertificate
[IO.File]::WriteAllBytes("$certPath", $certBytes)
run: ./scripts/download-codesigntool.ps1

- name: Create Archive
if: inputs.BuildArchive == true
working-directory: ${{ steps.transformInputs.outputs.projectDir }}
run: pupnet -y -v ${{ inputs.AppVersion }} -k zip -p DefineConstants=INSTALLATION_METHOD_ARCHIVE
env:
SignExecutable: ${{ inputs.SignExecutable }}
SigningCertificatePassword: ${{ secrets.PFX_KEY }}
CodeSignToolDir: ${{ steps.downloadCodeSignTool.outputs.codeSignToolDir }}
ES_USERNAME: ${{ secrets.ES_USERNAME }}
ES_PASSWORD: ${{ secrets.ES_PASSWORD }}
ES_CREDENTIAL_ID: ${{ secrets.ES_CREDENTIAL_ID }}
ES_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }}

- name: Create Setup
if: inputs.BuildInnoSetup == true
working-directory: ${{ steps.transformInputs.outputs.projectDir }}
run: pupnet -y -v ${{ inputs.AppVersion }} -k Setup -p DefineConstants=INSTALLATION_METHOD_INNO_SETUP
env:
SignExecutable: ${{ inputs.SignExecutable }}
SigningCertificatePassword: ${{ secrets.PFX_KEY }}
CodeSignToolDir: ${{ steps.downloadCodeSignTool.outputs.codeSignToolDir }}
ES_USERNAME: ${{ secrets.ES_USERNAME }}
ES_PASSWORD: ${{ secrets.ES_PASSWORD }}
ES_CREDENTIAL_ID: ${{ secrets.ES_CREDENTIAL_ID }}
ES_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }}

- name: Sign Setup
if: inputs.BuildInnoSetup == true && inputs.SignExecutable == true
working-directory: ${{ steps.transformInputs.outputs.projectDir }}
run: ../../scripts/sign.ps1 Deploy/OUT
env:
SignExecutable: ${{ inputs.SignExecutable }}
SigningCertificatePassword: ${{ secrets.PFX_KEY }}

- name: Remove PFX
if: inputs.SignExecutable == true
shell: pwsh
run: |
$certPath = Join-Path -Path ${{ steps.transformInputs.outputs.projectDir }} -ChildPath $env:SigningCertificate
Remove-Item -Path $certPath
CodeSignToolDir: ${{ steps.downloadCodeSignTool.outputs.codeSignToolDir }}
ES_USERNAME: ${{ secrets.ES_USERNAME }}
ES_PASSWORD: ${{ secrets.ES_PASSWORD }}
ES_CREDENTIAL_ID: ${{ secrets.ES_CREDENTIAL_ID }}
ES_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }}

- name: Set outputs
id: setOutputs
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,10 @@ jobs:
RetentionDays: 1
SignExecutable: true
secrets:
PFX_BASE64: ${{ secrets.PFX_BASE64 }}
PFX_KEY: ${{ secrets.PFX_KEY }}
ES_USERNAME: ${{ secrets.ES_USERNAME }}
ES_PASSWORD: ${{ secrets.ES_PASSWORD }}
ES_CREDENTIAL_ID: ${{ secrets.ES_CREDENTIAL_ID }}
ES_TOTP_SECRET: ${{ secrets.ES_TOTP_SECRET }}

release-github:
runs-on: ubuntu-latest
Expand Down
45 changes: 45 additions & 0 deletions scripts/download-codesigntool.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
Set-StrictMode -Version 'Latest'
$ErrorActionPreference = "Stop"
$ProgressPreference = 'SilentlyContinue' #'Continue

$rootDir = Resolve-Path "."
$downloadUrl = "https://www.ssl.com/download/codesigntool-for-windows/"
$downloadedFile = Join-Path $rootDir "CodeSignTool.zip"
$extractFolder = Join-Path $rootDir "CodeSignTool"

Write-Host "rootDir $rootDir"
Write-Host "downloadedFile $downloadedFile"
Write-Host "extractFolder $extractFolder"

# Remove extracted folder if exists, just in case (mainly used locally)
if (Test-Path $extractFolder) {
Remove-Item -Path $extractFolder -Recurse -Force
}

# Download (if it doesn't exist)
if (!(Test-Path $downloadedFile -PathType Leaf)) {
Invoke-WebRequest -OutFile $downloadedFile $downloadUrl
}

# Extract
Expand-Archive -Path $downloadedFile -DestinationPath $extractFolder -Force

# need to check for a nested single folder as 1.2.7 was packaged without this, all previous versions were not.
$folderCount = @(Get-ChildItem $extractFolder -Directory ).Count;

# if we have a single folder, then assume we have a nested folder that we need to fix
If ($folderCount -eq 1) {

# get nested folder path, there is only 1 at this point
$nestedFolderPath = (Get-ChildItem $extractFolder -Directory | Select-Object FullName)[0].FullName

Write-Host "nestedFolderPath $nestedFolderPath"

# move all child items from this nested folder to it's parent
Get-ChildItem -Path $nestedFolderPath -Recurse | Move-Item -Destination $extractFolder

# remove nested folder to keep it clean
Remove-Item -Path $nestedFolderPath -Force
}

echo "codeSignToolDir=$extractFolder" >> $env:GITHUB_OUTPUT
38 changes: 25 additions & 13 deletions scripts/sign.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,31 @@ if (Test-Path $executableToSign -PathType Leaf) {
exit 1;
}

# https://github.com/actions/runner-images/blob/main/images/win/Windows2022-Readme.md#installed-windows-sdks
$rootDirectory = "C:\Program Files (x86)\Windows Kits\10\bin\";
$sdkDirectory = Get-ChildItem -Path $rootDirectory -Name | Where-Object { $_ -like "10*" } | Sort-Object -Descending | Select-Object -First 1
Write-Host "Sdk Directory: $sdkDirectory"

$signToolPath = [System.IO.Path]::Combine($rootDirectory, $sdkDirectory, "x64", "signtool.exe")
Write-Host "signtool path: $signToolPath"

if (Test-Path $signToolPath -PathType Leaf) {
Write-Host "Found signtool.exe at: $signToolPath";
$codeSignToolDir = $env:CodeSignToolDir
if (Test-Path $codeSignToolDir -PathType Container) {
Write-Host "CodeSignTool directory $codeSignToolDir";
} else {
Write-Error "Singing tool at $signToolPath doesn't exist!";
Write-Error "CodeSignTool directory $codeSignToolDir doesn't exist!";
exit 1;
}

Write-Host "Signing $executableToSign";
$codeSignToolPath = Join-Path $codeSignToolDir "CodeSignTool"

# CodeSignTool requires user interaction to confirm an overwrite of the original file.
# We circumvent this by setting the output directory to some temp directory and replacing
# the original file with the newly signed file.

$tmpDir = Join-Path $(Resolve-Path .) "tmp"
if (Test-Path $tmpDir -PathType Container) {
Remove-Item -Path $tmpDir -Recurse -Force
}

& $signToolPath sign /f "$env:SigningCertificate" /p "$env:SigningCertificatePassword" /td sha256 /fd sha256 /tr "$env:TimestampServer" $executableToSign
New-Item -Path $tmpDir -Type Directory

$inputFile = $executableToSign
$outputFile = Join-Path $tmpDir $(Get-Item $inputFile).Name

& $codeSignToolPath sign -input_file_pathh="$inputFile" -output_dir_path="$tmpDir" -username="$env:ES_USERNAME" -password="$env:ES_PASSWORD" -credential_id="$env:ES_CREDENTIAL_ID" -totp_secret="$env:ES_TOTP_SECRET"
$exitCode = $LASTEXITCODE

if ($exitCode -eq 0) {
Expand All @@ -47,3 +54,8 @@ if ($exitCode -eq 0) {
Write-Error "Signing failed with code $exitCode"
exit $exitCode
}

Write-Host "Moving $outputFile to $inputFile"
Move-File -Path $outputFile -Destination $inputFile -Force

Remove-Item -Path $tmpDir -Recurse -Force

0 comments on commit 4c3a106

Please sign in to comment.