diff --git a/v3/lints/cabf_br/lint_eku_critical.go b/v3/lints/cabf_br/lint_eku_critical.go new file mode 100644 index 000000000..43a2f1394 --- /dev/null +++ b/v3/lints/cabf_br/lint_eku_critical.go @@ -0,0 +1,52 @@ +package cabf_br + +/* + * ZLint Copyright 2024 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 eKUCrit struct{} + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_eku_critical", + Description: "Subscriber Certificate extkeyUsage extension MUST NOT be marked critical", + Citation: "BRs: 7.1.2.7.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewEKUCrit, + }) +} + +func NewEKUCrit() lint.LintInterface { + return &eKUCrit{} +} + +func (l *eKUCrit) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.EkuSynOid) +} + +func (l *eKUCrit) Execute(c *x509.Certificate) *lint.LintResult { + if e := util.GetExtFromCert(c, util.EkuSynOid); e.Critical { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} diff --git a/v3/lints/cabf_br/lint_eku_critical_test.go b/v3/lints/cabf_br/lint_eku_critical_test.go new file mode 100644 index 000000000..72b7fdf6c --- /dev/null +++ b/v3/lints/cabf_br/lint_eku_critical_test.go @@ -0,0 +1,40 @@ +package cabf_br + +/* + * ZLint Copyright 2024 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 TestEkuCrit(t *testing.T) { + inputPath := "ekuCrit.pem" + expected := lint.Error + out := test.TestLint("e_eku_critical", inputPath) + if out.Status != expected { + t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status) + } +} + +func TestEkuNotCrit(t *testing.T) { + inputPath := "ekuNoCrit.pem" + expected := lint.Pass + out := test.TestLint("e_eku_critical", inputPath) + if out.Status != expected { + t.Errorf("%s: expected %s, got %s", inputPath, expected, out.Status) + } +} diff --git a/v3/testdata/ekuCrit.pem b/v3/testdata/ekuCrit.pem new file mode 100644 index 000000000..8807b83cd --- /dev/null +++ b/v3/testdata/ekuCrit.pem @@ -0,0 +1,81 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1711356925 (0x66013bfd) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Zlint Demo Test CA + Validity + Not Before: Mar 25 08:55:25 2024 GMT + Not After : Mar 25 08:55:25 2025 GMT + Subject: CN=example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:9a:23:2b:8d:c2:b2:9e:1f:f6:f6:b1:69:18:cc: + 22:ef:b6:e5:3a:08:00:79:38:66:94:9f:a5:bd:41: + 52:89:69:7c:7e:2d:86:3f:40:9c:00:8a:54:e3:3c: + 8a:de:89:96:8e:ea:9c:69:df:d8:f6:7f:75:40:23: + 95:23:23:fe:88:05:26:94:cb:aa:28:90:f0:9c:14: + 25:aa:d8:a4:dd:83:18:24:7c:eb:18:40:8e:a3:40: + 9c:ce:ab:72:06:20:97:c7:7c:2b:26:9e:c0:53:55: + 2d:cd:86:3b:81:8d:bf:8e:d8:6d:50:9e:91:a2:cd: + 5d:7d:e1:d0:fa:ca:0a:e9:5b:e5:e2:28:d3:48:cd: + bf:8a:32:52:25:94:c2:58:38:30:04:4a:69:5f:b1: + 3d:e1:b8:27:af:de:1f:95:54:f7:0d:04:aa:11:32: + 7d:80:d8:5d:5d:ab:25:32:93:4d:80:6a:5f:91:41: + 8f:21:69:c9:d7:69:1e:81:3d:fa:40:a1:d3:3e:77: + fe:21:01:29:8b:85:61:ac:f3:e2:e7:a8:48:78:a0: + 4f:8b:a0:bd:9d:6b:fd:e4:72:3c:4d:36:34:83:5e: + b3:1a:d2:5f:be:5e:9d:7c:64:1a:89:49:bb:e8:8a: + 84:0c:22:c2:21:f0:15:a9:74:72:26:99:43:f7:c5: + f7:8f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: critical + TLS Web Server Authentication + X509v3 Subject Alternative Name: + DNS:example.com + X509v3 Authority Key Identifier: + 8A:11:10:2B:49:EB:35:65:F9:FA:81:59:00:B4:67:35:C8:68:E3:39 + X509v3 Subject Key Identifier: + 16:6F:4D:56:39:2A:CD:36:7C:EC:CF:07:7B:CF:00:3B:CF:B7:9E:30 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + dc:cf:1d:60:84:b7:ad:78:e7:69:b8:64:7e:25:08:fc:85:13: + 5d:34:ec:0c:13:74:80:a6:92:8e:d8:0d:a7:2e:55:37:ab:02: + b8:ce:eb:94:cc:47:73:c7:ac:9c:67:9d:45:c1:79:40:14:be: + 79:bd:1e:68:73:a9:c8:c2:d4:ca:f7:ad:5e:65:09:8a:35:e7: + a7:71:25:2e:6c:07:ac:87:0c:11:24:fd:9a:3e:73:0d:21:e0: + 11:3a:e2:38:22:21:f2:48:7d:f8:a9:59:4d:b3:d9:42:f7:59: + 0c:2f:45:7d:16:77:05:d0:6e:a6:f1:0e:c0:8a:a5:de:e7:99: + da:cf:d0:e7:7d:66:2f:48:74:fe:f2:93:95:9a:4a:dc:4f:6d: + 0f:9e:43:89:43:a3:c6:74:27:d8:d3:e1:dc:f4:7a:f2:52:bd: + 19:d0:ea:f3:c2:1a:48:60:6c:44:11:27:ba:41:97:96:b8:ca: + 90:de:f7:e3:63:6a:1e:c3:83:fa:c3:77:1d:ee:2c:05:ce:25: + 8c:30:e8:18:03:20:6c:b3:b1:c5:9f:cc:bc:5f:4e:29:15:35: + 9d:53:e8:6e:27:0f:5f:75:07:23:6a:27:65:50:18:84:54:45: + 77:56:3e:1b:cc:9f:22:98:4a:95:4e:78:21:6a:bb:68:45:32: + 25:33:84:48 +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIEZgE7/TANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJa +bGludCBEZW1vIFRlc3QgQ0EwHhcNMjQwMzI1MDg1NTI1WhcNMjUwMzI1MDg1NTI1 +WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAJojK43Csp4f9vaxaRjMIu+25ToIAHk4ZpSfpb1BUolpfH4thj9A +nACKVOM8it6Jlo7qnGnf2PZ/dUAjlSMj/ogFJpTLqiiQ8JwUJarYpN2DGCR86xhA +jqNAnM6rcgYgl8d8KyaewFNVLc2GO4GNv47YbVCekaLNXX3h0PrKCulb5eIo00jN +v4oyUiWUwlg4MARKaV+xPeG4J6/eH5VU9w0EqhEyfYDYXV2rJTKTTYBqX5FBjyFp +yddpHoE9+kCh0z53/iEBKYuFYazz4ueoSHigT4ugvZ1r/eRyPE02NINesxrSX75e +nXxkGolJu+iKhAwiwiHwFal0ciaZQ/fF948CAwEAAaOBgzCBgDAOBgNVHQ8BAf8E +BAMCBaAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwEwFgYDVR0RBA8wDYILZXhhbXBs +ZS5jb20wHwYDVR0jBBgwFoAUihEQK0nrNWX5+oFZALRnNcho4zkwHQYDVR0OBBYE +FBZvTVY5Ks02fOzPB3vPADvPt54wMA0GCSqGSIb3DQEBCwUAA4IBAQDczx1ghLet +eOdpuGR+JQj8hRNdNOwME3SAppKO2A2nLlU3qwK4zuuUzEdzx6ycZ51FwXlAFL55 +vR5oc6nIwtTK961eZQmKNeencSUubAeshwwRJP2aPnMNIeAROuI4IiHySH34qVlN +s9lC91kML0V9FncF0G6m8Q7AiqXe55naz9DnfWYvSHT+8pOVmkrcT20PnkOJQ6PG +dCfY0+Hc9HryUr0Z0OrzwhpIYGxEESe6QZeWuMqQ3vfjY2oew4P6w3cd7iwFziWM +MOgYAyBss7HFn8y8X04pFTWdU+huJw9fdQcjaidlUBiEVEV3Vj4bzJ8imEqVTngh +artoRTIlM4RI +-----END CERTIFICATE----- diff --git a/v3/testdata/ekuNoCrit.pem b/v3/testdata/ekuNoCrit.pem new file mode 100644 index 000000000..230abc703 --- /dev/null +++ b/v3/testdata/ekuNoCrit.pem @@ -0,0 +1,81 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1711356869 (0x66013bc5) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Zlint Demo Test CA + Validity + Not Before: Mar 25 08:54:29 2024 GMT + Not After : Mar 25 08:54:29 2025 GMT + Subject: CN=example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c3:63:f6:59:0e:9c:2e:a7:e5:57:65:b8:d3:de: + 9b:10:5f:86:20:b6:5a:5d:5b:d8:85:35:94:95:1d: + c4:4a:cf:85:14:f5:ff:55:04:9e:5b:c3:b0:fe:fd: + be:7f:19:7f:38:e2:4b:ea:7d:a8:06:c5:76:ba:72: + 84:69:ba:0e:01:8a:64:be:48:28:40:4d:5f:10:41: + 8f:87:ac:87:e8:68:3f:87:52:26:27:ca:0e:70:a3: + ce:95:c0:fb:a4:05:38:41:87:d0:e0:f1:e6:12:05: + aa:76:ce:1c:4d:94:4b:02:1c:4f:0c:fa:76:ac:dc: + 22:77:ac:74:14:f2:2d:b4:c2:26:3d:ba:ef:8e:13: + 0c:dc:e3:1b:02:77:39:0c:3a:af:90:5b:19:f1:29: + d7:4c:7d:4d:a3:c2:a2:4f:de:1c:c5:7e:2a:02:8e: + 22:e2:df:f0:e0:1b:c3:bb:a6:ba:cc:b2:14:58:33: + 7d:fa:64:53:b4:5c:f1:50:d5:d0:d9:e0:c2:07:64: + e6:5f:91:60:14:2b:5a:eb:52:6f:f8:4a:f4:5d:fa: + 86:d6:44:3f:05:83:43:33:87:f1:2c:9f:33:20:d2: + 4a:b1:9a:1b:40:21:e9:ad:86:40:b7:a8:56:2e:34: + 0c:df:ec:9f:d5:fd:d3:13:2a:76:54:c0:94:f5:24: + e9:5f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Subject Alternative Name: + DNS:example.com + X509v3 Authority Key Identifier: + 8A:11:10:2B:49:EB:35:65:F9:FA:81:59:00:B4:67:35:C8:68:E3:39 + X509v3 Subject Key Identifier: + 22:BA:41:80:12:C0:27:C3:A7:B8:B7:0C:96:4D:9E:3F:72:8B:36:DA + X509v3 Extended Key Usage: + TLS Web Server Authentication + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + af:0a:00:aa:bd:f1:fa:f6:13:8d:c6:55:17:71:3c:86:84:81: + 3b:89:d8:c3:71:01:65:be:4d:95:79:bc:3a:55:aa:35:f1:d9: + 1c:e9:8c:aa:87:94:30:b9:37:37:6c:e8:34:30:6d:94:64:c8: + ed:d6:ed:72:9b:23:cb:c2:4f:bc:1d:3d:af:65:be:0f:20:79: + 09:90:7f:bd:ba:78:a3:f4:31:30:3a:a4:16:8c:0a:d8:6a:d3: + 20:b6:c4:b1:92:f4:63:64:f9:4c:40:71:22:b5:b3:ed:6a:a8: + 5d:1c:ea:df:c2:d0:68:53:1c:82:87:23:b4:a7:14:ac:a4:4f: + b4:bc:6e:d8:8d:70:4d:a2:ab:88:e9:bd:2f:ae:0c:5f:cb:2e: + 74:22:cc:64:23:25:6f:30:8b:af:4b:50:e0:50:8e:17:cd:2b: + 63:d0:cd:0f:0b:ad:92:88:b3:8c:ed:04:0e:41:b4:8a:08:7d: + de:7f:53:e2:32:e3:8f:87:98:d0:d8:cd:a4:5a:3f:c7:e1:5d: + d6:11:d0:63:f6:a0:fd:b6:a6:2e:9c:10:99:93:af:f8:ff:f5: + 3e:23:9d:08:a1:8a:61:57:d7:94:c7:df:68:89:92:ec:dc:13: + 41:8d:58:53:78:f5:b9:4a:f0:c1:25:56:2a:f5:a6:11:0b:de: + c7:30:57:74 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgIEZgE7xTANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJa +bGludCBEZW1vIFRlc3QgQ0EwHhcNMjQwMzI1MDg1NDI5WhcNMjUwMzI1MDg1NDI5 +WjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMNj9lkOnC6n5VdluNPemxBfhiC2Wl1b2IU1lJUdxErPhRT1/1UE +nlvDsP79vn8ZfzjiS+p9qAbFdrpyhGm6DgGKZL5IKEBNXxBBj4esh+hoP4dSJifK +DnCjzpXA+6QFOEGH0ODx5hIFqnbOHE2USwIcTwz6dqzcInesdBTyLbTCJj26744T +DNzjGwJ3OQw6r5BbGfEp10x9TaPCok/eHMV+KgKOIuLf8OAbw7umusyyFFgzffpk +U7Rc8VDV0Nngwgdk5l+RYBQrWutSb/hK9F36htZEPwWDQzOH8SyfMyDSSrGaG0Ah +6a2GQLeoVi40DN/sn9X90xMqdlTAlPUk6V8CAwEAAaN/MH0wDgYDVR0PAQH/BAQD +AgWgMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29tMB8GA1UdIwQYMBaAFIoRECtJ6zVl ++fqBWQC0ZzXIaOM5MB0GA1UdDgQWBBQiukGAEsAnw6e4twyWTZ4/cos22jATBgNV +HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEArwoAqr3x+vYTjcZV +F3E8hoSBO4nYw3EBZb5NlXm8OlWqNfHZHOmMqoeUMLk3N2zoNDBtlGTI7dbtcpsj +y8JPvB09r2W+DyB5CZB/vbp4o/QxMDqkFowK2GrTILbEsZL0Y2T5TEBxIrWz7Wqo +XRzq38LQaFMcgocjtKcUrKRPtLxu2I1wTaKriOm9L64MX8sudCLMZCMlbzCLr0tQ +4FCOF80rY9DNDwutkoizjO0EDkG0igh93n9T4jLjj4eY0NjNpFo/x+Fd1hHQY/ag +/bamLpwQmZOv+P/1PiOdCKGKYVfXlMffaImS7NwTQY1YU3j1uUrwwSVWKvWmEQve +xzBXdA== +-----END CERTIFICATE-----