Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support notarizing Apple's "installer packages" (.pkg files). #60

Closed
chrisbobbe opened this issue Dec 8, 2020 · 22 comments
Closed

Support notarizing Apple's "installer packages" (.pkg files). #60

chrisbobbe opened this issue Dec 8, 2020 · 22 comments

Comments

@chrisbobbe
Copy link

chrisbobbe commented Dec 8, 2020

In a sub-article to Apple's "Notarizing macOS Software Before Distribution" article, called "Customizing the Notarization Workflow", Apple says this:

The notary service accepts disk images (UDIF format), signed flat installer packages, and ZIP archives.

An "installer package" or a "flat installer package" is a .pkg file, it seems (article). Would you accept a PR that lets electron-notarize easily handle .pkg files?

electron-builder is easily configurable to output a signed .pkg file (doc), and notarizing it seems to be the natural thing to do. If I download and try to open a .pkg that hasn't been notarized, I get this message:

Screen-Shot-2020-11-30-at-9 24 32-PM

And I get no such message with a .pkg that has been notarized (more manually, with these steps, except using Xcode 12 instead of Xcode 10).

@MarshallOfSound
Copy link
Member

Would you accept a PR that lets electron-notarize easily handle .pkg files?

💯 yes

@GiancarlosIO
Copy link

GiancarlosIO commented Jun 26, 2021

@MarshallOfSound If I correctly understood, currently electron-notarize only can notarize zip files and not installer files like .dmg? 🤔

@alanning
Copy link

alanning commented Dec 7, 2021

@MarshallOfSound I'd like to work on this PR. Does this design sound OK to you?

  • Add a new filePath option.
  • Deprecate appPath (but still support it).
  • Use the extension of filePath to check if we need to zip it first before sending to Apple.

That way we can support notarizing all the file types.

Alternately we could just add a simple pkgPath option that would only support PKG files...

@GiancarlosIO currently electron-notarize only supports .app files.

@daniboomerang
Copy link

daniboomerang commented Feb 28, 2022

Hello
I'm struggling to get my pkg file notarized.

When I build the dist with electron-builder pkgutil says that pkg is correctly signed

pkgutil --check-signature Elixir\ Gaming.setup.pkg 
Package "Elixir Gaming.setup.pkg":
   Status: signed by a developer certificate issued by Apple for distribution
   Signed with a trusted timestamp on: 2022-02-02 05:09:03 +0000
   Certificate Chain:
    1. Developer ID Installer: Satoshis Games, SL (xxxxxxxx)
       Expires: 2027-01-29 07:25:34 +0000
       SHA256 Fingerprint:
           9E 09 6E 49 54 1A 6F A6 28 48 37 37 C9 80 61 5B E3 C6 8B 08 85 2A 
           BB E5 81 25 D2 7B CD 16 24 86
       ------------------------------------------------------------------------
    2. Developer ID Certification Authority
       Expires: 2027-02-01 22:12:15 +0000
       SHA256 Fingerprint:
           7A FC 9D 01 A6 2F 03 A2 DE 96 37 93 6D 4A FE 68 09 0D 2D E1 8D 03 
           F2 9C 88 CF B0 B1 BA 63 58 7F
       ------------------------------------------------------------------------
    3. Apple Root CA
       Expires: 2035-02-09 21:40:36 +0000
       SHA256 Fingerprint:
           B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C 
           68 C5 BE 91 B5 A1 10 01 F0 24

HOWEVER
When I send my pkg file for notarisation I get the following errors

https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma116/v4/05/62/40/056240bb-1cfb-1b53-c685-dbde8f010327/developer_log.json?accessKey=1646223510_4202343623139599939_8WIlgJeVlIlc5kP%2By07Q0zNr0sZrNvWKw534jf%2BP0n7xZnTnwmUSEta%2B9EPbw4hpW7TjDEN0wa3ZNke8Punhh2Xkp0kyRpcQpMayfM8TN3WemuzIn3zqiXbQlSvQnxWakcKlp9oAJ8NlTh3mBwh%2BWCKGjJqEKMSW3pPPbW9imS8%3D

I've been talking to the electron-builder guys.
Here is the detailed description of my issue and the converstion I'm having with them
electron-userland/electron-builder#6607 (comment)

They say they delegate in electron-osx-sign.
They tried to help me by proposing to patch electron-osx-sign so there is deep sign
I just tried but still fails

Then I found this thread and called my attention
I'm not sure anymore....is it possible to do what I'm trying to do? Is it possible to notarize a pkg file?
If so... Do you have any idea of how to solve my issue?

Regards 🙏

@MarshallOfSound @GiancarlosIO @alanning

@alanning
Copy link

alanning commented Mar 2, 2022

@daniboomerang It's been a while since I've looked at this but IIRC it is possible to notarize a pkg file.

Here is a tutorial of how to manually notarize a pkg file using the same tool that this package does (legacy code-path):
https://www.davidebarranca.com/2019/04/notarizing-installers-for-macos-catalina/

I couldn't access the errors you linked to but I have seen something on apple's forums re: scripts causing issues with notarization:
https://developer.apple.com/forums/thread/113954

Re: notarizing pkg files with this package specifically, we should be able to get this package notarizing non-app files with some simple/moderate changes. I think the main culprit is just the assumption that the input file is an app file, such as seen here:
https://github.com/electron/electron-notarize/blob/master/src/legacy.ts#L35

@daniboomerang
Copy link

Hi @alanning
Sorry I took some time to look at your answer

I looked at the turorial you shared.
Great one I have to say.

I was researching a lot on my own and came up with a very similar approach but using notary tool instead of altool.
I decided to try the tutorial though

Unfortunatelly the result after following the altool tutorial is

  • The same than the result following the Notary tool MANUAL approach (It's 100% same, but using notary tool instead of altool)
  • The same than the result using the electron-notarize AUTOMATIC approach

The 3 approaches I have tried have promising results as

1) I always get a correctly signed *pkg (SIGNING IS NEVER AN ISSUE)

 pkgutil --check-signature launcher_signed.pkg   

Package "launcher_signed.pkg":
   Status: signed by a developer certificate issued by Apple for distribution
   Signed with a trusted timestamp on: 2022-03-17 06:49:39 +0000
   Certificate Chain:
    1. Developer ID Installer: Satoshis Games, SL (xxxxxxx)
       Expires: 2027-01-29 07:25:34 +0000
       SHA256 Fingerprint:
           9E 09 6E 49 54 1A 6F A6 28 48 37 37 C9 80 61 5B E3 C6 8B 08 85 2A 
           BB E5 81 25 D2 7B CD 16 24 86
       ------------------------------------------------------------------------
    2. Developer ID Certification Authority
       Expires: 2027-02-01 22:12:15 +0000
       SHA256 Fingerprint:
           7A FC 9D 01 A6 2F 03 A2 DE 96 37 93 6D 4A FE 68 09 0D 2D E1 8D 03 
           F2 9C 88 CF B0 B1 BA 63 58 7F
       ------------------------------------------------------------------------
    3. Apple Root CA
       Expires: 2035-02-09 21:40:36 +0000
       SHA256 Fingerprint:
           B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C 
           68 C5 BE 91 B5 A1 10 01 F0 24

2) I manage to submit the file to apple service (APPLE SPECIFIC PASSWORD, CERTIFICATES AND SO ON ARE NOT AN ISSUE)

xcrun altool --notarize-app --primary-bundle-id "launcher.elixir.app" --username "myemail" --password "mypassword" --file "/Users/daniboomerang/Work/Repositories/morepathhere/launcher_signed.pkg"
No errors uploading '/Users/daniboomerang/Work/Repositories/morepathhere/launcher_signed.pkg'.
RequestUUID = 7754bca6-df08-4de6-bef8-ae0e84d94d73

The 3 approaches end up with the same problem
Apple notarizing complaining saying this

{
  "logFormatVersion": 1,
  "jobId": "7754bca6-df08-4de6-bef8-ae0e84d94d73",
  "status": "Invalid",
  "statusSummary": "Archive contains critical validation errors",
  "statusCode": 4000,
  "archiveFilename": "launcher_signed.pkg",
  "uploadDate": "2022-03-17T07:08:21Z",
  "sha256": "987fd83f462d206798a1f5cdf1d3c0ca014d971d2e79b704c5a3464998733cdf",
  "ticketContents": null,
  "issues": [
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/MacOS/Elixir Gaming",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/MacOS/Elixir Gaming",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/MacOS/Elixir Gaming",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (GPU).app/Contents/MacOS/Elixir Gaming Helper (GPU)",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (GPU).app/Contents/MacOS/Elixir Gaming Helper (GPU)",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (GPU).app/Contents/MacOS/Elixir Gaming Helper (GPU)",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libEGL.dylib",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libEGL.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libvk_swiftshader.dylib",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libvk_swiftshader.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/chrome_crashpad_handler",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/chrome_crashpad_handler",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/chrome_crashpad_handler",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/ReactiveObjC.framework/Versions/A/ReactiveObjC",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/ReactiveObjC.framework/Versions/A/ReactiveObjC",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Squirrel.framework/Versions/A/Squirrel",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Squirrel.framework/Versions/A/Squirrel",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Squirrel.framework/Versions/A/Resources/ShipIt",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Squirrel.framework/Versions/A/Resources/ShipIt",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Squirrel.framework/Versions/A/Resources/ShipIt",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (Renderer).app/Contents/MacOS/Elixir Gaming Helper (Renderer)",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (Renderer).app/Contents/MacOS/Elixir Gaming Helper (Renderer)",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (Renderer).app/Contents/MacOS/Elixir Gaming Helper (Renderer)",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper.app/Contents/MacOS/Elixir Gaming Helper",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper.app/Contents/MacOS/Elixir Gaming Helper",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper.app/Contents/MacOS/Elixir Gaming Helper",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Mantle.framework/Versions/A/Mantle",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Mantle.framework/Versions/A/Mantle",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (Plugin).app/Contents/MacOS/Elixir Gaming Helper (Plugin)",
      "message": "The binary is not signed.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (Plugin).app/Contents/MacOS/Elixir Gaming Helper (Plugin)",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "launcher_signed.pkg/launcher.elixir.app.pkg Contents/Payload/Applications/Elixir Gaming.app/Contents/Frameworks/Elixir Gaming Helper (Plugin).app/Contents/MacOS/Elixir Gaming Helper (Plugin)",
      "message": "The executable does not have the hardened runtime enabled.",
      "docUrl": null,
      "architecture": "x86_64"
    }
  ]
}

As explained in the electron builder repository
electron-userland/electron-builder#6607 (comment)

It looks like the pkg file has some stuff in their internal files that are not right for apple...

Any ideas...?

@daniboomerang
Copy link

daniboomerang commented Mar 21, 2022

@alanning also I wonder...the solution you provided me is about using apple altool
The question is...can electron-notarize package notarize a pgk or not? 🤔

Electron builder guy just answered me questioning the *.pkg can be notarised
electron-userland/electron-builder#6607 (comment)

@alanning
Copy link

@daniboomerang OK, here's the steps I would recommend:

  1. Make a simple, "Hello World" electron app
  2. Build the PKG using either, electron-builder (tutorial), or electron-packager (tutorial)
  3. Notarize the pkg manually
  4. Verify that the pkg is notarized successfully
  5. Figure out how to do the same for your actual app/pkg
  6. Then we can work on updating this electron-notarize package to support notarization of pkg files... (the actual purpose of this Issue)

For what it's worth I used electron-builder for our company, outputting both a DMG and a PKG, then manually notarizing the PKG.


Once you have gotten through Step 4 and are working on Step 5...

Just a guess but I suspect the issue you are running into is that the contents of the pkg need to be notarized in addition to the pkg itself. Seems like something I read about before but I don't have a source.

One reference I found talked about having to specify binaries and "extraResources" as part of the build config so may be something for you to look into:
https://til.simonwillison.net/electron/sign-notarize-electron-macos

@devsibwarra
Copy link

PR #95 allows any file extension with notarytool. Similar changes may allow the same support with the legacy tool

@daniboomerang
Copy link

daniboomerang commented Apr 20, 2022

@alanning
I tried the following

  • Created a "hello world" with electron and electron builder

  • Generated a pkg file with electron builder

  • Tried to notarize it manually:

    1. Signed it using pkgutil and checked the signature -> ✅
    2. Submitted it for notarization using xcrun altool --notarize-app
    3. Checked the notarization result and failed with the exact same errors I've got until today 🐞
  • Also tried to notarize it automatically using electron-notarize

    1. Added the notarize.js script ✅
    2. The app is automatically signed it when running electron-builder (I can check the pkg file is signed using pkgutil --check-signature
    3. The pkg is Submitted it for notarization by electron-botarize
    4. Checked the notarization result and failed with the exact same errors I've got until today 🐞

Doesn't this mean that the pkg file has something wrong in it?

@alanning you said

For what it's worth I used electron-builder for our company, outputting both a DMG and a PKG, then manually notarizing the PKG.

Could you share with me how do you exactly generate that PKG file? Do you use electron-builder? which options?

@alanning I have also pushed my hello world example
daniboomerang/test-notarize-electron-app#1

Do you think you could have a look at my configuration? Or even try to notarize it manually?

@daniboomerang
Copy link

Hello @devsibwarra
Thanks a lot for your comment
Not sure I understand what has happened in the PR you mentioned

Do you mean that before electron notarize didn't support pkg files and now it does?
Still not confident any changes in that PR can help me as I can't even notarise my pkg file manually...
Do you have an opinion on this?
#60 (comment)

Thanks

@devsibwarra
Copy link

@daniboomerang I ran into this issue and the linked PR when searching for a way to notarize my PKG file built by @electron-forge/maker-pkg. Guess I didn't dig into the previous comments enough and assumed the PR I had uncovered would apply to this issue.

Regarding #60 (comment) and your previous comment with the notarization errors, it feels like the underlying files are not completely code signed before being rolled into the PKG file.

I'm not familiar with how electron-builder handles the signing, but it looks to be using electron/osx-sign. Have you tried running with

DEBUG="electron-osx-sign*" npm run pack

The ElectronJS Community Discord may be a better area for help

@alanning
Copy link

@daniboomerang I'm happy to report that I was able to successfully notarize the example Electron app from your repo above using the manual method outlined here:
https://www.davidebarranca.com/2019/04/notarizing-installers-for-macos-catalina/

$ spctl -a -vvv -t install dist/Test-Notarize.pkg
dist/Test-Notarize.pkg: accepted
source=Notarized Developer ID
origin=Developer ID Installer: My Company, Inc. (ABC123)

The only changes I made were in package.json:

  1. Downgrade electron-builder to "electron-builder": "^22.10.5", since we are still using node 12 at my company (the version you had requires node 14).
  2. Change output pkg file name to "Test-Notarize.pkg"

Running npm install then npm run dist produced the pkg file as expected.

Then I followed the steps in the linked tutorial and after signing the apple docs again (because there are always new versions to sign) requesting the notarization worked.

So the good new is that the process works as expected with the demo electron app. If you are having trouble with it locally I would suggest first trying on a different machine just to see if that makes a difference. And then if its still not working try looking into what certificate you are signing with. I used my company's cert so if you are trying with a personal one maybe that is causing issues?

@daniboomerang
Copy link

daniboomerang commented Apr 22, 2022

Thanks so much @alanning !!
This is very interesting

Just tried again

  1. Downgraded electron-builder": "^22.10.5 as you did
  2. Had to upgrade node to 14.0.0
  3. npm install then npm run dist
  4. Updated the output to be Test-Notarize.pkg
  5. I am asked to introduce my keychain password for the signing

Screenshot 2022-04-22 at 11 36 56

  1. It creates the dist without problems. We can see the in the logs the certificate was found and is correct
  2. Check the signature

Screenshot 2022-04-22 at 11 46 45

  1. Send for notarisation

Screenshot 2022-04-22 at 11 46 52

  1. ### REJECTED!!! 😱 😱 😱 😱

Screenshot 2022-04-22 at 11 46 59

Certificates should be fine!

  • I'm using my company's certificate to sign the app
  • My app-specific password to send for notarisation

I will try in a different environment.

But...One question...
Do you go through the exact steps I go through? Does electron-builder automatically ask you for the keychain password and signs it for you? is everything in your side as my series of screenshots?

Thanks a lot @alanning for trying this!

@daniboomerang
Copy link

This is actually a very important question @alanning
Is electron builder signing for you or you are signing it manually using productsign --sign ?
Do you get this screen?
Screenshot 2022-04-22 at 11 36 56

@alanning
Copy link

@daniboomerang Looks like the issue is the signing step for you. From your last screenshot it looks like electron-builder is not able to find the proper cert to sign the app with. The app that is bundled up in the PKG file also needs to be signed by electron-builder.

Here's what it looked like for me:

➜  test-notarize-electron-app git:(feat/test-notarize) ✗ npm run dist

> [email protected] dist
> electron-builder

  • electron-builder  version=22.10.5 os=21.4.0
  • cannot check updates  error=TypeError: update_notifier_1.default is not a function
  • loaded configuration  file=package.json ("build" field)
  • writing effective config  file=dist/builder-effective-config.yaml
  • packaging       platform=darwin arch=x64 electron=17.4.1 appOutDir=dist/mac
  • downloading     url=https://github.com/electron/electron/releases/download/v17.4.1/electron-v17.4.1-darwin-x64.zip size=81 MB parts=8
  • downloaded      url=https://github.com/electron/electron/releases/download/v17.4.1/electron-v17.4.1-darwin-x64.zip duration=7.945s
  • signing         file=dist/mac/Test Notarize.app identityName=Developer ID Application: My Company, Inc. (abc123) identityHash=ABC123 provisioningProfile=none
  • building        target=pkg arch=x64 file=dist/Test-Notarize.pkg

Other, not as important stuff:

  • You are still using electron-builder v22.14.13 which requires Node v14 but that shouldn't matter.

  • I don't get the pop-up asking for password but that is probably because I granted it access to keychain sometime before.

  • The output of pkgutil --check-signature dist/Test-Notarize.pkg for me looks almost identical to what you posted. So the signing of the PKG file looks fine. You need the app file inside to also be signed.

@daniboomerang
Copy link

daniboomerang commented Jun 29, 2022

My god. I did it
This took me so long
Apple has the worst documentation in te entire world

alanning What I was missing was the Developer ID Application certificate
All this time I thought I only needed the Developer ID Installer certificate
The notarization service checks everything inside the package and that's why it was failing for me

Thanks to electron notarize I have now my *.app file signed and notarized
Also I end up with a *pkg file that is also signed

Here is my code

require('dotenv').config()
const { notarize } = require('electron-notarize')

exports.default = async function notarizing (context) {
  const { electronPlatformName, appOutDir } = context
  if (electronPlatformName !== 'darwin') {
    return
  }
  const appName = context.packager.appInfo.productFilename
  const password = '@keychain:MY_APP'

  const notarizationData = {
    appBundleId: 'myapp.app',
    appPath: `${appOutDir}/${appName}.app`,
    appleId: '[email protected]',
    appleIdPassword: password,
    teamId: 'MY TEMID'
  }

  console.log('Waiting for Apple notarization:', notarizationData)
  return await notarize(notarizationData)
}

However my *pkg is not notarized by electron notarize
If I want my pkg notarized I have to submit it manually

I'd love if I could include the notarization request for the generated *pkg file

Is that possible? Do you know the best way to do that? @alanning @devsibwarra

Thanks guys!

@hrueger
Copy link

hrueger commented Sep 18, 2022

Hi all,
I ran into the same issue, so I made this script which works like a charm:

/* eslint-disable @typescript-eslint/no-var-requires */
require("dotenv").config();
const { spawn } = require("node:child_process");
const os = require("os");

exports.default = async function notarizing(context) {
    const { artifactPaths } = context;
    if (os.platform() !== "darwin") {
        console.log("Not notarizing app because not running on MacOS.");
        return;
    }
    console.log("Notarizing app...");
    const filename = artifactPaths.find((p) => p.endsWith(".pkg"));
    if (!filename) {
        console.log("Could not find pkg artifact. Exit");
        process.exit(1);
    }
    console.log(`Found artifact: ${filename}`);
    const auth = `--apple-id ${process.env.APPLEID_EMAIL} --password "${process.env.APPLEID_PASSWORD}" --team-id ${process.env.APPLEID_TEAM_ID}`;
    const content = await exec(`xcrun notarytool submit ${filename} ${auth} --wait`);
    const uuid = content.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g)[0];
    await exec(`xcrun notarytool log ${uuid} ${auth}`);
    await exec(`xcrun stapler staple ${filename}`);

    console.log("App notarized successfully.");
};

function exec(cmd) {
    return new Promise((resolve, reject) => {
        console.log(cmd);
        const proc = spawn(cmd, [], { shell: true });

        const chunks = [];
        proc.stdout.on("data", (data) => {
            console.log(data.toString());
            chunks.push(data);
        });
        proc.stderr.on("data", (data) => {
            console.error(data.toString());
            chunks.push(data);
        });
        proc.on("close", (code) => {
            console.log(`Process exited with code ${code}.`);
            resolve(Buffer.concat(chunks).toString("utf8"));
        });
    });
}

Not that this must be called in the afterAllArtifactBuild Hook (not in afterSign):

	"afterAllArtifactBuild": "notarize.js",

Hope that helps someone 👍

@hrueger
Copy link

hrueger commented Sep 19, 2022

Hm, as I just found out, this introduces two new problems:

  • The .pkg file is uploaded to S3 before the notarize.js script runs
  • The latest-mac.yml, beta-mac.yml and alpha-mac.yml files are not uploaded at all.

tracked in electron-userland/electron-builder#7145

@le4onardo
Copy link

Hm, as I just found out, this introduces two new problems:

The .pkg file is uploaded to S3 before the notarize.js script runs
The latest-mac.yml, beta-mac.yml and alpha-mac.yml files are not uploaded at all.
tracked in electron-userland/electron-builder#7145

It seems using artifactBuildCompleted event instead of afterAllArtifactBuild does wait the notarization before publishing!
See electron-userland/electron-builder#7145 (comment)

@panther7
Copy link
Contributor

PR for support file: #154.

@erickzhao
Copy link
Member

Closed in #169

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants