diff --git a/ca/ca.go b/ca/ca.go index e55b2d66560..509adc972c6 100644 --- a/ca/ca.go +++ b/ca/ca.go @@ -126,7 +126,7 @@ type certificateAuthorityImpl struct { issuers issuerMaps certProfiles certProfilesMaps - prefix int // Prepended to the serial number + prefix uint8 // Prepended to the serial number maxNames int keyPolicy goodkey.KeyPolicy clk clock.Clock @@ -233,7 +233,7 @@ func NewCertificateAuthorityImpl( boulderIssuers []*issuance.Issuer, defaultCertProfileName string, certificateProfiles map[string]*issuance.ProfileConfig, - serialPrefix int, + serialPrefix uint8, maxNames int, keyPolicy goodkey.KeyPolicy, logger blog.Logger, @@ -244,7 +244,7 @@ func NewCertificateAuthorityImpl( var err error if serialPrefix < 1 || serialPrefix > 127 { - err = errors.New("serial prefix must be between 1 and 127") + err = errors.New("serial prefix must be between 1 (0x01) and 127 (0x7f)") return nil, err } diff --git a/ca/ca_test.go b/ca/ca_test.go index 3dc12206dea..a8fe83eec71 100644 --- a/ca/ca_test.go +++ b/ca/ca_test.go @@ -103,7 +103,7 @@ type testCtx struct { crl *crlImpl defaultCertProfileName string certProfiles map[string]*issuance.ProfileConfig - serialPrefix int + serialPrefix uint8 maxNames int boulderIssuers []*issuance.Issuer keyPolicy goodkey.KeyPolicy @@ -237,7 +237,7 @@ func setup(t *testing.T) *testCtx { crl: crl, defaultCertProfileName: "legacy", certProfiles: certProfiles, - serialPrefix: 17, + serialPrefix: 0x11, maxNames: 2, boulderIssuers: boulderIssuers, keyPolicy: keyPolicy, @@ -257,7 +257,7 @@ func TestSerialPrefix(t *testing.T) { nil, "", nil, - 0, + 0x00, testCtx.maxNames, testCtx.keyPolicy, testCtx.logger, @@ -271,7 +271,7 @@ func TestSerialPrefix(t *testing.T) { nil, "", nil, - 128, + 0x80, testCtx.maxNames, testCtx.keyPolicy, testCtx.logger, diff --git a/cmd/boulder-ca/main.go b/cmd/boulder-ca/main.go index b82d76db73e..fe5961c88f6 100644 --- a/cmd/boulder-ca/main.go +++ b/cmd/boulder-ca/main.go @@ -5,6 +5,7 @@ import ( "flag" "os" "reflect" + "strconv" "time" "github.com/letsencrypt/boulder/ca" @@ -61,15 +62,26 @@ type Config struct { } // How long issued certificates are valid for. - // Deprecated: Use Issuace.CertProfiles.MaxValidityPeriod instead. + // Deprecated: Use Issuance.CertProfiles.MaxValidityPeriod instead. Expiry config.Duration // How far back certificates should be backdated. - // Deprecated: Use Issuace.CertProfiles.MaxValidityBackdate instead. + // Deprecated: Use Issuance.CertProfiles.MaxValidityBackdate instead. Backdate config.Duration // What digits we should prepend to serials after randomly generating them. - SerialPrefix int `validate:"required,min=1,max=127"` + // Deprecated: Use SerialPrefixHex instead. + SerialPrefix int `validate:"required_without=SerialPrefixHex,omitempty,min=1,max=127"` + + // What hex string we should prepend to serials after randomly + // generating them. The minimum value is "01" to ensure that at least + // one bit in the prefix byte is set. The maximum value is "7f" to + // ensure that the first bit in the prefix byte is not set. The validate + // library cannot enforce mix/max values on strings, so that is done in + // NewCertificateAuthorityImpl. + // + // TODO(#7213): Replace `required_without` with `required` when SerialPrefix is removed. + SerialPrefixHex string `validate:"required_without=SerialPrefix,omitempty,hexadecimal,len=2"` // MaxNames is the maximum number of subjectAltNames in a single cert. // The value supplied MUST be greater than 0 and no more than 100. These @@ -152,6 +164,13 @@ func main() { c.CA.DebugAddr = *debugAddr } + serialPrefix := uint8(c.CA.SerialPrefix) + if c.CA.SerialPrefixHex != "" { + parsedSerialPrefix, err := strconv.ParseUint(c.CA.SerialPrefixHex, 16, 8) + cmd.FailOnError(err, "Couldn't convert SerialPrefixHex to int") + serialPrefix = uint8(parsedSerialPrefix) + } + if c.CA.MaxNames == 0 { cmd.Fail("Error in CA config: MaxNames must not be 0") } @@ -280,7 +299,7 @@ func main() { issuers, c.CA.Issuance.DefaultCertificateProfileName, c.CA.Issuance.CertProfiles, - c.CA.SerialPrefix, + serialPrefix, c.CA.MaxNames, kp, logger, diff --git a/test/config-next/ca.json b/test/config-next/ca.json index 9c5fa449f63..346ccc63c1b 100644 --- a/test/config-next/ca.json +++ b/test/config-next/ca.json @@ -142,7 +142,7 @@ } ] }, - "serialPrefix": 127, + "serialPrefixHex": "7f", "maxNames": 100, "lifespanOCSP": "96h", "goodkey": {