Hardened Runtime appears to prevent a bundled dylib from being loaded and I would greatly appreciate some help in figuring out what to do about it. I'm not entirely sure I'm not doing this the wrong way.
Setup
My setup is not an Xcode project of any description but an executable built by the hover tool. It runs fine unsigned, with expected security alerts. I pack this build into an .app which I pack into a .dmg. I sign everything and then notarise using the command-line tools, so all of the security alarms go away and all checks pass successfully, both codesign --verify and xcrun altool --notarization-info.
The app stops loading the dylib when I sign the code with -o runtime --timestamp so that Hardened Runtime gets enabled. If I remove these build flags, I get the app blocked by security mechanisms, but it runs fine again when unblocked from the system preferences.
The dylib
The dylib in question is libcrypto.1.1.dylib from the brew version of OpenSSL.
I copy it to MyApp.app/Contents/Frameworks and change the path to the library in my main executable to @loader_path/../Frameworks/libcrypto.1.1.dylib with the install_name_tool (checked with otool -l).
Effectively, the executable points to ../Frameworks/libcrypto.1.1.dylib.
The notarisation success log says the following among other things, and gives no warnings at all:
Code Block { "path": "MyApp.dmg/MyApp.app/Contents/Frameworks/libcrypto.1.1.dylib", "digestAlgorithm": "SHA-256", "cdhash": "852834600a6f9d6b6029d479227693e8d766df61", "arch": "x86_64" }
Theories
My current theories after several hours of research are these:
Hardened Runtime doesn't like the relative path of the dylib. (How do I use an absolute one?)
Hardened Runtime doesn't like the absence of LC_VERSION_MIN_MACOSX in the dylib: otool -l shows it's not there at all. (Can I add it to an existing dylib?)
I need to actually build the library for some reason. But why would that be? It's not signed in the brew version, I sign it with my certificate.
I'm doing something wrong entirely.
It transpired the Allow Unsigned Executable Memory Entitlement is required to load the dylib the way I describe here. Why, oh, why the error message couldn't be clearer?
I found this out by trial and error after stumbling upon a thread on Github.
To sum it up, all what was required is adding the following to hardened_runtime_entitlements.plist used with codesign tool.
Code Block <key>com.apple.security.cs.allow-unsigned-executable-memory</key> <true/>
Code Block codesign \ --force \ --deep \ --verbose \ --options=runtime \ --timestamp \ --entitlements ./osx/hardened_runtime_entitlements.plist \ --sign "XXXXXXXX" MyApp.app
The rest of what I describe in this thread stayed the same and appears to work fine.
Thanks for participating!