crypto/x509: add Certificate.RawSignatureAlgorithm
要約
概要
crypto/x509 パッケージの Certificate、CertificateRequest、RevocationList 構造体に RawSignatureAlgorithm []byte フィールドを追加することを提案するものです。これにより、Goが認識しない署名アルゴリズムを使用した証明書でも、その署名アルゴリズム識別子(AlgorithmIdentifier)のDERエンコードされたバイト列に直接アクセスできるようになります。
ステータス変更
(新規) → active
2026年4月22日、aclements(Goプロポーザルレビューグループ)がこのプロポーザルをactiveステータスとして週次プロポーザルレビューミーティングのアジェンダに追加しました。FiloSottileがAPIの具体的な形を提示してコアチームの議論が進んだことで、正式レビューの対象となりました。
技術的背景
現状の問題点
crypto/x509.ParseCertificate() は証明書を正常にパースできますが、Go標準ライブラリが知らない署名アルゴリズムが使われている場合、Certificate.SignatureAlgorithm フィールドを UnknownSignatureAlgorithm に設定するだけで終わります。
具体的な問題は、Merkle Tree Certificates(MTC) という新しい証明書形式の実装において顕在化しました。MTCは証明書透明性(Certificate Transparency)とTLS証明書発行を統合する仕様で、標準的なX.509にはない独自の署名アルゴリズムOIDを使用します。
現状、アプリケーションがその証明書の署名アルゴリズムが期待通りのOIDかどうかを確認する手段がありません。OIDそのものにアクセスできないためです。
// 現状: UnknownSignatureAlgorithmしか得られず、詳細を確認できない
cert, _ := x509.ParseCertificate(rawDER)
fmt.Println(cert.SignatureAlgorithm) // => UnknownSignatureAlgorithm
// OIDを確認したくても、フィールドが存在しない
提案された解決策
以下のフィールドを Certificate、CertificateRequest、RevocationList の3つの構造体に追加します。
RawSignatureAlgorithm []byte // DERエンコードされたAlgorithmIdentifier
X.509のAlgorithmIdentifierはOIDとオプションのパラメータ(ANY型)から構成されるため、単純にOIDだけを公開するよりもDERバイト列を公開する方が柔軟性が高い設計です。アプリケーションは期待するAlgorithmIdentifierのDERエンコード値と直接バイト比較できます。また、必要であれば cryptobyte などのライブラリを使ってパースすることも可能です。
なお、既存の pkix.AlgorithmIdentifier 型は旧来の asn1.ObjectIdentifier 型を使っており、FiloSottileはその型から離れる方向性を示しているため、この型を使った新フィールドは提案されていません。
これによって何ができるようになるか
未知の署名アルゴリズムを使用した証明書を処理するアプリケーションが、ライブラリをフォークすることなく標準的な方法で対応できるようになります。
コード例
// Before: UnknownSignatureAlgorithmになり、詳細を確認できない
cert, _ := x509.ParseCertificate(rawDER)
if cert.SignatureAlgorithm == x509.UnknownSignatureAlgorithm {
// MTCのOIDかどうかを確認する手段がない
return errors.New("unknown signature algorithm")
}
// After: RawSignatureAlgorithmで生のDERバイト列を取得し比較できる
cert, _ := x509.ParseCertificate(rawDER)
expectedMTCAlgorithm := []byte{ /* MTCのAlgorithmIdentifierのDERエンコード */ }
if !bytes.Equal(cert.RawSignatureAlgorithm, expectedMTCAlgorithm) {
return errors.New("unexpected signature algorithm")
}
// 必要であればcryptobyte等でパースすることも可能
議論のハイライト
- フィールド形式の選択: davidbenは「OIDだけでなく、オプションのANYパラメータも含むAlgorithmIdentifier全体を扱う必要がある」と指摘し、生のDERバイト列(
RawSignatureAlgorithm)が最もシンプルかつ他のフィールド(RawSubject等)と一貫した方針であると提案しました - 対象構造体の拡張: 当初は
Certificateのみが対象でしたが、aarongableがRevocationListでも同様のAlgorithmIdentifierセマンティクスが存在すると指摘し、FiloSottileがCertificateRequestも含め3構造体に対象を拡張しました pkix.AlgorithmIdentifier型を避けた理由: この型は旧来のasn1.ObjectIdentifierに依存しており、FiloSottileが移行を進めたい型であるため、新フィールドにはDERバイト列を採用しました- 関連する類似プロポーザルとの関係: Issue #74024(
VerifyOptions.UnknownAlgorithmVerifier)も同様の動機から提案されていますが、今回のプロポーザルは署名検証の拡張ではなく、アルゴリズム識別子への読み取りアクセスに絞った最小限のAPIです - MTCの実験的ステータス: MTC仕様はまだドラフト段階でOIDが確定していないため、MTCアルゴリズムをGoが直接サポートするのは時期尚早であり、rawフィールド公開が現実的な選択肢として浮上しました