1. ホーム
  2. xcode

[解決済み] Mac App Store用のフレームワークバンドルはどのようにコードサインするのですか?

2023-08-28 08:09:03

質問

最近投稿した後、以下のエラーが発生しました。

無効な署名 - ネストされたアプリバンドル (FooBar.app/Contents/Frameworks/GData.framework) は署名されていないか、署名が無効であるか、Apple のサブミッション証明書を使用して署名されていません。詳細については、『コードサイニングとアプリケーションサンドボックスガイド』を参照してください。

無効な署名 - ネストされたアプリバンドル (FooBar.app/Contents/Frameworks/Growl.framework) は、署名されていないか、署名が無効であるか、または Apple の提出証明書と署名されていません。詳細については、「コードサイニングとアプリケーションサンドボックスガイド」を参照してください。

無効な署名 - ネストされたアプリバンドル libcurl (FooBar.app/Contents/Frameworks/libcurl.framework) は署名されていないか、署名が無効であるか、Apple提出の証明書と署名されていません。詳細については、『コードサイニングとアプリケーションサンドボックスガイド』を参照してください。

というわけで、すべてのフレームワークバンドルに テクノート 2206 :

codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libcurl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./libcurl.framework/Versions/A/libssh2.1.dylib
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./Growl.framework/Versions/A/Growl
codesign -f -v -s "3rd Party Mac Developer Application: Name" ./GData.framework/Versions/A/GData

Technote2206にはこうあります。

<ブロッククオート

署名のフレームワーク

フレームワークがバンドルであることから、フレームワークに直接署名できると結論づけるのは論理的であるように思われます。しかし、これは事実ではありません。フレームワークに署名するときに問題を避けるために、フレームワーク全体ではなく、特定のバージョンに署名することを確認してください。

# これは間違った方法です。

codesign -s my-signing-identity ../FooBarBaz.framework です。

# これが正しい方法です。

codesign -s my-signing-identity ../FooBarBaz.framework/Versions/A

そして、その結果を検証してみると、私には良いように見えます。

% codesign -vvv FooBar.app/Contents/Frameworks/libcurl.framework
FooBar.app/Contents/Frameworks/libcurl.framework: valid on disk
FooBar.app/Contents/Frameworks/libcurl.framework: satisfies its Designated Requirement
% codesign -vvv FooBar.app/Contents/Frameworks/Growl.framework
FooBar.app/Contents/Frameworks/Growl.framework: valid on disk
FooBar.app/Contents/Frameworks/Growl.framework: satisfies its Designated Requirement

面白半分に、フレームワークのバンドルに直接署名してみましたが、やはり拒否されました。しかし、これはまさにドキュメントに書かれていることを実行してはいけないということです。

なぜそれが無効と見なされるのか、何か推測できますか?私は、自分のアプリにコード署名するために使用するのと同じ証明書を使用しています。

私の唯一の推測は、既存の plists (フレームワークの Info.plists で識別子を所有する必要がありますか?) またはエンタイトルメントに関係する何かでしょう -- 任意の提案?

どのように解決するのですか?

baptrの回答に基づいて、私はすべての私のフレームワークと他のバイナリリソース/補助実行ファイル(現在サポートされているタイプ:dylib、バンドル、およびログインアイテム)を符号化するこのシェルスクリプトを開発しました。

#!/bin/sh

# WARNING: You may have to run Clean in Xcode after changing CODE_SIGN_IDENTITY! 

# Verify that $CODE_SIGN_IDENTITY is set
if [ -z "${CODE_SIGN_IDENTITY}" ] ; then
    echo "CODE_SIGN_IDENTITY needs to be set for framework code-signing!"

    if [ "${CONFIGURATION}" = "Release" ] ; then
        exit 1
    else
        # Code-signing is optional for non-release builds.
        exit 0
    fi
fi

if [ -z "${CODE_SIGN_ENTITLEMENTS}" ] ; then
    echo "CODE_SIGN_ENTITLEMENTS needs to be set for framework code-signing!"

    if [ "${CONFIGURATION}" = "Release" ] ; then
        exit 1
    else
        # Code-signing is optional for non-release builds.
        exit 0
    fi
fi

ITEMS=""

FRAMEWORKS_DIR="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [ -d "$FRAMEWORKS_DIR" ] ; then
    FRAMEWORKS=$(find "${FRAMEWORKS_DIR}" -depth -type d -name "*.framework" -or -name "*.dylib" -or -name "*.bundle" | sed -e "s/\(.*framework\)/\1\/Versions\/A\//")
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        exit 1
    fi

    ITEMS="${FRAMEWORKS}"
fi

LOGINITEMS_DIR="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems/"
if [ -d "$LOGINITEMS_DIR" ] ; then
    LOGINITEMS=$(find "${LOGINITEMS_DIR}" -depth -type d -name "*.app")
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        exit 1
    fi

    ITEMS="${ITEMS}"$'\n'"${LOGINITEMS}"
fi

# Prefer the expanded name, if available.
CODE_SIGN_IDENTITY_FOR_ITEMS="${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
if [ "${CODE_SIGN_IDENTITY_FOR_ITEMS}" = "" ] ; then
    # Fall back to old behavior.
    CODE_SIGN_IDENTITY_FOR_ITEMS="${CODE_SIGN_IDENTITY}"
fi

echo "Identity:"
echo "${CODE_SIGN_IDENTITY_FOR_ITEMS}"

echo "Entitlements:"
echo "${CODE_SIGN_ENTITLEMENTS}"

echo "Found:"
echo "${ITEMS}"

# Change the Internal Field Separator (IFS) so that spaces in paths will not cause problems below.
SAVED_IFS=$IFS
IFS=$(echo -en "\n\b")

# Loop through all items.
for ITEM in $ITEMS;
do
    echo "Signing '${ITEM}'"
    codesign --force --verbose --sign "${CODE_SIGN_IDENTITY_FOR_ITEMS}" --entitlements "${CODE_SIGN_ENTITLEMENTS}" "${ITEM}"
    RESULT=$?
    if [[ $RESULT != 0 ]] ; then
        echo "Failed to sign '${ITEM}'."
        IFS=$SAVED_IFS
        exit 1
    fi
done

# Restore $IFS.
IFS=$SAVED_IFS

  1. プロジェクト内のファイルに保存します。私は自分のコピーを Scripts サブディレクトリに保存しています。
    • 私のは codesign-frameworks.sh .
  2. 組み込みフレームワークのコピー」ビルドフェーズの直後に、「スクリプトの実行」ビルドフェーズを追加します。
    • Codesign Embedded Frameworks」と呼ぶことができます。
  3. 貼り付け ./codesign-frameworks.sh (をスクリプトエディタのテキストフィールドに貼り付けてください。使用方法 ./Scripts/codesign-frameworks.sh を使用します。
  4. アプリをビルドします。バンドルされているすべてのフレームワークがコード化されます。

まだ、" アイデンティティ : あいまい (matches: ..." というエラーが発生する場合は、以下のコメントをお願いします。もうこのようなことは起こらないはずです。

2012-11-14 更新。codeign-frameworks.sh "に、名前に特殊文字(シングルクォートを含まない)を含むフレームワークのサポートを追加しました。

2013-01-30更新。codesign-frameworks.sh "に全てのパスの特殊文字をサポートするようにしました(これはシングルクォートを含むはずです)。

2013-10-29更新。実験的なdylibのサポートを追加しました。

2013-11-28に更新しました。エンタイトルメントサポートを追加。実験的なdylibのサポートを改善しました。

2014-06-13に更新しました。(ネストされた) フレームワークを含むフレームワークのコードサイン問題を修正。これは、フレームワークに -depth オプションに find というオプションがあり、これによって find が深さ優先の探索をするようになります。これが必要になったのは の問題で必要になりました。 . 要するに、内包するバンドルは、そのネストしたバンドルがすでに署名されている場合にのみ署名することができるのです。

2014-06-28 に更新しました。実験的なバンドルサポートを追加しました。

2014-08-22更新:コードの改善とIFSの復元に失敗しないようにしました。

2014-09-26に更新しました。ログイン項目への対応を追加。

2014-10-26に更新しました。ディレクトリのチェックを引用する。これにより、特殊文字を含むパスに対する「31/42行目:引数が多すぎる」エラーと、その結果発生する「コードオブジェクトが全く署名されていない」エラーが修正されました。

2014-11-07に更新しました。Xcode で自動 ID 解決を使用する場合のあいまいな ID エラー (「Mac Developer: ambiguous ...」など) を解決します。もう明示的に ID を設定する必要はなく、「Mac Developer」でいいんです!

更新 2015-08-07: セマンティクスを改善しました。

改善歓迎です。