From 97eb5fa82d3b3bf8d4cb45a64048547ee10f04e5 Mon Sep 17 00:00:00 2001 From: Zhuo Lu Date: Thu, 1 Jun 2017 12:55:30 +0800 Subject: [PATCH 1/4] Use Identity instance containing name and hash Fix #135 --- flat.js | 6 +++++- sign.js | 10 +++++----- util-entitlements.js | 2 +- util-identities.js | 12 +++++++++++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/flat.js b/flat.js index ee52e5f..042a89c 100644 --- a/flat.js +++ b/flat.js @@ -14,6 +14,7 @@ const debugwarn = util.debugwarn const execFileAsync = util.execFileAsync const validateOptsAppAsync = util.validateOptsAppAsync const validateOptsPlatformAsync = util.validateOptsPlatformAsync +const Identity = require('./util-identities').findIdentitiesAsync const findIdentitiesAsync = require('./util-identities').findIdentitiesAsync /** @@ -55,7 +56,7 @@ function validateFlatOptsAsync (opts) { function flatApplicationAsync (opts) { var args = [ '--component', opts.app, opts.install, - '--sign', opts.identity, + '--sign', opts.identity.name, opts.pkg ] if (opts.keychain) { @@ -82,6 +83,9 @@ var flatAsync = module.exports.flatAsync = function (opts) { var promise if (opts.identity) { debuglog('`identity` passed in arguments.') + if (opts['identity-validation'] === false || opts.identity instanceof Identity) { + return Promise.resolve() + } promise = findIdentitiesAsync(opts, opts.identity) } else { debugwarn('No `identity` passed in arguments...') diff --git a/sign.js b/sign.js index d165e40..87574c9 100644 --- a/sign.js +++ b/sign.js @@ -17,7 +17,9 @@ const execFileAsync = util.execFileAsync const validateOptsAppAsync = util.validateOptsAppAsync const validateOptsPlatformAsync = util.validateOptsPlatformAsync const walkAsync = util.walkAsync +const Identity = require('./util-identities').Identity const findIdentitiesAsync = require('./util-identities').findIdentitiesAsync +const ProvisioningProfile = require('./util-provisioning-profiles').ProvisioningProfile const preEmbedProvisioningProfile = require('./util-provisioning-profiles').preEmbedProvisioningProfile const preAutoEntitlements = require('./util-entitlements').preAutoEntitlements @@ -47,8 +49,6 @@ function validateOptsBinariesAsync (opts) { * @returns {Promise} Promise. */ function validateSignOptsAsync (opts) { - const ProvisioningProfile = require('./util-provisioning-profiles').ProvisioningProfile - if (opts.ignore) { if (typeof opts.ignore !== 'function' && typeof opts.ignore !== 'string') return Promise.reject(new Error('Ignore filter should be either a function or a string.')) } @@ -134,7 +134,7 @@ function signApplicationAsync (opts) { if (opts.binaries) childPaths = childPaths.concat(opts.binaries) var args = [ - '--sign', opts.identity, + '--sign', opts.identity.hash || opts.identity.name, '--force' ] if (opts.keychain) { @@ -222,7 +222,7 @@ var signAsync = module.exports.signAsync = function (opts) { var promise if (opts.identity) { debuglog('`identity` passed in arguments.') - if (opts['identity-validation'] === false) { + if (opts['identity-validation'] === false || opts.identity instanceof Identity) { return Promise.resolve() } promise = findIdentitiesAsync(opts, opts.identity) @@ -244,7 +244,7 @@ var signAsync = module.exports.signAsync = function (opts) { return promise .then(function (identities) { if (identities.length > 0) { - // Provisioning profile(s) found + // Identity(/ies) found if (identities.length > 1) { debugwarn('Multiple identities found, will use the first discovered.') } else { diff --git a/util-entitlements.js b/util-entitlements.js index 833328a..c294ff8 100644 --- a/util-entitlements.js +++ b/util-entitlements.js @@ -50,7 +50,7 @@ module.exports.preAutoEntitlements = function (opts) { appInfo.ElectronTeamID = opts['provisioning-profile'].message.Entitlements['com.apple.developer.team-identifier'] debuglog('`ElectronTeamID` not found in `Info.plist`, use parsed from provisioning profile: ' + appInfo.ElectronTeamID) } else { - appInfo.ElectronTeamID = opts.identity.substring(opts.identity.indexOf('(') + 1, opts.identity.lastIndexOf(')')) + appInfo.ElectronTeamID = opts.identity.name.substring(opts.identity.name.indexOf('(') + 1, opts.identity.name.lastIndexOf(')')) debuglog('`ElectronTeamID` not found in `Info.plist`, use parsed from signing identity: ' + appInfo.ElectronTeamID) } return writeFileAsync(appInfoPath, plist.build(appInfo), 'utf8') diff --git a/util-identities.js b/util-identities.js index c84a64a..37cfbdb 100644 --- a/util-identities.js +++ b/util-identities.js @@ -9,6 +9,16 @@ const debuglog = util.debuglog const flatList = util.flatList const execFileAsync = util.execFileAsync +/** + * @constructor + * @param {string} name - Name of the signing identity. + * @param {String} hash - SHA-1 hash of the identity. + */ +var Identity = module.exports.Identity = function (name, hash) { + this.name = name + this.hash = hash +} + /** * This function returns a promise checking the indentity proposed and updates the identity option to a exact finding from results. * @function @@ -37,7 +47,7 @@ module.exports.findIdentitiesAsync = function (opts, identity) { debuglog('Identity:', '\n', '> Name:', identityFound, '\n', '> Hash:', identityHashFound) - return identityHashFound + return new Identity(identityFound, identityHashFound) } }) }) From d1a9f2a7881c52ebc27765cd31f96e6077ac497e Mon Sep 17 00:00:00 2001 From: Zhuo Lu Date: Thu, 1 Jun 2017 14:22:58 +0800 Subject: [PATCH 2/4] Convert to Identity if identity validation skipped --- sign.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sign.js b/sign.js index 87574c9..36c3d30 100644 --- a/sign.js +++ b/sign.js @@ -222,7 +222,10 @@ var signAsync = module.exports.signAsync = function (opts) { var promise if (opts.identity) { debuglog('`identity` passed in arguments.') - if (opts['identity-validation'] === false || opts.identity instanceof Identity) { + if (opts['identity-validation'] === false) { + if (!(opts.identity instanceof Identity)) { + opts.identity = new Identity(opts.identity); + } return Promise.resolve() } promise = findIdentitiesAsync(opts, opts.identity) From eff0c97cd631b62046a3e17a4e29949b0868fae6 Mon Sep 17 00:00:00 2001 From: Zhuo Lu Date: Thu, 1 Jun 2017 14:29:00 +0800 Subject: [PATCH 3/4] Fix code style --- sign.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sign.js b/sign.js index 36c3d30..baaa1f4 100644 --- a/sign.js +++ b/sign.js @@ -224,7 +224,7 @@ var signAsync = module.exports.signAsync = function (opts) { debuglog('`identity` passed in arguments.') if (opts['identity-validation'] === false) { if (!(opts.identity instanceof Identity)) { - opts.identity = new Identity(opts.identity); + opts.identity = new Identity(opts.identity) } return Promise.resolve() } From 6aa85c0c5c2f873ce6b52bb0daac4e48f4ed680b Mon Sep 17 00:00:00 2001 From: Zhuo Lu Date: Fri, 2 Jun 2017 02:22:31 +0800 Subject: [PATCH 4/4] Document identity validation flag --- README.md | 18 +++++++++++++----- bin/electron-osx-flat-usage.txt | 3 +++ bin/electron-osx-sign-usage.txt | 9 ++++++--- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ab1989b..7f0a03d 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,7 @@ See [default.entitlements.mas.inherit.plist](https://github.com/electron-userlan `gatekeeper-assess` - *Boolean* -Flag to enable Gatekeeper assessment after signing the app. Disabling it is useful for signing with self-signed certificates. +Flag to enable/disable Gatekeeper assessment after signing the app. Disabling it is useful for signing with self-signed certificates. Gatekeeper assessment is enabled by default on `darwin` platform. Default to `true`. @@ -163,6 +163,11 @@ Default to be selected with respect to `provisioning-profile` and `platform` fro Signing platform `mas` will look for `3rd Party Mac Developer Application: * (*)`, and platform `darwin` will look for `Developer ID Application: * (*)` by default. +`identity-validation` - *Boolean* + +Flag to enable/disable validation for the signing identity. If enabled, the `identity` provided will be validated in the `keychain` specified. +Default to `true`. + `keychain` - *String* The keychain name. @@ -181,14 +186,12 @@ Default to auto detect by presence of `Squirrel.framework` within the applicatio `pre-auto-entitlements` - *Boolean* -Flag to enable automation of `com.apple.security.application-groups` in entitlements file and update `Info.plist` with `ElectronTeamID`. -Allowed values: `true`, `false`. +Flag to enable/disable automation of `com.apple.security.application-groups` in entitlements file and update `Info.plist` with `ElectronTeamID`. Default to `true`. `pre-embed-provisioning-profile` - *Boolean* -Flag to enable embedding of provisioning profile in the current working directory. -Allowed values: `true`, `false`. +Flag to enable/disable embedding of provisioning profile in the current working directory. Default to `true`. `provisioning-profile` - *String* @@ -304,6 +307,11 @@ Default to be selected with respect to `platform` from `keychain` or keychain by Flattening platform `mas` will look for `3rd Party Mac Developer Installer: * (*)`, and platform `darwin` will look for `Developer ID Installer: * (*)` by default. +`identity-validation` - *Boolean* + +Flag to enable/disable validation for signing identity. If enabled, the `identity` provided will be validated in the `keychain` specified. +Default to `true`. + `install` - *String* Path to install the bundle. diff --git a/bin/electron-osx-flat-usage.txt b/bin/electron-osx-flat-usage.txt index 96dcddd..e9071ff 100644 --- a/bin/electron-osx-flat-usage.txt +++ b/bin/electron-osx-flat-usage.txt @@ -17,6 +17,9 @@ DESCRIPTION Name of certificate to use when signing. Default to selected with respect to --platform from --keychain specified or keychain by system default. + --identity-validation, --no-identity-validation + Flag to enable/disable validation for the signing identity. + --install=install-path Path to install the bundle. Default to ``/Applications''. diff --git a/bin/electron-osx-sign-usage.txt b/bin/electron-osx-sign-usage.txt index b8e8e9c..dae0bdd 100644 --- a/bin/electron-osx-sign-usage.txt +++ b/bin/electron-osx-sign-usage.txt @@ -22,7 +22,7 @@ DESCRIPTION This option only applies when signing with entitlements. --gatekeeper-assess, --no-gatekeeper-assess - Flag to enable Gatekeeper assessment after signing the app. Disabling it is useful for signing with self-signed certificates. + Flag to enable/disable Gatekeeper assessment after signing the app. Disabling it is useful for signing with self-signed certificates. Gatekeeper assessment is enabled by default on ``darwin'' platform. --help @@ -32,6 +32,9 @@ DESCRIPTION Name of certificate to use when signing. Default to selected with respect to --provisioning-profile and --platform from --keychain specified or keychain by system default. + --identity-validation, --no-identity-validation + Flag to enable/disable validation for the signing identity. + --ignore=regex Regex that signals ignoring a file before signing. @@ -45,10 +48,10 @@ DESCRIPTION Default to auto detect from application bundle. --pre-auto-entitlements, --no-pre-auto-entitlements - Flag to enable automation of entitlements file and Info.plist. + Flag to enable/disable automation of entitlements file and Info.plist. --pre-embed-provisioning-profile, --no-pre-embed-provisioning-profile - Flag to enable embedding of provisioning profile. + Flag to enable/disable embedding of provisioning profile. --provisioning-profile=file Path to provisioning profile.