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


81

最近送信した後、次のエラーが発生しました。

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

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

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

だから私はTechnote2206に従ってすべてのフレームワークバンドルに署名しました:

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

テクノテ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

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

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

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


私も以前にアプリを提出したときにこれを発見しました。ありがたいことに、Appleはそれを拒否しませんでしたが、後でフレームワークに署名する必要があると述べました。Growlのグーグルコードの問題のページに投稿する方が良いと思います。すぐに人々は同じ問題にぶつかるでしょう。
koo 2011年

2
また、Growlフレームワークを使用してアプリを送信するときに、この問題が発生しました。私はあなたがgrowl.frameworkバンドル識別子をあなたが所有するものに変更してからそれをコード署名する必要があると推測しています。
アンドリュー

これは奇妙なことです。2つのフレームワーク(CorePlotとMacRuby)を含むアプリを公開しましたが、どちらも署名されていません。アプリバンドルでコード署名コマンドを実行したのは1回だけで、フレームワークに関するコメントなしでアプリが受け入れられました。アプリバンドル(bit.ly/charterapp)を見ると、両方のフレームワークが署名されているように見えます。アプリ全体に署名するだけでしたか?
p4010 2011年

@ p4010、私はしました-彼らは以前は署名されていませんでした。たとえば、Growlは、彼らが配布する単なるバンドルでした。今、私はしばらくの間このアプリを店に持っていたので、これは新しいサンドボックスのものと関係があると思います。アプリを提出したのはいつですか?
csexton 2011年

@Andrew、バンドル識別子の変更はあなたのために働きましたか?
csexton 2011年

回答:


45

baptrの回答に基づいて、すべてのフレームワークとその他のバイナリリソース/補助実行可能ファイル(現在サポートされているタイプ:dylib、bundle、loginアイテム)をコード署名するこのシェルスクリプトを開発しました。

#!/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. 「埋め込みフレームワークのコピー」ビルドフェーズの直後に「スクリプトの実行」ビルドフェーズを追加します。
    • これは「CodesignEmbeddedFrameworks」と呼ぶことができます。
  3. ./codesign-frameworks.shスクリプトエディタのテキストフィールドに(または上記のスクリプトと呼んだものを)貼り付けます。./Scripts/codesign-frameworks.shスクリプトをサブディレクトリに保存する場合に使用します。
  4. アプリを作成します。バンドルされているすべてのフレームワークはコード署名されます。

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

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

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

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

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

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

2014年6月28日更新:実験的なバンドルサポートの追加。

更新された2014-08-22:コードを改善し、IFSの復元の失敗を防ぎます。

2014年9月26日更新:ログイン項目のサポートを追加。

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

更新された2014-11-07:Xcodeで自動ID解決を使用する場合のあいまいなIDエラー(「Mac開発者:あいまい…」など)の解決。IDを明示的に設定する必要はなく、「MacDeveloper」を使用するだけです。

2015年8月7日更新:セマンティクスの改善。

改善を歓迎します!


これに感謝しますが、注意点ですが、ターゲットの名前にスペースが含まれていると機能しません。修正しようとしましたが、動作させることができなかったため、ターゲットを変更しました。
クレイグ

FRAMEWORK_DIRの名前にスペース/特殊文字が含まれている場合に機能するはずです。
JanX2 2012

ただし、codesignコマンドの最後に「--timestamp」を追加して、タイムスタンプオプションを無効にする必要もありました。
エルマーキャット

面白い。@Elmer Catは、たまたま、リリースされていないバージョンのOS Xでこれを行っていますか?マニュアルページでは、「システム固有のデフォルトの動作」を持つこのオプションについて説明しています。
JanX2 2013

1
Elmer Cat-実行しているXcodeのバージョンはわかりませんが、5.0.1を使用しており、フレームワークに自動的に署名していません。このスクリプトを見つけるまで、私は髪を引き裂いていました。
ブライアン

11

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

以下は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

4

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

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

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


3
夢の世界では「-deep」は期待どおりに機能しますが、私たちは夢の世界に住んでいません...
マイク

0

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

私はここでより拡張された答えを提供しました:サンドボックス化されたMacアプリのためにGrowl.frameworkを共同設計する方法

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.