diff --git a/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go b/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go new file mode 100644 index 000000000..06df676fd --- /dev/null +++ b/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go @@ -0,0 +1,55 @@ +/* + * 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. + */ + +package cabf_smime_br + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_commonname_mailbox_validated", + Description: "If present, the commonName attribute of a mailbox-validated certificate SHALL contain a mailbox address", + Citation: "S/MIME BRs: 7.1.4.2.2a", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewCommonNameMailboxValidated, + }) +} + +type commonNameMailboxValidated struct{} + +func NewCommonNameMailboxValidated() lint.LintInterface { + return &commonNameMailboxValidated{} +} + +func (l *commonNameMailboxValidated) CheckApplies(c *x509.Certificate) bool { + return util.IsMailboxValidatedCertificate(c) +} + +func (l *commonNameMailboxValidated) Execute(c *x509.Certificate) *lint.LintResult { + commonNames := []string{c.Subject.CommonName} + commonNames = append(commonNames, c.Subject.CommonNames...) + for _, cn := range commonNames { + if !util.IsMailboxAddress(cn) { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated_test.go b/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated_test.go new file mode 100644 index 000000000..77fa56221 --- /dev/null +++ b/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated_test.go @@ -0,0 +1,49 @@ +/* + * 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. + */ + +package cabf_smime_br + +import ( + "testing" + + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/test" +) + +func TestCommonNameMailboxValidated(t *testing.T) { + testCases := []struct { + Name string + InputFilename string + ExpectedResult lint.LintStatus + }{ + { + Name: "pass - valid email in commonName", + InputFilename: "smime/mailbox_validated_common_name_good_email.pem", + ExpectedResult: lint.Pass, + }, + { + Name: "fail - invalid email in commonName", + InputFilename: "smime/mailbox_validated_common_name_bad_email.pem", + ExpectedResult: lint.Error, + }, + } + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + result := test.TestLint("e_commonname_mailbox_validated", tc.InputFilename) + if result.Status != tc.ExpectedResult { + t.Errorf("expected result %v was %v - details: %v", tc.ExpectedResult, result.Status, result.Details) + } + }) + } +} diff --git a/v3/testdata/smime/mailbox_validated_common_name_bad_email.pem b/v3/testdata/smime/mailbox_validated_common_name_bad_email.pem new file mode 100644 index 000000000..021d7e3cd --- /dev/null +++ b/v3/testdata/smime/mailbox_validated_common_name_bad_email.pem @@ -0,0 +1,42 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 28 19:12:13 2024 GMT + Not After : Nov 30 00:00:00 9998 GMT + Subject: CN = bad + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:17:de:84:f0:62:95:f7:ec:ef:c9:a5:69:e9:a2: + d8:35:f6:fd:3e:85:63:c0:d2:fe:20:00:c5:67:72: + 02:be:a7:75:18:49:1b:6c:fb:16:db:48:9c:27:01: + 98:a7:bd:50:5a:4c:f0:9f:45:d5:fa:77:9c:f5:78: + 6e:f0:dc:c7:06 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Extended Key Usage: + E-mail Protection + X509v3 Certificate Policies: + Policy: 2.23.140.1.5.1.3 + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:44:02:20:41:c6:a1:86:82:cd:43:d4:0f:c7:c5:5b:62:08: + f7:84:b1:d6:c2:82:93:16:91:84:1e:4a:13:e9:b6:ab:43:28: + 02:20:62:18:31:09:d1:25:da:49:0a:86:8f:7a:d9:94:98:c6: + 25:04:34:ab:c1:e6:7c:0c:8d:a8:4e:21:42:f9:9a:3c +-----BEGIN CERTIFICATE----- +MIIBKjCB0qADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI4MTkxMjEzWhgP +OTk5ODExMzAwMDAwMDBaMA4xDDAKBgNVBAMTA2JhZDBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABBfehPBilffs78mlaemi2DX2/T6FY8DS/iAAxWdyAr6ndRhJG2z7 +FttInCcBmKe9UFpM8J9F1fp3nPV4bvDcxwajLTArMBMGA1UdJQQMMAoGCCsGAQUF +BwMEMBQGA1UdIAQNMAswCQYHZ4EMAQUBAzAKBggqhkjOPQQDAgNHADBEAiBBxqGG +gs1D1A/HxVtiCPeEsdbCgpMWkYQeShPptqtDKAIgYhgxCdEl2kkKho962ZSYxiUE +NKvB5nwMjahOIUL5mjw= +-----END CERTIFICATE----- + diff --git a/v3/testdata/smime/mailbox_validated_common_name_good_email.pem b/v3/testdata/smime/mailbox_validated_common_name_good_email.pem new file mode 100644 index 000000000..01ae52aed --- /dev/null +++ b/v3/testdata/smime/mailbox_validated_common_name_good_email.pem @@ -0,0 +1,42 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 28 19:11:49 2024 GMT + Not After : Nov 30 00:00:00 9998 GMT + Subject: CN = user@example.com + Subject Public Key Info: + Public Key Algorithm: id-ecPublicKey + Public-Key: (256 bit) + pub: + 04:c7:3e:09:79:8e:69:75:31:48:00:b8:60:1a:1f: + ab:ee:94:ce:23:cf:5b:e2:77:da:5f:0b:72:ad:e2: + 2f:d8:e2:70:93:26:f5:c4:8f:e8:5e:bb:af:0b:49: + ee:b7:d9:a2:67:62:00:0b:eb:5f:e8:e8:63:21:83: + 7a:3b:f8:e4:88 + ASN1 OID: prime256v1 + NIST CURVE: P-256 + X509v3 extensions: + X509v3 Extended Key Usage: + E-mail Protection + X509v3 Certificate Policies: + Policy: 2.23.140.1.5.1.3 + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:44:02:20:17:bf:bb:d5:29:55:28:3f:27:00:8b:36:ae:3f: + 2e:9e:29:bb:2d:b3:a8:48:3e:93:ac:a4:c2:1d:86:6c:19:61: + 02:20:61:3d:f7:4e:a2:59:fa:87:7d:38:f4:bc:5d:d6:3e:aa: + 74:a4:8d:6f:6a:e2:ce:17:ab:82:cd:b3:51:ec:0f:48 +-----BEGIN CERTIFICATE----- +MIIBNzCB36ADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI4MTkxMTQ5WhgP +OTk5ODExMzAwMDAwMDBaMBsxGTAXBgNVBAMMEHVzZXJAZXhhbXBsZS5jb20wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAATHPgl5jml1MUgAuGAaH6vulM4jz1vid9pf +C3Kt4i/Y4nCTJvXEj+heu68LSe632aJnYgAL61/o6GMhg3o7+OSIoy0wKzATBgNV +HSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTALMAkGB2eBDAEFAQMwCgYIKoZIzj0E +AwIDRwAwRAIgF7+71SlVKD8nAIs2rj8unim7LbOoSD6TrKTCHYZsGWECIGE9906i +WfqHfTj0vF3WPqp0pI1vauLOF6uCzbNR7A9I +-----END CERTIFICATE----- +