Developer's Blog

OS X の Kernel Extension に署名する

Fenrir Advent Calendar 2015

こんにちは。無茶振りするほうのエンジニア門多です。The Go Programming Languageとどちらにするか迷ったのですが、まだ読めていないので、 Fenrir Advent Calendar 2015 の 8日目は Kernel Extension の開発ができるようになったこと、にしました。

Kernel Extension とは

ざっくりと表現すると、Mac OS X のOS そのものに機能追加を行うためのプログラムです。ターミナルで kextstat を実行すると、いま読み込まれている Extension が表示されると思います。

$ kextstat
Index Refs Address            Size       Wired      Name (Version) <Linked Against>
    1   91 0xffffff7f80a30000 0x8c50     0x8c50     com.apple.kpi.bsd (14.5.0)
    2    7 0xffffff7f80c8a000 0x28c0     0x28c0     com.apple.kpi.dsep (14.5.0)
    3  114 0xffffff7f80a03000 0x20500    0x20500    com.apple.kpi.iokit (14.5.0)
    4  123 0xffffff7f80a24000 0xbf50     0xbf50     com.apple.kpi.libkern (14.5.0)

ほとんどが Apple の Extension ですが、ドライバをインストールしている場合は、それらの Extension も入っているのではないでしょうか。Extension の実態は、以下の2箇所に .kext パッケージとして存在します。

  • /System/Library/Extensions
  • /Library/Extensions

前者が、OS が提供している Extension が含まれる場所で、後者は(おおまかには)ユーザが追加した Extension を入れる場所です。.kext パッケージは OS が自動で読み込みます。(OS 起動後に追加した Extension も都度読まれる)

Kernel Extension と署名 (Code Signing)

OS X は 10.10(Yosemite) 以降、未署名の Extension が使えなくなりましたので、すべての Extension は署名をしなければなりません。ただし、Extension 開発時に限り、以下の方法で署名がなくても動作させることができます。

$ sudo nvram boot-args='kext-dev-mode=1'
(終わったら再起動)

これはあくまで開発環境でのみ使うべきだと思います。未署名でも動くからといって、dev-mode=1 のままにしておくのはおすすめしません。

Kernel Extension を署名する

Mac OS アプリの署名には Developer ID を使いますが、購入直後は Kernel Extension の署名には使えません。Kernel Extension への署名は、Apple Developer Program を取得した後に、Apple へ申請を出して認可してもらう必要があります。

Kernel Extension に署名するまでの手続きを紹介します。あくまで今年の手続きであり、将来は変更される可能性があります。

Apple Developer Program へ登録

Apple Developer Program の「登録」ボタンから開発者登録を行います。途中で、Apple ID を持っているかどうか聞かれますので、持っていればログインし、なければその場で作成します。

Apple ID でログインができたら、登録手続きを進めましょう。個人の開発者である場合は Individual、組織の場合は Company/Organization アカウントとして登録してください。途中で、開発する予定のプラットフォーム (iOS, Mac, Safari) や、作成するアプリのジャンル、興味対象などを聞かれますが、どれを選んでも差はありません。

最後に、オンラインストアで Apple Developer Program を購入して完了です。購入完了メールはすぐに届きますが、Activation Code が届くまでにはしばらく時間がかかりますので、気長に待ちましょう。(1週間近くかかりました)

Kernel Extension の署名に失敗

この段階で、Mac アプリの署名が行えるようになります。また、Kernel Extensionの署名も見た目上は行えますし、以下の確認用コマンドもすべて成功します。

$ codesign --verify -dvvv Xxxx.kext
$ codesign --verify -vvvv Xxxx.kext
$ spctl -a -vvvv Xxxx.kext
$ kextutil -t Xxxx.kext

ですが、実際にカーネルが Extension のロードを行うと、不適切な署名として拒否されます。これは、最初にも書きましたが、Kernel Extension へ署名するには、特別な権限を付与された Developer ID を使う必要があり、Developer Programを購入しただけでは権限が与えられていないために起こります。

Kernel Extension 開発者申請

Apple が用意しているフォームを使って申請します。最初に用途を聞かれるので「Consumer or Enterprise Distribution」を選択してください。他の選択を選ぶと申請不要だとして先に進めません。その後、「Kextの配布対象者」と「申請理由」を尋ねられますが、その程度です。特に難しいことはありません。

フォームが受領されればメールが届きますが、1通目の時点ではまだ審査が行われていません。Apple の審査が完了するのを待ちましょう。(1ヶ月近くかかりました…)

審査が終わったら2通目のメールが届きます。

Kernel Extension 署名可能な証明書の取得

201512_kext

これで、Kernel Extension を署名可能な証明書が取得できるようになっています。Developer CenterのCertificates メニューから新規作成(+ボタン)し、Developer ID を選んで、新しい証明書を作成します。Developer ID のところに、 and Kernel Extension というラベルが増えていますね。

Kernel Extension 審査通過以前に取得していた Developer ID の証明書では、通過後でもKextの署名はできません。名前はまったく同じ Developer ID なのでとてもわかりづらいのですが、通過後に新しく作成したものを使えば、Xcode で Kext の署名を行うことができます。

まとめ

あまり情報がない手続きだったため苦労しましたが、Kernel Extension の開発が可能になると、やれることの幅が単純に広がるのでいいですね。Mac Developer Library から “Kernel Extension” を検索すると、まとまったドキュメントが読めますので、お楽しみください。

フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!

Copyright © 2019 Fenrir Inc. All rights reserved.