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

MacOS Code Signing #179

Closed
alexelisenko opened this issue Jul 2, 2019 · 15 comments
Closed

MacOS Code Signing #179

alexelisenko opened this issue Jul 2, 2019 · 15 comments
Labels
hover MacOS Specifically concerns MacOS

Comments

@alexelisenko
Copy link

Hello,

I am trying to get my app code signed, but Apple now requires all apps to be notarized. I am getting the following error back from Apple:

The executable does not have the hardened runtime enabled.

This is referring to the main executable created by hover build. I have tried adding the hardening to the Xcode project, but Im assuming hover build does not use the xcode project to build it.. How do I add the hardened runtime capability when using hover?

@alexelisenko
Copy link
Author

The documentation from Apple:

Hardened runtime is available in the Capabilities pane of Xcode 10 or later, but you can enable the feature manually using earlier versions of Xcode, as long as you’re on macOS 10.13.6 or later. To do this, add the following flag to the OTHER_CODE_SIGN_FLAGS build setting:

--options=runtime

Is there a way to provide this build settings when creating the cmd binary?

@alexelisenko
Copy link
Author

I think I found how to do it, the codesign utility lets you add the option:

codesign -s "<COMMON_NAME>" -fv --options runtime App.app/Contents/MacOS/<EXECUTABLE>

@pchampio
Copy link
Member

pchampio commented Jul 2, 2019

I'm sorry, but I cannot help you on this one. Please report your finding here, as it might help others.

@GeertJohan
Copy link
Member

This sounds like something we may want to do for the release build of an app? Or should it also be done for debug builds?
Related issue #156

I have very little experience with MacOS, help is welcome and much appreciated @alexelisenko

@GeertJohan GeertJohan added hover MacOS Specifically concerns MacOS labels Jul 2, 2019
@alexelisenko
Copy link
Author

alexelisenko commented Jul 2, 2019

I have been able to successfully sign, notarize and distribute the app with a DMG installer. My findings:

Step 1: build with either hover or manual

hover build -t "lib/main.dart" I dont use the main_desktop.dart

Step 2: create .app package:

/MyApp.app
    /Contents
         Info.plist
         /MacOS
         /Resources

Step 3: move the build output to the MacOS folder in the app package

Move the following files to the .app directory under the MacOS folder

/assets
/flutter_assets
FlutterEmbedder.framework
icudtl.dat
myapp_binary

Step 4: modify Info.plist, add icons and/or installer background to /Resources

It is very important to have the following fields in the Info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleExecutable</key>
        <string>*YOUR EXECUTABLE (myapp_binary)*</string>
        <key>CFBundleIconFile</key>
        <string>icon.icns</string>
        <key>CFBundleIdentifier</key>
        <string>*YOUR BUNDLE*</string>
        <key>NSHighResolutionCapable</key>
        <true/>
        <key>LSUIElement</key>
        <true/>
</dict>
</plist>

Step 5: Sign the app package

First sign the app bundle:
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep MyApp.app

Sign the executable with the runtime options (This is now required for MacOS 10.14+)
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep --options runtime MyApp.app/Contents/MacOS/MyAppBinary

Sign the FlutterEmbedder Framework separately
codesign -s "YOUR DEVELOPER ID COMMON NAME" -fv --deep MyApp.app/Contents/MacOS/FlutterEmbedder.framework/Versions/A/

Step 6: Notarize the package with Apple

You will need an application specific password for the following steps

https://support.apple.com/en-ca/HT204397

How to generate an app-specific password
Sign in to your Apple ID account page.
In the Security section, click Generate Password below App-Specific Passwords.
Follow the steps on your screen.
After you generate your app-specific password, enter or paste it into the password field of the app as you would normally.

Compress the .app directory into zip, then:

xcrun altool --notarize-app --primary-bundle-id "YOUR BUNDLE ID" --username "YOUR DEVELOPER EMAIL" --password "YOUR APP SPECIFIC PASSWORD" --file MyApp.zip

Once the zip is uploaded, you will get a REQUEST-ID back, use it to check the status

Check status: xcrun altool --notarization-info <REQUEST-ID> -u "YOUR DEVELOPER EMAIL" -p "YOUR APP SPECIFIC PASSWORD"

If there is an error, you will see it in the output of the check status ^ command. There will be a link to a log file which will contain the errors to fix.

If approved, staple the app: xcrun stapler staple MyApp.app/

Step 7: create DMG

I used the create-dmg tool: brew install create-dmg

Then run with command:

create-dmg --volname "MyApp Installer" \
--volicon MyApp.app/Contents/Resources/icon.icns \
--background MyApp.app/Contents/Resources/installer-bg.png \
--window-size 800 400 \
--icon-size 100 \
--icon "MyApp.app" 200 200 \
--app-drop-link 600 185 \
"MyApp-1.0.dmg" "MyApp.app/"

All Done

Do not sign the DMG, the MacOS gatekeeper will detect the signed app in the image. If you sign the dmg, you will need to notarize it too, and there are many bug reports with notarizing image files.

@pchampio
Copy link
Member

pchampio commented Jul 2, 2019

This sounds like something we may want to do for the release build of an app? Or should it also be done for debug builds?

It's is more related to packaging (hover dist maybe?)
related to #99

@GeertJohan
Copy link
Member

Indeed this will be useful for packaging. Thanks @alexelisenko !

@alexelisenko
Copy link
Author

@Drakirus @GeertJohan I have found that using the --options runtime, which is required by Apple for the app to be notarized, caused a Dart crash. I have files bug reports.

Also, is there any updates on how MacOS 10.15+ will be handled? It is my understanding that OpenGL is no longer supported.

@pchampio
Copy link
Member

pchampio commented Jul 14, 2019

Hopefully you can get the --options runtime bug to be fixed 🤞.
About OpenGL not been supported on MacOS, we did talk about it in #40.
tl;dr: It might be a non-issue if Metal gets ported into go-gl/glfw.

@alexelisenko
Copy link
Author

@Drakirus I have found the issue with enabling hardened runtime.

You need to also add entitlements for allowing JIT, since AOT with Dart in the flutterembedder is not supported yet, which is why it crashes.

I will post the exact entitlement file and codesign command that is working for me.

@pchampio pchampio mentioned this issue Jul 23, 2019
3 tasks
@pchampio
Copy link
Member

Moved to #207.

@pchampio
Copy link
Member

@alexelisenko what is related to code signing can be reported in this issue.

@wud147
Copy link

wud147 commented Jul 26, 2019

@Drakirus I have found the issue with enabling hardened runtime.

You need to also add entitlements for allowing JIT, since AOT with Dart in the flutterembedder is not supported yet, which is why it crashes.

I will post the exact entitlement file and codesign command that is working for me.

Hi, have you figured out the entitlement file that is working for you? I met the same issue:(

@alexelisenko
Copy link
Author

@wud147 Yes, You need to codesign with the entitlement file:

codesign -s "Developer ID Application: <APPLE DEVELOPER IDENTITY>" -fv --entitlements entitlements.xml --deep --options runtime MyAPP.app

The entitlement file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>com.apple.security.cs.allow-jit</key>
        <true/>
        <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
        <true/>
        <key>com.apple.security.cs.disable-library-validation</key>
        <true/>
        <key>com.apple.security.cs.disable-executable-page-protection</key>
        <true/>
    </dict>
</plist>

@kivutar
Copy link

kivutar commented Nov 4, 2019

Once codesigned and notarized, did you notice any issue launching the app?
I have a go-glfw app that refuses to launch the first time after clicking "Open" in the Gatekeeper dialog.
I'd like to know if this also happen with go-flutter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hover MacOS Specifically concerns MacOS
Development

No branches or pull requests

5 participants