« ^ »

macOSにインストールしたプログラムをコード署名する

所要時間: 約 4分

macOSでgdbを使うとすると以下のエラーが出ることがある。

Starting program: /srv/aee369d717aea571e8360afd3741432d/main.out
Unable to find Mach task port for process-id 18347: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))

これはgdbがコード署名されてないためにエラーが発生している。codesignとはソフトウェアに対する署名に関連する操作を行うコマンドで、macOSではセキュリティ上の理由から署名されていないソフトウェアによるデバッグ操作(プロセスへのアタッチ)を禁止している。

野良ビルドされたプログラムを配布させ、セキュリティ的な問題を発生させないようにする対応という事だろうか。Appleが認証したアプリケーションしか使えないようにする対応に思えなくもない。今回はgdbを自己署名証明書を使ってコード署名していく。

コード署名されているか確認する

コード署名されているかどうかは codesign コマンドを用いて確認できる。

$ codesign -vv /usr/local/bin/gdb
/usr/local/bin/gdb: code object is not signed at all
In architecture: x86_64

上記の例ではgdbにコード署名されているかどうかを確認している。

/usr/local/bin/gdb: code object is not signed at all

とある通りコード署名されていないことがわかる。

homebrewなどでインストールしたgdbはコード署名されていない。 そのためgdbを使うためにはインストールした後、コード署名をしなければならない。

macOSのキーチェーンアクセスで自己署名証明書を作成する

コード署名を行うには証明書が必要になる。 今回は個人的に使うだけの証明書なので自己証明書として作成する。

証明書の作成ダイアログを開く

キーチェーンアクセスのメニューから証明書の作成ダイアログを開く。

./img-open-keychain-access.png

証明書の値を設定する

作成する署名書の値を設定する。今回の証明書の名前は gdb-cert とする。

名称備考
名前gdb-certこの値は好きな値で良い
固有名のタイプ自己署名ルート
証明書のタイプコード署名
デフォルトを無効化ONチェックを入れる
./img-create-cert-01.png

設定ができたら 続ける をクリックする。

./img-create-cert-02.png

証明書のシリアル番号と有効期限

証明書のシリアル番号と有効期限を設定する。今回は10年にしたが本来はもっと短い値にした方が良い。

./img-create-cert-03.png

証明書の個人情報

証明書に使用される個人情報を入力する。今回は自分で使うだけなのですべて省略した。

./img-create-cert-04.png

鍵ペア情報

鍵のサイズとアルゴリズムを選択する。個人用の証明書なのでデフォルトの値(2048ビット/RSA)を使うことにした。

./img-create-cert-05.png

鍵用途拡張領域

鍵の使用用途を制限できる。今回はソフトウェア署名したいだけなので署名に関連するものをチェックした。

./img-create-cert-06.png ./img-create-cert-07.png ./img-create-cert-08.png ./img-create-cert-09.png

保存場所

キーチェーンの保存場所を選択する。 システムでも良かったが、自分だけが使う端末にインストールしたソフトウェア署名用なので ログイン を選択した。

./img-create-cert-10.png

完了

すべての設定が終わると自己証明書が作成される。

./img-create-cert-11.png

自己証明書を信頼する

作成した自己証明書を証明するものはない。 このような自作の証明書を使うためには、作成した自己証明書を 信頼する ようにキーチェーンアクセス上から設定変更する。

./img-create-cert-12.png

変更時にはパスワードの入力が求められる。

./img-create-cert-13.png

gdbをコード署名する

先ほど作成した自己証明書を用いてgdbをコード署名する。

次のようなXMLを作成する。

<?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.debugger</key>
    <true/>
  </dict>
</plist>

このファイルと codesign コマンドを用いてコード署名を実行する。

$ codesign --entitlements ./gdb-entitlement.xml -fs gdb-cert /usr/local/bin/gdb

成功すると何も表示されない。 もしエラーが出る場合はコード署名に失敗する場合を参考にしてもらいたい。

コード署名に失敗する場合

コード署名のコマンドを実行すると errSecInternalComponent というエラーが表示された。

$ codesign --entitlements gdb-entitlement.xml -fs gdb-cert /usr/local/bin/gdb
/usr/local/bin/gdb: errSecInternalComponent
$ echo $?
1

色々な原因が考えられるが、今回は秘密鍵へのアクセス制御が原因だった。 秘密鍵へのアクセス制御が アクセスを許可する前に確認 という設定になっていた。 この設定を この項目の使用をすべてのアプリケーションに許可 に変更した。

./img-change-key-access.png

コード署名できたかを確認する

codesign でコード署名ができたかを確認する。

$ codesign -vv /usr/local/bin/gdb
/usr/local/bin/gdb: valid on disk
/usr/local/bin/gdb: satisfies its Designated Requirement

/usr/local/bin/gdb: valid on disk

とある通り、署名できていることがわかる。

その他

ほとんど同じような内容ではあるが、野良ビルドしたEmacsを署名する手順について、Emacsをコード署名する / macOSにインストールしたEmacsからマイクにアクセスするに記載した。