Gatekeeper 拒绝了我的应用程序包

Gatekeeper rejects my application bundle

苹果签名系统让我百思不得其解。这让我发疯。

我有一个在 macOS 10.12 上手动签名的 Qt 应用程序(因此不通过 XCode 生态系统)。

签名后,我运行 codesign --verify --deep --strict --verbose=2 PATHTOAPP 在这里推荐:https://developer.apple.com/library/content/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG211

我得到:

valid on disk satisfies its Designated Requirement

这是预期的有效结果。

当我执行 codesign -dv --verbose=4 PATHTOAPP 时,我得到:

Authority=Developer ID Application: MYAPPLEID Authority=Developer ID
Certification Authority Authority=Apple Root CA
Sealed Resources version=2

当我 运行 它针对 Apple 提供的检查签名工具时,我得到一个 YES,这意味着它已正确签名。

但是当我 运行 它针对 spctl -a -t exec -vv PATHTOAPP 我得到一个:

rejected (embedded framework contains modified or invalid version)

最后,Gatekeeper 拒绝了我的应用程序

不幸的是,spctl 实用程序没有提供有关问题所在和查看位置的线索。 我不明白,因为带有最深和最严格标志的代码设计表明没问题。

知道如何获取更多信息吗?

EDIT1: I 运行 spctl --assess --raw --verbose PATHTOAPP 我明白了:

<key>assessment:authority</key>
<dict>
    <key>assessment:authority:flags</key>
    <integer>0</integer>
    <key>assessment:authority:source</key>
    <string>obsolete resource envelope</string>
    <key>assessment:authority:weak</key>
    <true/>
</dict>
<key>assessment:cserror</key>
<integer>-67009</integer>
<key>assessment:remote</key>
<true/>
<key>assessment:verdict</key>
<false/>

现在我不知道该相信什么了,是 "embedded framework contains modified or invalid version" 还是 "obsolete resource envelope"(为什么)?

当我在这里检查错误代码时:https://github.com/CamJN/Security/blob/77b26b3e434caec74403da43bcfb02532a25d7ff/libsecurity_codesigning/lib/CSCommon.h

我明白了:

errSecCSWeakResourceRules =         -67013, /* resource envelope is obsolete */
errSecCSBadFrameworkVersion =       -67009, /* embedded framework contains modified or invalid version */

EDIT2: 确实是我的 Frameworks 文件夹的内容导致了问题。当我在签名之前删除其中的所有内容时,它通过了 spctl 验证。

问题是,如果我只使用一个单一的纯框架,例如 QtCore(来自 Qt 5.7.0),我会立即收到 spctl 错误:

rejected (embedded framework contains modified or invalid version)

原来每个框架的内容都漏掉了FRAMEWORK。framework/Versions/Current符号链接

所需的符号链接:

FRAMEWORK.framework/Resources
FRAMEWORK.framework/Versions/Current

创建这些符号链接的简单脚本(在 Frameworks 文件夹中):

find . -path '*.framework/Versions/[0-9]' -and -not -type l -print0 | while read -d $'[=11=]' FRMPATH
    do
        ln -s ${FRMPATH/*framework\//}/Resources $FRMPATH/../../Resources
        ln -s ${FRMPATH/*Versions\//} $FRMPATH/../Current
    done

我还发现了一个让 Gatekeeper 接受自签名证书的命令(当您没有 Apple Developer ID 但需要针对 spctl 进行测试时很有用):

spctl --add --requirement "certificate leaf[subject.CN] = \"MY CERTIFICATE\"" --label "MyCustomCertificate"

(其中 MY CERTIFICATE 必须替换为您自己的名称,self-signed/self-generated 证书)