Skip to content

Commit d6e4f9a

Browse files
authored
Ceremony: allow CRL ceremonies to skip certain lints (#8368)
Zlint has added more lints, some of which (like zmap/zlint#916) are insufficiently smart and can't tell the difference between a Subscriber CRL and a Root CRL. We need the ability to skip lints like this, so give the CRL ceremony the same capability as we already have for our various certificate ceremonies.
1 parent 513e113 commit d6e4f9a

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

cmd/ceremony/crl.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
"github.com/letsencrypt/boulder/linter"
1414
)
1515

16-
func generateCRL(signer crypto.Signer, issuer *x509.Certificate, thisUpdate, nextUpdate time.Time, number int64, revokedCertificates []x509.RevocationListEntry) ([]byte, error) {
16+
func generateCRL(signer crypto.Signer, issuer *x509.Certificate, thisUpdate, nextUpdate time.Time, number int64, revokedCertificates []x509.RevocationListEntry, skipLints []string) ([]byte, error) {
1717
template := &x509.RevocationList{
1818
RevokedCertificateEntries: revokedCertificates,
1919
Number: big.NewInt(number),
@@ -42,7 +42,7 @@ func generateCRL(signer crypto.Signer, issuer *x509.Certificate, thisUpdate, nex
4242
}
4343
template.ExtraExtensions = append(template.ExtraExtensions, *idp)
4444

45-
err = linter.CheckCRL(template, issuer, signer, []string{})
45+
err = linter.CheckCRL(template, issuer, signer, skipLints)
4646
if err != nil {
4747
return nil, fmt.Errorf("crl failed pre-issuance lint: %w", err)
4848
}

cmd/ceremony/crl_test.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,28 @@ import (
1818
)
1919

2020
func TestGenerateCRLTimeBounds(t *testing.T) {
21-
_, err := generateCRL(nil, nil, time.Now().Add(time.Hour), time.Now(), 1, nil)
21+
_, err := generateCRL(nil, nil, time.Now().Add(time.Hour), time.Now(), 1, nil, []string{})
2222
test.AssertError(t, err, "generateCRL did not fail")
2323
test.AssertEquals(t, err.Error(), "thisUpdate must be before nextUpdate")
2424

2525
_, err = generateCRL(nil, &x509.Certificate{
2626
NotBefore: time.Now().Add(time.Hour),
2727
NotAfter: time.Now(),
28-
}, time.Now(), time.Now(), 1, nil)
28+
}, time.Now(), time.Now(), 1, nil, []string{})
2929
test.AssertError(t, err, "generateCRL did not fail")
3030
test.AssertEquals(t, err.Error(), "thisUpdate is before issuing certificate's notBefore")
3131

3232
_, err = generateCRL(nil, &x509.Certificate{
3333
NotBefore: time.Now(),
3434
NotAfter: time.Now().Add(time.Hour * 2),
35-
}, time.Now().Add(time.Hour), time.Now().Add(time.Hour*3), 1, nil)
35+
}, time.Now().Add(time.Hour), time.Now().Add(time.Hour*3), 1, nil, []string{})
3636
test.AssertError(t, err, "generateCRL did not fail")
3737
test.AssertEquals(t, err.Error(), "nextUpdate is after issuing certificate's notAfter")
3838

3939
_, err = generateCRL(nil, &x509.Certificate{
4040
NotBefore: time.Now(),
4141
NotAfter: time.Now().Add(time.Hour * 24 * 370),
42-
}, time.Now(), time.Now().Add(time.Hour*24*366), 1, nil)
42+
}, time.Now(), time.Now().Add(time.Hour*24*366), 1, nil, []string{})
4343
test.AssertError(t, err, "generateCRL did not fail")
4444
test.AssertEquals(t, err.Error(), "nextUpdate must be less than 12 months after thisUpdate")
4545
}
@@ -79,17 +79,26 @@ func TestGenerateCRLLints(t *testing.T) {
7979
cert, err = x509.ParseCertificate(certBytes)
8080
test.AssertNotError(t, err, "failed to parse test cert")
8181

82-
// This CRL should fail the following lint:
83-
// - e_crl_acceptable_reason_codes (because 6 is forbidden)
82+
// This CRL should fail the "e_crl_next_update_invalid" lint because the
83+
// validity interval is more than 10 days, and this lint can't tell the
84+
// difference between end-entity and CA CRLs.
8485
_, err = generateCRL(&wrappedSigner{k}, cert, time.Now().Add(time.Hour), time.Now().Add(100*24*time.Hour), 1, []x509.RevocationListEntry{
8586
{
8687
SerialNumber: big.NewInt(12345),
8788
RevocationTime: time.Now().Add(time.Hour),
88-
ReasonCode: 6,
8989
},
90-
})
90+
}, []string{})
9191
test.AssertError(t, err, "generateCRL did not fail")
92-
test.AssertContains(t, err.Error(), "e_crl_acceptable_reason_codes")
92+
test.AssertContains(t, err.Error(), "e_crl_next_update_invalid")
93+
94+
// But we can tell it to ignore that lint, too.
95+
_, err = generateCRL(&wrappedSigner{k}, cert, time.Now().Add(time.Hour), time.Now().Add(100*24*time.Hour), 1, []x509.RevocationListEntry{
96+
{
97+
SerialNumber: big.NewInt(12345),
98+
RevocationTime: time.Now().Add(time.Hour),
99+
},
100+
}, []string{"e_crl_next_update_invalid"})
101+
test.AssertNotError(t, err, "generateCRL should have ignored the failing lint")
93102
}
94103

95104
func TestGenerateCRL(t *testing.T) {
@@ -112,7 +121,7 @@ func TestGenerateCRL(t *testing.T) {
112121
cert, err := x509.ParseCertificate(certBytes)
113122
test.AssertNotError(t, err, "failed to parse test cert")
114123

115-
crlPEM, err := generateCRL(&wrappedSigner{k}, cert, time.Now().Add(time.Hour), time.Now().Add(time.Hour*2), 1, nil)
124+
crlPEM, err := generateCRL(&wrappedSigner{k}, cert, time.Now().Add(time.Hour), time.Now().Add(time.Hour*2), 1, nil, []string{})
116125
test.AssertNotError(t, err, "generateCRL failed with valid profile")
117126

118127
pemBlock, _ := pem.Decode(crlPEM)

cmd/ceremony/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ type crlConfig struct {
450450
RevocationReason int `yaml:"revocation-reason"`
451451
} `yaml:"revoked-certificates"`
452452
} `yaml:"crl-profile"`
453+
SkipLints []string `yaml:"skip-lints"`
453454
}
454455

455456
func (cc crlConfig) validate() error {
@@ -1004,7 +1005,7 @@ func crlCeremony(configBytes []byte) error {
10041005
revokedCertificates = append(revokedCertificates, revokedCert)
10051006
}
10061007

1007-
crlBytes, err := generateCRL(signer, issuer, thisUpdate, nextUpdate, config.CRLProfile.Number, revokedCertificates)
1008+
crlBytes, err := generateCRL(signer, issuer, thisUpdate, nextUpdate, config.CRLProfile.Number, revokedCertificates, config.SkipLints)
10081009
if err != nil {
10091010
return err
10101011
}

0 commit comments

Comments
 (0)