ドライバーのデジタル署名の基礎
久方ぶりです。まさかたです。
さて、今回は、ドライバーのデジタル署名のお話をしたいと思います。
始めに、ドライバーのデジタル署名についてあまりご存知ない方に、簡単にデジタル署名とは何か?なぜドライバーに署名が必要なのか?ということについてお話ししたいと思います。
まず 「署名」 という言葉の意味について辞書を見てみますと、例えば「本人が自分の名を書類などに書くこと。また、その書かれたもの。」と書かれております。
これは、ドライバーにおける署名も同様で、ドライバーの場合は、書類にではなくドライバーパッケージもしくはドライバーのバイナリそのものに対して、作成者本人が誰であるかを示す名前を記すことになります。
それでは、なぜドライバーに対して、作成者が誰であるのかを示す必要があるのでしょうか?
これは言うまでもないことかもしれませんが、作成者の分からないドライバーをご自身の PC にインストールすることは、決して安全とは言えないからです。
というのも、現在は UMDF やプリンタードライバーのように、一部のドライバーはユーザーモード空間で動作するものがありますが、多くのドライバーはカーネルモード空間で動作しています。
カーネルモード空間は、その名の通り、OS の主要な機能を管理するモジュールを始めとして、その他のドライバーも動作するようなメモリ空間です。
そのため、カーネルモードで動くドライバーは、うっかりにせよ意図的にせよ、そのような OS やドライバーが管理するメモリを触ることができてしまうわけです。
ただ、実際には、そのようなメモリをあっさりと書き換えることができ、さらにそのまま動作してしまっては、意図しない動作をしてしまったり、大切なデータが破壊されたり、さらにはデバイスが誤動作、故障することもあり得ます。
そこで OS は、カーネルモード空間上で、このような不正な操作を検出した場合には、このまま動作を継続させてさらに深刻な事態に陥ることを回避するために、その動作を停止させます。
この動作の停止が、一般的にブルースクリーンですとか、BSOD (Blue Screen of Dead) と呼ばれる形で表面に出てくることがあります。
話が逸れましたが、ご自身の PC にドライバーをインストールする場合、それが誰によって作成されたのか、信頼できるものであるかを確認することは大切なことです。
そして、それを確認するための手段のひとつとして、デジタル署名というものがあるわけです。
なお、Windows Vista や Windows 7 では、署名のされていないドライバーや、署名の発行元の信頼性を確認できないドライバーをインストールしようとした場合、以下のような警告が表示されます。
図1. ドライバーソフトウェアの発行元を検証できません
32bit OS では、上記の警告が出た場合でも、「このドライバーソフトウェアをインストールします」を選択してインストールすれば、動作させることができますが、64bit OS では署名は必須となっており、署名がない場合は、ドライバーをインストールしたとしても動作させることができませんのでご注意ください。
さて、具体的にドライバーに対して、どのようにして署名を行うかについてですが、署名そのものについての技術的なお話は、暗号化などさらに深い話が待っていますので、ここでは割愛させていただきます。
ただ、Windows OS のドライバーで利用可能な署名の方法にはいくつか種類があり、一般的には INF ファイルや SYS ファイルを含むドライバーパッケージから作成したカタログファイルに対して、デジタル署名を行う方法がよく使われます。
カタログファイルを使った署名の他に、ドライバーパッケージの SYS ファイルなどのバイナリに直接署名を行う、埋め込み署名というものもありますが、これはブートドライバーやカタログファイルを使用しない場合など、特殊な用途ということもありますので、今回は、カタログファイルへの署名のお話しだけとさせてください。
このデジタル署名については、使われる証明書の種別に応じて、さらに以下のように大別されていますので、ご都合に応じて証明書を選択して、ご利用いただくこととなります。
① WHQL (Windows Hardware Quality Lab) 署名
・ドライバ パッケージに Microsoft WHQL の証明書を使用して署名
・WLK (Windows Logo Kit) のテストをパスする必要がある
・Microsoft WHQL が INF ファイルに記載されている情報を基にカタログ ファイルを生成
② Authenticode 署名(自己署名)
・root 証明を行っている証明機関が発行した証明書を使用して、ドライバーの作成者ごとに署名
・第三者証明機関に証明書の発行依頼が必要
・ドライバーの作成者ごとに、カタログ ファイルを生成して署名
・Windows Server 2003 以降の Windows OS で対応。(Windows XP では Authenticode 署名は有効な署名として機能しません)
③ テスト署名
・ドライバーの作成者ごとに、root 証明も含めて、テスト用の証明書を作成
・テスト用の証明書を PC ごとにインストール
・作成者ごとに、カタログ ファイルを生成して署名
・Windows OS をテスト モードで起動しないと有効にならない
・内部でのテストを目的とした署名
① や ② に関する細かな手順は、以下の技術情報を見ていただければと思います。
Authenticode を使用して、Windows Server 2003 用のドライバ パッケージにデジタル署名する
<https://www.microsoft.com/japan/whdc/driver/install/authenticode.mspx>
デバイス ドライバ パッケージに署名する
<https://technet.microsoft.com/ja-jp/library/cc771511(WS.10).aspx>
また、② と ③ の実際の署名の手順については、下記のドキュメントが参考になるかと思いますので、詳細はそちらに譲りたいと思います。
カーネル モードのコード署名の手順
<https://msdn.microsoft.com/ja-jp/windows/hardware/gg487328.aspx>
また、以前、なおきお~さんからもこちらの記事の中で、署名に関する話題が少し取り上げられていましたので、そちらもご参考としていただければと思います。
以下では、上記の 「カーネル モードのコード署名の手順」 の URL からダウンロードできる「カーネルモードコード署名のチュートリアル」のドキュメントで書かれている手順を読まれていることを前提に、この手順に従わなかった場合どうなるのか?というのを見てみたいと思います。
予め、どう失敗すると、どのような症状が出るかを見ていただければ、署名がうまくいかなかった場合に、症状から原因を推察できるかもしれません。そんな形でお役に立てたら幸いです。
今回は、Windows 7 x64 上で、手元ですぐに確認できるテスト署名でやってみました。使ったドライバーは、例によって Toaster のバス ドライバーとファンクション ドライバーです。
まずは署名の手順の概要について、上記のドキュメントから抜粋すると、以下のような流れになっています。
そこで、それぞれの手順で抜けやミスがあるとすれば、という観点で、失敗するケース (蛍光色の箇所) を考えてみました。
■ドライバーパッケージにテスト署名する手順
1. テスト署名用にコンピュータを準備します。
2. MakeCert を使用してテスト証明書を作成します。
3. MakeCat または Inf2Cat を使用してカタログ ファイルを作成します。 => カタログファイルを作成した後にドライバーパッケージを変更してしまった場合。
4. SignTool を使用してカタログ ファイルにテスト署名します。=> 署名をしなかった場合。もしくは署名後にドライバーパッケージを変更してしまった場合。
5. [信頼されたルート証明機関] 証明書ストアにテスト証明書をインストールします。 => 証明書をインストールしなかった場合。もしくはインストールが不十分な場合。
■テスト システムの準備
1. テスト証明書をインストールします。 => 証明書をインストールしなかった場合、もしくは片方にだけインストールした場合
2. カーネル モード テスト署名のブート構成オプションを有効にします。 =>テストモードにしなかった場合
3. コードの整合性イベント ログとシステム監査を有効にします。
4. テスト コンピュータを再起動します。
上記を踏まえて、例として、以下の表のような署名失敗ケースを考えてみました。ついでに結果も書いてますので、ご参考としてください。赤字がイレギュラーな箇所です。
図 2. このドライバーはデジタル署名されていません。
図3. Code 52 の発生 (ハードウェアの追加ウィザード上)
図 4. コード 52 (デバイスマネージャ上)
図 5. 証明書の発行元の確認
ちなみに、証明書やカタログファイルが破損している場合、signtool にて署名する段階で、例えば以下のようなエラーが発生して正常に署名ができませんので、この時点でのトラブルはすぐに見分けがつくかと思います。
signtool は、「カーネルモードコード署名のチュートリアル」でも紹介されている署名用のツールですので、詳しくはそちらをご参照ください。
以下では、signtool で発生するエラーとして、2つの例を示していますが、これはあくまで一例であり、証明書やカタログファイルの破損個所によっては、異なるエラーが出力される場合もあります。
例1 :証明書が無効な場合の signtool のエラーの一例
The following certificate was selected: Issued to: Contoso.com(Test) Issued by: Contoso.com(Test) Expires: Sun Jan 01 08:59:59 2040 SHA1 hash: 2EF2908C7317827CE042FA49E5EF1EA5E99D5F10
Done Adding Additional Store SignTool Error: An unexpected internal error has occurred. Error information: "Error: SignerSign() failed." (-2146881278/0x80093102) Number of files successfully Signed: 0 Number of warnings: 0 Number of errors: 1 |
例 2 :カタログファイルが破損している場合の signtool のエラーの一例
The following certificate was selected: Issued to: Contoso.com(Test) Issued by: Contoso.com(Test) Expires: Sun Jan 01 08:59:59 2040 SHA1 hash: 2EF2908C7317827CE042FA49E5EF1EA5E99D5F10
Done Adding Additional Store SignTool Error: This file format cannot be signed because it is not recognized. SignTool Error: An error occurred while attempting to sign: toaster.cat
Number of files successfully Signed: 0 Number of warnings: 0 Number of errors: 1 |
ただ、実際には、破損した証明書やカタログファイルの場合、以下のようにファイルそのものを開いてみるだけで無効であることが分かることがほとんどですので、上記のように署名する時点でエラーが出た場合には、一度ご確認された方がいいかもしれません。
図6. 壊れた証明書を開いてみた場合
図7. 壊れたカタログファイルを開いてみた場合
以上の結果を見て分かりますように、条件によって、出てくる症状も変わってきますので、原因について、ある程度の見当もつくかもしれません。
…が、結果としては同じ症状になるものもいくつかあるのが分かるかと思います。このような場合に役に立つのが、SetupAPI ログです。
この SetupAPI ログは、その名の通り、Setup API を使用した処理の中で出力されるログになります。
ログの見方については、以下のドキュメントが参考になるかと思いますので、ドライバーのインストールにおけるトラブルシューティングをされる可能性のある方は、一度ご覧いただくことをお勧めします。
SetupAPI ログを使用したインストールのトラブルシューティング
<https://msdn.microsoft.com/ja-jp/windows/hardware/gg463393.aspx>
ではでは。