Skip to content

Commit

Permalink
use eToken for signing (#950)
Browse files Browse the repository at this point in the history
* fix typo

* use eToken for signing, create a dedicated step for signing

* update workflow, we have a certificate and no longer a container for win

* env var $GITHUB_REF not expanded in step input causing workflow to fail

* bump runner, so that we get an updated version of openssl

OpenSSL 1.1.1f-1ubuntu2.22 in Ubuntu 20.04 https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2004-Readme.md
OpenSSL 3.0.2-0ubuntu1.15 in Ubuntu 22.04 https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md

* add flag to correctly recognize the algorithm

see openssl/openssl#23089

* remove double quotes, they cause errors with new version of openssl:
`Could not read certificate from <stdin>`
  • Loading branch information
umbynos committed May 16, 2024
1 parent 2fa738f commit fc0a137
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 36 deletions.
69 changes: 45 additions & 24 deletions .github/workflows/check-certificates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
if: >
(github.event_name != 'pull_request' && github.repository == 'arduino/arduino-create-agent') ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'arduino/arduino-create-agent')
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04

strategy:
fail-fast: false
Expand All @@ -37,9 +37,11 @@ jobs:
- identifier: macOS signing certificate # Text used to identify certificate in notifications.
certificate-secret: INSTALLER_CERT_MAC_P12 # Name of the secret that contains the certificate.
password-secret: INSTALLER_CERT_MAC_PASSWORD # Name of the secret that contains the certificate password.
type: pkcs12
- identifier: Windows signing certificate
certificate-secret: INSTALLER_CERT_WINDOWS_PFX
password-secret: INSTALLER_CERT_WINDOWS_PASSWORD
certificate-secret: INSTALLER_CERT_WINDOWS_CER
# The password for the Windows certificate is not needed, because its not a container, but a single certificate.
type: x509

steps:
- name: Set certificate path environment variable
Expand All @@ -58,9 +60,10 @@ jobs:
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
run: |
(
openssl pkcs12 \
openssl ${{ matrix.certificate.type }} \
-in "${{ env.CERTIFICATE_PATH }}" \
-noout -passin env:CERTIFICATE_PASSWORD
-noout -passin env:CERTIFICATE_PASSWORD \
-legacy
) || (
echo "::error::Verification of ${{ matrix.certificate.identifier }} failed!!!"
exit 1
Expand All @@ -83,25 +86,43 @@ jobs:
CERTIFICATE_PASSWORD: ${{ secrets[matrix.certificate.password-secret] }}
id: get-days-before-expiration
run: |
EXPIRATION_DATE="$(
(
openssl pkcs12 \
-in "${{ env.CERTIFICATE_PATH }}" \
-clcerts \
-nodes \
-passin env:CERTIFICATE_PASSWORD
) | (
openssl x509 \
-noout \
-enddate
) | (
grep \
--max-count=1 \
--only-matching \
--perl-regexp \
'notAfter=(\K.*)'
)
)"
if [[ ${{ matrix.certificate.type }} == "pkcs12" ]]; then
EXPIRATION_DATE="$(
(
openssl pkcs12 \
-in ${{ env.CERTIFICATE_PATH }} \
-clcerts \
-nodes \
-passin env:CERTIFICATE_PASSWORD \
-legacy
) | (
openssl x509 \
-noout \
-enddate
) | (
grep \
--max-count=1 \
--only-matching \
--perl-regexp \
'notAfter=(\K.*)'
)
)"
elif [[ ${{ matrix.certificate.type }} == "x509" ]]; then
EXPIRATION_DATE="$(
(
openssl x509 \
-in ${{ env.CERTIFICATE_PATH }} \
-noout \
-enddate
) | (
grep \
--max-count=1 \
--only-matching \
--perl-regexp \
'notAfter=(\K.*)'
)
)"
fi
DAYS_BEFORE_EXPIRATION="$((($(date --utc --date="$EXPIRATION_DATE" +%s) - $(date --utc +%s)) / 60 / 60 / 24))"
Expand Down
59 changes: 47 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
run:
shell: bash

# by default disable CGO, it's not needed (except on macos)
# by default disable CGO, it's not needed (except on macos)
env:
CGO_ENABLED: 0

Expand Down Expand Up @@ -157,7 +157,7 @@ jobs:
create-macos-bundle:
needs: build

# for not they are exaclty the same
# for now they are exaclty the same
strategy:
matrix:
arch: [amd64, arm64]
Expand Down Expand Up @@ -371,9 +371,6 @@ jobs:
# vars used by installbuilder
INSTALLBUILDER_PATH: "/opt/installbuilder-23.11.0/bin/builder"
INSTALLER_VARS: "project.outputDirectory=$PWD project.version=${GITHUB_REF##*/} workspace=$PWD realname=Arduino_Create_Agent"
# installbuilder will read this vars automatically (defined in installer.xml):
INSTALLER_CERT_WINDOWS_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }}
INSTALLER_CERT_WINDOWS_PFX: "/tmp/ArduinoCerts2020.pfx"

strategy:
fail-fast: false # if one os is failing continue nonetheless
Expand Down Expand Up @@ -424,11 +421,6 @@ jobs:
- name: Save InstallBuilder license to file
run: echo "${{ secrets.INSTALLER_LICENSE }}" > /tmp/license.xml

- name: Save Win signing certificate to file
run: echo "${{ secrets.INSTALLER_CERT_WINDOWS_PFX }}" | base64 --decode > ${{ env.INSTALLER_CERT_WINDOWS_PFX}}
if: matrix.os == 'windows-2019'

# installbuilder reads the env vars with certs paths and use it to sign the installer.
- name: Launch Bitrock installbuilder
run: ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.installbuilder-name }} --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} architecture=${{ matrix.arch }}

Expand All @@ -443,6 +435,49 @@ jobs:
path: ArduinoCreateAgent*
if-no-files-found: error

# This job will sign the Windows installer
sign-windows:
runs-on: [self-hosted, windows-sign-pc]
needs: package

defaults:
run:
shell: bash

env:
INSTALLER_CERT_WINDOWS_CER: "/tmp/cert.cer"
# We are hardcoding the path for signtool because is not present on the windows PATH env var by default.
# Keep in mind that this path could change when upgrading to a new runner version
SIGNTOOL_PATH: "C:/Program Files (x86)/Windows Kits/10/bin/10.0.19041.0/x86/signtool.exe"

strategy:
matrix:
arch: [amd64, 386]

steps:
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: ArduinoCreateAgent-windows-${{ matrix.arch }}

- name: Save Win signing certificate to file
run: echo "${{ secrets.INSTALLER_CERT_WINDOWS_CER }}" | base64 --decode > ${{ env.INSTALLER_CERT_WINDOWS_CER}}

- name: Sign EXE
env:
CERT_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }}
CONTAINER_NAME: ${{ secrets.INSTALLER_CERT_WINDOWS_CONTAINER }}
# https://stackoverflow.com/questions/17927895/automate-extended-validation-ev-code-signing-with-safenet-etoken
run: |
"${{ env.SIGNTOOL_PATH }}" sign -d "Arduino Create Agent" -f ${{ env.INSTALLER_CERT_WINDOWS_CER}} -csp "eToken Base Cryptographic Provider" -k "[{{${{ env.CERT_PASSWORD }}}}]=${{ env.CONTAINER_NAME }}" -fd sha256 -tr http://timestamp.digicert.com -td SHA256 -v "ArduinoCreateAgent-${GITHUB_REF##*/}-windows-${{ matrix.arch }}-installer.exe"
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: ArduinoCreateAgent-windows-${{ matrix.arch }}-signed
path: ArduinoCreateAgent-*-windows-${{ matrix.arch }}-installer.exe

# This job will generate a dmg mac installer, sign/notarize it.
generate-sign-dmg:
needs: notarize-macos
Expand Down Expand Up @@ -544,7 +579,7 @@ jobs:
create-release:
runs-on: ubuntu-20.04
environment: production
needs: [build, package, generate-sign-dmg]
needs: [build, generate-sign-dmg, sign-windows]

steps:
- name: Checkout
Expand All @@ -563,7 +598,7 @@ jobs:
mv -v ArduinoCreateAgent-linux-amd64/* release/
cat ArduinoCreateAgent-osx-amd64/*.tar | tar -xvf - -i -C release/
rm -v release/._ArduinoCreateAgent*.dmg
mv -v ArduinoCreateAgent-windows*/* release/
mv -v ArduinoCreateAgent-windows*-signed/* release/
- name: VirusTotal Scan
id: virustotal_step
Expand Down

0 comments on commit fc0a137

Please sign in to comment.