can't codesign the .app file using Visual Studio for Mac

I'm developing a C sharp application in Visual Studio for Mac.
I have it set up to be signed with a developer ID signature to get it notarized by Apple.
But it's not working.

Here are the steps.

(1). Sign the code using Visual Studio for Mac.
(2). However, this .app file will crash.
(3). When I create a dmg and request notarization with the xcrun altool command, I get the following error.
Code Block
{
"logFormatVersion": 1,
"jobId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "Invalid",
"statusSummary": "Archive contains critical validation errors",
"statusCode": 4000,
"archiveFilename": "MyApp.dmg",
"uploadDate": "2020-08-18T08:29:55Z",
"sha256": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"ticketContents": null,
"issues": [
{
"severity": "error",
"code": null,
"path": "MyApp.dmg/MyApp.app/Contents/MonoBundle/SQLite.Interop.dll",
"message": "The signature of the binary is invalid.",
"docUrl": null,
"architecture": "x86_64"
}
]
}


Even if this succeeds, it won't matter because it will crash...
Thinking that SQLite.Interop.dll was the cause, I signed the code directly after step (1) and it started successfully.

Code Block
$ codesign --force --verify --verbose \
--sign "Developer ID Application: MyCompany (XXXXXXXXX)" \
"SQLite.Interop.dll" \
--deep \
--options runtime \
--timestamp

However, requesting a notarization with the xcrun altool command returns an error like this:
Code Block
{
"logFormatVersion": 1,
"jobId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"status": "Invalid",
"statusSummary": "Archive contains critical validation errors",
"statusCode": 4000,
"archiveFilename": "MyApp.dmg",
"uploadDate": "2020-08-18T08:29:55Z",
"sha256": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"ticketContents": null,
"issues": [
{
"severity": "error",
"code": null,
"path": "MyApp.dmg/MyApp.app/Contents/MacOS/MyApp",
"message": "The signature of the binary is invalid.",
"docUrl": null,
"architecture": "x86_64"
}
]
}

I thins this is due to a change in the signature of the dependency SQLite.Interop.dll, which has resulted in an incorrect signature in MyApp.
How can I solve this?

Here's what I've already tried.
  • Manually sign MyApp.dmg/MyApp.app/Contents/MacOS/MyApp again.

  • Sign SQLite.Interop.dll manually before the procedure (1).

Here is some information that will assist
  • Settings for signing .csproj files

Code Block
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<EnableCodeSigning>true</EnableCodeSigning>
<CreatePackage>false</CreatePackage>
<EnablePackageSigning>false</EnablePackageSigning>
<IncludeMonoRuntime>true</IncludeMonoRuntime>
<UseSGen>true</UseSGen>
<UseRefCounting>true</UseRefCounting>
<LinkMode>SdkOnly</LinkMode>
<AOTMode>None</AOTMode>
<CodeSigningKey>Developer ID Application: MyCompany (XXXXXXXXXXX)</CodeSigningKey>
<PackageSigningKey>3rd Party Mac Developer Installer</PackageSigningKey>
<UseHardenedRuntime>true</UseHardenedRuntime>
<CodeSignEntitlements>Entitlements.plist</CodeSignEntitlements>
<CodeSignExtraArgs>--deep</CodeSignExtraArgs>
</PropertyGroup>

  • Entitlements.plist

Code Block
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
</dict>
</plist>


I'm using SQLite.Interop.dll in System.Data.SQLite.Core, which I got from NuGet.
Code Block
packages/System.Data.SQLite.Core.1.0.111.0/runtimes/osx-x64/native/netstandard2.0/SQLite.Interop.dll

I'm developing a C# application in Visual Studio for Mac.

To start, don’t use --deep. See --deep Considered Harmful for an explanation as to why. Rather, you should sign each code item separately, from the inside out.

Also, you need to think carefully about your code nesting. Contents/MonoBundle/ is not a valid code nesting site. A better choice would be Contents/Frameworks/. See the Nested Code section of Technote 2206 macOS Code Signing In Depth

I think the above two points will get you heading in the right direction. Beyond that I recommend that you read through Signing a Mac Product For Distribution. It has a bunch of detailed info on this process.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thanks for your answer.

I understood that Contents/MonoBundle/ is not a valid code nesting site.
However, Visual Studio for Mac uses this directory and there seems to be no way to change it.
Is there a way to change this directory to Contents/Frameworks/ or is there another solution?

or is there another solution?

Adopt a tool that actually follow the rules? (-:

Seriously though, if your third-party tool breaks the rules by default, you should definitely file a bug against it. It’s not like TN2206 is a new document.

Anyway, the standard way to work around problems like this is to put the code item in the correct place and replacing it with a relative symlink. I discuss this concept in the Use Symlinks to Deal with Alien Structures section of my Signing a Mac Product For Distribution post.

If that doesn’t work, putting code in a non-code site is not a complete showstopper, but you don’t to make sure that you sign the code correctly before signing the bundle in which it’s nested (which --deep won’t do for you).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I took care of these points.
  • not using the --deep option.

  • Place only the code items in Contents/Frameworks and create Symlink to Contents/Frameworks in Contents/MonoBundle

There were various files under the Contents/MonoBundle, and I used the otool -h -v command to investigate whether the file was a Mach-O object or not.
Then I moved the file to Contents/Frameworks and created Symlink to Contents/Frameworks in Contents/MonoBundle.

At this point, the app will launch normally.
Then I signed it with the following command.
Code Block
codesign -v --force --timestamp --sign [signature code] \
/path/to/solution_directory/MyApp/bin/Release/MayApp.app/Contents/Frameworks/SQLite.Interop.dll

Code Block
codesign -v --force --timestamp --sign [signature code] \
/path/to/solution_directory/MyApp/bin/Release/MayApp.app/Contents/Frameworks/libmono-native.dylib

Code Block
codesign -v --force --timestamp --sign [signature code] \
/path/to/solution_directory/MyApp/bin/Release/MayApp.app/Contents/Frameworks/libMonoPosixHelper.dylib

Code Block
codesign -v --force -o runtime --timestamp --sign [signature code] \
--entitlements /path/to/solution_directory/MyApp/obj/Release/Entitlements.xcent \
/path/to/solution_directory/MyApp/bin/Release/MayApp.app


But when I try to run the application, it crashes.
This is the crash log.
Code Block
~
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [20121]
VM Regions Near 0:
-->
__TEXT 000000010005b000-0000000100479000 [ 4216K] r-x/r-x SM=COW /Users/USER/*/MyApp.app/Contents/MacOS/MyApp
~


Is there something wrong with it?

I took care of these points.

Cool.

Is there something wrong with it?

Well, clearly (-:

Can you post the full crash report? Use a text attachment (the paperclip icon) so it doesn’t bloat the timeline.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Can you post the full crash report? Use a text attachment (the paperclip icon) so it doesn’t bloat the timeline.

Thank you for your kindness... This is the full crash report.


Consider this:

Code Block
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY


It indicates that your code crashed by dereferencing a NULL pointer. And this:

Code Block
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 … mono_arch_create_sdb_trampoline + 122 (*****-amd64.c:860)
1 … mini_get_breakpoint_trampoline + 60 (mini-trampolines.c:1701)
2 … mono_arch_init + 22 (mini-amd64.c:1435)
3 … mini_init + 746 (mini-runtime.c:4244)
4 … mono_main + 6052 (driver.c:2610)
5 … xamarin_main + 1116 (launcher.m:674)
6 … main + 36 (launcher.m:693)
7 … start + 1


This shows that your code actually started running and then crashed in the Mono runtime. I’ve crashes like this before and, as far as I know, they’re caused by an incompatibility between the Mono runtime and the hardened runtime that Apple requires on all notarised apps. There is almost always a way around this — by setting various hardened runtime exception entitlements — but the exact steps depend on how the Mono runtime is failing.

My advice is that you try setting the com.apple.security.cs.allow-jit entitlement. That should be sufficient for Mono to run. If that doesn’t work, you should talk to the Mono folks.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
I was able to launch the app.
Thank you so much for your thoughtful answers!

I will ask questions here if I get a chance to do so again.
can't codesign the .app file using Visual Studio for Mac
 
 
Q