google / j2objc

A Java to iOS Objective-C translation tool and runtime.
http://j2objc.org
Apache License 2.0
5.99k stars 963 forks source link

Cannot use JRE.xcframework with Xcode 15 Release Candidate due to code signing issue #2169

Closed mungler closed 11 months ago

mungler commented 11 months ago

Hi,

We've been using JRE.xcframework for a while now, and its been working great. We note the imminent release of macOS Sonoma and Xcode 15, so decided to try building in the Xcode 15 RC. However, our app now refuses to build, with the error:

"/frameworks/JRE.xcframework:1:1 The signature of “JRE.xcframework” cannot be verified", and when clicked, offers to move it to the trash, with a further message:

"Validation Error: bundle format unrecognized, invalid, or unsuitable"

I've tried:

None of these seem to help.

I'm wondering if there's something missing from the generated xcframework bundles - i've seen reference to a Resources folder, is there perhaps some file that needs to live there?

Anyone with a better handle on this stuff able to help?

mungler commented 11 months ago

Closing in favour of #2101 - sorry, failed to notice this has been logged already. This will prevent us upgrading to Sonoma when its released later this month until its resolved.

bryan1anderson commented 11 months ago

You included a couple steps I hadn't tried yet. Thanks for this. Also have run into the same problem..

litstrong commented 11 months ago

Hi mungler@, may I ask where you see the references to the Resources folder?

mungler commented 11 months ago

Re: "Resources", i'll try to find out, sorry, I just noticed in passing when I spent most of yesterday googling on the subject. Will update here if/when I find anything concrete.

Here's the thing that makes me think the package is malformed somehow - even reading the signing info results in an error. Compare:

rory@Zaphod ~> touch foo
rory@Zaphod ~> codesign -dv foo
foo: code object is not signed at all

rory@Zaphod ~ [1]> codesign --timestamp -s "Apple Development: Rory Sinclair (99******HA)" foo
rory@Zaphod ~> codesign -dv foo
Executable=/Users/rory/foo
Identifier=foo
Format=generic
CodeDirectory v=20200 size=131 flags=0x0(none) hashes=0+2 location=embedded
Signature size=9172
Timestamp=14 Sep 2023 at 09:24:29
Info.plist=not bound
TeamIdentifier=B********5
Sealed Resources=none
Internal requirements count=1 size=168
rory@Zaphod ~> 

versus:

rory@Zaphod ~/W/j/d/frameworks (master)> codesign -dv JRE.xcframework
JRE.xcframework: bundle format unrecognized, invalid, or unsuitable
rory@Zaphod ~/W/j/d/frameworks (master) [1]> 

So it seems the codesign tool doesn't even recognise the xcframework as something that could have a signature.

PS If we're going to discuss here, I guess its worth reopening this Issue.

mungler commented 11 months ago

The thing is, the patch to gen_xcframework.sh would be trivial if the resulting framework was something that the codesign tool saw as valid. But we need to figure out why it doesn't, I guess.

mungler commented 11 months ago

Actually, thinking about it a bit more, if - like us - you embed the JRE.xcframework in an app, you can get xcode to sign it as part of the app during build. So I think its perfectly valid for such a framework to be unsigned (though of course Apple encourage developers of frameworks to sign their output, for 'supply chain security' reasons) - the problem we have is more just that the package is not considered valid by the tool. So i'm not actually certain we need to bother patching the script to get it to sign the package as part of the j2objc build itself.

TL;DR: I don't think we need to sign the package, it just needs to be in a format that the 'codesign' tool considers valid for querying and signing.

mungler commented 11 months ago

I did an experiment with our own static library project. Note that 'codesign' can both read and write the signing information:

rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound)> file liblibasw_ios.a
liblibasw_ios.a: current ar archive
rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound)> lipo -info liblibasw_ios.a
Non-fat file: liblibasw_ios.a is architecture: arm64
rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound)> xcodebuild -create-xcframework -output foo.xcframework -library liblibasw_ios.a
xcframework successfully written out to: /Users/rory/Workspace/iOS_v3/libasw_ios/2.58.3/foo.xcframework
rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound)> codesign -dv foo.xcframework
foo.xcframework: code object is not signed at all
rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound) [1]> codesign --timestamp -s "Apple Development: Rory Sinclair (9********A)" foo.xcframework
rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound)> codesign -dv foo.xcframework
Executable=/Users/rory/Workspace/iOS_v3/libasw_ios/2.58.3/foo.xcframework/Info.plist
Identifier=foo
Format=bundle
CodeDirectory v=20200 size=195 flags=0x0(none) hashes=1+3 location=embedded
Signature size=9171
Timestamp=14 Sep 2023 at 10:14:42
Info.plist entries=3
TeamIdentifier=B********5
Sealed Resources version=2 rules=10 files=1
Internal requirements count=1 size=168
rory@Zaphod ~/W/i/l/2.58.3 (sprint/greyhound)> 
bryan1anderson commented 11 months ago

Firebase had something similar. Their fix might help us figure it out. https://github.com/firebase/firebase-ios-sdk/issues/11401

mungler commented 11 months ago

Well, i've actually solved this locally for my team, and i'm working on a patch for j2objc now. Namely moving the 'Headers' folder to the root of the bundle, instead of a symlink, and ditching the Versions folder entirely. With that setup, 'codesign' now correctly identifies the bundle as unsigned:

rory@Zaphod ~/W/j/d/frameworks (asmallworld/framework_patch)> ls JRE.xcframework
Headers/                        
ios-arm64_x86_64-simulator/
Info.plist                      macos-arm64_x86_64/
ios-arm64_arm64e/               watchos-arm64_32_armv7k/
ios-arm64_x86_64-maccatalyst/   watchos-arm64_x86_64-simulator/
rory@Zaphod ~/W/j/d/frameworks (asmallworld/framework_patch)> codesign -dv JRE.xcframework/
JRE.xcframework/: code object is not signed at all
rory@Zaphod ~/W/j/d/frameworks (asmallworld/framework_patch) [1]> 
bryan1anderson commented 11 months ago

Yes that symlink and versions was the issue! @litstrong

mungler commented 11 months ago

Fixed by PR https://github.com/google/j2objc/pull/2175

litstrong commented 11 months ago

Thanks @bryan1anderson and @mungler!

Looks like it is because Apple changes how they organize the folder structure (see here). This can also be fixed by using command documented in the above to generate the XCFramework (I verified it can generate the same folder structure shown here, e.g.: without symlink on the Headers).

mungler commented 11 months ago

Fixed by PRs #2175 and #2181