crl_override (and extensions) in /api/v1/sign request body are silently ignored by the HTTP API

オープン 初心者向け
#1,439 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 3 日以内に返信

@Hashim1999164 がすでに取り組んでいます。

2026年8月12日 から。

  • #1444 @Hashim1999164 による — オープン

評価

難易度
2/5
見積もり時間
半日
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
静か
技術スタック
go
領域
api, backend

調査の方向性

api/signhandler/signhandler.go から始め、jsonSignRequest を jsonReqToTrue() を通じて追跡し、その後 HTTP パスを signer/local/local.go と比較します。提供されている curl コマンドを使ってリクエストを再現し、openssl で証明書を調べます。crl_override と extensions が両方の API 署名パスを通じて保持され、結果の証明書に要求した拡張が現れれば完了です。

索引モデルが issue の本文から書いたものです。

説明

Version: 1.6.5 (also present on master as of this writing) · Go 1.20.14

Summary

signer.SignRequest defines a CRLOverride field (JSON tag crl_override) that the local signer honors to set a per-request CRL Distribution Point. However, when signing through the HTTP /api/v1/sign (and /api/v1/authsign) API, the field is silently dropped. The issued certificate contains no CRL Distribution Points extension (2.5.29.31), and no error or warning is returned. The same applies to the extensions field.

Expected behavior

Posting crl_override to /api/v1/sign embeds a CRLDistributionPoints (2.5.29.31) extension in the issued certificate, matching the behavior of the local signer library and the documented SignRequest schema.

Actual behavior

The request succeeds, but the returned certificate has no 2.5.29.31 extension. crl_override is accepted (no validation error) yet has no effect.

Root cause

The HTTP handler does not unmarshal the body into signer.SignRequest. It uses an intermediate jsonSignRequest struct, then jsonReqToTrue() copies only a fixed subset of fields into the real SignRequest. Neither crl_override nor extensions is part of that struct or the copy:

api/signhandler/signhandler.go:

// This type is meant to be unmarshalled from JSON so that there can be a
// hostname field in the API
// TODO: Change the API such that the normal struct can be used.
type jsonSignRequest struct {
	Hostname string          `json:"hostname"`
	Hosts    []string        `json:"hosts"`
	Request  string          `json:"certificate_request"`
	Subject  *signer.Subject `json:"subject,omitempty"`
	Profile  string          `json:"profile"`
	Label    string          `json:"label"`
	Serial   *big.Int        `json:"serial,omitempty"`
	Bundle   bool            `json:"bundle"`
}
func jsonReqToTrue(js jsonSignRequest) signer.SignRequest {
	// ... never sets CRLOverride or Extensions ...
	return signer.SignRequest{
		Hosts:   js.Hosts,
		Subject: sub,
		Request: js.Request,
		Profile: js.Profile,
		Label:   js.Label,
		Serial:  js.Serial,
	}
}

By contrast, signer/local/local.go does honor CRLOverride (so it works when CFSSL is used as a Go library), which makes the API behavior surprising:

if req.CRLOverride != "" {
	safeTemplate.CRLDistributionPoints = []string{req.CRLOverride}
}
// ... preserved across FillTemplate via save/restore of distPoints ...

The existing TODO: Change the API such that the normal struct can be used. comment acknowledges this divergence.

Steps to reproduce

Run a CFSSL server with any signing profile (no crl_url set in config.json):

cfssl serve -address 0.0.0.0 -port 8888 -ca ca.pem -ca-key ca-key.pem -config config.json

Sign a CSR via the HTTP API with crl_override:

curl -s http://localhost:8888/api/v1/cfssl/sign -d '{
  "certificate_request": "'"$(awk 'NF {sub(/\r/,""); printf "%s\\n",$0}' test.csr)"'",
  "crl_override": "http://example.com/my.crl"
}' | jq -r '.result.certificate' > out.pem

Inspect the issued certificate:

openssl x509 -in out.pem -noout -text | grep -A2 "CRL Distribution"
# (no output — extension is absent)

Observed: no X509v3 CRL Distribution Points in the certificate.
Expected: the extension present with URI http://example.com/my.crl.

Workaround

Set crl_url in the signing profile (config.json), which FillTemplate applies server-side:

{ "signing": { "default": { "crl_url": "http://example.com/my.crl", "expiry": "8760h", "usages": ["signing","server auth"] } } }

This works but is static per-profile and cannot vary per request.

Suggested fix

Add CRLOverride string \json:"crl_override"(andExtensions) to jsonSignRequestand copy them in both branches ofjsonReqToTrue(), or follow the existing TODO and unmarshal directly into signer.SignRequest. Alternatively, if per-request override is intentionally unsupported over HTTP, document it and return a validation error when these fields are supplied.

主要言語
Go
スター
9.5k
フォーク
1.2k
平均マージ
8日 2時間
マージ済み PR(30日)
3

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

cloudflare/cfssl のほかの issue

cloudflare/cfssl の issue をすべて見る

似ている issue

Go の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。