Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Signing Not Working for AdditionalAppExtensions #15598

Closed
adam-russell opened this issue Jul 31, 2022 · 10 comments · Fixed by #15829
Closed

Code Signing Not Working for AdditionalAppExtensions #15598

adam-russell opened this issue Jul 31, 2022 · 10 comments · Fixed by #15829
Assignees
Labels
iOS Issues affecting Xamarin.iOS msbuild Issues affecting our msbuild tasks/targets regression The issue or pull request is a regression
Milestone

Comments

@adam-russell
Copy link

Steps to Reproduce

NativeExtensionEmbedding.zip

  1. Download solution attached NativeExtensionEmbedding.zip
  2. Unzip solution file
  3. Update Native and Managed apps with valid provisioning profiles
  4. Run dotnet tool restore in the NativeExtensionEmbedding directory
  5. Run dotnet cake --target=PublishIPA
  6. In the IPA that's now in AppPackages/ManagedContainer.ipa, unzip it and look at Payload/ManagedContainer.app/PlugIns/NativeTodayExtension.appex, and see there's no _CodeSignature at all

Expected Behavior

There is a code signature for NativeTodayExtension.appex inside the IPA

Actual Behavior

The IPA itself is signed, but NativeTodayExtension.appex is not signed. This worked correctly with Xamarin.iOS 15.8.0.5. It is broken with Xamarin.iOS 15.10.0.5 (unless I'm doing something wrong)

Environment

Version information
Visual Studio Community 2022 for Mac
Version 17.0.7 (build 7)
Installation UUID: e414baf3-158a-4f60-baf1-f1796b783205

Runtime
.NET 6.0.5 (64-bit)
Architecture: Arm64

Roslyn (Language Service)
4.1.0-3.22075.3+592501cbb9c9394072a245c15b3458ff88155d85

NuGet
Version: 6.0.0.262

.NET SDK (Arm64)
SDK: /usr/local/share/dotnet/sdk/6.0.302/Sdks
SDK Versions:
	6.0.302
	6.0.301
	6.0.300
	6.0.203
	6.0.202
	6.0.201
	6.0.200
MSBuild SDKs: /Applications/Visual Studio.app/Contents/MonoBundle/MSBuild/Current/bin/Sdks

.NET SDK (x64)
SDK Versions:
	3.1.421
	3.1.420
	3.1.419

.NET Runtime (Arm64)
Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
	6.0.7
	6.0.6
	6.0.5
	6.0.4
	6.0.3
	6.0.2

.NET Runtime (x64)
Runtime: /usr/local/share/dotnet/x64/dotnet
Runtime Versions:
	3.1.27
	3.1.26
	3.1.25

Xamarin.Profiler
Version: 1.8.0.19
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

Updater
Version: 11

Apple Developer Tools
Xcode 13.4.1 (20504)
Build 13F100

Xamarin.Mac
Version: 8.10.0.5 (Visual Studio Community)
Hash: 96b3edb6d
Branch: d17-2
Build date: 2022-05-18 07:32:06-0400

Xamarin.iOS
Version: 15.10.0.5 (Visual Studio Community)
Hash: 96b3edb6d
Branch: d17-2
Build date: 2022-05-18 07:32:07-0400

Xamarin Designer
Version: 17.1.5.90
Hash: 53f47efde
Branch: remotes/origin/d17-0-vsmac
Build date: 2022-07-20 22:42:03 UTC

Xamarin.Android
Version: 12.3.3.3 (Visual Studio Community)
Commit: xamarin-android/d17-2/4e061b7
Android SDK: /Users/adamrussell/Library/Developer/Xamarin/android-sdk-macosx
	Supported Android versions:
		12.0 (API level 31)
		8.1  (API level 27)
		11.0 (API level 30)
		10.0 (API level 29)
		9.0  (API level 28)

SDK Command-line Tools Version: 5.0
SDK Platform Tools Version: 31.0.3
SDK Build Tools Version: 30.0.3

Build Information: 
Mono: dffa5ab
Java.Interop: xamarin/java.interop/d17-2@9760f0a9
ProGuard: Guardsquare/proguard/v7.0.1@912d149
SQLite: xamarin/sqlite/3.38.2@7b1e016
Xamarin.Android Tools: xamarin/xamarin-android-tools/d17-2@fc3c2ac

Microsoft Build of OpenJDK
Java SDK: /Library/Java/JavaVirtualMachines/microsoft-11.jdk
11.0.12
Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

Eclipse Temurin JDK
Java SDK: /Library/Java/JavaVirtualMachines/temurin-8.jdk
1.8.0.302
Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

Android SDK Manager
Version: 17.2.0.37
Hash: 7f5a6ef
Branch: remotes/origin/d17-2
Build date: 2022-07-20 22:42:07 UTC

Android Device Manager
Version: 0.0.0.1116
Hash: e47e6c8
Branch: remotes/origin/d17-2
Build date: 2022-07-20 22:42:07 UTC

Build Information
Release ID: 1700070007
Git revision: 5a924af5432fc0ed4adc294eb2edb6a95c97cf2e
Build date: 2022-07-20 22:39:54+00
Build branch: release-17.0
Build lane: release-17.0

Operating System
Mac OS X 12.5.0
Darwin 21.6.0 Darwin Kernel Version 21.6.0
    Sat Jun 18 17:05:47 PDT 2022
    root:xnu-8020.140.41~1/RELEASE_ARM64_T8101 arm64

Build Logs

buildlogs.zip

I ran the same Cake script with Xamarin.iOS 15.8.0.5, then immediately after with 15.10.0.5. 15.8.0.5 produces the correct results, 15.10.0.5 does not.

I've included build logs in this zip for both.

GOOD_Xamarin_iOS_15.8.0.5.binlog

and

BAD_Xamarin_IOS_15.10.0.5.binlog

Example Project (If Possible)

NativeExtensionEmbedding.zip

Additional Details

I ran into this a few days ago when I updated a production build to use Xamarin.iOS 15.10.0.5 without any other major changes, and was initially confused when it started getting rejected by TestFlight/AppStoreConnect.

I tried to make this example as close to possible to the test app that's in this repo:
https://github.com/xamarin/xamarin-macios/tree/main/tests/common/TestProjects/NativeExtensionEmbedding
The only changes were to use distribution provisioning profiles (changing the bundle identifiers slightly so I could use some with real provisioning profiles), changing the managed app to use a release build, and adding the build.cake script at the top level so you can see my build.

I used a distribution cert to make sure it's closer to a real example (sorry, that probably means you need to change the associations on your own machine to actually build the sample).

Hopefully I'm just missing something in the way code signing works now, as it looks to have been rewritten. It looks like a bug to me, though.

(I'm not very familiary with MSBuild, but maybe in Target -> _CollectCodeSigningData, the paths should resolve as those within the IPA folders after the appex has ben copied rather than the original build outputs? I could be completely off, though, since I don't quite follow how the new codesigning flow works.)

@chamons
Copy link
Contributor

chamons commented Aug 2, 2022

I can confirm this, using cake to build the native component and VSfM to build the managed (just to confirm it wasn't introduced by cake).

codesign --verify --verbose managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app/PlugIns/NativeTodayExtension.appex 
managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app/PlugIns/NativeTodayExtension.appex: invalid resource directory (directory or signature have been modified)

From reading my local build log it appears we are copying the extension in, removing it's code signature, but not resigning it locally.

You could work around this by manually invoking the codesign command first on the extension and then again on your application, like this (but with the arguments from your build log):

codesign -v --force --timestamp=none --sign C386F1974736B0EF9202C122B59CA5BDB0D2A10F --entitlements /Users/donblas/Downloads/NativeExtensionEmbedding/managed/ManagedContainer/obj/iPhone/Debug/Entitlements.xcent managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app/PlugIns/NativeTodayExtension.appex
codesign -v --force --timestamp=none --sign C386F1974736B0EF9202C122B59CA5BDB0D2A10F --entitlements /Users/donblas/Downloads/NativeExtensionEmbedding/managed/ManagedContainer/obj/iPhone/Debug/Entitlements.xcent /Users/donblas/Downloads/NativeExtensionEmbedding/managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app

Which seems to work for me:

% codesign --verify --verbose managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app/PlugIns/NativeTodayExtension.appex
managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app/PlugIns/NativeTodayExtension.appex: valid on disk
managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app/PlugIns/NativeTodayExtension.appex: satisfies its Designated Requirement
 % codesign --verify --verbose managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app                                   
managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app: valid on disk
managed/ManagedContainer/bin/iPhone/Debug/ManagedContainer.app: satisfies its Designated Requirement

@chamons chamons added iOS Issues affecting Xamarin.iOS regression The issue or pull request is a regression msbuild Issues affecting our msbuild tasks/targets labels Aug 2, 2022
@chamons chamons added this to the Future milestone Aug 2, 2022
@chamons
Copy link
Contributor

chamons commented Aug 2, 2022

I suspect this has the same refactoring root cause as #15594

@adam-russell
Copy link
Author

Thanks for confirming @chamons

Yes, it does work fine for me as a workaround to manually code sign extensions then the app -- just less convenient.

@adam-russell
Copy link
Author

Just in case it helps anyone else who runs into this issue: I'm using fastlane to resign the IPA now, just because it'll resign an IPA in place and is more convenient that writing a shell script to do it.

Here's what I'm doing (and this seems to be fine with packages submitted to TestFlight):

I downloaded provisioning profile files and put them in a Provisioning Profiles folder.

Then I created a fastlane folder under the path where I was going to run the command, then added a Fastfile inside that folder with contents something like this (obviously adjusted to actual values and actual app extensions):

lane :do_resign do
resign(
  ipa: "AppPackages/YourIpaName.ipa",
  signing_identity: "Apple Distribution: Name Here (ABCDE12345)",
  provisioning_profile: {
    "com.yourcompany.appname" => "Provisioning Profiles/AppName.mobileprovision",
    "com.yourcompany.appname.widget" => "Provisioning Profiles/Widget.mobileprovision",
    "com.yourcompany.appname.intentsextension" => "Provisioning Profiles/Intents_Extension.mobileprovision",
    "com.yourcompany.appname.watchkitapp.watchkitextension" => "Provisioning Profiles/WatchKit_Extension_Provisioning_Profile.mobileprovision",
    "com.yourcompany.appname.watchkitapp" => "Provisioning Profiles/Watch_Provisioning_Profile.mobileprovision"
  }
)
end

Then you can run the command fastlane do_resign

@JeroenBer
Copy link

I am having the same issues now I moved to VS 2022. Using Xamarin.iOS 15.12.0.2.

Can this be fixed ?

@rolfbjarne
Copy link
Member

Can this be fixed ?

Yes, I'm working on fixing it. However, I can't promise any dates yet.

@JeroenBer
Copy link

O that would be great, will the fix also apply to the current Xamarin version ? (Not .NET 7) ?

@chamons
Copy link
Contributor

chamons commented Aug 26, 2022

Until we know the size of the fix (because it is fixed) it will be guessing at this point how risky it would be to backport.

@adam-russell
Copy link
Author

Thanks for fixing @rolfbjarne! Your PR works well for my app, and App Store Connect accepts the package fine after your changes.

@rolfbjarne
Copy link
Member

@adam-russell great, thanks for confirming!

rolfbjarne added a commit that referenced this issue Sep 7, 2022
…to sign. Fixes #15598. (#15829)

* Add additional app extensions to the list of items we need to sign.
* Improve msbuild test for additional app extensions:
    * Build for both device and simulator.
    * Hopefully fix the signing problems that occurred on the bots last time we tried.
    * Assert that both the container and extension are signed during the build when we build for device.

A 10-line fix with 3300 lines of tests...

Fixes #15598.
@ghost ghost locked as resolved and limited conversation to collaborators Oct 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS Issues affecting Xamarin.iOS msbuild Issues affecting our msbuild tasks/targets regression The issue or pull request is a regression
Projects
None yet
4 participants