Skip to content

Commit

Permalink
Part 1 of SC-62 related updates to zlint (#739)
Browse files Browse the repository at this point in the history
* Updated lint for common name handling. The definition for the CN field has switched from deprecated to NOT RECOMMENDED (essentially SHOULD NOT). An IneffectiveDate was added to the original lint.

Added a new lint for subscriber cert basic constraints checking. Post-SC62, basicConstraint MAY be included but MUST be critical if present.

Added a date for SC62 Effective

* fix CheckApplies

* edited the wrong file, reverted and edited the right file.

* add PEMs that exercise the tests properly

* Update v3/lints/cabf_br/lint_sub_cert_basic_constraints_not_critical.go

Co-authored-by: Christopher Henderson <[email protected]>

* Update v3/lints/cabf_br/lint_sub_cert_basic_constraints_not_critical.go

Co-authored-by: Christopher Henderson <[email protected]>

* fix missing import

---------

Co-authored-by: Christopher Henderson <[email protected]>
  • Loading branch information
cardonator and christopher-henderson authored Sep 17, 2023
1 parent 5c4e05f commit 1fd1c0d
Show file tree
Hide file tree
Showing 10 changed files with 353 additions and 6 deletions.
63 changes: 63 additions & 0 deletions v3/lints/cabf_br/lint_sub_cert_basic_constraints_not_critical.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
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 (
"fmt"

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

type subCertBasicConstCrit struct{}

/************************************************
CA/Browser Forum BRs: 7.1.2.7.6 Subscriber Certificate Extensions
| __Extension__ | __Presence__ | __Critical__ | __Description__ |
| ---- | - | - | ----- |
| `basicConstraints` | MAY | Y | See [Section 7.1.2.7.8](#71278-subscriber-certificate-basic-constraints) |
************************************************/

func init() {
lint.RegisterLint(&lint.Lint{
Name: "e_sub_cert_basic_constraints_not_critical",
Description: "basicConstraints MAY appear in the certificate, and when it is included MUST be marked as critical",
Citation: "CA/Browser Forum BRs: 7.1.2.7.6",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.SC62EffectiveDate,
Lint: NewSubCertBasicConstCrit,
})
}

func NewSubCertBasicConstCrit() lint.LintInterface {
return &subCertBasicConstCrit{}
}

func (l *subCertBasicConstCrit) CheckApplies(c *x509.Certificate) bool {
return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.BasicConstOID)
}

func (l *subCertBasicConstCrit) Execute(c *x509.Certificate) *lint.LintResult {
if e := util.GetExtFromCert(c, util.BasicConstOID); e != nil {
if e.Critical {
return &lint.LintResult{Status: lint.Pass}
} else {
return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Basic Constraints extension is present (%v) and marked as non-critical", e.Id)}
}
}
return &lint.LintResult{Status: lint.Fatal, Details: "Error processing Basic Constraints extension"}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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 (
"testing"

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

func TestBasicConstNotCrit(t *testing.T) {
inputPath := "basicConstraintsNotCriticalSC62.pem"
expected := lint.Error
out := test.TestLint("e_sub_cert_basic_constraints_not_critical", inputPath)
if out.Status != expected {
t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status)
}
}

func TestBasicConstCrit(t *testing.T) {
inputPath := "basicConstraintsCriticalSC62.pem"
expected := lint.Pass
out := test.TestLint("e_sub_cert_basic_constraints_not_critical", inputPath)
if out.Status != expected {
t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status)
}
}
13 changes: 7 additions & 6 deletions v3/lints/cabf_br/lint_subject_common_name_included.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ Required/Optional: Deprecated (Discouraged, but not prohibited)

func init() {
lint.RegisterLint(&lint.Lint{
Name: "n_subject_common_name_included",
Description: "Subscriber Certificate: commonName is deprecated.",
Citation: "BRs: 7.1.4.2.2",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.CABEffectiveDate,
Lint: NewCommonNames,
Name: "n_subject_common_name_included",
Description: "Subscriber Certificate: commonName is deprecated.",
Citation: "BRs: 7.1.4.2.2",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.CABEffectiveDate,
IneffectiveDate: util.SC62EffectiveDate,
Lint: NewCommonNames,
})
}

Expand Down
55 changes: 55 additions & 0 deletions v3/lints/cabf_br/lint_subject_common_name_included_sc62.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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 commonNamesSC62 struct{}

/***************************************************************
BRs: 7.1.2.7.1
Required/Optional: NOT RECOMMENDED
***************************************************************/

func init() {
lint.RegisterLint(&lint.Lint{
Name: "w_subject_common_name_included",
Description: "Subscriber Certificate: commonName is NOT RECOMMENDED.",
Citation: "BRs: 7.1.2.7.1",
Source: lint.CABFBaselineRequirements,
EffectiveDate: util.SC62EffectiveDate,
Lint: NewCommonNamesSC62,
})
}

func NewCommonNamesSC62() lint.LintInterface {
return &commonNamesSC62{}
}

func (l *commonNamesSC62) CheckApplies(c *x509.Certificate) bool {
return util.IsSubscriberCert(c)
}

func (l *commonNamesSC62) Execute(c *x509.Certificate) *lint.LintResult {
if c.Subject.CommonName == "" {
return &lint.LintResult{Status: lint.Pass}
} else {
return &lint.LintResult{Status: lint.Warn}
}
}
40 changes: 40 additions & 0 deletions v3/lints/cabf_br/lint_subject_common_name_included_sc62_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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 (
"testing"

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

func TestCNSC62(t *testing.T) {
inputPath := "commonNameExistsSC62.pem"
expected := lint.Warn
out := test.TestLint("w_subject_common_name_included", inputPath)
if out.Status != expected {
t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status)
}
}

func TestNoCNSC62(t *testing.T) {
inputPath := "commonNameGoodSC62.pem"
expected := lint.Pass
out := test.TestLint("w_subject_common_name_included", inputPath)
if out.Status != expected {
t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status)
}
}
38 changes: 38 additions & 0 deletions v3/testdata/basicConstraintsCriticalSC62.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Intermediate
Validity
Not Before: Sep 30 00:00:00 2023 GMT
Not After : Nov 30 00:00:00 9998 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:1c:d4:af:92:68:2f:bc:38:53:2e:45:d6:79:d4:
42:e6:9f:b4:72:51:2d:cc:be:55:77:6b:53:37:ff:
05:90:4d:a7:67:84:8c:5e:9f:b6:f3:73:da:80:a9:
4a:bc:30:66:27:94:a9:92:5a:2f:32:9e:a3:64:ae:
fc:0a:2f:2e:34
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:44:02:20:51:1e:6f:c4:98:db:72:aa:cf:29:0a:01:6b:5a:
bf:fd:d0:89:05:88:4a:0d:06:b2:50:1b:a0:7c:20:47:ea:bd:
02:20:28:03:af:10:58:2e:d9:23:b2:9f:15:58:27:60:4c:39:
29:66:f0:15:a0:f4:c2:ca:02:71:f6:b1:4c:9d:b8:39
-----BEGIN CERTIFICATE-----
MIIBFjCBvqADAgECAgEDMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
aWF0ZTAgFw0yMzA5MzAwMDAwMDBaGA85OTk4MTEzMDAwMDAwMFowADBZMBMGByqG
SM49AgEGCCqGSM49AwEHA0IABBzUr5JoL7w4Uy5F1nnUQuaftHJRLcy+VXdrUzf/
BZBNp2eEjF6ftvNz2oCpSrwwZieUqZJaLzKeo2Su/AovLjSjEDAOMAwGA1UdEwEB
/wQCMAAwCgYIKoZIzj0EAwIDRwAwRAIgUR5vxJjbcqrPKQoBa1q//dCJBYhKDQay
UBugfCBH6r0CICgDrxBYLtkjsp8VWCdgTDkpZvAVoPTCygJx9rFMnbg5
-----END CERTIFICATE-----
38 changes: 38 additions & 0 deletions v3/testdata/basicConstraintsNotCriticalSC62.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Intermediate
Validity
Not Before: Sep 30 00:00:00 2023 GMT
Not After : Nov 30 00:00:00 9998 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:f1:a6:22:0b:be:40:27:99:bd:42:d3:8d:ca:92:
5e:96:95:e4:b5:42:42:8b:6e:08:d8:01:1d:41:05:
89:ee:6c:09:b2:9a:7f:51:3d:bd:c1:c1:4c:61:0e:
05:a8:af:ba:59:c2:68:ef:5b:ea:5c:a6:cc:06:61:
97:31:19:71:eb
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:45:02:21:00:a2:db:24:9e:2e:a8:e5:41:eb:4a:0e:cc:51:
71:8b:0d:09:f3:8e:91:cb:75:47:a7:a6:a4:20:e1:61:22:de:
ee:02:20:2f:9d:a1:2d:fd:18:bf:9e:83:ab:00:98:2c:36:f3:
6a:12:7c:43:67:80:09:1c:2d:ba:65:97:97:69:fa:2a:05
-----BEGIN CERTIFICATE-----
MIIBFDCBu6ADAgECAgEDMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
aWF0ZTAgFw0yMzA5MzAwMDAwMDBaGA85OTk4MTEzMDAwMDAwMFowADBZMBMGByqG
SM49AgEGCCqGSM49AwEHA0IABPGmIgu+QCeZvULTjcqSXpaV5LVCQotuCNgBHUEF
ie5sCbKaf1E9vcHBTGEOBaivulnCaO9b6lymzAZhlzEZceujDTALMAkGA1UdEwQC
MAAwCgYIKoZIzj0EAwIDSAAwRQIhAKLbJJ4uqOVB60oOzFFxiw0J846Ry3VHp6ak
IOFhIt7uAiAvnaEt/Ri/noOrAJgsNvNqEnxDZ4AJHC26ZZeXafoqBQ==
-----END CERTIFICATE-----
35 changes: 35 additions & 0 deletions v3/testdata/commonNameExistsSC62.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Intermediate
Validity
Not Before: Sep 30 00:00:00 2023 GMT
Not After : Nov 30 00:00:00 9998 GMT
Subject: CN = Leaf
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:bf:4e:e5:1a:6b:71:87:3b:db:68:be:df:81:a5:
ed:1d:7f:a2:84:17:5b:ab:7f:4d:83:a7:2c:b0:6a:
99:4e:fb:c8:a5:4f:c9:53:20:35:05:5e:22:5e:4a:
b9:43:e1:b0:76:d7:7f:7f:48:fa:28:bb:b3:9b:05:
6c:11:6a:8a:af
ASN1 OID: prime256v1
NIST CURVE: P-256
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:44:02:20:1d:25:98:b6:67:15:7b:c5:e8:ae:fb:07:38:f9:
6d:30:e9:2b:a5:45:21:aa:2b:25:bf:d8:da:c0:68:71:8a:c5:
02:20:75:b0:ae:a1:13:64:8f:cd:74:3a:e2:c8:96:2a:05:50:
5e:51:a3:eb:4b:32:de:8d:b6:c1:d6:18:13:79:f3:5c
-----BEGIN CERTIFICATE-----
MIIBFzCBv6ADAgECAgEDMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
aWF0ZTAgFw0yMzA5MzAwMDAwMDBaGA85OTk4MTEzMDAwMDAwMFowDzENMAsGA1UE
AxMETGVhZjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL9O5RprcYc722i+34Gl
7R1/ooQXW6t/TYOnLLBqmU77yKVPyVMgNQVeIl5KuUPhsHbXf39I+ii7s5sFbBFq
iq+jAjAAMAoGCCqGSM49BAMCA0cAMEQCIB0lmLZnFXvF6K77Bzj5bTDpK6VFIaor
Jb/Y2sBocYrFAiB1sK6hE2SPzXQ64siWKgVQXlGj60sy3o22wdYYE3nzXA==
-----END CERTIFICATE-----
35 changes: 35 additions & 0 deletions v3/testdata/commonNameGoodSC62.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN = Intermediate
Validity
Not Before: Sep 30 00:00:00 2023 GMT
Not After : Nov 30 00:00:00 9998 GMT
Subject:
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:bf:62:3c:0c:7c:c9:3f:73:ee:5c:e5:80:08:dd:
90:10:4e:e3:01:ce:1d:55:ca:3e:95:a5:5d:96:24:
f4:14:08:0e:14:8a:4d:9c:62:38:2c:82:1b:df:66:
2a:d1:34:de:04:c5:df:50:a6:8a:91:3b:01:b4:3c:
32:ed:15:f3:9f
ASN1 OID: prime256v1
NIST CURVE: P-256
Signature Algorithm: ecdsa-with-SHA256
Signature Value:
30:46:02:21:00:92:f0:ec:d3:99:21:92:98:06:a9:9c:66:6b:
e6:7b:6d:ee:e0:fa:d4:36:2a:ed:75:cc:6e:e5:b0:d9:45:4c:
64:02:21:00:f7:45:a7:d1:db:66:ac:f3:af:c4:a8:fa:07:a3:
97:8c:f6:2c:02:0a:fa:14:36:16:42:d2:91:91:f4:7b:97:d9
-----BEGIN CERTIFICATE-----
MIIBCjCBsKADAgECAgEDMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
aWF0ZTAgFw0yMzA5MzAwMDAwMDBaGA85OTk4MTEzMDAwMDAwMFowADBZMBMGByqG
SM49AgEGCCqGSM49AwEHA0IABL9iPAx8yT9z7lzlgAjdkBBO4wHOHVXKPpWlXZYk
9BQIDhSKTZxiOCyCG99mKtE03gTF31CmipE7AbQ8Mu0V85+jAjAAMAoGCCqGSM49
BAMCA0kAMEYCIQCS8OzTmSGSmAapnGZr5ntt7uD61DYq7XXMbuWw2UVMZAIhAPdF
p9HbZqzzr8So+gejl4z2LAIK+hQ2FkLSkZH0e5fZ
-----END CERTIFICATE-----
2 changes: 2 additions & 0 deletions v3/util/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ var (
CABF_SMIME_BRs_1_0_0_Date = time.Date(2023, time.September, 1, 0, 0, 0, 0, time.UTC)
// Enforcement date of CRL reason codes from Ballot SC 061
CABFBRs_1_8_7_Date = time.Date(2023, time.July, 15, 0, 0, 0, 0, time.UTC)
// Updates to the CABF BRs and EVGLs from Ballot SC 062 https://cabforum.org/2023/03/17/ballot-sc62v2-certificate-profiles-update/
SC62EffectiveDate = time.Date(2023, time.September, 15, 0, 0, 0, 0, time.UTC)
)

var (
Expand Down

0 comments on commit 1fd1c0d

Please sign in to comment.