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

Go Proposal Weekly Digest

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

#76133accepted

crypto/x509: add Certificate.RawSignatureAlgorithm

ステータス変更: likely_accept accepted

要約

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

概要

crypto/x509 パッケージの CertificateCertificateRequestRevocationList の3つの型に RawSignatureAlgorithm []byte フィールドを追加するプロポーザルです。このフィールドにより、Goが認識しない署名アルゴリズム(例:実験的な新規アルゴリズム)が使われた証明書に対しても、その署名アルゴリズム識別子をDERエンコードされたバイト列として取得できるようになります。

ステータス変更

likely_acceptaccepted
2026年4月29日の週次プロポーザルレビューで likely_accept となり、その後2026年5月6日に反対意見が出なかったため accepted に昇格しました。@aclements がプロポーザルレビューグループを代表して決定を公表しています。

技術的背景

現状の問題点

crypto/x509.ParseCertificate() は、Goが既知の署名アルゴリズム(RSA、ECDSA、Ed25519など)のみを SignatureAlgorithm フィールドにマッピングします。未知のアルゴリズムが使われた証明書を解析した場合、SignatureAlgorithmUnknownSignatureAlgorithm に設定されてしまい、どのアルゴリズムが実際に使われているかを確認する手段がありませんでした。
この問題は、Merkle Tree Certificates(MTC)の実装を進めていた提案者が直面した課題です。MTCはTLSのCertificate Transparencyを発行プロセスに統合した新しい証明書形式で、id-alg-mtcProof(OID: 1.3.6.1.4.1.44363.47.0)という独自の署名アルゴリズムを使います。この署名はMerkleインクルージョンプルーフで構成され、IETF DRAFTでまだ標準化が進行中のため、OIDが確定していない実験的な段階です。

// 現状: 未知の署名アルゴリズムを持つ証明書を解析した場合
cert, _ := x509.ParseCertificate(mtcCertDER)
fmt.Println(cert.SignatureAlgorithm) // => UnknownSignatureAlgorithm
// アルゴリズムの詳細を確認する手段がない

提案された解決策

3つの型に RawSignatureAlgorithm []byte フィールドを追加します。このフィールドは証明書内の AlgorithmIdentifier(OIDとオプションのANYパラメータを含むASN.1構造体)をDERエンコードされたバイト列として保持します。

// Certificate、CertificateRequest、RevocationList に追加されるフィールド
RawSignatureAlgorithm []byte // DER encoded AlgorithmIdentifier

既存の RawIssuerRawSubject などの Raw* フィールドとの設計方針の一貫性を保つアプローチです。pkix.AlgorithmIdentifier 型を使う選択肢も検討されましたが、この型が古い asn1.ObjectIdentifier 型に依存しているため採用されませんでした。

これによって何ができるようになるか

コード例

// Before: 従来の書き方(未知のアルゴリズムを確認できない)
cert, _ := x509.ParseCertificate(der)
if cert.SignatureAlgorithm == x509.UnknownSignatureAlgorithm {
    // どのアルゴリズムかを確認する手段がなく、処理を進められない
    return errors.New("unknown signature algorithm")
}
// After: RawSignatureAlgorithm を使った書き方
cert, _ := x509.ParseCertificate(der)
// DERエンコードされたAlgorithmIdentifierを期待値と直接バイト比較
expectedMTCAlgID := /* id-alg-mtcProofのDERエンコード */ []byte{...}
if bytes.Equal(cert.RawSignatureAlgorithm, expectedMTCAlgID) {
    // MTCのプルーフ検証ロジックを実行
    err := verifyMTCProof(cert.Signature, mtcTrustStore)
}
// または cryptobyte を使ってOIDを個別に取得する
var algID cryptobyte.String
if !string(cert.RawSignatureAlgorithm).ReadASN1(&algID, asn1.SEQUENCE) {
    // エラー処理
}
// OIDや付随するパラメータを解析して詳細確認

具体的なユースケースは以下の通りです。

  1. Merkle Tree Certificates(MTC)の実装: 証明書透明性をTLS証明書発行に統合した新規格の実験的実装で、標準化前の段階でも ParseCertificate を利用できる。
  2. ポスト量子暗号への移行: ML-DSAなどの新しい署名アルゴリズムを試験的に利用する際に、Goが標準サポートしていないアルゴリズムの識別が可能になる。
  3. 証明書の監査・解析ツール: 証明書の署名アルゴリズムを詳細にロギング・監査するツールで、未知アルゴリズムの詳細情報を取得できる。

議論のハイライト

  • []byte vs pkix.AlgorithmIdentifier: FiloSottile(Goコアチーム)は pkix.AlgorithmIdentifier 型の使用を避けたいと明言。この型が廃止を予定している asn1.ObjectIdentifier に依存しているため、DERバイト列での露出を選択した。
  • MTC署名アルゴリズムの直接サポートは時期尚早: 仕様がまだドラフト段階でOIDが確定していないため、フルサポートを追加するのではなく、Raw形式での露出という最小限のアプローチが採択された。
  • 適用範囲の拡大: 当初は Certificate のみが対象だったが、aarongable(Googleエンジニア)の提案により RevocationList も、FiloSottile の判断により CertificateRequest も追加された。いずれもASN.1構造上で同様の signatureAlgorithm フィールドを持つためです。
  • 設計の一貫性: 既存の RawIssuerRawSubjectPublicKeyInfo などの Raw* フィールドのパターンに倣うことで、APIの一貫性を維持している。
  • 代替案として関連する VerifyOptions.UnknownAlgorithmVerifier(#74024): コールバックで未知アルゴリズムの署名検証を担う別のプロポーザルも存在するが、今回のプロポーザルはより低レベルで汎用的なアクセス手段を提供する位置づけ。

関連リンク