Windows
環境、Java
環境、OpenSSL
環境におけるPKI
利用製品の調査を行 った結果についてまとめる。Windows
環境ではソースコードが手に入らないため、抽象度の高いAPI
までしか追跡することはできなかった。しかし
Microsoft
製のアプリケーションに限っ ては、テスト結果がAPI
を使って実装したサンプルプログラムを直接実行した場 合のテスト結果と同じであることから、各アプリケーションがそのAPI
を使用し ているであろうと推測される。OpenSSL
環境では認証パス構築、失効リスト参照のような基本的機能をアプリ ケーションが独自に実装してはおらず、OpenSSL
のライブラリによって提供され たAPI
を利用していることがわかった。また、Java
環境においても認証パス構築、失効リスト参照で使用される名前比較部分は単一のクラスにまとめられており、
複数箇所に分散していないことが確認できた。
表 5-1 名前比較を内包している部分
環境 名前比較を内包している部分
Windows CertCreateCertificateChainEngine/アプリケーション独自 混在 Java sun.security.x509.X500Nameクラス
OpenSSL X509_NAME_cmp()関数
現在の実装状況を見ると各環境の特徴を色濃く表しており、標準に対して独自 の解釈を当てはめた後の状態であるといわざるを得ない。しかしながら、独自解 釈に基づく実装、すなわち、UTF8String対応を推し進めるにあたって変更が必 要な部分が、小規模にまとまっていることもわかった。Widows環境において例 外も存在したが、たくさん存在するアプリケーションすべてを修正する必要はな く、ライブラリさえ対応すれば多くの問題が解決可能である。明るい材料である といえるだろう。
5.1
環境毎の差異について各環境の実装状況にばらつきがあるのは、標準が曖昧である事が当然、理由の 一つである。テスト結果をみると、各環境における一般的なプログラミング手法、
習慣なども影響を与えている事が見て取れる。どのように実装すべきなのかよく わからない部分に対して、各実装がそれぞれの環境における一般的な手順、その 環境において常識といわれる手法を当てはめた結果として、今回明らかになった ような差異を生じていると思われる。
表 5-2 名前比較ルールの環境ごとの差異
Windows Java OpenSSL
PrintableStringとUTF8String の比較
アプリケーショ
ンで異なる 区別しない 常に異なる
PrintableString ○ ○ ○
UTF8String - ○ -
ASCIIの大文 字小文字を区 別しない、空白
の処理 その他 - - -
UTF8String アプリケーショ
ンで異なる ○ - 全角文字の大
文字小文字を 区別しない、空
白の処理 その他 - - -
全角と半角の区別 あり 半角にできる物に
関して、なし あり
直感的に各環境の違いを把握しやすいように、表
5-2
に示した内容を、厳密さ をあきらめて、感覚的な言葉で表したビューを表5-3
に示す。表
5-3
名前比較ルールの環境ごとの差異(簡易な表現)PrintableString同士の比較 UTF8String同士 の比較
UTF8Stringと Printableの比較 Windows環境 規定よりも厳しい(正規化な
し)
規定よりも厳しい
(正規化なし) 常にマッチしない Java環境 規定に適合 規定よりもルーズ 規定よりもルーズ
OpenSSL環境 規定に適合 規定よりも厳しい
(正規化なし) 常にマッチしない
Java
ではそもそも、あらゆる文字データはUnicode
として扱われ、内部的には
UTF-8
でエンコードされた文字が使用されている。そのため、ASCII
と、そうでない部分、いわゆる半角文字と全角文字を区別する方が、しない場合と比較 して、より煩雑な作業となる。テスト結果からも、このような状況を反映して、
ASCII
とそうでないものを区別せず、同一視して扱っていることを見て取れる。OpenSSL
が開発されたUnix
環境では基本的に1
バイトの文字が使用されてお り、マルチバイト文字を扱うことはかなり煩雑な作業となってしまう。歴史的に マルチバイトを扱う事はあまり考慮されてこなかった環境であるため、マルチバ イト文字を扱うライブラリなども充実しているとはいえない状況である。そのよ うな状況で開発されたOpenSSL
環境のテスト結果からも、マルチバイト文字に 関しては文字としての扱いではなく、単なるデータとして扱っていることがわか る。Windows
環境では使用するライブラリの種類や、OS、ライブラリのバージョンによってマルチバイト文字の扱いやすさが異なっている。ちょうど、Java環境
と
OpenSSL
環境の中間に当たる程度でマルチバイト、Unicodeに適応した環境であるといえるだろう。テストでは
Microsoft
社製のアプリケーションはおそらく
CryptoAPI
に依存しているためすべて同じ結果となったが、アプリケーションによっては異なる動作をする状況が存在することが判明した。Java環境、
OpenSSL
環境と比較してUTF8String
対応がより困難な状況であるといえる。5.1.1 UTF8String
対応するにはName
の比較がUTF8String
問題のすべてではない。しかしName
の比較に限 っていえば、このような状況を改変し、すべての環境でUTF8String
とPrintableString
を比較する機能を正しく実現するには、表 5 1にあげたライブラ リ部分が修正され、アプリケーション開発者が意識せずともUTF8String
対応が なされてゆく状態が理想的である。ライブラリ部分の開発者が、UTF8String問 題を正しく理解し、移行期限までに修正が行われるのであれば大きな混乱もなく 移行が終了するであろう。警戒すべきはライブラリの修正が進まず、アプリケーション開発者が独自に
UTF8String
問題への対策を行った場合である。同一環境中に基本的に一つしか実装がない状態であっても、環境毎の差異が問題になってくる。
たとえばテスト番号
134
番のようにまったく同じデータをPrintableString
とUTF8String
でエンコードした証明書検証において、Java環境では検証成功するのに、OpenSSL環境と
Windows
環境では失敗するという現象が発生してしまっ ている。ここに、さらに、同一環境上に複数の解釈に基づく実装ができあがって しまうことになると、大きな混乱を招くことになるであろう。5.1.1.1
アプリケーション開発者への提言アプリケーション開発者は、独自に
UTF8String
問題への対応を行おうとすべ きではない。ライブラリが内包する問題点を正しく把握し、理解する必要はある がそれを独自に解決しようとせず、ライブラリの開発動向に注目するにとどめる べきである。やむを得ず独自に対応する場合でも、ライブラリ側の対応が完了し た時点でできるだけ速やかにライブラリによる処理に切り替えられるように留意 して、設計すべきである。特に
Java
環境でのアプリケーションでは全角文字と、半角文字の区別をライブ ラリが行っていないという点に注意する必要がある。その証明書が信用に足りる のかどうか、最終的に判断するのはアプリケーション利用者であり、文字情報を 見た人間である。従って、たとえば証明書検証の結果問題なしと判断された証明 書であっても、Name
部分に全角のアルファベットが使用されていたら強調表示 を行う等すれば、有名企業の名前を騙るフィッシング詐欺などの試みに対しては 有効であろう。5.1.1.2
ライブラリ開発者への提言正しく仕様を理解し、実装する必要があるのはいうまでもない。ただし、標準 を策定している側は、実装環境の現状に対し、必ずしも十分な配慮ができていな
い場合もあるため、実装する側からのフィードバックを行うことは、とても有益 である。
実装上で注意すべき点としては、特に実行環境による影響を受けないための配 慮が必要である点が上げられる。高度に抽象化された、文字列を操作する
API
に は実行環境の言語環境、ロケールが影響を及ぼすことが多い。おなじ「文字列」「エ ンコード方式」などといった言葉を使ってはいるが、証明書のName
に関する部 分に関しては一般的な、テキストエディタプログラムで扱うような文字列として の扱いをしてはならない。調査によって
OpenSSL
環境ではtolower(3)
関数を使用していることがわかっ たが、たとえばLinux
上で次のコードを実行すると、環境変数LANG=C
のとき はFALSE
、LANG=da_DK
の時はTRUE
となる。これは、tolower(3)
関数がデン マークロケールであればグレイブのついたAを小文字に変換できるが、標準のC
ロケールでは変換できないために発生する現象である。#include <locale.h>
#include <ctype.h>
main(){
int a, b, c;
setlocale(LC̲ALL, "");
a = 0xC0;
b = 0xE0;
c = tolower(a);
printf("%s\n", (b == c)?"TRUE":"FALSE");
}
「大文字と小文字を区別せずに比較する」処理を行う際、比較対象を双方小文 字に変換してから比較を行うような処理は、テキスト処理を行う場面では広く一 般的に行われるものであるし、ふつう
tolower(3)関数を使用して処理しても問題
を生じるものではない。しかし、証明書の認証パスを構築するような局面では、どのような言語環境で実行されても同じ結果を生むように十分注意して設計され なければならない。
5.1.1.3
証明書発行者への提言表