...
1 package rfc
2
3 import (
4 "github.com/zmap/zcrypto/encoding/asn1"
5 "github.com/zmap/zcrypto/x509"
6 "github.com/zmap/zlint/v3/lint"
7 "github.com/zmap/zlint/v3/util"
8
9 "github.com/letsencrypt/boulder/linter/lints"
10 )
11
12 type crlHasNumber struct{}
13
14
20
21 func init() {
22 lint.RegisterRevocationListLint(&lint.RevocationListLint{
23 LintMetadata: lint.LintMetadata{
24 Name: "e_crl_has_number",
25 Description: "CRLs must have a well-formed CRL Number extension",
26 Citation: "RFC 5280: 5.2.3",
27 Source: lint.RFC5280,
28 EffectiveDate: util.RFC5280Date,
29 },
30 Lint: NewCrlHasNumber,
31 })
32 }
33
34 func NewCrlHasNumber() lint.RevocationListLintInterface {
35 return &crlHasNumber{}
36 }
37
38 func (l *crlHasNumber) CheckApplies(c *x509.RevocationList) bool {
39 return true
40 }
41
42 func (l *crlHasNumber) Execute(c *x509.RevocationList) *lint.LintResult {
43 if c.Number == nil {
44 return &lint.LintResult{
45 Status: lint.Error,
46 Details: "CRLs MUST include the CRL number extension",
47 }
48 }
49
50 crlNumberOID := asn1.ObjectIdentifier{2, 5, 29, 20}
51 ext := lints.GetExtWithOID(c.Extensions, crlNumberOID)
52 if ext != nil && ext.Critical {
53 return &lint.LintResult{
54 Status: lint.Error,
55 Details: "CRL Number MUST NOT be marked critical",
56 }
57 }
58
59 numBytes := c.Number.Bytes()
60 if len(numBytes) > 20 || (len(numBytes) == 20 && numBytes[0]&0x80 != 0) {
61 return &lint.LintResult{
62 Status: lint.Error,
63 Details: "CRL Number MUST NOT be longer than 20 octets",
64 }
65 }
66 return &lint.LintResult{Status: lint.Pass}
67 }
68
View as plain text