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

Broken signature when embedding helper app inside main app bundle. #15594

Closed
snechaev opened this issue Jul 29, 2022 · 4 comments · Fixed by #15894
Closed

Broken signature when embedding helper app inside main app bundle. #15594

snechaev opened this issue Jul 29, 2022 · 4 comments · Fixed by #15894
Assignees
Labels
bug If an issue is a bug or a pull request a bug fix regression The issue or pull request is a regression
Milestone

Comments

@snechaev
Copy link
Contributor

snechaev commented Jul 29, 2022

Steps to Reproduce

  1. Grab solution attached signTest1.zip
  2. Build in a Release configuration with VS Mac or with msbuild /p:Configuration=Release -bl ./signTest1.sln
  3. Run terminal and go to the main/bin/Release folder
  4. Run the following commands and check the output
codesign --verify --verbose ./Main.app
codesign --verify --verbose ./Main.app/Contents/SharedSupport/helper.app

Expected Behavior

(See Additional details section below for some details about what I'm trying to do here)

Both Main.app and embedded ./Main.app/Contents/SharedSupport/helper.app are signed correctly, so output should be

>codesign --verify --verbose ./Main.app
./Main.app: valid on disk
./Main.app: satisfies its Designated Requirement

>codesign --verify --verbose ./Main.app/Contents/SharedSupport/helper.app
./Main.app/Contents/SharedSupport/helper.app: valid on disk
./Main.app/Contents/SharedSupport/helper.app: satisfies its Designated Requirement

The Main.app as a whole should be able to pass Apple's notarizatoin.

Actual Behavior

The signature of helper.app is broken due to the changed files inside the app bundle

> codesign --verify --verbose ./Main.app
./Main.app: valid on disk
./Main.app: satisfies its Designated Requirement

> codesign --verify --verbose ./Main.app/Contents/SharedSupport/helper.app
./Main.app/Contents/SharedSupport/helper.app: a sealed resource is missing or invalid
file modified: /Users/sergey/work/signTest1/main/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libMonoPosixHelper.dylib
file modified: /Users/sergey/work/signTest1/main/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libmono-native.dylib

If we send Main.app to the notarization, we will got the error about this broken signature.

Additionally, if we check the signature of the helper.app in the it's original location helper/bin/Release then we got correct signature

> codesign --verify --verbose ../../../helper/bin/Release/helper.app
../../../helper/bin/Release/helper.app: valid on disk
../../../helper/bin/Release/helper.app: satisfies its Designated Requirement

Environment

Version information

Problem can be reproduced on VS mac 2022 (full detail below) and on latest VS mac 2019.

Visual Studio Professional 2022 for Mac
Version 17.0.7 (build 7)
Installation UUID: 20bbd9a3-604d-4dc4-a548-0bb1d566d971

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

Roslyn (Language Service)
4.1.0-3.22075.3+592501cbb9c9394072a245c15b3458ff88155d85

NuGet
Version: 6.0.0.262

.NET SDK (x64)
SDK: /usr/local/share/dotnet/sdk/6.0.302/Sdks
SDK Versions:
	6.0.302
	3.1.421
MSBuild SDKs: /Applications/Visual Studio.app/Contents/MonoBundle/MSBuild/Current/bin/Sdks

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

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

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 Professional)
Hash: 96b3edb6d
Branch: d17-2
Build date: 2022-05-18 07:32:06-0400

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

Xamarin.Android
Not Installed

Microsoft Build of OpenJDK
Java SDK: Not Found

Eclipse Temurin JDK
Java SDK: Not Found

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

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

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

Operating System
Mac OS X 12.4.0
Darwin 21.5.0 Darwin Kernel Version 21.5.0
    Tue Apr 26 21:08:22 PDT 2022
    root:xnu-8020.121.3~4/RELEASE_X86_64 x86_64

Build Logs

msbuild.binlog.zip

Example Project (If Possible)

signTest1.zip

Additional details

I need to embedded helper application (helper.app) inside my main application appbundle. And all this should be signed to be able to pass notarization process.
To do so, I do the following

  • configured both projects (helper & main) to sign app bundle with appropriate apple certificates
  • added additional targets into the main.csproj to copy ready-to-use (built and signed) helper.app from helper/bin/Relese into the SharedSupport folder inside the main.app appbundle.
  • the mentioned targets is called before signing main.app appbundle.

The solution is based on this sample https://github.com/xamarin/mac-samples/tree/main/UseMSBuildToCopyFilesToBundleExample.

The part added into the 'main.csproj' is following

    <ItemGroup>
        <LibProject Include="$(SolutionDir)/helper/helper.csproj"/>
    </ItemGroup>

    <Target Name="GetBundleFiles" Outputs="@(LibContentFiles)">
        <MSBuild Projects="@(LibProject)" Targets="Build">
        </MSBuild>

        <ItemGroup>
            <LibContentFiles Include="$(SolutionDir)/helper/bin/Release/helper.app/**/*.*;" />
        </ItemGroup>

        <PropertyGroup>
            <BasePath>$(SolutionDir)helper/bin/Release</BasePath>
        </PropertyGroup>

        <ItemGroup>
            <!--Path inside app bundle -->
            <LibContentFileTargetPath Include="@(LibContentFiles-&gt;Replace($(BasePath), $(AppBundleDir)/Contents/SharedSupport/))" />
        </ItemGroup>

        <Message Text="$(BasePath)" />
        <Message Text="$(AppBundleDir)" />
        <Message Text="@(LibContentFiles)" />
        <Message Text="@(LibContentFileTargetPath)" />
    </Target>

    <PropertyGroup>
        <CreateAppBundleDependsOn>$(CreateAppBundleDependsOn);GetBundleFiles;CopyOurFiles;</CreateAppBundleDependsOn>
    </PropertyGroup>

    <Target Name="CopyOurFiles" Inputs="@(LibContentFiles)" Outputs="@(LibContentFileTargetPath)">
        <Copy SourceFiles="@(LibContentFiles)" DestinationFiles="@(LibContentFileTargetPath)" />
    </Target>

This solution worked fine for a long time in VS219, but stopped worked in the latest VS2019 build and in VS2022.

For me this issue is critical as I can't build a release of my app. And I also can't downgrade VS as there is no links for older versions available.

Update: problem is also reproducible for net6 sdk-style project. The workaround mentioned below is also works in such a case.

@chamons
Copy link
Contributor

chamons commented Jul 29, 2022

The way you are doing this looks it should work, and I believe it used to (since I personally wrote that sample).

The problem is that the msbuild that did signing was rewritten and is getting confused:

The stamp file 'obj/Release/codesign/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libMonoPosixHelper.dylib' does not exist, so the item '/Users/donblas/Downloads/signTest1/main/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libMonoPosixHelper.dylib' needs to be codesigned. (TaskId:184)
The stamp file 'obj/Release/codesign/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libmono-native.dylib' does not exist, so the item '/Users/donblas/Downloads/signTest1/main/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libmono-native.dylib' needs to be codesigned. (TaskId:184)
The stamp file 'obj/Release/codesign/bin/Release/Main.app/Contents/MonoBundle/libMonoPosixHelper.dylib' does not exist, so the item '/Users/donblas/Downloads/signTest1/main/bin/Release/Main.app/Contents/MonoBundle/libMonoPosixHelper.dylib' needs to be codesigned. (TaskId:184)
The stamp file 'obj/Release/codesign/bin/Release/Main.app/Contents/MonoBundle/libmono-native.dylib' does not exist, so the item '/Users/donblas/Downloads/signTest1/main/bin/Release/Main.app/Contents/MonoBundle/libmono-native.dylib' needs to be codesigned. (TaskId:184)
The stamp file 'bin/Release/Main.app/Contents/_CodeSignature/CodeResources' does not exist, so the item '/Users/donblas/Downloads/signTest1/main/bin/Release/Main.app' needs to be codesigned. (TaskId:184)

and is assuming that you have obj files that match the files you have copied in.

When @rolfbjarne returns from vacation he can comment on if this still is the best way to add files, but until then you can hack around by adding these two lines to your CopyOurFiles target:

        <WriteLinesToFile File="$(IntermediateOutputPath)/codesign/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libMonoPosixHelper.dylib" Lines="" Overwrite="True"/>
        <WriteLinesToFile File="$(IntermediateOutputPath)/codesign/bin/Release/Main.app/Contents/SharedSupport/helper.app/Contents/MonoBundle/libmono-native.dylib" Lines="" Overwrite="True"/>
% codesign --verify --verbose main/bin/Release/Main.app/Contents/SharedSupport/helper.app
main/bin/Release/Main.app/Contents/SharedSupport/helper.app: valid on disk
main/bin/Release/Main.app/Contents/SharedSupport/helper.app: satisfies its Designated Requirement
% codesign --verify --verbose main/bin/Release/Main.app/                                 
main/bin/Release/Main.app/: valid on disk
main/bin/Release/Main.app/: satisfies its Designated Requirement

@chamons chamons added this to the Future milestone Jul 29, 2022
@snechaev
Copy link
Contributor Author

Thank you! I can confirm that workaround works perfectly and I was able to adapt it to the production project build process.

@Jon2G
Copy link

Jon2G commented Aug 20, 2022

Works for me too!
Thank you so much, wish i have seen this before wasted so much time.

@rolfbjarne rolfbjarne modified the milestones: Future, .NET 7 Aug 25, 2022
@rolfbjarne rolfbjarne added the bug If an issue is a bug or a pull request a bug fix label Aug 31, 2022
@rolfbjarne
Copy link
Member

We recently rewrote our codesigning logic, and an assumption was made that we should sign every *.dylib in the app bundle (because otherwise Apple will reject any app submissions).

Unfortunately we didn't include any way to opt out of this new behavior, so I'll have to implement that.

@rolfbjarne rolfbjarne added the regression The issue or pull request is a regression label Aug 31, 2022
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Sep 7, 2022
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Sep 7, 2022
…to be signed. Fixes xamarin#15594.

Add support for two new MSBuild item groups:

* CodesignBundle: lists additional app bundles inside the main bundle which should
  be signed (typically manually copied into the app bundle by the developer).
* SkipCodesignItems: lists files we'd sign by default, but which shouldn't be signed.

Fixes xamarin#15594.
@ghost ghost locked as resolved and limited conversation to collaborators Oct 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug If an issue is a bug or a pull request a bug fix regression The issue or pull request is a regression
Projects
None yet
4 participants