From 34134e1bab5d0388933ba958bafd138dfa660421 Mon Sep 17 00:00:00 2001 From: Hugo Montero Date: Mon, 1 Apr 2024 16:03:19 -0600 Subject: [PATCH 1/3] add sign script for win --- .circleci/config.yml | 15 ++++++ package.json | 1 + scripts/win-sign.js | 107 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 scripts/win-sign.js diff --git a/.circleci/config.yml b/.circleci/config.yml index 0a1fac559..756b1b7a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -63,6 +63,19 @@ commands: - run: name: Build Package command: npm run build + sign-win: + description: "A command to sign windows executable" + parameters: + node-version: + type: string + steps: + - install-node: + node-version: << parameters.node-version >> + - run: + name: Sign Executable + command: | + sudo apt install nsis osslsigncode + npm run sign:win jobs: test-unix: parameters: @@ -130,6 +143,8 @@ jobs: steps: - build-package: node-version: << parameters.node-version >> + - sign-win: + node-version: << parameters.node-version >> - store_artifacts: path: build diff --git a/package.json b/package.json index 8079a42f1..a616d3abc 100644 --- a/package.json +++ b/package.json @@ -153,6 +153,7 @@ "coverage:e2e": "nyc npm run test:e2e:silent", "coverage:report": "nyc report --reporter=html", "build": "pkg .", + "sign:win": "node ./scripts/win-sign.js", "clean": "npm run clean:modules", "clean:modules": "rm -rf ./node_modules", "update-changelog": "VERSION=`node --print --eval \"require('./package.json').version\"` bash -c 'read -p \"Update CHANGELOG.md for version $VERSION and press ENTER when done.\"' && git add CHANGELOG.md", diff --git a/scripts/win-sign.js b/scripts/win-sign.js new file mode 100644 index 000000000..9cd2ac79b --- /dev/null +++ b/scripts/win-sign.js @@ -0,0 +1,107 @@ +#!/usr/bin/env node +require('dotenv').config(); +const path = require('path'); +const fs = require('fs-extra'); +const execa = require('execa'); +const pkgJSON = require('../package.json'); +const log = require('../src/lib/log').info; +const logErrorAndExit = require('../src/lib/log').error; +const particleBuildName = 'particle-cli-win-x64'; +const BUILD_DIR = path.join(__dirname, '..', 'build'); + +(async () => { + try { + + log('Signing Windows Installers'); + + const signingParams = getSigningParams(pkgJSON, '/tmp'); + const { p12, name, version, certificate } = signingParams; + + log(`Saving windows signing certificate for ${name}@${version} to ${p12}`); + + await fs.writeFile(p12, Buffer.from(certificate, 'base64')); + const bin = path.join(BUILD_DIR, `${particleBuildName}.exe`); + const unsigned = path.join(BUILD_DIR, `${particleBuildName}-unsigned.exe`); + + log(`Signing .exe for ${name}@${version} on x64`); + + await fs.copy(bin, unsigned); + await winSign({ unsigned, signed: bin }, signingParams); + + log('removing temporal files'); + await fs.remove(p12); + + } catch (error) { + return logErrorAndExit(error); + } + log('All Done!'); +})(); + +// UTILS ////////////////////////////////////////////////////////////////////// +function winSign(exe, params) { + const { p12, bin, homepage, password } = params; + const args = [ + 'sign', + '-pkcs12', + p12, + '-pass', + password, + '-n', + bin, + '-i', + homepage, + '-h', + 'sha512', + '-ts', + 'timestamp.digicert.com', + '-in', + exe.unsigned, + '-out', + exe.signed + ]; + + return execa('osslsigncode', args); +} + +function getSigningParams(pkgJSON, tmpDir) { + const { name, version } = pkgJSON; + const homepage = pkgJSON.homepage; // Directly using the package's homepage + + if (!version || !homepage) { + throw new Error(`${name} package has malformed package.json - 'version', and 'homepage' fields are required`); + } + const envVars = getEnvVars(); + + if (!envVars.certificate.value || !envVars.password.value) { + throw new Error(`'${envVars.certificate.var}' and '${envVars.password.var}' environment variables must be set`); + } + + const p12 = path.join(tmpDir, 'win-cert.p12'); + const certificate = envVars.certificate.value; + const password = envVars.password.value; + + return { + p12, + name, + version, + homepage, + certificate, + password + }; +} + +function getEnvVars() { + const certificate = 'PARTICLE_WINDOWS_SIGNING_CERT'; + const password = 'PARTICLE_WINDOWS_SIGNING_PASS'; + + return { + certificate: { + var: certificate, + value: process.env[certificate] + }, + password: { + var: password, + value: process.env[password] + } + }; +} From 79b1f71ca2e4b6db638144e2ddc74d37268de2e0 Mon Sep 17 00:00:00 2001 From: Hugo Montero Date: Tue, 2 Apr 2024 08:31:08 -0600 Subject: [PATCH 2/3] update img with osslsigncode --- .circleci/config.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 756b1b7a0..4484a91a7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ tag_filters: &tag_filters executors: linux: docker: - - image: particle/cimg-node-cross-compile:16.16-2 + - image: particle/cimg-node-cross-compile:16.16-3 auth: username: $DOCKERHUB_USERNAME password: $DOCKERHUB_PASSWORD @@ -74,7 +74,6 @@ commands: - run: name: Sign Executable command: | - sudo apt install nsis osslsigncode npm run sign:win jobs: test-unix: From d131ded0216431aac2f9384bb69e263f58116888 Mon Sep 17 00:00:00 2001 From: Hugo Montero Date: Tue, 2 Apr 2024 08:37:48 -0600 Subject: [PATCH 3/3] rename output to sign it (doesnt allow overwrite) --- .circleci/config.yml | 2 -- scripts/win-sign.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4484a91a7..768a68748 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -69,8 +69,6 @@ commands: node-version: type: string steps: - - install-node: - node-version: << parameters.node-version >> - run: name: Sign Executable command: | diff --git a/scripts/win-sign.js b/scripts/win-sign.js index 9cd2ac79b..bc267a380 100644 --- a/scripts/win-sign.js +++ b/scripts/win-sign.js @@ -25,7 +25,7 @@ const BUILD_DIR = path.join(__dirname, '..', 'build'); log(`Signing .exe for ${name}@${version} on x64`); - await fs.copy(bin, unsigned); + await fs.move(bin, unsigned); // Move the original exe to a new file to sign it await winSign({ unsigned, signed: bin }, signingParams); log('removing temporal files');