DerekCook / CoreMidi4J

Core MIDI Service provider Interace (SPI) for Java 1.7 and above on OS X
Eclipse Public License 1.0
55 stars 15 forks source link

Unable to notarize app that uses this library #45

Open mrlimbic opened 2 years ago

mrlimbic commented 2 years ago

I am trying to notarize an app but it is failing on use of this library.

I assume the previous step (signing all the dylibs & executables in the jars by jpackage) couldn't sign this one like it has managed to do for other library jars. However signing doesn't produce an error.

Any ideas why this library might be different?

  "issues": [
    {
      "severity": "error",
      "code": null,
      "path": "Vordio-6.4.1859.dmg/Vordio.app/Contents/app/libs/coremidi4j-1.6.jar/uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib",
      "message": "The binary is not signed with a valid Developer ID certificate.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "Vordio-6.4.1859.dmg/Vordio.app/Contents/app/libs/coremidi4j-1.6.jar/uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "x86_64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "Vordio-6.4.1859.dmg/Vordio.app/Contents/app/libs/coremidi4j-1.6.jar/uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib",
      "message": "The binary is not signed with a valid Developer ID certificate.",
      "docUrl": null,
      "architecture": "arm64"
    },
    {
      "severity": "error",
      "code": null,
      "path": "Vordio-6.4.1859.dmg/Vordio.app/Contents/app/libs/coremidi4j-1.6.jar/uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib",
      "message": "The signature does not include a secure timestamp.",
      "docUrl": null,
      "architecture": "arm64"
    }
DerekCook commented 2 years ago

Hi,

I am having the same issue in that I am looking to notarize my software (have signed up and am paying Apple their $$$$s) and Jpackage does not seem to sign native code extensions within Jars

I have done a little hack locally for now to prove the issue is resolvable by inflating the jar, manually code signing the CoreMIDI4J dylib file and then re-compressing the zip and renaming it to jar.

All a bit of a faf, but this modified Jar allowed the notarize process to succeed following rerunning JPackage and the notarize process.

The next step is to look at signing the CoreMIDI4J download when it is rebuilt. This is something James and I were discussing a month or so back as, ideally, I need James's experience having already set this up for his projects (rather than me figuring it from scratch myself, but life has gotten in the way as usual.

Anyhow, I am happy to look into this as it is something we need to do, but I will wait a few days to see if James can help out first as we discussed.

In the meantime, I could make my temp solution available as a temporary download to see if that gets you going.

brunchboy commented 2 years ago

I unfortunately don’t have a ton of time to spare on this right now, my own projects are needing more attention than I have time for, but I am successfully able to code-sign and notarize Beat Link Trigger, which embeds CoreMIDI4J. There is a GitHub Action workflow which does this whenever I push commits to the main branch, perhaps you can find the pieces you are missing in there? For building the Mac signed and notarized disk image a script file is used.

mrlimbic commented 2 years ago

Luckily I could just exclude this library for now as the sys ex midi is only used in a hidden pre-release feature that most people won't even see.

Let me know when the reason for this is understood and fixable.

Thanks.

BTW If it helps the jpackage signing only really works well enough on latest java 18 releases. There were a lot of fixes (such as unsigning everything before signing it). This particular midi library problem was the last issue I found. It might be worth talking to the jpackage people. They may have an idea why it fails. In theory jpackage should go into the jar then unsign/resign any dylibs but for some reason with this one it can't.

brunchboy commented 2 years ago

@mrlimbic this is likely to be understood and fixable more quickly if you can dig in and understand and fix it and submit a pull request. Both Derek and I are quite busy with other projects that use CoreMidi4J, and we are currently able to sign our applications when we need to, so if you need a change here, I’d encourage you to see if you can figure out what it needs to be.

mrlimbic commented 2 years ago

OK I'll report it to jpackage people. It is probably a bug in that.

DerekCook commented 2 years ago

Thanks James, I will take a look when I can.

In the meantime, this is what I have done as a short term measure, not only for CoreMIDI4J but also some other jar files I have where there are dylib files in them and notarization fails. For example nrjavaserial that provides a comms library that I need for accessing an Ardiono based device via a USB hosted serial port.

So, I have a "code signing area that has coremidi4j-1.6.jar in it, and I have also extracted the dylib as a relative path under that.

So, under my code signing area I have

coremidi4j-1.6.jar , and uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib (extracted from coremidi4j-1.6.jar) entitlements.plist

entitlements.plist has the following content

<?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.app-sandbox</key> <false/> <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-executable-page-protection</key> <true/> <key>com.apple.security.cs.disable-library-validation</key> <true/> <key>com.apple.security.cs.allow-dyld-environment-variables</key> <true/> <key>com.apple.security.device.audio-input</key> <true/> </dict> </plist>

In OSX terminal, cd to the code signing area and run the following command to sign the dylib

codesign --force --timestamp --options runtime --verbose=4 --entitlement /entitlements.plist --prefix <<YOUR SIGNING PREFIX>> --sign "<<YOUR DEVELOPER ID>>" uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib

This will codesign the dylib

You can check the code signing working by running the following

codesign -dvv native/osx/libNRJavaSerial.jnilib

Add add the signed dylib back into the jar using the following

jar uf coremidi4j-1.6.jar uk/co/xfactorylibrarians/coremidi4j/libCoreMidi4J.dylib

And then use this modified jar file in your package being built by JPackage, and when you notarize the software it should now pass the notarization

mrlimbic commented 2 years ago

OK. If I understand that correctly my issue issue was not declaring the "audio input" entitlement so midi works. jpackage is only supplying the basic set for general jvm requirements. If so that makes sense. jpackage allows you to supply a different entitlements file with an extra setting so I'll try that.

DerekCook commented 2 years ago

I am not certain. I just picked this up from an example James shared. It would be interesting if that solves it.

brunchboy commented 2 months ago

Somehow the notarization tool decided to be pickier for me today too, and this became one of about four binaries in my Beat Link Trigger jar that were no longer acceptable for notarization. I ended up adding a build stage to explode the jar, code-sign all of them with my own developer account, then recreate the jar, and that seems to be working. Extracting and updating just the four problem files would probably have been more efficient, but I didn’t revisit this discussion until after I had it working.

DerekCook commented 2 months ago

Somehow the notarization tool decided to be pickier for me today too, and this became one of about four binaries in my Beat Link Trigger jar that were no longer acceptable for notarization. I ended up adding a build stage to explode the jar, code-sign all of them with my own developer account, then recreate the jar, and that seems to be working. Extracting and updating just the four problem files would probably have been more efficient, but I didn’t revisit this discussion until after I had it working.

OK. I think it was something we were going to look at in terms of could it be done on my Apple Developer account, which I had to get to get my software past Gatekeep as it has become more overzealous over the years. But the trail went cold. Happy to resurrect but I need to know what you have done. Or if you have it working, so long as one of us is building it so it is code signed, it doesn't really matter who does it. Although I guess it would be ideal to get to the stage that either of us could upload and it gets code signed.

Let me if you wish to push further on this, or are happy with how things are for now, and maybe something to pick up when a little more time allows (e.g. over a break period when I tend to have more time these days)

brunchboy commented 2 months ago

The way things stand is that I am able to fix the signature when my own application that embeds it is being built by Github Actions, but everyone else who wants to use it (and publish an application that uses it) will need to figure out how to apply a similar fix.

It won’t make that much difference to me personally if we can fix that, because I still have to fix three other libraries that I embed anyway, and I don’t have any leverage with them nor expectation that they are likely going to get signed. So the incremental lift of signing CoreMidi4J in my continuous integration pipeline is minimal.

But it would certainly be nice to other people if you could get this signed by the build process on GitHub Actions whenever commits are pushed to the main branch, the way I do with Beat Link Trigger. If you’d like to attempt that, you can examine my workflow and build script if that would be helpful, and I would be happy to answer any questions about how they work.

brunchboy commented 2 months ago

Note that a lot of the workflow is more complex and unrelated to your needs, the part that deals with building the signed disk image is the short cluster of six lines that start here. We could do something similar to pass in the necessary secrets for the library to get code signed as it is built (but there would not be a need to put it in a disk image, I would not think).

DerekCook commented 1 month ago

Note that a lot of the workflow is more complex and unrelated to your needs, the part that deals with building the signed disk image is the short cluster of six lines that start here. We could do something similar to pass in the necessary secrets for the library to get code signed as it is built (but there would not be a need to put it in a disk image, I would not think).

Thanks, James.

I would like to crack this once and for all using my Apple Developer account, but as ever I am stupidly busy and do not right now want to get diverted from updating montage.factory for the new Yamaha Montage M in what spare time I do have for programming.

So I have put this task into my build backlog, and I will tackle it once I have achieved a montage.factory release - likely to be later in the year. I will of course reach out if I have issues and of course to update you on progress.