Electron-builder: Codesign for Windows on Travis fails

Created on 23 Jan 2019  路  7Comments  路  Source: electron-userland/electron-builder

Version: 20.38.4
Target: nsis

We're using the new Windows image over at Travis and have split up our builds so that Linux builds on the Xenial image, Mac on the OSX image and Windows/Nsis on the Windows image.

Everything works fine until we activate Codesign, the Windows build then fails on:

executing       file=C:\Users\travis\AppData\Local\electron-builder\Cache\winCodeSign\winCodeSign-2.4.0\windows-10\x64\signtool.exe args=sign /t http://timestamp.verisign.com/scripts/timstamp.dll /f C:\Users\travis\AppData\Local\Temp\t-3PzAcB\0.p12 /d <binary name> /du https://<domain-name> /p <hash> (sha256 hash) /debug C:\Users\travis\build\<path>\dist\win\win-unpacked\<binary name>.exe env={}

(binary name, domain name, hash, path removed from output)

Doing the same on a local Windows 10 machine using git bash works fine, it also works fine if we disable codesigning (by unsetting the CSC_LINK & CSC_KEY_PASSWORD variables). We tested using bash locally since that's what Travis is using to run the build.

Any advice? Happy to share more information if needed.

Most helpful comment

In case someone finds this issue looking for a way to fix this with Travis, I finally got this to work properly. I had to make two changes to my project which did not have any specific codesign configuation other than the WIN_CSC_LINK and WIN_CSC_KEY_PASSWORD variables.

In my .travis.yml I had to add this line to the before_install section:

certutil -p $WIN_CSC_KEY_PASSWORD -importpfx ./travis/cert.p12

And in the Electron Builder configuration I had to add the certificateSubjectName to the win section as is described over here: https://www.electron.build/configuration/win

All 7 comments

I was able to sign it manually, as a work around. Have a look here: https://travis-ci.community/t/codesigning-on-windows/1385

Hi @bompi88. Thanks for your suggestion.

How do you build the windows installer without codesigning? We depend on the CSC_LINK and CSC_KEY_PASSWORD variables to get the OSX binary signed. Below our setup which works fine for Linux and OSX but not for Windows.

install:
  - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install awscli; fi
  - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install -y windows-sdk-10.0; fi
  - npm install

script:
  - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then electron-builder; fi
  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then electron-builder; fi
  - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then Powershell -Command 'Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine'; fi
  - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then PowerShell -Command 'electron-builder'; fi

Hi @pontusr, I manually sign all binary resources before I run electron-builder. After I've built an
.exe file with electron-builder, I manually sign this as well. This is only a workaround, as signtool.exe seems to use the Cert store Cert:\CurrentUser\My? and the logged in user in travis seems to not have access to this Certificate Store. I import my Cert to the LocalMachine store and uses it from there instead.

I'm downloading an encrypted certificate .pfx file from a private blob, using gpg to decrypt using a key I have as an env var. Using this key I sign the binary using signtool.exe.

codesign.sh:

#!/usr/bin/env bash

set -e

export PATH="C:\Program Files (x86)\Windows Kits\10\bin\x64":$PATH
export BINARY_FILE=$1

choco install -y windows-sdk-10.0

printenv

curl -v "$CERT_URL" --output cert.pfx.gpg
gpg --passphrase ${CERT_DECRYPT_PASSWORD} --batch -o cert.pfx -d cert.pfx.gpg

ls -lah
ls -lah deploy

powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine
powershell Get-ExecutionPolicy -List

powershell $PWD/.build/codesign.ps1
signtool.exe verify -pa "$BINARY_FILE"

codesign.ps1:

Set-PSDebug -Trace 1

dir cert:/LocalMachine

$Password = ConvertTo-SecureString -String $Env:CERT_PASSWORD -AsPlainText -Force
Import-PfxCertificate -FilePath cert.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $Password
Start-Process -PassThru -Wait signtool.exe -ArgumentList "sign -v -debug -sm -s My -n `"$Env:CERT_SUBJECTNAME`" -d `"$Env:CODESIGN_DESC`" `"$Env:BINARY_FILE`""

I also turn off Windows Defender stuff on before_install to speed up the build (Not sure which commands that actually are necessary, but it speeds up 2x on my builds):

windows_defender_exceptions.sh: (You should use the npm cache dir instead of yarn, if you use npm)

export NODEPATH=$(where.exe node.exe)
export PROJECTDIR=$(pwd)
export ZIP=$PROJECTDIR/node_modules/7zip-bin/win/x64/7za.exe
export YARNCACHE=$(yarn cache dir)
export BUILDCACHE=$USERPROFILE\\.cache
export TEMPDIR=$LOCALAPPDATA\\Temp

echo "NODEPATH=${NODEPATH}"
echo "YARNCACHE=${YARNCACHE}"
echo "BUILDCACHE=${BUILDCACHE}"
echo "PROJECTDIR=${PROJECTDIR}"
echo "TEMPDIR=${TEMPDIR}"
echo "ZIP=${ZIP}"

set

powershell Add-MpPreference -ExclusionProcess ${NODEPATH}
powershell Add-MpPreference -ExclusionProcess ${ZIP}
powershell Add-MpPreference -ExclusionPath ${YARNCACHE}
powershell Add-MpPreference -ExclusionPath ${BUILDCACHE}
powershell Add-MpPreference -ExclusionPath ${PROJECTDIR}
powershell Add-MpPreference -ExclusionPath ${TEMPDIR}

echo "DisableArchiveScanning..."
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Set-MpPreference -DisableArchiveScanning \$true'"
echo "DisableBehaviorMonitoring..."
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Set-MpPreference -DisableBehaviorMonitoring \$true'"
echo "DisableRealtimeMonitoring..."
powershell Start-Process -PassThru -Wait PowerShell -ArgumentList "'-Command Set-MpPreference -DisableRealtimeMonitoring \$true'"

powershell Get-MpPreference

.travis.yml:

language: node_js
node_js: "10"
os: windows

env:
  global:
    - CERT_DECRYPT_PASSWORD=<>
    - CERT_PASSWORD=<>
    - CERT_SUBJECTNAME=<>
    - CERT_URL=<>
    - CODESIGN_DESC=<>

before_install:
    - ./.build/windows_defender_exceptions.sh
script:
    - npm dist:win
    - .build/codesign.sh dist/Arundo\ Edge\ Client*.exe
    - .build/codesign.sh dist/win-unpacked/Arundo\ Edge\ Client.exe

Hi again @bompi88 and thanks for your suggestion.

Unfortunately we're using electron-builder as part of another flow which we cannot change and thus require codesigning to be done by electron-builder.

I will continue to investigate - but we'll probably revert to sign the Windows build on non-windows OS when using Travis.

As this is likely an issue with Codesign on the new Windows images over at Travis I'm closing this.

In case someone finds this issue looking for a way to fix this with Travis, I finally got this to work properly. I had to make two changes to my project which did not have any specific codesign configuation other than the WIN_CSC_LINK and WIN_CSC_KEY_PASSWORD variables.

In my .travis.yml I had to add this line to the before_install section:

certutil -p $WIN_CSC_KEY_PASSWORD -importpfx ./travis/cert.p12

And in the Electron Builder configuration I had to add the certificateSubjectName to the win section as is described over here: https://www.electron.build/configuration/win

How do you build the windows installer without codesigning? We depend on the CSC_LINK and CSC_KEY_PASSWORD variables to get the OSX binary signed. Below our setup which works fine for Linux and OSX but not for Windows.

If anyone comes across this in the future, this is how I got it to work:

before_install:
  - if [ "$TRAVIS_OS_NAME" = "windows" ] || [ "$TRAVIS_OS_NAME" = "linux" ]; then unset CSC_KEY_PASSWORD CSC_LINK; fi
Was this page helpful?
0 / 5 - 0 ratings