自堕落な技術者の日記

基本は喰ってるか飲んでるかですが、よく趣味でカラオケ・PKI・署名・認証・プログラミング・情報セキュリティをやっています。旅好き。テレビ好きで芸能通

XML

XAdESにおける発行者名前比較の問題(第9回:最終回)

≪第8回

今回で最終回となります。これまで、XML形式の長期署名フォーマットXAdESの識別名一致確認において以下の事柄を紹介してきました。


  1. XAdESの仕様ではSigningCertificate、CompleteCertificateRefsおよびCompleteRevocationRefsに記載された証明書識別名が証明書、CRL、OCSP応答データと一致することを確認しなければならない。

  2. XAdESにおいて証明書識別名はRFC 2253により生成されるが、これは正規化形式ではないので生成側、検証側の実装が異なれば一致確認を行うのは難しい。

  3. 実際にテストを行いRFC 2253識別名文字列の生成を行ってみると実装により違いがあることがわかった。

  4. 現在存在するXAdESの多くの実装では規定された識別名との一致確認を行っていないために問題とならなかったようだ。

  5. 識別名の一致確認を容易かつ厳密に行えるCAdESと比較して、XAdESの実装では識別名の確認を行っていないか不十分であるため、XAdESの方が検証情報の真正性のレベルは低くなる。



XAdESのための認証局・証明書選び



もし、署名者、タイムスタンプ局の認証局を選ぶことができるならば以下の点に注意すると良いと思います。逆にこれから認証局を構築するなら同様の点に注意してください。


  1. 全ての認証局の識別名の属性タイプは(CN,OU,O,L,C)のみが使われているものを選ぶ(例:CN=Root CA,O=Hoge,C=JP)

  2. 全ての認証局の識別名の属性タイプに(emailAddress,stateOrProvince)が使われていないことを確認する

  3. 全ての認証局の識別名のDirectoryString TypeはPrintableStringかUTF8Stringのみを用いる

  4. 鬼門となりそうなASCIIの記号文字(',', ';', '<', '>', '=', '#', '\', '"', など)は極力識別名には使わない



アプリケーション側が認証局選べるハッピーなケースなんてほとんど無いんですけどね、、、(^^;

XAdES相互運用性のアプリケーション側の注意点



生成も検証も同じアプリを使う場合には気にしなくていいですが、他の会社の文書交換とか署名生成と検証とが違うアプリケーションの場合には、選んでしまった認証局の種類、アプリケーションの種類によって「生成、検証の双方のドメインで」以下のような注意をすると良いのではないかと思います。


  1. 詳細なテストの前に検証側実装が識別名名の一致確認を厳密に実装しているか確認してみる。実装していないなら問題は生じない

  2. 一方がMicrosoft系の実装であれば慎重に動作確認を行う

  3. 使用される全てのCA証明書で主体者名の属性タイプにemailAddress、stateOrProvinceが含まれていればXAdES参照情報の一致確認に問題が生じないか確認しておく

  4. CA証明書主体者名のDirectoryString TypeがPrintableString、UTF8String以外であれば慎重に動作確認する

  5. CA証明書主体者名の属性値にASCIIの記号文字(',', ';', '<', '>', '=', '#', '\', '"', など)が含まれている場合には慎重に動作確認する

  6. 使用される全てのCA証明書で主体者名の属性タイプがCN,OU,O,L,Cであれば問題は少ないが一応動作確認をしておく

  7. 検証時に名前が一致しなかったとしても、エラーとはせず警告程度に留めておいた方がよい



XAdESの改定に向けて



現在、ETSIで行われた実証実験の結果を受けてETSI TS 101 903 v1.3.2 XAdESの改訂の項目洗い出しやディスカッションがETSI TC ESIで行われています。

今回のXAdESの名前比較は、CAdESと同等の置換攻撃に対する耐性を持たせるためにはきちんとやらなければいけないはずですが、識別名文字列の生成結果が一意にならないために、一致検証を行っていなかったりする実装がほとんどであり、XAdES v1.3.2の仕様の検証要件自体が形骸化しています。

できもしないような現状の一致検証の要件は取り下げてもらい、必要性を感じているなら、識別名オクテットのハッシュ値を比較し、文字列としては比較しないなどの別の方法による識別名の一致確認を行うべきであると考えており、これをETSI TC ESIや仕様のエディタに継続的に訴えかけていくつもりでいます。

ETSIのプラグテストの設計の際、今回ご紹介した問題を仕様のエディタ兼プラグテストの取りまとめの方に説明し、「名前比較はXAdESでは真面目にやろうとすると難しいし、現状ではあまり意味がないのでテスト項目から外しましょう」という事で納得してもらいましたので、概ねこの問題については理解してもらっているものと思っています。

以上、全9回に分けてXAdESにおける識別名の名前比較の問題について説明してきました。いかがでしたか?細かい部分が理解いただけなかったとしても、それは私の説明の仕方に問題があるんだと思います(^^;なんとな〜〜く「XAdESの名前比較は面倒臭い、、、」という事だけ知って頂ければ幸いです。

ではでは、、、

<追記>
以前書いたBER/DERの問題は、ちょっとウソを書いてしまっているので近いうちに直します、、、、m(_ _)m



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因
第6回 RFC 2253識別名文字列を生成する実装の紹介とテストの概要
第7回 RFC 2253識別名文字列を生成する実装の標準準拠性テスト結果
第8回 XMLDSig Second Editionでも参照されるRFC 2253の改訂版RFC 4514との差異
第9回(最終回) まとめと今後のXAdESの改訂

XAdESにおける発行者名前比較の問題(第8回)

≪第7回へ

これまで識別名の文字列化のための標準RFC 2253について説明してきましたが、実は2006年6月にこれの後継となるRFC 4514が公開されています。

2008年6月にW3CのXML署名に関する勧告の改訂版「XML Signature Syntax and Processing (Second Edition)が公開されました。以前にもブログで説明したような気がしますが、この改訂の2つの目玉は

・正規化はCanonical XML 1.1をデフォルトとする
・識別名文字列の生成にはRFC 2253ではなく新版のRFC 4514を使う

だと思います。XAdESでも(エディタが後方互換性の事など深く考えずに安易に)XMLDSig Second EditionやRFC 4514を参照するよう移行するのは時間の問題だと思います。

今回は、このRFC 4514について旧版であるRFC 2253との差分を中心に紹介したいと思います。

RFC 2253とRFC 4514の違いのポイント



幸い"RFC 4514 Appendix B"にRFC 2253との違いがまとめられています。ポイントを整理すると


  • LDAPv2の識別名文字列化(RFC 1779)は移行期間を終え使えなくなった、つまり・・・

    • 属性値をダブルクォートで括る(CN="hoge")のはダメ

    • RDNを区切るカンマの前後の空白文字(CN=hoge,_C=JP)はダメ

    • RDNをセミコロン";"で区切ってはダメ

    • 属性タイプが古いOID表記(例 'oid.1.2.3=hoge'や'OID1.2.3=hoge')はダメ

    • 従ってMicrosoft実装の場合には注意が必要



  • 属性値の等号'='はエスケープしてもよい

  • 属性値の等号'#'は途中に現れてもエスケープしてもよい

  • 属性値の空白文字は途中に現れてもエスケープしてもよい

  • 属性値のヌル文字は'\00'でエスケープする

  • 全ての文字を16進数エスケープ表記(例 '\1F')してよい

  • RFC 4514は識別名文字列は一意にならない(=正規化しない)事を明記



、、、、ってな所です。Microsoft の CryptoAPIや.NET Frameworkの実装に依存している場合には識別名の表示が古いRFC 1779ベースになってしまうので、RFC 4514のみしか扱えない実装では、うまく読み込みできない可能性があるので注意が必要です。

W3CではXMLDSig SEの策定の際にRFC 4514の差分を確認するようなテストケース("W3C Test Cases for C14N 1.1 and XMLDSig Interoperability")も作っているようです。

これまでにも述べているようにXMLDSigでは検索のために識別名文字列を使うのでRFC 2253だろうがRFC 4514だろうが完全一致しなかろうがテストの必要など無く、むしろ検証情報の一致確認で完全性が求められるXAdESでこそRFC 2253やRFC 4514の識別名文字列一致のテストをしなければならないわけで、2008年9月のETSI XAdESプラグテストでもそのように主張したんですが、いま一つ理解されないまま流されてしまいました(−_−;

テスト用のデータはW3Cでは正式には配っていないようなんですが、ApacheのCVSの中とかに誰かがテストした結果が残っていたような気もします。

テストケースとテストデータを作って相互運用テストはしたみたいですが、製品としてRFC 4514をサポートするような実装は今のところまだ出ていないようです。

今日は、さっくりとココまで、、、(^^v

次回は最終回ですよん。

ではでは



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因
第6回 RFC 2253識別名文字列を生成する実装の紹介とテストの概要
第7回 RFC 2253識別名文字列を生成する実装の標準準拠性テスト結果
第8回 XMLDSig Second Editionでも参照されるRFC 2253の改訂版RFC 4514との差異
第9回(最終回) まとめと今後のXAdESの改訂

XAdESにおける発行者名前比較の問題(第7回)

≪第6回へ

前回は証明書識別名のRFC 2253文字列が得られる入手しやすそうな5つの実装を紹介しました。

Sun Java SE 6 Update 3 (build 1.6.0_03-b05)
BouncyCastle Java Crypto Library 1.3.8
IAIK JCE Toolkit 3.142
Microsoft .NET Framework 3.5
OpenSSL 0.9.8i (cygwin)

今回はこれらの実装を使った場合、生成されるRFC 2253文字列にそれぞれどのような違いがあるのかテストしてみたいと思います。

テスト1: 属性タイプ名に関するテスト



テスト対象の実装を用いてテスト用に生成された証明書の発行者名よりRFC 2253文字列を生成し、属性タイプ名(例: C, OU)がRFC 2253で規定に従っているかをテストします。

テストを行う属性タイプ名は
(1) RFC 2253で例として挙げられている属性タイプ名
(2) RFC 3280で扱うと規定されている属性タイプ名
計18をテストします。

属性タイプ名として期待される値は以下とします。
(1) RFC 2253で例として挙げられていればこれを用いる
(2) 上記(1)以外でRFC 2256で属性タイプ名が規定されていればこれを用いる
(3) 上記(1)、(2)以外ならばOID表記(例 1.2.3=#1F3D...)

テストの結果は以下の表のようになりました。

RFC2253テスト1属性タイプ名のテスト



結果の表から以下の事が言えるかと思います。


  • .NETの実装ではIsserやSubjectのプロパティはRFC 2253というよりもむしろ
    古いRFC 1779に準拠しており、RDNのカンマ区切りの後ろに空白文字が含まれたり
    古いOID表記(例 "OID1.2.3=Test")が使われる場合、値が16進形式(例 "#1F3D..")
    になっていないなどRFC 2253の生成要件を満たしているとは言えない。

  • 良く使われているC,O,OU,CN,L,DCについては、ほぼ問題が無い。

  • 良く使われる"ST(stateOrProvince)"で.NETの実装は"S="と表記するので
    注意が必要

  • 良く使われるEmailAddressについては、そもそもRFC 2253、RFC 2256で
    属性タイプ名が規定されておらず、そのために相互運用性に問題がある。
    EmailAddressはRFC 3280では後方互換性のため主体者名にのみ使えるとしている
    ので発行者名しか使わないXAdESでは問題なさそうだが、Thawteなど
    一部のパブリックな証明書発行サービスでも主体者名にEmailAddressを
    含めているものはある。

  • 一般にOpenSSLは証明書に関して標準に忠実であると考えられていたが、
    RFC 2253の属性タイプ名に関してはむしろSun Java JCEの方が非常に厳格で
    RFC 2253の例で示されたもののみを属性名文字列として表記しており、
    未知のものはOID表記にしてしまう。



テスト2: DirectoryString Typeに関するテスト



証明書の識別名に使用されるPrintableStringやUTF8StringなどのDirectoryString Typeは、ITU-T X.680で規定されていて、RFC 3280では利用できる範囲を限定(プロファイリング)しています。

DirectoryString TypeがRFC 2253識別名文字列に影響を受けるのか調べるためにテストを行いました。UTF8StringやTeletexStringなど国際化対応の文字列についてはASCII文字以外の日本語などの文字列でもテストを行いました。

各実装でのDirectoryString Type対応テストの結果は以下の通りです。

RFC2253テスト2DirectoryString Typeのテスト



表中、緑色で示されるDirectoryString Type(UTF8String, PrintableString等)はRFC 3280で利用可能なDirectoryString Typeです。

結果の表より以下のことが言えると思います。


  • よく使用されるUTF8String, PrintableString, IA5Stringについては問題ない

  • RFC 3280で使用できるとされているTeletexString, BMPString, UniversalStringについては一部の実装において使用している文字エンコーディングISO 2022, USC2, USC4から正しくUTF-8に変換されずに文字化けとなっているケースがあった

  • OpenSSLとIAIKにおいて処理中エラーとなるケースがあった。16進数形式で表示するならまだしもエラーとなり処理を継続できないのは実装の重大な欠陥であると考えられる。(OpenSSLはSSLが扱えることが目的なのでRFC 3280で扱えるTypeだけを処理できれば十分なのかもしれない)

  • Microsoft .NETの実装はどのようなTypeでも最も正しく表示させることができる

  • Sun Java JCEの実装は対応するDirectoryString Typeの範囲が最も狭い



テスト3: エスケープに関するテスト



識別名の属性値の部分をRFC 2253で文字列にする場合、一部の文字、例えばカンマ","やセミコロン";"などバックスラッシュ"\"でエスケープしなければならない文字があります。エスケープのルールについては"RFC 2253 2.4. Converting an AttributeValue from ASN.1 to a String"で規定されています。

ここでは実装が正しく属性値のエスケープ処理を行っているかテストします。

各実装でのエスケープ処理のテスト結果は以下の通りです。

RFC2253テスト3エスケープ処理のテスト



結果の表より以下のことが言えると思います。


  • Microsoft .NET の実装はエスケープが必要なケースでは属性値をダブルクォート'"'で括るというRFC 2253の旧版であるRFC 1779に基づいた実装である

  • シャープ'#'や空白文字では一部RFC 2253従わない実装があった

  • OpenSSLとIAIKはエスケープ処理に関してはRFC 2253に完全に準拠している



RFC 2253生成要件準拠性の採点



3つのテストの結果を受け各テストにおいてどれくらいRFC 2253の生成要件を満足しているかを(主観的に(^^;)5点で採点し、15点満点で各実装の準拠性を比較したのが以下です。

RFC2253生成テストの採点結果2




正直な話、どれも「帯に短し襷に長し」といった感じでピリッとしませんね。RFC 2253の生成ルーチンについては自前できちんとしたものを持っておいた方がいいんじゃないかという気さえします。

各実装におけるRFC 2253文字列生成の特徴をまとめます。








実装生成の特徴
Sun Java JCERFC 2253の例のレベルで局所的に完璧に実装しているが、属性タイプなど扱えない範囲が多すぎる
BouncyTeletexStringを使わない限り概ね良いが、エスケープの実装には注意が必要
IAIK属性タイプの実装はほぼ合格だが、エスケープも満点だが対応してないDirectoryString Typeがあるのが欠点か?
Microsoft .NET基本は旧版のRFC 1779なのでXAdESで利用するのに問題がある。DirectoryString Typeの対応は素晴らしい
OpenSSLRFC 3280の証明書を使う限りはほぼ問題無いが、扱えないDirectoryString Typeの際にエラーとなり16進数形式ですら値を返せないのは大きな欠点


以上、比較的普及していると思われる実装のRFC 2253生成機能の標準準拠性をテストした結果を報告しました。

次回についてですが、実は今回紹介しているRFC 2253は古くて新しいXML署名の標準でRFC 2253の改訂版である"RFC 4514 Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names"が参照され使用されています。

XAdESで引用されているのはRFC 2253ですが、近い将来新しいXML署名の標準であったりRFC 4514を引用されるようになると思います。次回はこのRFC 4514について紹介しようと思っています。

今回も長くなっちゃいましたね。

ではでは



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因
第6回 RFC 2253識別名文字列を生成する実装の紹介とテストの概要
第7回 RFC 2253識別名文字列を生成する実装の標準準拠性テスト結果
第8回 XMLDSig Second Editionでも参照されるRFC 2253の改訂版RFC 4514との差異
第9回(最終回) まとめと今後のXAdESの改訂

XAdESにおける発行者名前比較の問題(第5回)

≪第4回へ

前回は証明書識別名のASN.1バイナリを文字列表現するための標準RFC 2253を紹介し、RFC 2253により生成された文字列一通りにはならず、文字列一致をさせることは難しいということを説明しました。

今回は、RFC 2253文字列の一致確認をする際の相互運用性阻害要因について説明していこうと思います。

属性タイプ(AttributeType)について



属性タイプの表記はRFC 2253 2.3節で規定されています。

If the AttributeType is in a published table of attribute types associated with LDAP [4], then the type name string from that table is used, otherwise it is encoded as the dotted-decimal encoding of the AttributeType's OBJECT IDENTIFIER.
(RFC 2253 2.3節Converting AttributeTypeAndValueより)


RFC 2253によると一般的な属性タイプは"C"(国名:countryName)、"O"(組織名:organizationName)のような属性タイプの名前(type name)を表す文字列で表記されます。

ここでまず問題となるのが"published table of attribute types"が一体どれを指しているのかという事です。"RFC 2256 5. Attribute Types"を指していると思われますが、明確にこれを指しているわけではない事、RFC 3280で使用できる属性タイプをカバーしているわけではない事、RFC 2256では小文字で始まる文字列(例 "cn", "serialNumber", "o", "title"等)である事といった点が気になります。

RFC 2253 2.3節の例では以下のように大文字で限定されたものだけです。

String  X.500 AttributeType
------------------------------
CN commonName
L localityName
ST stateOrProvinceName
O organizationName
OU organizationalUnitName
C countryName
STREET streetAddress
DC domainComponent
UID userid

(RFC 2253 2.3節Converting AttributeTypeAndValueより)


XAdESではディレクトリ一般ではなくデジタル証明書に限定して考えればいいと思うのですが、広く使われている証明書プロファイルであるRFC 3280では、受け入れられる属性タイプに関する規定があります。(RFC 3280 4.1.2.4 節 Issuer参照) "4.1.2.6節 Subject"では、後方互換性のためEメールアドレスをSubjectに入れることもあると書かれています。

RFC 3280で受理できると規定された属性タイプとRFC 2253、RFC 2256の属性タイプ名を表にまとめてみました。相互運用性上ややヤバメなのを黄色、比較的頻繁に使用され非常にヤバメなのをオレンジで記してあります。

RFC3280の属性タイプ比較



emailAddress、domainComponent、serialNumberなんかは規定や例が片方にしかなかったり、そもそもRFC 3280で規定がなかったりなど問題を起こしそうな雰囲気です。stateOrProvinceがヤバイ理由は別の機会に説明します。

これらの表に無いものは概ねOID 10進数ドット繋ぎ(例 2.5.4.30等)で表記されることになります。

以下に表記する側、即ち文字列を生成する側の属性タイプに関する問題点をまとめます。

・どれをタイプ名で表示でき、どれがOID表記(例 2.5.4.30)となるのか明確でない
・大文字か小文字か明確でない(例は大文字だがtype nameの定義は小文字)
・RFC 225XではRFC 3280で規定された利用可能属性タイプが網羅されていない

Attribute Valueについて



属性値から属性値を表す文字列への変換は"RFC 2253 2.4. Converting an AttributeValue from ASN.1 to a String"で規定されています。

そのままではマズイ文字のエスケープについては規定に書かれた通りやるのは当たり前として、文字列比較の際に相互運用性上問題になりそうなところはこの辺りです。

・値が文字列表現できれば、そのままUTF-8エンコーディングで表記
・できなければ"#"+属性値のBERエンコード16進数表記
・属性タイプがOID表記ならば"#"+属性値のBERエンコード16進数表記を使う(SHOULD)
・文字列表現したとしても1バイトを"\"+16進数として表現してよい(例 "\A6")

つまり文字列でもよいし16進数表記でも構わないということです。

さらには、属性値が文字列表現を持っているか、原文では以下

If the AttributeValue is of a type which does not have a string representation defined for it
(RFC 2253 2.4. Converting an AttributeValue from ASN.1 to a Stringより)


で判断して文字列で表現するか16進数表現するかを決めるのですが、全く曖昧な基準となっています。属性値はPrintableString、UTF8String、TeletexString、BMPStringなど様々なDirectoryString Typeを使うことが可能ですが、これらのASN.1型の違いによって実際の実装は異なる属性値文字列表記を返すようです。

この事については次回、実装の紹介で説明したいと思います。

"RFC 3280 4.1.2.4 Issuer"ではRFC 3280に準拠したX.509公開鍵証明書の発行者や主体者の識別名でどのようなDirectoryString Typeを使ってよいかが規定されています。これを表にまとめたのが以下です。

RFC3280で対応するDirectory StringType



RFC 3280に準拠せず大元のITU-T X.509にだけ準拠する場合には特にこのような制限はありません。文字列表現があるにもかかわらずDirectoryString Typeの種類によってはRFC 2253で文字列表記とならずBER表記となってしまうような実装があるという事です。

Multi valued RDNについて



LDAPでは一つのRDNに複数のAttributeTypeAndValuesを含めることができます。これを"Multi-valued RDN"と呼びます。複数ある場合にRFC 2253ではプラス"+"で繋いで表記します。

RFC 2253ではプラス記号の両側に空白があったとしてもこれを無いものとして受理しなければなりませんが、準拠する実装は空白をつけてはいけません。

もう一点、注意しなければならないのがASN.1エンコーディングのDERとBERの違いです。X.509公開鍵証明書はDERですが、属性値全体が16進数形式で表記される場合には属性値をBERエンコーディングして表記します。例はこんな感じ、、、

O=Test (※PrintableStringの場合)
↓属性値16進数表記
2.5.4.10=#310D300B060355040A130454657374


DERはBERのサブセットなので、DERであればBERでもあります。これらの大きな違いというのは

(1) DERは一意に表現され同じ意味のデータが別のエンコード値になることはない
(2) BERは同じ意味のデータを幾つか別のエンコード値で表現できる
 (2-1) DERではSET OF構造の要素を辞書順ソートし一意にするがBERではソートしない
 (2-2) DERはプリミティブ型があれば必ずこれのみを用いる
 (2-3) BERではOCTETSTRINGなどプリミティブ型を構造型(constructor form)でも
    表現することができ、固定長(definite)と終端記号(00 00)を用いる
    不定長(indefinite)形式とを合わせ3種類の表現方法がある。

識別名の属性値で(2-3)のBER構造型を使うことはほぼ無いですが、(2-1)のソート順序が問題となるケースがあり、それがMulti-valued RDNの識別名であるケースです。

例として以下のMulti-valued RDNを持つ識別名を考えてみましょう。
CN=aa+O=aa,C=JP


まず、RDNはSET OFというASN.1構造を用います。この識別名がDERでエンコーディングされている場合、このMulti-valued RDNのCNとOの順序はCN(commonName)のOIDが2.5.4.3、O(organizationName)のOIDが2.5.4.10であることから値が同じ'aa'ならばCN、Oの順序になりこれはきちんとDERでソートされていると言えます。

この識別名からBER 16進数形式の属性値を作る場合に、証明書中のDERエンコードされた識別名オクテット列を用いれば全く問題ないのですが、BERを再構成しSET OFは順序は関係ない構造であるからと順序を入れ替えてBERを作ってしまうと証明書識別名と合わないことになってしまいます。

識別名(DN)全体について



RFC 2253では相対識別名同士はカンマ(",")で繋ぎます。生成時と検証時でちょっと違っていてXAdESを生成する際にはRFC 2253の生成時の要件を満たさなければなりません。

【生成時の要件】
・属性タイプと属性値は等号("=")で繋ぐ
・RDNをカンマ(",")で繋ぐ
・カンマの両側には空白は入れない

【検証時の要件】
・属性タイプと属性値を繋ぐ等号("=")の両側に空白文字があっても受け入れる
・RDNを繋ぐカンマの両側に空白文字があってもこれを受け入れる
・RDNの区切り文字がセミコロン";"であっても受け入れる



以上、RFC 2253で識別名を文字列で表現した結果は、どうやら一意にはなりそうには無く、単純に文字列比較はできず、正規化の類も完全にこれを実装するのは難しそうだという理由が「なんとなく」おわかり頂けたでしょうか。(難しいかな、、、(^^;)

今回はこれくらいにしておきましょう。
かなり長編でマニアックな内容になってしまいゴメンナサイ。

次回はRFC 2253で識別名文字列を出力できそうな実装が、実際どうなっているのかについてご紹介したいと思ってます。

ではでは



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因

XAdESにおける発行者名前比較の問題(第4回)

≪前回第3回へ

なんか忙しくって随分時間が空いてしまってゴメンナサイm(_ _)m
今回はいよいよRFC 2253で証明書識別名を文字列で表すところの紹介です。

識別名の文字列変換方式を定めたRFC 2253



RFC 2253 'Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names' とは、証明書中の発行者名や主体者名などの名前(X500Name)やディレクトリエントリの識別名をUTF-8エンコーディングされた国際化文字列に変換するルールを定めたものです。

XAdESの発行者名はRFC 2253により文字列変換された後にXML要素として格納されるので今回はこのRFC 2253について見ていきましょう。

幸いIPAでRFC 2253の和訳がありますのでこちらをご覧ください。

http://www.ipa.go.jp/security/rfc/RFC2253JA.html (IPA和訳)
http://tools.ietf.org/html/rfc2253.html (原文)

識別名の文字列変換は以下のような目的で必要となります。
(1) ディレクトリの検索・追加・変更のための文字列形式の検索キーを作るため
(2) ディレクトリエントリを表示するため
(3) 証明書・CRL・OCSPなどで使われる名前を表示するため

識別名自体はASN.1構造化バイナリ表現されたものですから、これをどのような識別名が与えられたとしても文字列で表現できるようにしたのがRFC 2253です。

変換ルールをまとめたのが以下です。(ちっともまとまってない(^^;)


  • RDNの並びはRDNの末尾から先頭に向かってカンマ","繋ぎで表す

  • RDNの中に複数AttributeTypeAndValueがある場合(Multi AVA)にはプラス'+'で繋ぐ(例:CN=Taro+OU=Foo)

  • AttributeTypeAndValue は「AttributeTypeの文字列=AttributeValueの文字列」

  • AttributeTypeはRFC 2252に関連する表(即ちRFC 2256)にあればその文字列を使う(全部小文字なことに注意)

  • 表にない場合、10進ドット表記(例 "0.1.2.34.456") が使われる

  • よくあるAttributeTypeの文字列表現はCN,L,ST,O,OU,C,STREET,DC,UIDなどの例がある(※あくまで例です。大文字であることも注意) (2.3節)

  • AttributeValueが文字列できなければ"#1f3df..."のようなBER16進表現で (2.4節)

  • AttributeValueが以下を含む場合エスケープする (2.4節)

    • 値文字列が空白か"#"で始まるならバックスラッシュ'\'でエスケープ

    • 値文字列の終わりが空白文字ならエスケープ

    • ',', '+', '"', '\', '<', '>', ';'の場合

    • AttributeValueでは他の文字もエスケープしてよい

    • AttributeValueではエスケープ文字は16進表現'\xx'でもよい



  • 旧仕様RFC 1779の構文も受け入れなければならない(MUST) (4節)

  • RDN区切りのカンマ','の代わりにセミコロン';'も受け入れる(MUST) (4節)

  • カンマやセミコロンの両側の空白を許す(MUST) (4節)

  • AttributeTypeがOID表現の場合には"oid."もしくは"OID"が前についても受け入れる(MUST) (4節)



RFC 2253の例で示されている識別名はこんな感じです。

CN=Steve Kille,O=Isode Limited,C=GB
OU=Sales+CN=J. Smith,O=Widget Inc.,C=US
CN=L. Eagle,O=Sue\, Grabbit and Runn,C=GB
CN=Before\0DAfter,O=Test,C=GB
1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB
SN=Lu\C4\8Di\C4\87


RFC 2253で変換した識別名文字列は一意じゃない!



ある識別名から上で説明したRFC 2253の変換規則を使って文字列にしてみると、いろんな表現方法があって一つには決まらないってことがよくわかります。例えば

OU=Test,C=JP


を考えてみましょう。

ざっと思いつくRFC 2253識別名文字列はこんな感じです。

O=Test,C=JP    RFC 2253例にもある普通の表現
o=Test,C=JP    RFC 2256の表ではAttributeTypeは小文字になっている
O=Test_,_C=JP   RDNの区切りの前後に空白があってよい
O=Test;C=JP    RDNの区切り文字はセミコロンでもよい
O=Tes\74,C=JP   値の文字をエスケープしてもよい
O=#310D300B060355040A130454657374,C=JP 値がBER16進数でだめとは書いてない
2.5.4.10=#310D300B060355040A130454657374,C=JP ドットなら値BERはSHOULD
oid.2.5.4.10=#310D300B060355040A130454657374,C=JP "oid."をつけてよい
OID2.5.4.10=#310D300B060355040A130454657374,C=JP "OID"をつけてよい
※空白文字はアンダーバー"_"で表示しています。


どうです?これだけ表現方法があって一意には決まらないんです。RFC 2253の文字列一致比較が単純にはうまくいかないことが、おわかり頂けたでしょうか?

それ故にXAdESの識別名の文字列比較は厄介なのです。

じゃぁ、作ればいいじゃん、、、と、RFC 2253の文字列比較に完全に対応しようとしている貴方、、、、止めた方がいいと思いますよ。砕け散った埴輪の復元作業みたいなもんです。完全には元には戻らないので単純に比較はできません。

文字列からASN.1 DERやBERバイナリを復元しようとする無駄なこともやってはいけません。(RFC 2253 7.2 参照) (手持ちのXAdESの実装は一致比較のためにコレをやっちゃっています(^^;)

今日は随分長くなってしまったので、この辺で終りにしましょう。
次回はRFC 2253の文字列比較の相互運用性上問題になりそうなど〜〜でもよいところをうじうじ、ちくちく細かく見ていこうと思います。



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因
第6回 RFC 2253識別名文字列を生成する実装の紹介とテストの概要
第7回 RFC 2253識別名文字列を生成する実装の標準準拠性テスト結果
第8回 XMLDSig Second Editionでも参照されるRFC 2253の改訂版RFC 4514との差異
第9回(最終回) まとめと今後のXAdESの改訂

XAdESにおける発行者名前比較の問題(第3回)

≪第2回へ

前回はETSI 101 903 XAdES v1.3.2における発行者識別名の一致検証の記述について説明しました。

今回は、XAdESと似たCMSバイナリ形式の長期署名フォーマットCAdESだってSigningCertificate、CompleteCertificateRefs、CompleteRevocationRefsが同じようにあるのに何故CAdESでは問題にならないのか、また、XAdESの元の仕様であるXML署名を規定したXMLDSigだってIssuerSerialはあるのに何故問題にならないのか、RFC 2253の説明に入る前に少し寄り道して説明したいと思います。

証明書・CRL・OCSP応答の(発行者)識別名の定義と例



RFC 3280 4.1.2.4 Issuerで記述されているように証明書の発行者や主体者の識別名はX.501のName型として定義されています。ASN.1構造の定義はこんな感じ、、、、

Name ::= CHOICE { RDNSequence }
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
AttributeTypeAndValue ::= SEQUENCE {
 type   AttributeType,
 value   AttributeValue }
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= ANY DEFINED BY AttributeType
(RFC 3280 4.1.2.4 Issuerより)


具体例を示すと、以下が証明書中の名前(Name)であり相対識別名(Relative Distinguished Name)の並び(SEQUENCE)で表されます。

SEQUENCE {
 SET { SEQUENCE {OID countryName, PrintableString 'JP'} }
 SET { SEQUENCE {OID organizationName, PrintableString 'Entrust'} }
 SET { SEQUENCE {OID commonName, PrintableString 'Root CA'} } }


並びの順序は証明書のためのエントリがディレクトリに登録されて際のDIT(Directory Information Tree)の上から順に格納します。通常は国(C=JP)やドメインコンポーネント(DC=COM)なんかが上にきます。

そして部分的に取り出していくと、以下が相対識別名

SET { SEQUENCE {OID countryName, PrintableString 'JP'} }


これが属性タイプと値の組(AttributeTypeAndValue)になります。

SEQUENCE {OID countryName, PrintableString 'JP'}


上の名前(Name)の例をRFC 2253で文字列表現にすると

CN=Root CA,O=Entrust,C=JP


のようになるわけです。

CAdESにおける検証情報の発行者名比較



前述のCN=Root CA,O=Entrust,C=JPの識別名を証明書から取り出してASN.1のバイト列表現に変換するとこのようになります

SEQUENCE {
 SET { SEQUENCE { OID countryName, PrintableString 'JP' } }
 SET { SEQUENCE { OID organizationName, PrintableString 'Entrust' } }
 SET { SEQUENCE { OID commonName, PrintableString 'Root CA' } } }
↓↓ASN.1でエンコードすると以下のバイト列になります
30:31:
 31:0B:30:09:06:03:55:04:06:13:02:4A:50:31:10:30:0E:06:03:55:04:0A
 31:10:30:0E:06:03:55:04:0A:13:07:45:6E:74:72:75:73:74
 31:10:30:0E:06:03:55:04:03:13:07:52:6F:6F:74:20:43:41


CAdESでは、発行者識別名ASN.1構造の識別名オクテット(=バイト列)をそのまま検証情報参照情報として持っているので、証明書・CRL・OCSP応答中の発行者識別名との一致確認はそのままバイト単位で比較するため厳密な一致確認が可能です。

以前、ECOMの実証実験では名前をそのままバイトコピーせず、自分で作り直したために例えばPrintableStringがUTF8Stringに変わってしまい、一致しなかったなどというケースもありましたが、今は実験に参加している実装でそのような不具合は無いと思います。

何故、W3C XMLDSIGでは問題にはならないのか



W3C XMLDSigではW3C 4.4.4 The X509Data Elementで規定されているように署名者の鍵や証明書などを格納するKeyInfo要素の中にX509IssuerNameやX509SubjectName要素として証明書の識別名が入れられるようになっています。

このX509IssuerNameやX509SubjectNameもRFC 2253により証明書中の発行者名、主体者名を文字列にして保持するわけですが、特に比較して一致しなければならないとかいう検証要件はありません。それは、証明書を何らかのサービスやシステムから取得するために参考として用いる名前であって、検索できさえすればよく一致している必要は無いのです。このため、XMLDSigではRFC 2253で生成される結果が一意でなかったとしても問題とはならないのです。

一方 XAdES では、完全性確認のめにRFC 2253文字列が使われますから、一意でないと一致せずにエラーということになります。

以上、今回はCAdESやXMLDSigでは名前一致が問題にはならず、XAdESだけの問題であるという事を見てきました。

次回はRFC 2253そのものについてと、RFC 2253で単純に文字列比較なんかできないということの入り口までたどり着けると良いと思っています。

ではでは



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因
第6回 RFC 2253識別名文字列を生成する実装の紹介とテストの概要
第7回 RFC 2253識別名文字列を生成する実装の標準準拠性テスト結果
第8回 XMLDSig Second Editionでも参照されるRFC 2253の改訂版RFC 4514との差異

XAdESにおける発行者名前比較の問題(第2回)

≪前回(第一回)|次回(第3回)≫

前回は、XAdESにおいては識別名の一致確認に問題があるという紹介をしたところまででした。

今回は、XAdESの仕様はどうなっているのかを見ていきましょう。

XAdESにおける検証情報中の発行者名一致確認の要件



ETSI TS 101 903 XAdES v1.3.2では、Annex G (informative): Details on XAdES signatures validationに検証続きが説明されており、CompleteCertificateRefsの証明書参照情報の検証方法については以下のように規定されています。
(注:厳密には規定でないことは後述)

G.2.2.12 Checking CompleteCertificateRefs and AttributeCertificateRefs (p92)

2) Check that for each certificate in the aforementioned set, the property contains its corresponding reference. For doing this the values of the IssuerSerial, ds:DigestMethod and ds:DigestValue should be checked as indicated in clause G.2.2.5 steps 1 and 3.
2) 前述の集合中の個々の証明書に対し、プロパティがその証明書に関連した参照情報を持っているか確認する。これを行うために IssuerSerial、ds:DigestMethodおよびdsDigestValueが G.2.2.5 節のステップ1および3で示したように確認しなければならない。


IssuerSerialの具体例はこんな感じ、、、

<IssuerSerial>
 <ds:X509IssuerName>CN=Root CA,O=Entrust,C=JP</ds:X509IssuerName>
 <ds:X509SerialNumber>123</ds:X509SerialNumber>
</IssuerSerial>


この参照先になっているG.2.2.5が以下のSigningCertificateの検証方法の記述です。

G.2.2.5 Checking SigningCertificate (p90)

1) Compare the name of the issuer and the serial number of the certificate with those indicated in the IssuerSerial element. For doing this, the application must follow the indications given in XMLDSIG clause 4.4.4 on how to generate the string corresponding to the issuer's distinguished name. If not, take the next reference and re-start again in 1. If they match, continue with 2.
1) 証明書中の発行者名とシリアル番号とIssuerSerial要素で示されたものとを比較する。これを行うためにアプリケーションは発行者識別名に相当する文字列の生成方法について、W3C XMLDSIG仕様の4.4.4節で与えられた指示に従わなければならない。一致しない場合、次の参照を用いステップ1を再実行する。一致した場合、ステップ2に続く。


つまりXAdESの証明書、CRL、OCSP応答の発行者名の文字列を得るにはXMLDSIG 4.4.4節を見ろということです。

XMLDSIG 4.4.4節に深く入りこむのは別の機会にして、簡単にはXMLDSIG 4.4.4節では証明書中の識別名をRFC 2253 Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names(LDAPv3: 識別名のUTF-8文字列表現)により文字列表現にすることを言っています。

証明書・CRL・OCSP応答から発行者名を取り出し、これをRFC 2253で文字列表現にし、XAdESのプロパティと比較して一致していなければならないわけです。

但し、XAdES(およびCAdES)では参照情報だけでなくタイムスタンプなど全ての検証方法は全てInformative(=参考情報)でありNormative(=規定)ではないのです。私がETSIに対しAnnex Gに書かれた検証方法について意見したり細かいコメントをするとETSIのエディタは「いやぁ〜〜、それはあくまでInformative(=参考情報)だからねぇ、、、、」と逃げる人がいます(^^;検証方法を規定しないフォーマットなんか意味無いっつ〜〜〜の!!!(すみません、語気が荒くて)

例えばX.509やRFC 3280などでは証明書の検証方法を、RFC 3852ではCMSの検証方法を規定しています。検証方法がInformativeというのは「仏作って魂入れず」というか有り得ない話です。(この辺りも改訂を内々にお願いしている最中ですが、ETSIに理解されているかどうか、、、、)

今日は深くなりすぎたのでこれぐらいにしたいと思います。

次回は核心に進む前に、CAdESやXMLDSigだってIssuerSerialみたいなのを参照情報として使っているのに何で問題にならないのか、少し寄り道して説明しようと思います。

ではでは



XAdESの証明書識別名の比較問題 (もくじ)
第1回 はじめに
第2回 XAdESにおける名前比較の要件
第3回 なぜCAdESやXMLDSigでは問題とならないのか
第4回 RFC 2253による識別名バイナリの文字列化
第5回 RFC 2253識別名文字列を比較する際の相互運用性阻害要因
第6回 RFC 2253識別名文字列を生成する実装の紹介とテストの概要
第7回 RFC 2253識別名文字列を生成する実装の標準準拠性テスト結果
第8回 XMLDSig Second Editionでも参照されるRFC 2253の改訂版RFC 4514との差異
第9回(最終回) まとめと今後のXAdESの改訂

Visual C# 2008 Express

ちょっとXML署名関係で調べたいことがあり Microsoft Visual C# 2008 Express Editionでプログラムを作ってみました。やっぱり基本的にはSharp Developよりもよく出来ているなぁ、、、、、

たまにしか使わないので、すぐ忘れてしまいますが

(1)暗号系のプログラムを作成する際にはSystem.Securityの参照を追加する

.NET での参照の追加


(2)プロジェクトはマイドキュメントのVisual Studio 2008\Projectsに作られる

ので、これは備忘録として、、、、(^^;

oXygen XML Editor

oXygen XML Editor - Professional - V9.3


XMLエディタなんですが、

XML Digital Signature and XML Canonicalization - The digital signature is a requirement when exchanging information in an untrusted network. Since XML is used for content storage it is important to be able to sign the XML files or messages.


でも、3〜4万とかなりお高め、、、、、、
Jython + XML系のライブラリで何とかよいXMLエディタができないもんかと
思案中、、、、

・部分的に署名してみたり
・部分的に正規化してみたり
・部分的にハッシュを計算してみたり

マイクロソフトがOOXMLの相互運用性を強化、HTMLトランスレータを開発へ

マイクロソフトがOOXMLの相互運用性を強化、HTMLトランスレータを開発へ : IT業界動向 - Computerworld.jp


Office 2007の署名機能はとても良くできているので将来XAdESでも対応できるようになればなぁ、、、と思っているんですがOffice 2007で保存したドキュメントをOpen Documentに変換して保存したら「当然」署名はつけ直しですよね、、、、ちょっと面倒くさい、、、、、
最新記事
Categories
Archives
Twitter
記事Google検索

本ブログ内をGoogle検索
Yahoo!アクセス解析
Travel Advisor
記事検索
QRコード
QRコード
  • ライブドアブログ