Installer, bootstrapper, and executable signing for Windows (#4406)

* Added a codesigning script to pre and post build steps in the Windows installer CD job

* Changed `windows_installer` job name to `installer_vs2019`

* Added `installer-nightly` tag for `installer_vs2019`

* Updated `build_config.json` to use an envvar for the installer url and bucket

Signed-off-by: Mike Chang <changml@amazon.com>
monroegm-disable-blank-issue-2
Mike Chang 4 years ago committed by GitHub
parent e1c49e436d
commit 0b718d435c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -32,6 +32,9 @@ set(_addtional_defines
-dCPACK_RESOURCE_PATH=${CPACK_SOURCE_DIR}/Platform/Windows/Packaging
)
file(REAL_PATH "${CPACK_SOURCE_DIR}/.." _root_path)
file(TO_NATIVE_PATH "${_root_path}/scripts/signer/Platform/Windows/signer.ps1" _sign_script)
if(CPACK_LICENSE_URL)
list(APPEND _addtional_defines -dCPACK_LICENSE_URL=${CPACK_LICENSE_URL})
endif()
@ -55,6 +58,30 @@ set(_light_command
-o "${_bootstrap_output_file}"
)
set(_signing_command
psexec.exe
-accepteula
-nobanner
-s
powershell.exe
-NoLogo
-ExecutionPolicy Bypass
-File ${_sign_script}
)
message(STATUS "Signing package files in ${_cpack_wix_out_dir}")
execute_process(
COMMAND ${_signing_command} -packagePath ${_cpack_wix_out_dir}
RESULT_VARIABLE _signing_result
ERROR_VARIABLE _signing_errors
OUTPUT_VARIABLE _signing_output
ECHO_OUTPUT_VARIABLE
)
if(NOT ${_signing_result} EQUAL 0)
message(FATAL_ERROR "An error occurred during signing package files. ${_signing_errors}")
endif()
message(STATUS "Creating Bootstrap Installer...")
execute_process(
COMMAND ${_candle_command}
@ -80,6 +107,19 @@ file(COPY ${_bootstrap_output_file}
message(STATUS "Bootstrap installer generated to ${CPACK_PACKAGE_DIRECTORY}/${_bootstrap_filename}")
message(STATUS "Signing bootstrap installer in ${CPACK_PACKAGE_DIRECTORY}")
execute_process(
COMMAND ${_signing_command} -bootstrapPath ${CPACK_PACKAGE_DIRECTORY}/${_bootstrap_filename}
RESULT_VARIABLE _signing_result
ERROR_VARIABLE _signing_errors
OUTPUT_VARIABLE _signing_output
ECHO_OUTPUT_VARIABLE
)
if(NOT ${_signing_result} EQUAL 0)
message(FATAL_ERROR "An error occurred during signing bootstrap installer. ${_signing_errors}")
endif()
# use the internal default path if somehow not specified from cpack_configure_downloads
if(NOT CPACK_UPLOAD_DIRECTORY)
set(CPACK_UPLOAD_DIRECTORY ${CPACK_PACKAGE_DIRECTORY}/CPackUploads)
@ -100,11 +140,9 @@ if(NOT CPACK_UPLOAD_URL)
return()
endif()
file(REAL_PATH "${CPACK_SOURCE_DIR}/.." _root_path)
file(TO_NATIVE_PATH "${_cpack_wix_out_dir}" _cpack_wix_out_dir)
file(TO_NATIVE_PATH "${_root_path}/python/python.cmd" _python_cmd)
file(TO_NATIVE_PATH "${_root_path}/scripts/build/tools/upload_to_s3.py" _upload_script)
file(TO_NATIVE_PATH "${_cpack_wix_out_dir}" _cpack_wix_out_dir)
function(upload_to_s3 in_url in_local_path in_file_regex)

@ -0,0 +1,37 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
file(REAL_PATH "${CPACK_SOURCE_DIR}/.." _root_path)
set(_cpack_wix_out_dir ${CPACK_TOPLEVEL_DIRECTORY})
file(TO_NATIVE_PATH "${_root_path}/scripts/signer/Platform/Windows/signer.ps1" _sign_script)
set(_signing_command
psexec.exe
-accepteula
-nobanner
-s
powershell.exe
-NoLogo
-ExecutionPolicy Bypass
-File ${_sign_script}
)
message(STATUS "Signing executable files in ${_cpack_wix_out_dir}")
execute_process(
COMMAND ${_signing_command} -exePath ${_cpack_wix_out_dir}
RESULT_VARIABLE _signing_result
ERROR_VARIABLE _signing_errors
OUTPUT_VARIABLE _signing_output
ECHO_OUTPUT_VARIABLE
)
if(NOT ${_signing_result} EQUAL 0)
message(FATAL_ERROR "An error occurred during signing executable files. ${_signing_errors}")
endif()
message(STATUS "Signing exes complete!")

@ -108,7 +108,6 @@ set(_raw_text_license [[
]])
if(LY_INSTALLER_DOWNLOAD_URL)
set(WIX_THEME_WARNING_IMAGE ${CPACK_SOURCE_DIR}/Platform/Windows/Packaging/warning.png)
if(LY_INSTALLER_LICENSE_URL)
@ -138,6 +137,10 @@ if(LY_INSTALLER_DOWNLOAD_URL)
# the bootstrapper will at the very least need a different upgrade guid
generate_wix_guid(CPACK_WIX_BOOTSTRAP_UPGRADE_GUID "${_guid_seed_base}_Bootstrap_UpgradeCode")
set(CPACK_PRE_BUILD_SCRIPTS
${CPACK_SOURCE_DIR}/Platform/Windows/PackagingPreBuild.cmake
)
set(CPACK_POST_BUILD_SCRIPTS
${CPACK_SOURCE_DIR}/Platform/Windows/PackagingPostBuild.cmake
)

@ -351,17 +351,21 @@
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"
}
},
"windows_installer": {
"installer_vs2019": {
"TAGS": [
"nightly-clean"
"nightly-clean",
"nightly-installer"
],
"PIPELINE_ENV":{
"NODE_LABEL":"windows-packaging"
},
"COMMAND": "build_installer_windows.cmd",
"PARAMETERS": {
"CONFIGURATION": "profile",
"OUTPUT_DIRECTORY": "build\\windows_vs2019",
"CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_UNITY_BUILD=TRUE -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DLY_INSTALLER_WIX_ROOT=\"!WIX! \"",
"EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=https://www.o3debinaries.org -DLY_INSTALLER_LICENSE_URL=https://www.o3debinaries.org/license",
"CPACK_BUCKET": "spectra-prism-staging-us-west-2",
"EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=!INSTALLER_DOWNLOAD_URL! -DLY_INSTALLER_LICENSE_URL=!INSTALLER_DOWNLOAD_URL!/license",
"CPACK_BUCKET": "!INSTALLER_BUCKET!",
"CMAKE_LY_PROJECTS": "",
"CMAKE_TARGET": "ALL_BUILD",
"CMAKE_NATIVE_BUILD_ARGS": "/m /nologo"

@ -0,0 +1,99 @@
#
# Copyright (c) Contributors to the Open 3D Engine Project.
# For complete copyright and license terms please see the LICENSE at the root of this distribution.
#
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
#
param (
[String[]] $exePath,
[String[]] $packagePath,
[String[]] $bootstrapPath,
[String[]] $certificate
)
# Get prerequisites, certs, and paths ready
$tempPath = [System.IO.Path]::GetTempPath() # Order of operations defined here: https://docs.microsoft.com/en-us/dotnet/api/system.io.path.gettemppath?view=net-5.0&tabs=windows#remarks
$certThumbprint = Get-ChildItem -Path Cert:LocalMachine\MY -CodeSigningCert -ErrorAction Stop | Select-Object -ExpandProperty Thumbprint # Grab first certificate from local machine store
if ($certificate) {
Write-Output "Checking certificate thumbprint $certificate"
Get-ChildItem -Path Cert:LocalMachine\MY -ErrorAction SilentlyContinue | Where-Object {$_.Thumbprint -eq $certificate} # Prints certificate Thumbprint and Subject if found
if($?) {
$certThumbprint = $certificate
}
else {
Write-Error "$certificate thumbprint not found, using $certThumbprint thumbprint instead"
}
}
Try {
$signtoolPath = Resolve-Path "C:\Program Files*\Windows Kits\10\bin\*\x64\signtool.exe" -ErrorAction Stop | Select-Object -Last 1 -ExpandProperty Path
$insigniaPath = Resolve-Path "C:\Program Files*\WiX*\bin\insignia.exe" -ErrorAction Stop | Select-Object -Last 1 -ExpandProperty Path
}
Catch {
Write-Error "Signtool or Wix insignia not found! Exiting."
}
function Write-Signature {
param (
$signtool,
$thumbprint,
$filename
)
$attempts = 2
$sleepSec = 5
Do {
$attempts--
Try {
& $signtool sign /tr http://timestamp.digicert.com /td sha256 /fd sha256 /sha1 $thumbprint /sm $filename
& $signtool verify /pa /v $filename
return
}
Catch {
Write-Error $_.Exception.InnerException.Message -ErrorAction Continue
Start-Sleep -Seconds $sleepSec
}
} while ($attempts -lt 0)
throw "Failed to sign $filename" # Bypassed in try block if the command is successful
}
# Looping through each path insteaad of globbing to prevent hitting maximum command string length limit
if ($exePath) {
Write-Output "### Signing EXE files ###"
$files = @(Get-ChildItem $exePath -Recurse *.exe | % { $_.FullName })
foreach ($file in $files) {
Write-Signature -signtool $signtoolPath -thumbprint $certThumbprint -filename $file
}
}
if ($packagePath) {
Write-Output "### Signing CAB files ###"
$files = @(Get-ChildItem $packagePath -Recurse *.cab | % { $_.FullName })
foreach ($file in $files) {
Write-Signature -signtool $signtoolPath -thumbprint $certThumbprint -filename $file
}
Write-Output "### Signing MSI files ###"
$files = @(Get-ChildItem $packagePath -Recurse *.msi | % { $_.FullName })
foreach ($file in $files) {
& $insigniaPath -im $files
Write-Signature -signtool $signtoolPath -thumbprint $certThumbprint -filename $file
}
}
if ($bootstrapPath) {
Write-Output "### Signing bootstrapper EXE ###"
$files = @(Get-ChildItem $bootstrapPath -Recurse *.exe | % { $_.FullName })
foreach ($file in $files) {
& $insigniaPath -ib $file -o $tempPath\engine.exe
Write-Signature -signtool $signtoolPath -thumbprint $certThumbprint -filename $tempPath\engine.exe
& $insigniaPath -ab $tempPath\engine.exe $file -o $file
Write-Signature -signtool $signtoolPath -thumbprint $certThumbprint -filename $file
Remove-Item -Force $tempPath\engine.exe
}
}
Loading…
Cancel
Save