Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mtgag committed Aug 30, 2023
2 parents d4f2f9f + 71d5e4b commit 88c933e
Show file tree
Hide file tree
Showing 56 changed files with 2,476 additions and 323 deletions.
455 changes: 300 additions & 155 deletions v3/integration/config.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion v3/integration/small.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
"e_issuer_dn_country_not_printable_string": {},
"e_issuer_field_empty": {},
"e_key_usage_and_extended_key_usage_inconsistent": {
"ErrCount": 18858
"ErrCount": 1020
},
"e_mp_authority_key_identifier_correct": {
"ErrCount": 125
Expand Down
3 changes: 3 additions & 0 deletions v3/lint/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ func (l *CertificateLint) Execute(cert *x509.Certificate, config Configuration)
if l.Source == CABFBaselineRequirements && !util.IsServerAuthCert(cert) {
return &LintResult{Status: NA}
}
if l.Source == CABFSMIMEBaselineRequirements && !util.IsEmailProtectionCert(cert) {
return &LintResult{Status: NA}
}
lint := l.Lint()
err := config.MaybeConfigure(lint, l.Name)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions v3/lint/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ var (
// LintResult contains a LintStatus, and an optional human-readable description.
// The output of a lint is a LintResult.
type LintResult struct {
Status LintStatus `json:"result"`
Details string `json:"details,omitempty"`
Status LintStatus `json:"result"`
Details string `json:"details,omitempty"`
LintMetadata LintMetadata `json:"-"`
}

// MarshalJSON implements the json.Marshaler interface.
Expand Down
25 changes: 13 additions & 12 deletions v3/lint/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@ import (
type LintSource string

const (
UnknownLintSource LintSource = "Unknown"
RFC3279 LintSource = "RFC3279"
RFC5280 LintSource = "RFC5280"
RFC5480 LintSource = "RFC5480"
RFC5891 LintSource = "RFC5891"
RFC8813 LintSource = "RFC8813"
CABFBaselineRequirements LintSource = "CABF_BR"
CABFEVGuidelines LintSource = "CABF_EV"
MozillaRootStorePolicy LintSource = "Mozilla"
AppleRootStorePolicy LintSource = "Apple"
Community LintSource = "Community"
EtsiEsi LintSource = "ETSI_ESI"
UnknownLintSource LintSource = "Unknown"
RFC3279 LintSource = "RFC3279"
RFC5280 LintSource = "RFC5280"
RFC5480 LintSource = "RFC5480"
RFC5891 LintSource = "RFC5891"
RFC8813 LintSource = "RFC8813"
CABFBaselineRequirements LintSource = "CABF_BR"
CABFSMIMEBaselineRequirements LintSource = "CABF_SMIME_BR"
CABFEVGuidelines LintSource = "CABF_EV"
MozillaRootStorePolicy LintSource = "Mozilla"
AppleRootStorePolicy LintSource = "Apple"
Community LintSource = "Community"
EtsiEsi LintSource = "ETSI_ESI"
)

// UnmarshalJSON implements the json.Unmarshaler interface. It ensures that the
Expand Down
60 changes: 60 additions & 0 deletions v3/lints/cabf_br/lint_cabf_crl_reason_code_not_critical.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package cabf_br

/*
* ZLint Copyright 2023 Regents of the University of Michigan
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import (
"github.com/zmap/zcrypto/x509"
"github.com/zmap/zlint/v3/lint"
"github.com/zmap/zlint/v3/util"
)

type crlReasonCodeNotCritical struct{}

func init() {
lint.RegisterRevocationListLint(&lint.RevocationListLint{
LintMetadata: lint.LintMetadata{
Name: "e_cab_crl_reason_code_not_critical",
Description: "If present, CRL Reason Code extension MUST NOT be marked critical.",
Citation: "BRs: 7.2.2",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.CABEffectiveDate,
},
Lint: NewCrlReasonCodeNotCritical,
})
}

func NewCrlReasonCodeNotCritical() lint.RevocationListLintInterface {
return &crlReasonCodeNotCritical{}
}

func (l *crlReasonCodeNotCritical) CheckApplies(c *x509.RevocationList) bool {
return len(c.RevokedCertificates) > 0
}

func (l *crlReasonCodeNotCritical) Execute(c *x509.RevocationList) *lint.LintResult {
for _, c := range c.RevokedCertificates {
if c.ReasonCode == nil {
continue
}
for _, ext := range c.Extensions {
if ext.Id.Equal(util.ReasonCodeOID) {
if ext.Critical {
return &lint.LintResult{Status: lint.Error, Details: "CRL Reason Code extension MUST NOT be marked as critical."}
}
}
}
}
return &lint.LintResult{Status: lint.Pass}
}
64 changes: 64 additions & 0 deletions v3/lints/cabf_br/lint_cabf_crl_reason_code_not_critical_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package cabf_br

import (
"strings"
"testing"

"github.com/zmap/zlint/v3/lint"
"github.com/zmap/zlint/v3/test"
)

/*
* ZLint Copyright 2023 Regents of the University of Michigan
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

func TestCrlReasonCodeNotCritical(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
path string
want lint.LintStatus
wantSubStr string
}{
{
name: "CRL reason code critical",
path: "crlReasonCodeCrit.pem",
want: lint.Error,
wantSubStr: "MUST NOT be marked as critical",
},
{
name: "CRL with reason code 5",
path: "crlWithReasonCode5.pem",
want: lint.Pass,
},
{
name: "CRL no revoked certificates",
path: "crlEmpty.pem",
want: lint.NA,
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
gotStatus := test.TestRevocationListLint(t, "e_cab_crl_reason_code_not_critical", tc.path)
if tc.want != gotStatus.Status {
t.Errorf("%s: expected %s, got %s", tc.path, tc.want, gotStatus.Status)
}
if !strings.Contains(gotStatus.Details, tc.wantSubStr) {
t.Errorf("%s: expected %s, got %s", tc.path, tc.wantSubStr, gotStatus.Details)
}
})
}

}
68 changes: 68 additions & 0 deletions v3/lints/cabf_br/lint_cabf_crl_valid_reason_codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package cabf_br

/*
* ZLint Copyright 2023 Regents of the University of Michigan
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import (
"github.com/zmap/zcrypto/x509"
"github.com/zmap/zlint/v3/lint"
"github.com/zmap/zlint/v3/util"
)

type crlHasValidReasonCodes struct{}

func init() {
lint.RegisterRevocationListLint(&lint.RevocationListLint{
LintMetadata: lint.LintMetadata{
Name: "e_cab_crl_has_valid_reason_code",
Description: "Only the following CRLReasons MAY be present: 1, 3, 4, 5, 9.",
Citation: "BRs: 7.2.2",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.CABFBRs_1_8_7_Date,
},
Lint: NewCrlHasValidReasonCode,
})
}

func NewCrlHasValidReasonCode() lint.RevocationListLintInterface {
return &crlHasValidReasonCodes{}
}

func (l *crlHasValidReasonCodes) CheckApplies(c *x509.RevocationList) bool {
return len(c.RevokedCertificates) > 0
}

var validReasons = map[int]bool{
1: true,
3: true,
4: true,
5: true,
9: true,
}

func (l *crlHasValidReasonCodes) Execute(c *x509.RevocationList) *lint.LintResult {
for _, c := range c.RevokedCertificates {
if c.ReasonCode == nil {
continue
}
code := *c.ReasonCode
if code == 0 {
return &lint.LintResult{Status: lint.Error, Details: "The reason code CRL entry extension SHOULD be absent instead of using the unspecified (0) reasonCode value."}
}
if _, ok := validReasons[code]; !ok {
return &lint.LintResult{Status: lint.Error, Details: "Reason code not included in BR: 7.2.2"}
}
}
return &lint.LintResult{Status: lint.Pass}
}
76 changes: 76 additions & 0 deletions v3/lints/cabf_br/lint_cabf_crl_valid_reason_codes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cabf_br

import (
"strings"
"testing"

"github.com/zmap/zlint/v3/lint"
"github.com/zmap/zlint/v3/test"
)

/*
* ZLint Copyright 2023 Regents of the University of Michigan
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

func TestCrlValidReasonCodes(t *testing.T) {
t.Parallel()
testCases := []struct {
name string
path string
want lint.LintStatus
wantSubStr string
}{
{
name: "CRL with reason code 0",
path: "crlWithReasonCode0.pem",
want: lint.Error,
wantSubStr: "The reason code CRL entry extension SHOULD be absent instead of using the unspecified",
},
{
// This test case is significant since reason code 2 is not allowed by CABF
name: "CRL with reason code 2",
path: "crlWithReasonCode2.pem",
want: lint.Error,
wantSubStr: "Reason code not included in BR: 7.2.2",
},
{
name: "CRL with reason code 5",
path: "crlWithReasonCode5.pem",
want: lint.Pass,
},
{
name: "CRL with reason code 7",
path: "crlWithReasonCode7.pem",
want: lint.Error,
wantSubStr: "Reason code not included in BR: 7.2.2",
},
{
name: "CRL thisUpdate before enforcement",
path: "crlThisUpdate20230505.pem",
want: lint.NE,
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
gotStatus := test.TestRevocationListLint(t, "e_cab_crl_has_valid_reason_code", tc.path)
if tc.want != gotStatus.Status {
t.Errorf("%s: expected %s, got %s", tc.path, tc.want, gotStatus.Status)
}
if !strings.Contains(gotStatus.Details, tc.wantSubStr) {
t.Errorf("%s: expected %s, got %s", tc.path, tc.wantSubStr, gotStatus.Details)
}
})
}
}
Loading

0 comments on commit 88c933e

Please sign in to comment.