特定のeIDAS PKIによるOCSP応答では、時々、BIT STRINGからアンパックしたときに、INTEGER構成要素に不必要な先行00バイトがあり、したがってDERエンコードされていないECDSA署名が含まれる署名値を時々取得します。
376 10: . . . . . SEQUENCE {
378 8: . . . . . . OBJECT IDENTIFIER ecdsaWithSHA256 (1 2 840 10045 4 3 2)
: . . . . . . . (ANSI X9.62 ECDSA algorithm with SHA256)
: . . . . . . }
388 71: . . . . . BIT STRING, encapsulates {
391 68: . . . . . . SEQUENCE {
393 32: . . . . . . . INTEGER
: . . . . . . . . 6D 7F 95 D5 8E 9B E1 18 m.......
: . . . . . . . . 60 DC A6 D6 91 37 0D B4 `....7..
: . . . . . . . . AF D5 C9 A0 E8 21 40 4A .....!@J
: . . . . . . . . 94 8B 9F AA 6C DC F2 8C
427 32: . . . . . . . INTEGER
: . . . . . . . . 00 1B FD 92 CB 1E E2 A8 ........
: . . . . . . . . 2B 18 FC 37 ED 42 D0 66 +..7.B.f
: . . . . . . . . E6 52 63 88 47 88 EE 00 .Rc.G...
: . . . . . . . . FF 37 CF 20 8F F8 3C C1
: . . . . . . . . Error: Integer has non-DER encoding.
: . . . . . . . }
: . . . . . . }
ここですでにASN.1ダンプユーティリティは、この非DERエンコーディングはエラーであると主張し、現在のBouncyCastleバージョンもそうです(DERエンコーディングのチェックは2016年10月のコミットで導入されましたが、残念ながら問題や標準の参照はありません)コメント)。
BouncyCastleが厳しすぎるのか、OCSPレスポンダが実際に無効な応答を作成するのかを知りたい残念ながら、そこで使用されているエンコーディングを明確に示す基準(eIDAS PKIに関連)はまだ見つかりません。
OCSPのRFC 6960は言う
応答の値は、BasicOCSPResponseのDERエンコードにする必要があります(SHALL)。
BasicOCSPResponse ::= SEQUENCE { tbsResponseData ResponseData, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING, certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
しかし、これはBIT STRING signature
DERエンコードされ、データはカプセル化されません。
TR-03111(ドイツ連邦情報セキュリティ局による楕円曲線暗号に関する技術ガイドライン)によると
X9.62形式では、ECDSA署名(r; s)は、次の構文でASN.1構造としてエンコードされます。
ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER }
署名をビット文字列に埋め込むには、DERでエンコードされたECDSA-Sig-Valueをビット文字列の値(タグと長さフィールドを含む)にする必要があります。
しかし、ドイツ連邦情報セキュリティ局の要件は、eIDAS PKIにとって一般的には規範的ではありません。
X9.62では、
これらのASN.1定義はDistinguished Encoding Rules([〜#〜] der [〜#〜])を使用してエンコードされる可能性がありますが、他のエンコードルールも使用できます。
ISO/IEC 8825-1:2003によると、BER/DERでエンコードされた整数は次のようになります。
8.3.2整数値エンコーディングのコンテンツオクテットが複数のオクテットで構成されている場合、最初のオクテットのビットと2番目のオクテットのビット8は次のとおりです。およびb)すべてがゼロであってはならない。注–これらのルールは、整数値が常に最小のオクテット数でエンコードされることを保証します。
どうやらdumpasn1はこれを正確にチェックします:
if( i == 0 )
{
if( ( value == 0x00 ) && ( ( ch & 0x80 ) == 0x00 ) )
warnNonDER = TRUE;
if( ( value == 0xFF ) && ( ( ch & 0x80 ) == 0x80 ) )
warnNonDER = TRUE;
if( warnNonDER )
{
intBuffer[ 0 ] = ( int ) value;
intBuffer[ 1 ] = ch;
}
}
参照: https://github.com/clibs/dumpasn1/blob/master/dumpasn1.c#L1398
だから、エンコーディングはと言っているのでBER/DERはINTEGERでエンコードされているので、そうでなければなりません。