Codesign signs my framework as a directory. Why? - ios

I have troubles with the code signing.
I am trying to codesign a framework and use the following command in my script
codesign --verbose --force --sign $(EXPANDED_CODE_SIGN_IDENTITY) $<TARGET_FILE_DIR:${app}>/Frameworks/${fw}.framework
Fo some reasons, that I can't understand, I have my framework signed as a directory
When I do codesign -vvv myLibrary.framework, everything is reported as properly signed, but later when I try to load the framework with dlopen, I see the error that signature is incorrect.
Why do I have it signed as directory ?
Thanks for any ideas.

Found the problem. Info.plist should specify executable and it was not set correctly. It was set to the directory name basically.
So, signcode signs everything as directory.

Related

Does codesign sign apps recursively by default?

I am doing some build-script archaeology and we have a fairly complex build in which we remove code signatures using codesign --remove so we can remove architectures using lipo.
In the end the app is signed like this (I see it in the log):
codesign --force -s DeveloperIDCertificate --keychain pathToKeychain YourApp.app
My question is: Is this a recursive operation? We are not using --deep, but perhaps it's deep by default when signing the whole .app?
It is not recursive.
And documentation says to avoid using --deep and that it is better to iterate through the files yourself.
See: https://developer.apple.com/forums/thread/128166 under the Sign Your Code section.

dylib Library not loaded due to restricted binary after apple code signing

I put a executable binary XXX in my app works on MacOS ,and code sign it. My app will use this service through port.
Executable binary XXX will register a service through plist file after install my app , plist file contains DYLD_LIBRARY_PATH which tells executable binary where to find the dylib to use.
launchctl load -wF "$HOME/Library/LaunchAgents/local.plist"
launchctl start local
Here is the problem:
it worked fine after i build a app.
but when i signed it all and notarized, then open my app to use ,it would get errors as follow:
dyld: Library not loaded: ##HOMEBREW_PREFIX##/opt/libev/lib/libev.4.dylib
Referenced from: /Users/buffer/Library/Application Support/XXX
Reason: unsafe use of relative rpath ##HOMEBREW_PREFIX##/opt/libev/lib/libev.4.dylib in /Users/buffer/Library/Application Support/XXX with restricted binary
It will use default dylib path(##HOMEBREW_PREFIX##/opt/libev/lib/libev.4.dylib) that comes from executable binary XXX, not my custom DYLD_LIBRARY_PATH. Apple has restricted binary use such unsafe relative rpath.
Updated:
My app will start a shell script to install executable binary XXX and dylib ,
Executable binary XXX will register as a service to start and stop through plist as below
launchctl load -wF "$HOME/Library/LaunchAgents/local.plist"
launchctl start local
My executable binary XXX path and DYLD_LIBRARY_PATH both located at /Users/buffer/Library/Application Support/myApp/*** , it start separately as a service for my app to use.
I have found some situations below:
1.I have a same executable binary XXX signed at 2018-09-25 , it works fine.
2.And executable binary XXX that have not been signed worked fine too.
3.But when i have signed executable binary XXX now and use it with dylib , it will get errors above.
So ,whether apple sign algorithm has changed and make this error occurs ?
here is my code sign command for now as below:
codesign --force --options runtime --sign "Developer ID Application: ****" XXX
Finally:
I have found problem,
Apple require developer enable Hardened runtime for every app to notrize now. if you enable Hardened runtime but not specify entitlements , then some permissions will be disabled as default .
My permission for use DYLD Environment Variables has been disabled as default
you can check this document below
Hardened Runtime Entitlements
If you customize code sign workflow like me , you can specify entitlements when you codesign as below,entitlements.plist contains permissions you want enable
codesign --force --options runtime --entitlements /Users/buffer/Desktop/entitlements.plist --sign "Developer ID Application: ****" XXX
As of macOS 10.10.4, for security reasons, you are not allowed to use a dylib outside the directories that Apple deems as secure as, for example:
/System/
/usr/bin/
/Library/Frameworks/
The code signing documentation entitled "Checking Gatekeeper Conformance" expressly states that:
Beginning with macOS 10.10.4, Gatekeeper verifies that no libraries are loaded from outside an app bundle. If an app uses #rpath or an absolute path to link to a dynamic library outside of the app, Gatekeeper rejects the app. This restriction applies to the app’s main executable and any other executable in the bundle, including libraries. This restriction applies even if the path does not exist (which normally causes the dynamic linker to fall back to a library inside the bundle). The error will appear in the system log, with a message like the following for an app MyApp.app trying to link against the library libLibrary.dylib in the nonstandard location /foo
Thus, you should embed your dylib inside your application.
Apparently, another possible solution is to use a signed installer to install a common framework at /Library/Frameworks/, but this solution was offered by DTS, and is apparently not part of the official documentation.
I learned from Apple DTS that there is a known bug in macOS Catalina 10.15.3 and earlier (already fixed in 10.15.4 beta) wherein a notarized command line app that links against a .dylib outside of its bundle (and command line apps are typically not in a bundle) will still fail Gatekeeper checks that trigger when the quarantine flag is set on the command line executable.
To workaround the problem, Apple DTS recommends:
The easiest workaround is to sign your tool with both the hardened runtime and library validation flags.
That is, change your invocation of codesign from this:
% codesign -s …stuff… -o runtime …stuff… helloworld
to this:
% codesign -s …stuff… -o runtime,library …stuff… helloworld
Explicitly setting the library flag disables this Gatekeeper check and allows your tool to run on macOS 10.15.{0,1,2,3}. Please make a note to remove this flag once 10.15.4 is released and widely adopted.

Unable to archive project

I am unable to archive my Swift project. When it's archiving, it fails at 90% of the progress. Showing the following error.
The project runs well in the simulator and on my device. But suddenly i am getting this error when archiving... It all worked well before.. Does anyone have any idea?
I got this problem with cocoapods, you should edit the file "YourTarget-framework.sh" in Pods > Target Support Files > Pods-Your Target.
You need to locate this line:
local code_sign_cmd="/usr/bin/codesign --force --sign {EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1""
Replace it by :
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '"$1"'"
The path to the binary contains spaces ([...]/ArchiveIntermediates/Trusti - Release/[...]). This should be the problem. The error message displays the path cut before the first space.
I think you should use another product name, and adapt it in InfoPlist.strings if necessary.

Jenkins succeeds without producing IPA file

I have setup an mac mini slave on jenkins. The build process succeeds and my .app file and .dysm files etc are all created successfully.
I have Pack application and build .ipa? checked and defined a ipa filename pattern and an output directory.
When I run the build process, it actually creates the full path of my output directory, but at the end of the path, there is nothing in the final folder. No IPA. Again, the .app and other files are created successfully in the workspace build folder.
Also doesn't work if I leave the output directory blank or change it to other locations.
Jenkins succeeds with this message:
** BUILD SUCCEEDED **
Cleaning up previously generated .ipa files
Cleaning up previously generated .dSYM.zip files
Packaging IPA
Finished: SUCCESS
But alas, no IPA. Any ideas?
I was not able to solve the issue directly, so I am still interested in answers from someone who might have a more direct solution using the Xcode plug in with the pack and build ipa option.
Instead, I removed this option (unchecked it) and added another build phase for execute shell script.
I then added the script from this SO answer (modified for my use) and was able to export the ipa successfully.
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" -o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" --sign "${DEVELOPER_NAME}" --embed "${PROVISONING_PROFILE}"
RELEASE_BUILDDIR and BUILD_HISTORY_DIR were changed to my own paths, and -sign and -embed were not needed because i'm using the same profile as the one that created the original .app file
I did have to use mkdir -p to make the path or it wouldn't succeed for me
So I was having the same problem and this is how I solved it:
In the Jenkins job, in the configure interface, under Advanced Xcode build options, I specified a Build output directory: ${WORKSPACE}/builds.
I also added a shell script to execute prior to the Xcode build phase:
mkdir -p "${WORKSPACE}/builds"
Now when I click the check box for "Pack application and build .ipa?", specify a .ipa filename pattern and use the output directory: ipa , the job runs, succeeds, and gives me a .ipa I can see in the Workspace at /builds/ipa/{name}.ipa
I hope this helps.
Had exactly the same problem as you.
Besides "Pack application and build .ipa", you also have to check "Unlock Keychain?" which can be found at "Code signing & OS X keychain options".
Furthermore, set the keychain path to:
${HOME}/Library/Keychains/login.keychain
The keychain password for me was the same as my user password. If you leave that field empty, you will see that your build freezes at a certain point. Inside the terminal where you started jenkins, you will see that it waits for you to type the password.
Hope it helped.

Codesign returned 1 (object ifile format invalid or unsuitable) bug

I'm working with Xcode 4.1 build 4B110f trying to get my iOS app ready for upload. It passes the Product|Archive step with no errors, asking twice for permission to sign something. But when I try a validate of the archive from the Organizer, it fails:
### Codesigning '/Users/uqrchern/Library/MobileDevice/Provisioning Profiles/70D2381D-3733-4F5D-88B2-4729572C2864.mobileprovision' with 'iPhone Distribution: Ron Chernich'
+ /usr/bin/codesign --force --preserve-metadata --sign iPhone Distribution: Ron Chernich --resource-rules=/var/folders/ul/ula1AHKnGpqQ9ftDnUL-l++++TM/-Tmp-/rybczU3EBd/Payload/ABRA-D.app/ResourceRules.plist --entitlements /var/folders/ul/ula1AHKnGpqQ9ftDnUL-l++++TM/-Tmp-/rybczU3EBd/entitlements_plistrZ1Vwko6 /var/folders/ul/ula1AHKnGpqQ9ftDnUL-l++++TM/-Tmp-/rybczU3EBd/Payload/ABRA-D.app
Program /usr/bin/codesign returned 1 : [/var/folders/ul/ula1AHKnGpqQ9ftDnUL-l++++TM/-Tmp-/rybczU3EBd/Payload/ABRA-D.app: replacing existing signature
/var/folders/ul/ula1AHKnGpqQ9ftDnUL-l++++TM/-Tmp-/rybczU3EBd/Payload/ABRA-D.app: object file format invalid or unsuitable
]
error: codesign failed with error 1
I've looked at all the similar problems and solutions (some of which make no sense whatever, or apply to really old versions of the tools). None have made the slightest difference.
I've also checked 3 times that verify is using the "production" certificate, as is the codesign step that produces the archive. I've even turned the above output into a schell script so I could try all certificates manually: same result every time.
Maybe the .app file being signed really is unsuitable?
Incidentally, codesign has no version flag, but the man page is dated June 1 2006. The binary has a file date of Nov 20 2010.
UPDATE (next day):
Researching the problem further found an obscure reference saying that codesign needs the following environment var set:
CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
Using the output from a failed Validate run, I created a shell script which exported this var just before the failing codesign --force step and viola! The codesign works.
But this does not really help me prepare my code for upload. Is there a way to include this into the script run by the Organizer Validate button??
A LITTLE LATER STILL, THE SOLUTION! :
Under the theory there is a script someplace which generates all the commands run during an Organizer Validate... run, I did some digging with grep and find. The script indeed exists and it's name is:
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication
It's just Perl and the fix is to add the required environment var to the associative array %ENV right at the start, say at line 72:
$ENV{CODESIGN_ALLOCATE} = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate';
This totally fixes the problem. I've no idea where all the other posters on the web who think they fixed it by combinations of deleting certificates, building clean, shutting down and restarting Xcode, etc, etc are coming from. I'll just quietly assert that this fix favors science over superstition and works for me under Xcode 4.1 Build 4B110f and its associated PackageApplication script, running under Snow Leopard 10.6.8 with Perl 5.10.0
Just so that this can be taken off the unanswered list. Like you said, you need to add CODESIGN_ALLOCATE to the $ENV array:
$ENV{CODESIGN_ALLOCATE} = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate';
If everyone is in agreement here, I think this question can finally be closed.
When using a more recent version of Xcode, the default location is:
$ENV{CODESIGN_ALLOCATE} = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate';
In case you get this on a recent version of Xcode, what you actually want is, in the shell:
export CODESIGN_ALLOCATE=`xcode-select -print-path`/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
which will use the codesign_allocate from the version of Xcode you are using.
You can update the version of Xcode the command line tools use by running xcode-select -switch
I had this workaround in place for a long time, but after upgrading to Xcode 4.3 with iOS 5.1 SDK, my signing script (which calls codesign) stopped working with a cannot find code object on disk error:
output/Enterprise/Payload/MyProduct.app/MyProduct: replacing invalid existing signature
output/Enterprise/Payload/MyProduct.app/MyProduct: cannot find code object on disk
Code signing failed, not creating .ipa file
It seems this workaround isn't necessary for binaries built with Xcode 4.3. To fix, I updated my bash script to check if the location exists before exporting it:
# Only export the environment variable if the location exists,
# otherwise it breaks the signing process!
if [ -f "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate" ]
then
echo Export environment variable for codesign_allocate location
export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
fi

Resources