メインコンテンツへスキップ

Go Proposal Weekly Digest

Go言語のproposal更新を毎週お届け

#76133active

crypto/x509: add Certificate.RawSignatureAlgorithm

新規提案

要約

AIによる要約であり、誤りを含む場合があります。

概要

crypto/x509 パッケージの CertificateCertificateRequestRevocationList 構造体に 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を確認したくても、フィールドが存在しない

提案された解決策

以下のフィールドを CertificateCertificateRequestRevocationList の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フィールド公開が現実的な選択肢として浮上しました

関連リンク