Skip to content

Commit 990a074

Browse files
Add lints for S/MIME BR 7.1.2.3l (#805)
* Add lints for S/MIME BR 7.1.2.3l * Save results of util functions as variables to make logic clearer. --------- Co-authored-by: Christopher Henderson <[email protected]>
1 parent 32bba7a commit 990a074

10 files changed

+467
-35
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* ZLint Copyright 2024 Regents of the University of Michigan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy
6+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11+
* implied. See the License for the specific language governing
12+
* permissions and limitations under the License.
13+
*/
14+
15+
package cabf_smime_br
16+
17+
import (
18+
"github.com/zmap/zcrypto/x509"
19+
"github.com/zmap/zlint/v3/lint"
20+
"github.com/zmap/zlint/v3/util"
21+
)
22+
23+
func init() {
24+
lint.RegisterCertificateLint(&lint.CertificateLint{
25+
LintMetadata: lint.LintMetadata{
26+
Name: "e_legal_entity_identifier",
27+
Description: "Mailbox/individual: prohibited. Organization/sponsor: may be present",
28+
Citation: "7.1.2.3.l",
29+
Source: lint.CABFSMIMEBaselineRequirements,
30+
EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date,
31+
},
32+
Lint: NewLegalEntityIdentifier,
33+
})
34+
}
35+
36+
type legalEntityIdentifier struct{}
37+
38+
func NewLegalEntityIdentifier() lint.LintInterface {
39+
return &legalEntityIdentifier{}
40+
}
41+
42+
func (l *legalEntityIdentifier) CheckApplies(c *x509.Certificate) bool {
43+
return util.IsSubscriberCert(c) && util.IsSMIMEBRCertificate(c)
44+
}
45+
46+
func (l *legalEntityIdentifier) Execute(c *x509.Certificate) *lint.LintResult {
47+
leiPresent := util.IsExtInCert(c, util.LegalEntityIdentifierOID)
48+
leiExt := util.GetExtFromCert(c, util.LegalEntityIdentifierOID)
49+
leiRolePresent := util.IsExtInCert(c, util.LegalEntityIdentifierRoleOID)
50+
leiRoleExt := util.GetExtFromCert(c, util.LegalEntityIdentifierRoleOID)
51+
52+
switch {
53+
case util.IsMailboxValidatedCertificate(c), util.IsIndividualValidatedCertificate(c):
54+
if leiPresent {
55+
// Mailbox-validated and Individual-validated prohibited.
56+
return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier extension present"}
57+
}
58+
case util.IsOrganizationValidatedCertificate(c):
59+
if leiPresent && leiExt.Critical {
60+
// LEI (1.3.6.1.4.1.52266.1) MAY be present and SHALL NOT be marked critical.
61+
return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier extension present and critical"}
62+
}
63+
if leiRolePresent {
64+
// This is affirming the negative. Sponsor validated certificates MAY have an LEI Role, so
65+
// it is being taken here that not explicitly as such for organization validated certificates
66+
// implies that they are not allowed.
67+
return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier Role extension present"}
68+
}
69+
case util.IsSponsorValidatedCertificate(c):
70+
if leiPresent && leiExt.Critical {
71+
// LEI (1.3.6.1.4.1.52266.1) MAY be present and SHALL NOT be marked critical.
72+
return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier extension present and critical"}
73+
}
74+
if leiRolePresent && leiRoleExt.Critical {
75+
// LEI Role (1.3.6.1.4.1.52266.2) MAY be present and SHALL NOT be marked critical.
76+
return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier Role extension present and critical"}
77+
}
78+
default:
79+
return &lint.LintResult{Status: lint.Error, Details: "Unknown validation type"}
80+
}
81+
82+
return &lint.LintResult{Status: lint.Pass}
83+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package cabf_smime_br
2+
3+
import (
4+
"testing"
5+
6+
"github.com/zmap/zlint/v3/lint"
7+
"github.com/zmap/zlint/v3/test"
8+
)
9+
10+
func TestLegalEntityIdentifier(t *testing.T) {
11+
testCases := []struct {
12+
Name string
13+
InputFilename string
14+
ExpectedResult lint.LintStatus
15+
ExpectedDetails string
16+
}{
17+
{
18+
Name: "pass - mailbox validated, Legal Entity Identifier not present",
19+
InputFilename: "smime/mailboxValidatedLegacyWithCommonName.pem",
20+
ExpectedResult: lint.Pass,
21+
},
22+
{
23+
Name: "error - mailbox validated, Legal Entity Identifier present",
24+
InputFilename: "smime/mailbox_validated_with_lei.pem",
25+
ExpectedResult: lint.Error,
26+
ExpectedDetails: "Legal Entity Identifier extension present",
27+
},
28+
{
29+
Name: "error - individual validated, Legal Entity Identifier present",
30+
InputFilename: "smime/individual_validated_with_lei.pem",
31+
ExpectedResult: lint.Error,
32+
ExpectedDetails: "Legal Entity Identifier extension present",
33+
},
34+
{
35+
Name: "error - organization validated, Legal Entity Identifier critical",
36+
InputFilename: "smime/organization_validated_with_lei_critical.pem",
37+
ExpectedResult: lint.Error,
38+
ExpectedDetails: "Legal Entity Identifier extension present and critical",
39+
},
40+
{
41+
Name: "error - organization validated, Legal Entity Identifier Role present",
42+
InputFilename: "smime/organization_validated_with_lei_role.pem",
43+
ExpectedResult: lint.Error,
44+
ExpectedDetails: "Legal Entity Identifier Role extension present",
45+
},
46+
{
47+
Name: "error - sponsor validated, Legal Entity Identifier critical",
48+
InputFilename: "smime/sponsor_validated_with_lei_critical.pem",
49+
ExpectedResult: lint.Error,
50+
ExpectedDetails: "Legal Entity Identifier extension present and critical",
51+
},
52+
{
53+
Name: "error - sponsor validated, Legal Entity Identifier Role present",
54+
InputFilename: "smime/sponsor_validated_with_lei_role_critical.pem",
55+
ExpectedResult: lint.Error,
56+
ExpectedDetails: "Legal Entity Identifier Role extension present and critical",
57+
},
58+
}
59+
60+
for _, tc := range testCases {
61+
t.Run(tc.Name, func(t *testing.T) {
62+
result := test.TestLint("e_legal_entity_identifier", tc.InputFilename)
63+
if result.Status != tc.ExpectedResult {
64+
t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status)
65+
}
66+
67+
if tc.ExpectedDetails != result.Details {
68+
t.Errorf("expected details: %q, was %q", tc.ExpectedDetails, result.Details)
69+
}
70+
})
71+
}
72+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Certificate:
2+
Data:
3+
Version: 3 (0x2)
4+
Serial Number: 3 (0x3)
5+
Signature Algorithm: ecdsa-with-SHA256
6+
Issuer:
7+
Validity
8+
Not Before: Feb 27 20:23:43 2024 GMT
9+
Not After : Nov 30 00:00:00 9998 GMT
10+
Subject:
11+
Subject Public Key Info:
12+
Public Key Algorithm: id-ecPublicKey
13+
Public-Key: (256 bit)
14+
pub:
15+
04:cd:01:83:83:79:70:8b:18:4b:21:2b:90:21:06:
16+
46:67:63:13:21:83:7c:13:e8:7b:e5:b9:bd:d9:4e:
17+
6d:c4:83:ad:1b:76:3f:92:be:b5:cb:f5:25:ea:10:
18+
1b:a8:dc:c1:53:f4:c1:d6:68:c5:bc:db:3f:79:90:
19+
8a:c5:56:28:cb
20+
ASN1 OID: prime256v1
21+
NIST CURVE: P-256
22+
X509v3 extensions:
23+
X509v3 Extended Key Usage:
24+
E-mail Protection
25+
X509v3 Certificate Policies:
26+
Policy: 2.23.140.1.5.4.3
27+
1.3.6.1.4.1.52266.1:
28+
0.
29+
Signature Algorithm: ecdsa-with-SHA256
30+
Signature Value:
31+
30:46:02:21:00:92:2e:20:05:41:95:b7:20:54:9b:91:4c:dd:
32+
95:2e:6b:1c:05:5a:a6:87:d0:26:b5:e5:d8:2b:b7:bb:0c:1b:
33+
b4:02:21:00:e8:f2:41:83:94:1e:1b:22:bd:9b:2b:2b:1a:f6:
34+
19:49:fc:9b:48:87:fc:ef:f7:01:b5:29:47:73:55:89:52:4a
35+
-----BEGIN CERTIFICATE-----
36+
MIIBLzCB1aADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjAyMzQzWhgP
37+
OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATNAYOD
38+
eXCLGEshK5AhBkZnYxMhg3wT6Hvlub3ZTm3Eg60bdj+SvrXL9SXqEBuo3MFT9MHW
39+
aMW82z95kIrFVijLoz4wPDATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL
40+
MAkGB2eBDAEFBAMwDwYJKwYBBAGDmCoBBAIwADAKBggqhkjOPQQDAgNJADBGAiEA
41+
ki4gBUGVtyBUm5FM3ZUuaxwFWqaH0Ca15dgrt7sMG7QCIQDo8kGDlB4bIr2bKysa
42+
9hlJ/JtIh/zv9wG1KUdzVYlSSg==
43+
-----END CERTIFICATE-----
44+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-------------Leaf-------------
2+
Certificate:
3+
Data:
4+
Version: 3 (0x2)
5+
Serial Number: 3 (0x3)
6+
Signature Algorithm: ecdsa-with-SHA256
7+
Issuer:
8+
Validity
9+
Not Before: Feb 27 21:32:26 2024 GMT
10+
Not After : Nov 30 00:00:00 9998 GMT
11+
Subject:
12+
Subject Public Key Info:
13+
Public Key Algorithm: id-ecPublicKey
14+
Public-Key: (256 bit)
15+
pub:
16+
04:f6:9a:d1:8b:a9:66:fe:3b:dd:44:58:3b:30:3d:
17+
a8:18:ab:05:c5:0a:f7:dd:7e:10:fd:82:16:2a:78:
18+
22:d1:da:13:3e:f3:13:24:7a:53:5d:a5:a2:c1:fa:
19+
04:d6:65:e5:ee:39:03:03:b6:0b:0a:35:54:a7:1b:
20+
c4:17:74:a0:c4
21+
ASN1 OID: prime256v1
22+
NIST CURVE: P-256
23+
X509v3 extensions:
24+
X509v3 Extended Key Usage:
25+
E-mail Protection
26+
X509v3 Certificate Policies:
27+
Policy: 2.23.140.1.5.1.3
28+
1.3.6.1.4.1.52266.1:
29+
0.
30+
Signature Algorithm: ecdsa-with-SHA256
31+
Signature Value:
32+
30:45:02:20:6e:d8:65:3b:9b:b9:08:77:e2:bc:2b:a6:24:1e:
33+
95:3c:60:61:21:68:35:3e:be:77:95:26:d8:cc:bd:24:f4:37:
34+
02:21:00:ed:f8:2e:11:8f:1f:5b:ba:15:5e:25:27:0a:53:dc:
35+
7f:f3:d6:33:6f:cd:64:45:ac:a6:37:ba:fa:4d:48:1b:05
36+
-----BEGIN CERTIFICATE-----
37+
MIIBLjCB1aADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjEzMjI2WhgP
38+
OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT2mtGL
39+
qWb+O91EWDswPagYqwXFCvfdfhD9ghYqeCLR2hM+8xMkelNdpaLB+gTWZeXuOQMD
40+
tgsKNVSnG8QXdKDEoz4wPDATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL
41+
MAkGB2eBDAEFAQMwDwYJKwYBBAGDmCoBBAIwADAKBggqhkjOPQQDAgNIADBFAiBu
42+
2GU7m7kId+K8K6YkHpU8YGEhaDU+vneVJtjMvST0NwIhAO34LhGPH1u6FV4lJwpT
43+
3H/z1jNvzWRFrKY3uvpNSBsF
44+
-----END CERTIFICATE-----
45+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Certificate:
2+
Data:
3+
Version: 3 (0x2)
4+
Serial Number: 3 (0x3)
5+
Signature Algorithm: ecdsa-with-SHA256
6+
Issuer:
7+
Validity
8+
Not Before: Feb 27 20:24:36 2024 GMT
9+
Not After : Nov 30 00:00:00 9998 GMT
10+
Subject:
11+
Subject Public Key Info:
12+
Public Key Algorithm: id-ecPublicKey
13+
Public-Key: (256 bit)
14+
pub:
15+
04:99:e8:3b:1a:e3:b2:a5:f2:15:04:66:e3:a5:33:
16+
c7:f5:e3:91:1b:fd:0d:9a:50:8b:71:21:e6:90:c6:
17+
63:09:94:44:52:f7:6c:27:4e:48:11:13:cb:20:aa:
18+
3b:b9:f9:8b:d4:8b:82:a7:a1:36:b3:84:8d:a2:f3:
19+
59:fa:8e:24:77
20+
ASN1 OID: prime256v1
21+
NIST CURVE: P-256
22+
X509v3 extensions:
23+
X509v3 Extended Key Usage:
24+
E-mail Protection
25+
X509v3 Certificate Policies:
26+
Policy: 2.23.140.1.5.2.3
27+
1.3.6.1.4.1.52266.1: critical
28+
0.
29+
Signature Algorithm: ecdsa-with-SHA256
30+
Signature Value:
31+
30:46:02:21:00:ad:ff:32:f7:5d:60:46:16:5c:11:3c:52:c4:
32+
0c:6e:42:56:73:49:51:ac:19:30:ee:fe:a8:2a:50:92:3c:a3:
33+
92:02:21:00:99:b4:76:21:39:93:d4:b5:fd:fb:c6:ff:48:f4:
34+
56:e6:67:ed:84:aa:bb:18:63:83:0b:8f:73:67:b4:89:71:ec
35+
-----BEGIN CERTIFICATE-----
36+
MIIBMjCB2KADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjAyNDM2WhgP
37+
OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASZ6Dsa
38+
47Kl8hUEZuOlM8f145Eb/Q2aUItxIeaQxmMJlERS92wnTkgRE8sgqju5+YvUi4Kn
39+
oTazhI2i81n6jiR3o0EwPzATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL
40+
MAkGB2eBDAEFAgMwEgYJKwYBBAGDmCoBAQH/BAIwADAKBggqhkjOPQQDAgNJADBG
41+
AiEArf8y911gRhZcETxSxAxuQlZzSVGsGTDu/qgqUJI8o5ICIQCZtHYhOZPUtf37
42+
xv9I9FbmZ+2EqrsYY4MLj3NntIlx7A==
43+
-----END CERTIFICATE-----
44+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Certificate:
2+
Data:
3+
Version: 3 (0x2)
4+
Serial Number: 3 (0x3)
5+
Signature Algorithm: ecdsa-with-SHA256
6+
Issuer:
7+
Validity
8+
Not Before: Feb 27 21:24:08 2024 GMT
9+
Not After : Nov 30 00:00:00 9998 GMT
10+
Subject:
11+
Subject Public Key Info:
12+
Public Key Algorithm: id-ecPublicKey
13+
Public-Key: (256 bit)
14+
pub:
15+
04:65:5a:40:93:2d:68:a9:f2:bc:25:f1:d5:73:41:
16+
7e:d1:8b:df:e3:ff:78:c6:35:18:e7:1a:01:18:19:
17+
87:5f:7e:db:97:6b:73:bd:b2:52:5c:58:87:59:4e:
18+
6a:2d:8d:4e:ea:7a:c9:84:7e:68:18:61:64:a0:c6:
19+
35:7d:e0:e4:b8
20+
ASN1 OID: prime256v1
21+
NIST CURVE: P-256
22+
X509v3 extensions:
23+
X509v3 Extended Key Usage:
24+
E-mail Protection
25+
X509v3 Certificate Policies:
26+
Policy: 2.23.140.1.5.2.3
27+
1.3.6.1.4.1.52266.2:
28+
0.
29+
Signature Algorithm: ecdsa-with-SHA256
30+
Signature Value:
31+
30:45:02:20:74:8e:47:17:c0:68:88:aa:48:2d:bb:e1:ea:5e:
32+
b1:4b:9e:34:52:3d:84:81:64:8d:7f:c0:c7:2c:34:36:a8:8b:
33+
02:21:00:fe:54:e1:63:17:25:a7:2f:b8:89:d1:19:d8:81:a2:
34+
bc:e6:d1:0b:7a:f7:e0:3b:8a:5e:d3:63:dd:d2:d0:91:8d
35+
-----BEGIN CERTIFICATE-----
36+
MIIBLjCB1aADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjEyNDA4WhgP
37+
OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARlWkCT
38+
LWip8rwl8dVzQX7Ri9/j/3jGNRjnGgEYGYdfftuXa3O9slJcWIdZTmotjU7qesmE
39+
fmgYYWSgxjV94OS4oz4wPDATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL
40+
MAkGB2eBDAEFAgMwDwYJKwYBBAGDmCoCBAIwADAKBggqhkjOPQQDAgNIADBFAiB0
41+
jkcXwGiIqkgtu+HqXrFLnjRSPYSBZI1/wMcsNDaoiwIhAP5U4WMXJacvuInRGdiB
42+
orzm0Qt69+A7il7TY93S0JGN
43+
-----END CERTIFICATE-----
44+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
Certificate:
2+
Data:
3+
Version: 3 (0x2)
4+
Serial Number: 3 (0x3)
5+
Signature Algorithm: ecdsa-with-SHA256
6+
Issuer:
7+
Validity
8+
Not Before: Feb 27 20:27:18 2024 GMT
9+
Not After : Nov 30 00:00:00 9998 GMT
10+
Subject:
11+
Subject Public Key Info:
12+
Public Key Algorithm: id-ecPublicKey
13+
Public-Key: (256 bit)
14+
pub:
15+
04:70:4c:86:07:80:17:0b:2c:db:4d:32:0b:fa:5b:
16+
2b:7a:90:09:60:f5:d9:10:f9:1f:c7:a9:1d:b2:84:
17+
91:0c:88:ac:de:c2:85:a3:39:2b:89:70:6d:44:16:
18+
49:ae:46:92:82:c6:d8:05:7d:3c:16:80:9b:fb:11:
19+
41:df:03:ee:05
20+
ASN1 OID: prime256v1
21+
NIST CURVE: P-256
22+
X509v3 extensions:
23+
X509v3 Extended Key Usage:
24+
E-mail Protection
25+
X509v3 Certificate Policies:
26+
Policy: 2.23.140.1.5.3.3
27+
1.3.6.1.4.1.52266.1: critical
28+
0.
29+
Signature Algorithm: ecdsa-with-SHA256
30+
Signature Value:
31+
30:45:02:21:00:a8:1d:cf:1e:5e:8d:ea:40:f2:30:0b:4b:b9:
32+
11:42:75:de:30:00:7b:31:ba:0f:df:64:83:72:0f:2e:94:a7:
33+
84:02:20:4d:95:81:58:2a:2b:ab:86:3a:ae:37:25:10:79:56:
34+
7c:07:01:34:06:5f:4c:f9:cc:40:1d:31:e4:94:48:34:db
35+
-----BEGIN CERTIFICATE-----
36+
MIIBMTCB2KADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjAyNzE4WhgP
37+
OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwTIYH
38+
gBcLLNtNMgv6Wyt6kAlg9dkQ+R/HqR2yhJEMiKzewoWjOSuJcG1EFkmuRpKCxtgF
39+
fTwWgJv7EUHfA+4Fo0EwPzATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL
40+
MAkGB2eBDAEFAwMwEgYJKwYBBAGDmCoBAQH/BAIwADAKBggqhkjOPQQDAgNIADBF
41+
AiEAqB3PHl6N6kDyMAtLuRFCdd4wAHsxug/fZINyDy6Up4QCIE2VgVgqK6uGOq43
42+
JRB5VnwHATQGX0z5zEAdMeSUSDTb
43+
-----END CERTIFICATE-----
44+

0 commit comments

Comments
 (0)