Add macOS notarization (including stapling) #18187

pull jonasschnelli wants to merge 3 commits into bitcoin:master from jonasschnelli:2020/02/macos_runtime_hardening changing 3 files +26 −3
  1. jonasschnelli commented at 7:17 pm on February 20, 2020: contributor

    fixes #15774.

    Adds runtime hardening (which is necessary for macOS app notarization) https://developer.apple.com/documentation/security/hardened_runtime

    Notarization doc: https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution

    Hardened Runtime doc: https://developer.apple.com/documentation/security/hardened_runtime

    App Notarization has been tested here and here

    Additional release process notes are included.

    Needs backport.

  2. jonasschnelli added the label macOS on Feb 20, 2020
  3. jonasschnelli added the label Needs backport (0.19) on Feb 20, 2020
  4. jonasschnelli added the label Needs backport (0.18) on Feb 20, 2020
  5. jonasschnelli requested review from fanquake on Feb 20, 2020
  6. practicalswift commented at 8:17 pm on February 20, 2020: contributor
    Concept ACK
  7. in contrib/macdeploy/detached-sig-create.sh:26 in a89e4b4e86 outdated
    22@@ -23,7 +23,7 @@ fi
    23 rm -rf ${TEMPDIR} ${TEMPLIST}
    24 mkdir -p ${TEMPDIR}
    25 
    26-${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}"
    27+${CODESIGN} --options runtime -f --file-list ${TEMPLIST} "$@" "${BUNDLE}"
    


    fanquake commented at 0:22 am on February 21, 2020:

    After reading through the docs it seems that passing --timestamp here would also be required for notarization; given that we are signing manually?

    Include a secure timestamp with your code-signing signature. (The Xcode distribution workflow includes a secure timestamp by default. For custom workflows, include the –timestamp option when running the codesign tool.)


    fanquake commented at 0:35 am on February 21, 2020:

    Is there any reason why we can’t pass --strict to codesign here as well?

     0     --strict options
     1             When validating code, apply additional restrictions beyond the defaults.
     2
     3             symlinks  Check that symbolic links inside the code bundle point to sealed files inside its bundle.
     4                       This means that broken symbolic links are rejected, as are links to places outside the bundle
     5                       and to places that are not, for whatever reason, sealed by the signature.
     6
     7             sideband  Check that no resource forks, Finder attributes, or similar sideband data is present in the
     8                       signed code.  This is now automatically enforced by signing operations.
     9             Options can be specified as a comma-separated list. Use plain --strict or --strict=all to be as strict
    10             as possible. Note that --strict=all may include more checking types over time.
    11             Not all strictness check make sense in all circumstances, which is why these behaviors are not the
    12             defualt.
    

    jonasschnelli commented at 1:55 pm on February 21, 2020:
    Isn’t that for validation only?

    jonasschnelli commented at 2:15 pm on February 21, 2020:
    Good point. Added.

    fanquake commented at 2:22 am on February 22, 2020:
    Yes that looks correct.
  8. fanquake commented at 0:39 am on February 21, 2020: member

    Concept ACK

    Can you combine #18131 into this PR. I think it makes more sense to merge them together.

    I still like the idea of explicitly passing our entitlements to codesign, i.e --entitlements entitlements.xml using the file in #18171. That would also serve as some sort of documentation for what the defaults are, particularly for non-macOS users. However I’ll close that PR for now and we can discuss here.

  9. Add --options runtime (runtime hardening) to macOS codesign
    Runtime hardening is necessary for app notarization
    https://developer.apple.com/documentation/security/hardened_runtime
    55c089ad70
  10. jonasschnelli force-pushed on Feb 21, 2020
  11. jonasschnelli commented at 2:22 pm on February 21, 2020: contributor

    I added the --timestamp option. Made a manual test run. Could successfully notarize the dmg (see log below).

    I manually signed the newest nighly build https://bitcoin.jonasschnelli.ch/gitian/builds/22 by modifying the gitian-osx-signer.yml. All modified files are in the folder manual_notarization_test. @fanquake: Adding the -entitlements now makes little sense IMO since it would be unused (it would just contain the default values). We can always add it later.

    0          Date: 2020-02-21 14:11:11 +0000
    1          Hash: 2462d19115966e6fc6e4c7afd264e9ec389dfbcde6cb34d0b9b5ba6524d75cd4
    2    LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/84/d5/ee/84d5ee0f-e41e-29bf-4437-a3472e64a696/developer_log.json?accessKey=1582488795_6966001537870455962_Wr%2FztxOgDaSMx2v8B38P0D5i0tZW72CPjeDQ6dBVcqHi0V%2F%2BH%2FJSPK%2BC%2FHbaR7bRDf4GL4TDt1tIPMmhG6PgL4F5ehG6j80nF3HnzuHL%2FKGNALfbpotahmDjtLXsq1JVG4pSYbYgx1MO0TNnyu5dVEumhjSvwM2XyTVI%2B5qz6rU%3D
    3   RequestUUID: b4e6478d-7656-404e-9de2-411b153fe184
    4        Status: success
    5   Status Code: 0
    6Status Message: Package Approved
    
  12. jonasschnelli commented at 2:23 pm on February 21, 2020: contributor
  13. in doc/release-process.md:268 in c9954b4432 outdated
    263+
    264+```bash
    265+xcrun altool --notarize-app --primary-bundle-id "org.bitcoinfoundation.Bitcoin-Qt" -u "<code-signer-apple-developer-account-username>" -p "<password>" --file bitcoin-${VERSION}-osx.dmg
    266+```
    267+
    268+The notarizaion takes a few minutes. Check the status:
    


    fanquake commented at 0:47 am on February 24, 2020:
    nit: notarization

    jonasschnelli commented at 7:30 am on February 24, 2020:
    Thanks. Fixed.
  14. fanquake commented at 1:42 am on February 24, 2020: member

    Could successfully notarize the dmg

    To clarify; even though we upload the .dmg for notarization, we are only notarizing the .app bundle right?

    0codesign --verify bitcoin-osx-signed.dmg -v
    1bitcoin-osx-signed.dmg: code object is not signed at all
    

    For the .app bundle (after mounting the .dmg), I’m seeing:

    0codesign --verify --strict=all /Volumes/Bitcoin-Core/Bitcoin-Qt.app -v
    1/Volumes/Bitcoin-Core/Bitcoin-Qt.app: valid on disk
    2/Volumes/Bitcoin-Core/Bitcoin-Qt.app: satisfies its Designated Requirement
    
     0codesign --display /Volumes/Bitcoin-Core/Bitcoin-Qt.app -v
     1Executable=/Volumes/Bitcoin-Core/Bitcoin-Qt.app/Contents/MacOS/Bitcoin-Qt
     2Identifier=org.bitcoinfoundation.Bitcoin-Qt
     3Format=app bundle with Mach-O thin (x86_64)
     4CodeDirectory v=20500 size=195212 flags=0x10000(runtime) hashes=6093+3 location=embedded
     5Signature size=8973
     6Timestamp=21 Feb 2020 at 10:01:11 pm
     7Info.plist entries=17
     8TeamIdentifier=YZC7WH3MRU
     9Runtime Version=10.14.0
    10Sealed Resources version=2 rules=13 files=12
    11Internal requirements count=1 size=192
    
  15. jonasschnelli force-pushed on Feb 24, 2020
  16. jonasschnelli commented at 7:32 am on February 24, 2020: contributor
    @fanquake: you can’t notarize .app folders. From the docs: You can notarize an existing disk image, installer package, or ZIP archive containing your app. I think that has to do with the fact that an .app bundle is actually a folder (probably not ideal for hashing).
  17. jonasschnelli renamed this:
    Add --options runtime (runtime hardening) to macOS codesign
    Add macOS notarization (including stapling)
    on Feb 26, 2020
  18. jonasschnelli commented at 10:21 am on February 26, 2020: contributor
    I extended this patch to also include the required stapling actions.
  19. jonasschnelli force-pushed on Feb 26, 2020
  20. jonasschnelli force-pushed on Feb 26, 2020
  21. jonasschnelli commented at 11:56 am on February 26, 2020: contributor

    I tested the process described in the PRs release-notes documentation: https://bitcoin.jonasschnelli.ch/gitian/build/27 https://bitcoin.jonasschnelli.ch/gitian/builds/27/manual_notarization_plus_stapling/

    One can verify the code signature by codesign -v --strict Bitcoin-Qt.app and the notarization stapling xcrun stapler validate Bitcoin-Qt.app.

  22. Sjors commented at 12:44 pm on February 26, 2020: member

    ACK b513774304cc9d8f77d578cc62607f7733d76424. I’m able to verify the code signature and the notarisation of the example build @jonasschnelli uploaded.

    I’ll keep an eye on it during upcoming gitian releases.

    The stapled signature alleviates my privacy concerns, for now.

    In the release process, I guess this needs to be appended:

    Only once the Windows/macOS builds each have 3 matching signatures may they be signed (and notarised) with their respective release keys. If a notarized macOS build is never released, it will still be accepted by GateKeeper. If this is particularly dangerous Apple could be contacted to revoke it.


    Some useful background on what happens if a certificate is revoked. TL&DR previously stapled builds won’t be affected, thanks to the --timestamp: https://lapcatsoftware.com/articles/notarization.html

    Regarding revocation of individual tickets, Apple docs are vague:

    If you discover unauthorized versions of your software, you can work with Apple to revoke the tickets associated with those versions.

    I wonder what happens if Apple spontaneously decides, or is ordered to, revoke a notarisation ticket.

    Would users just see the same screen as they would if we don’t staple at all? Or is there a special very scary screen? I can’t find any reports of this happening in the wild. It also begs the question how macOS goes about checking if an attached staple has been revoked. It’s not clear if this gives them any more power to prevent apps from being installed, compared to when they’re not notarised.

    This stuff is surprisingly (?) poorly documented given the privacy and user autonomy implications. We should keep an eye on what happens in the wild with other apps, so we can reconsider our notarisation policy for future releases if needed.

  23. laanwj commented at 5:48 pm on February 26, 2020: member
    light code review ACK b513774304cc9d8f77d578cc62607f7733d76424, thanks a lot for working on this. Would be nice if @dongcarl or @theuni could take a look at the gitian build changes too.
  24. laanwj added this to the milestone 0.20.0 on Feb 26, 2020
  25. in doc/release-process.md:236 in b513774304 outdated
    232+    #checkout the appropriate branch for this release series
    233     rm -rf *
    234     tar xf signature-osx.tar.gz
    235     tar xf signature-win.tar.gz
    236+    #copy the notarization ticket
    237+    cp dist/Bitcoin-Qt.app/Contents/CodeResoucres osx/dist/Bitcoin-Qt.app/Contents/
    


    luke-jr commented at 7:25 pm on February 26, 2020:
    Is “resources” misspelled intentionally?

    jonasschnelli commented at 9:14 pm on February 26, 2020:
    Thanks. Fixed.
  26. in doc/release-process.md:219 in b513774304 outdated
    215+
    216+    xcrun altool --notarization-info <RequestUUID-from-notarize-app-step> -u "<code-signer-apple-developer-account-username>" -p "<password>"
    217+
    218+Staple the notarization ticket onto the application
    219+
    220+    xcrun stapler staple dist/Bitcoin-Qt.app
    


    luke-jr commented at 7:26 pm on February 26, 2020:
    Can gitian-osx-signer.yml do this, so we have gitian signatures on the final DMG?

    jonasschnelli commented at 9:18 pm on February 26, 2020:

    I don’t think so since stapler is an macOS developer tool. Unsure if this can be made portable.

    But, we have gitian signatures on the final dmg. Everything remains deterministic. It’s just the code signature and the notarization ticket that needs to be made manual and centralised. Though the notarization ticket is bound to the hash of the dmg (which is built deterministic).

    I think t is pointless for the macOS code signing key holder to notarize something else because the .dmg hash would not match and the notarization check would fail.


    luke-jr commented at 9:42 pm on February 26, 2020:
    So we’re NOT planning to upload the stapled DMG anywhere?

    jonasschnelli commented at 7:30 am on February 27, 2020:

    We do. The staple command above does create the CodeResources file (that actually contains the notarization ticket). The macOS code signer commits that file together with the code signatures. See this example: https://github.com/jonasschnelli/bitcoin-detached-sigs/tree/0.19/osx/dist/Bitcoin-Qt.app/Contents.

    The detached-sig-apply.sh takes also that CodeResource file and places it in the final deterministic created app-folder that end up in the final dmg.


    Sjors commented at 8:47 am on February 27, 2020:
    It’s a bit confusing that there are two CodeResources files, that might be worth documenting. There’s one in Bitcoin-Qt.app/Contents/ that you copy below, that’s new. And then there’s one in _CodeSignature, which is bigger.
  27. in contrib/gitian-descriptors/gitian-osx-signer.yml:15 in b513774304 outdated
    11@@ -12,6 +12,7 @@ remotes:
    12   "dir": "signature"
    13 files:
    14 - "bitcoin-osx-unsigned.tar.gz"
    15+- "signature-osx.tar.gz"
    


    luke-jr commented at 7:27 pm on February 26, 2020:
    How do we not provide this file? AFAIK anything listed here is required by gitian?

    jonasschnelli commented at 9:14 pm on February 26, 2020:
    AFAIK it only produces a warning (sha256sum: signature-osx.tar.gz: No such file or directory).
  28. add macOS notarization info to the release process doc 2b611be101
  29. gitian osx signer: add support for a local signature file 3d596b9f74
  30. jonasschnelli force-pushed on Feb 26, 2020
  31. jonasschnelli assigned theuni on Feb 26, 2020
  32. jonasschnelli unassigned theuni on Feb 26, 2020
  33. jonasschnelli requested review from dongcarl on Feb 26, 2020
  34. jonasschnelli requested review from theuni on Feb 26, 2020
  35. Sjors commented at 8:34 am on February 27, 2020: member

    @luke-jr e.a. when you extract a DMG file it creates a virtual disk volume with a couple of files that aid installation:

    Typically the user drags the Bitcoin Core.app file to the Applications symlink in order to install.

    It’s that .app file that we staple not the dmg archive. That’s all Gate Keeper cares about, because it checks when you launch the application, not during download or installation. This has the nice benefit that we get to keep the DMG deterministic.

  36. Sjors commented at 12:41 pm on February 27, 2020: member
  37. Sjors commented at 7:25 pm on February 27, 2020: member
    See IRC meeting, this probably won’t make it into v0.19.1 To preserve user privacy against Apple’s servers, I suggest that we don’t notarise the v0.19.1 release. The user will have to right-click to install, just like v0.19.0. The v0.20.0 release can have the stapled notarization, which hopefully doesn’t get sent to any server.
  38. jonasschnelli commented at 7:27 pm on February 27, 2020: contributor

    To preserve user privacy against Apple’s servers, I suggest that we don’t notarise the v0.19.1 release

    I guess users with default security settings will also face a online check even if it is not notarized? Since the notarization process does not change the binary/installer.

    Someone should really do some test in a VM when and under what settings it checks against the gatekeeper servers. Maybe I’ll find time for that soon.

  39. Sjors commented at 7:32 pm on February 27, 2020: member

    I guess users with default security settings will also face a online check even if it is not notarized? Since the notarization process does not change the binary/installer.

    That’s a good point. Maybe if it detects lack of runtime hardening it doesn’t ping the server.

    Someone should really do some test in a VM when and under what settings it checks against the gatekeeper servers.

    This would be great. If it makes no difference then we might as well notarize it.

  40. Sjors commented at 7:35 pm on February 27, 2020: member
  41. jonasschnelli commented at 10:35 am on February 28, 2020: contributor

    I just wiresharked a fresh install macOS 10.15 VM where I downloaded the notarized and stapled test build https://bitcoin.jonasschnelli.ch/gitian/builds/27/manual_notarization_plus_stapling/.

    It looks like even with stapling, there is a OSCP request going on.

    In contrast, a “right-click open” will not cause any TCP traffic.

    As for privacy (against apple), the “right-click-open” method seems to be the preferred one. Notarizing probably worsens the privacy for Bitcoin Core users.

  42. Sjors commented at 10:44 am on February 28, 2020: member

    My guess is that they’re checking to see if a previously notarized piece of software has been flagged as malware since. Which begs the question what the point of stapling is, just enabling offline installs?

    I tend to agree we should stick to “right-click-open” for the time being. But let’s leave the PR open.

  43. jonasschnelli removed this from the milestone 0.20.0 on Mar 5, 2020
  44. jonasschnelli added this to the milestone Future on Mar 5, 2020
  45. laanwj commented at 6:15 pm on March 6, 2020: member

    It looks like even with stapling, there is a OSCP request going on.

    Thanks for digging into this!

  46. jonasschnelli removed the label Needs backport (0.18) on Mar 26, 2020
  47. jonasschnelli removed the label Needs backport (0.19) on Mar 26, 2020
  48. jonatack commented at 7:26 pm on March 26, 2020: member
    Nice investigating, @jonasschnelli! I agree that sticking to the right-click-open and erring on the side of privacy is best, if we can avoid Apple phoning home, along with improving user communication/documentation in the DMG and on the website.
  49. DrahtBot added the label Needs rebase on Apr 3, 2020
  50. DrahtBot commented at 12:03 pm on April 3, 2020: member

    🐙 This pull request conflicts with the target branch and needs rebase.

  51. fanquake commented at 1:32 pm on May 2, 2020: member
    Giving that we may be doing this at some point in the future; going to close this for now.
  52. fanquake closed this on May 2, 2020

  53. fanquake deleted a comment on Dec 12, 2020
  54. DrahtBot locked this on Feb 15, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-05 22:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me