web-dev-qa-db-ja.com

Mac App Storeのフレームワークバンドルをどのようにコード署名しますか?

最近の提出後、次のエラーが表示されました。

無効な署名-ネストされたアプリバンドル(FooBar.app/Contents/Frameworks/GData.framework)が署名されていないか、署名が無効であるか、Apple送信証明書で署名されていません。参照詳細については、コード署名およびアプリケーションサンドボックスガイドをご覧ください。

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

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

そこで、 Technote 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

Technote 2206のコメント:

署名フレームワーク

フレームワークがバンドルであると考えると、フレームワークに直接署名できると結論付けることは論理的に思えます。ただし、そうではありません。フレームワークに署名する際の問題を回避するには、フレームワーク全体ではなく特定のバージョンに署名するようにしてください。

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

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

楽しみのために、フレームワークバンドルに直接署名してみましたが、まだ拒否されました。しかし、それはまさに文書がしないと言ったことです。

なぜそれが無効とみなされるのでしょうか?アプリのコード署名に使用するのと同じ証明書を使用しています。これは過去に機能した証明書です。

私の唯一の推測は、既存のリスト(フレームワークのInfo.plistsで識別子を所有する必要がありますか)または資格-何か提案がありますか?

80
csexton

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. アプリをビルドします。バンドルされているすべてのフレームワークはコード署名されます。

それでも「Identity:あいまいな(一致:…」エラーが発生する場合は、以下にコメントしてください。これはもう起こらないはずです。

2012-11-14の更新:名前に特殊文字を含むフレームワーク(これには一重引用符は含まれません)のサポートを「codesign-frameworks.sh」に追加します。

2013-01-30更新:「codesign-frameworks.sh」へのすべてのパスでの特殊文字のサポートの追加(これには一重引用符が含まれている必要があります)。

2013-10-29更新:実験的dylibサポートの追加。

2013-11-28更新:資格サポートの追加。実験的なdylibサポートの改善。

2014年6月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更新:セマンティクスの改善。

改善を歓迎します!

41
JanX2

コメントには、バンドルのバージョンディレクトリ内のオブジェクトに署名したことが示されています。 Technoteは、ディレクトリ自体に署名することを示します。

以下は、Technoteによりよく一致します。

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

これは私がそれを修正した方法です。

  • ターゲットのビルド設定に入ります
  • 「その他のコード署名フラグ」という行にFing
  • リリースパラメータに-deep valueを入力します
  • XCodeを閉じる
  • Macの派生データフォルダーに入り、古い派生データを削除します(デフォルトパスは/ Users/YOUR_USER_NAME/Library/Developer/Xcode/DerivedData)
  • Xcodeを開いてビルドする

ビルドアーカイブの後、アプリを再度送信します...

3
emreoktem

ここで言及されていないことの1つは、バージョン管理されたフレームワークディレクトリ内の/ Resources内にInfo.plistが必要であるということです。そうしないと、バージョン付きディレクトリに署名しようとすると、「バンドル形式が認識されない、無効、または不適切」というエラーが表示されます。

私はここでより詳細な回答を提供しました: Sandboxed Mac AppのGrowl.frameworkを共同設計する方法

0
Ross Bencina