diff --git a/v3/lints/cabf_smime_br/lint_legal_entity_identifier.go b/v3/lints/cabf_smime_br/lint_legal_entity_identifier.go new file mode 100644 index 000000000..0cd6b6bbe --- /dev/null +++ b/v3/lints/cabf_smime_br/lint_legal_entity_identifier.go @@ -0,0 +1,83 @@ +/* + * 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_legal_entity_identifier", + Description: "Mailbox/individual: prohibited. Organization/sponsor: may be present", + Citation: "7.1.2.3.l", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewLegalEntityIdentifier, + }) +} + +type legalEntityIdentifier struct{} + +func NewLegalEntityIdentifier() lint.LintInterface { + return &legalEntityIdentifier{} +} + +func (l *legalEntityIdentifier) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsSMIMEBRCertificate(c) +} + +func (l *legalEntityIdentifier) Execute(c *x509.Certificate) *lint.LintResult { + leiPresent := util.IsExtInCert(c, util.LegalEntityIdentifierOID) + leiExt := util.GetExtFromCert(c, util.LegalEntityIdentifierOID) + leiRolePresent := util.IsExtInCert(c, util.LegalEntityIdentifierRoleOID) + leiRoleExt := util.GetExtFromCert(c, util.LegalEntityIdentifierRoleOID) + + switch { + case util.IsMailboxValidatedCertificate(c), util.IsIndividualValidatedCertificate(c): + if leiPresent { + // Mailbox-validated and Individual-validated prohibited. + return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier extension present"} + } + case util.IsOrganizationValidatedCertificate(c): + if leiPresent && leiExt.Critical { + // LEI (1.3.6.1.4.1.52266.1) MAY be present and SHALL NOT be marked critical. + return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier extension present and critical"} + } + if leiRolePresent { + // This is affirming the negative. Sponsor validated certificates MAY have an LEI Role, so + // it is being taken here that not explicitly as such for organization validated certificates + // implies that they are not allowed. + return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier Role extension present"} + } + case util.IsSponsorValidatedCertificate(c): + if leiPresent && leiExt.Critical { + // LEI (1.3.6.1.4.1.52266.1) MAY be present and SHALL NOT be marked critical. + return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier extension present and critical"} + } + if leiRolePresent && leiRoleExt.Critical { + // LEI Role (1.3.6.1.4.1.52266.2) MAY be present and SHALL NOT be marked critical. + return &lint.LintResult{Status: lint.Error, Details: "Legal Entity Identifier Role extension present and critical"} + } + default: + return &lint.LintResult{Status: lint.Error, Details: "Unknown validation type"} + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/v3/lints/cabf_smime_br/lint_legal_entity_identifier_test.go b/v3/lints/cabf_smime_br/lint_legal_entity_identifier_test.go new file mode 100644 index 000000000..ea6642532 --- /dev/null +++ b/v3/lints/cabf_smime_br/lint_legal_entity_identifier_test.go @@ -0,0 +1,72 @@ +package cabf_smime_br + +import ( + "testing" + + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/test" +) + +func TestLegalEntityIdentifier(t *testing.T) { + testCases := []struct { + Name string + InputFilename string + ExpectedResult lint.LintStatus + ExpectedDetails string + }{ + { + Name: "pass - mailbox validated, Legal Entity Identifier not present", + InputFilename: "smime/mailboxValidatedLegacyWithCommonName.pem", + ExpectedResult: lint.Pass, + }, + { + Name: "error - mailbox validated, Legal Entity Identifier present", + InputFilename: "smime/mailbox_validated_with_lei.pem", + ExpectedResult: lint.Error, + ExpectedDetails: "Legal Entity Identifier extension present", + }, + { + Name: "error - individual validated, Legal Entity Identifier present", + InputFilename: "smime/individual_validated_with_lei.pem", + ExpectedResult: lint.Error, + ExpectedDetails: "Legal Entity Identifier extension present", + }, + { + Name: "error - organization validated, Legal Entity Identifier critical", + InputFilename: "smime/organization_validated_with_lei_critical.pem", + ExpectedResult: lint.Error, + ExpectedDetails: "Legal Entity Identifier extension present and critical", + }, + { + Name: "error - organization validated, Legal Entity Identifier Role present", + InputFilename: "smime/organization_validated_with_lei_role.pem", + ExpectedResult: lint.Error, + ExpectedDetails: "Legal Entity Identifier Role extension present", + }, + { + Name: "error - sponsor validated, Legal Entity Identifier critical", + InputFilename: "smime/sponsor_validated_with_lei_critical.pem", + ExpectedResult: lint.Error, + ExpectedDetails: "Legal Entity Identifier extension present and critical", + }, + { + Name: "error - sponsor validated, Legal Entity Identifier Role present", + InputFilename: "smime/sponsor_validated_with_lei_role_critical.pem", + ExpectedResult: lint.Error, + ExpectedDetails: "Legal Entity Identifier Role extension present and critical", + }, + } + + for _, tc := range testCases { + t.Run(tc.Name, func(t *testing.T) { + result := test.TestLint("e_legal_entity_identifier", tc.InputFilename) + if result.Status != tc.ExpectedResult { + t.Errorf("expected result %v was %v", tc.ExpectedResult, result.Status) + } + + if tc.ExpectedDetails != result.Details { + t.Errorf("expected details: %q, was %q", tc.ExpectedDetails, result.Details) + } + }) + } +} diff --git a/v3/testdata/smime/individual_validated_with_lei.pem b/v3/testdata/smime/individual_validated_with_lei.pem new file mode 100644 index 000000000..c2993a9e0 --- /dev/null +++ b/v3/testdata/smime/individual_validated_with_lei.pem @@ -0,0 +1,44 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 27 20:23:43 2024 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:cd:01:83:83:79:70:8b:18:4b:21:2b:90:21:06: + 46:67:63:13:21:83:7c:13:e8:7b:e5:b9:bd:d9:4e: + 6d:c4:83:ad:1b:76:3f:92:be:b5:cb:f5:25:ea:10: + 1b:a8:dc:c1:53:f4:c1:d6:68:c5:bc:db:3f:79:90: + 8a:c5:56:28:cb + 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.4.3 + 1.3.6.1.4.1.52266.1: + 0. + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:46:02:21:00:92:2e:20:05:41:95:b7:20:54:9b:91:4c:dd: + 95:2e:6b:1c:05:5a:a6:87:d0:26:b5:e5:d8:2b:b7:bb:0c:1b: + b4:02:21:00:e8:f2:41:83:94:1e:1b:22:bd:9b:2b:2b:1a:f6: + 19:49:fc:9b:48:87:fc:ef:f7:01:b5:29:47:73:55:89:52:4a +-----BEGIN CERTIFICATE----- +MIIBLzCB1aADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjAyMzQzWhgP +OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATNAYOD +eXCLGEshK5AhBkZnYxMhg3wT6Hvlub3ZTm3Eg60bdj+SvrXL9SXqEBuo3MFT9MHW +aMW82z95kIrFVijLoz4wPDATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL +MAkGB2eBDAEFBAMwDwYJKwYBBAGDmCoBBAIwADAKBggqhkjOPQQDAgNJADBGAiEA +ki4gBUGVtyBUm5FM3ZUuaxwFWqaH0Ca15dgrt7sMG7QCIQDo8kGDlB4bIr2bKysa +9hlJ/JtIh/zv9wG1KUdzVYlSSg== +-----END CERTIFICATE----- + diff --git a/v3/testdata/smime/mailbox_validated_with_lei.pem b/v3/testdata/smime/mailbox_validated_with_lei.pem new file mode 100644 index 000000000..f2cd158a0 --- /dev/null +++ b/v3/testdata/smime/mailbox_validated_with_lei.pem @@ -0,0 +1,45 @@ +-------------Leaf------------- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 27 21:32:26 2024 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:f6:9a:d1:8b:a9:66:fe:3b:dd:44:58:3b:30:3d: + a8:18:ab:05:c5:0a:f7:dd:7e:10:fd:82:16:2a:78: + 22:d1:da:13:3e:f3:13:24:7a:53:5d:a5:a2:c1:fa: + 04:d6:65:e5:ee:39:03:03:b6:0b:0a:35:54:a7:1b: + c4:17:74:a0:c4 + 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 + 1.3.6.1.4.1.52266.1: + 0. + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:45:02:20:6e:d8:65:3b:9b:b9:08:77:e2:bc:2b:a6:24:1e: + 95:3c:60:61:21:68:35:3e:be:77:95:26:d8:cc:bd:24:f4:37: + 02:21:00:ed:f8:2e:11:8f:1f:5b:ba:15:5e:25:27:0a:53:dc: + 7f:f3:d6:33:6f:cd:64:45:ac:a6:37:ba:fa:4d:48:1b:05 +-----BEGIN CERTIFICATE----- +MIIBLjCB1aADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjEzMjI2WhgP +OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT2mtGL +qWb+O91EWDswPagYqwXFCvfdfhD9ghYqeCLR2hM+8xMkelNdpaLB+gTWZeXuOQMD +tgsKNVSnG8QXdKDEoz4wPDATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL +MAkGB2eBDAEFAQMwDwYJKwYBBAGDmCoBBAIwADAKBggqhkjOPQQDAgNIADBFAiBu +2GU7m7kId+K8K6YkHpU8YGEhaDU+vneVJtjMvST0NwIhAO34LhGPH1u6FV4lJwpT +3H/z1jNvzWRFrKY3uvpNSBsF +-----END CERTIFICATE----- + diff --git a/v3/testdata/smime/organization_validated_with_lei_critical.pem b/v3/testdata/smime/organization_validated_with_lei_critical.pem new file mode 100644 index 000000000..025420948 --- /dev/null +++ b/v3/testdata/smime/organization_validated_with_lei_critical.pem @@ -0,0 +1,44 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 27 20:24:36 2024 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:99:e8:3b:1a:e3:b2:a5:f2:15:04:66:e3:a5:33: + c7:f5:e3:91:1b:fd:0d:9a:50:8b:71:21:e6:90:c6: + 63:09:94:44:52:f7:6c:27:4e:48:11:13:cb:20:aa: + 3b:b9:f9:8b:d4:8b:82:a7:a1:36:b3:84:8d:a2:f3: + 59:fa:8e:24:77 + 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.2.3 + 1.3.6.1.4.1.52266.1: critical + 0. + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:46:02:21:00:ad:ff:32:f7:5d:60:46:16:5c:11:3c:52:c4: + 0c:6e:42:56:73:49:51:ac:19:30:ee:fe:a8:2a:50:92:3c:a3: + 92:02:21:00:99:b4:76:21:39:93:d4:b5:fd:fb:c6:ff:48:f4: + 56:e6:67:ed:84:aa:bb:18:63:83:0b:8f:73:67:b4:89:71:ec +-----BEGIN CERTIFICATE----- +MIIBMjCB2KADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjAyNDM2WhgP +OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASZ6Dsa +47Kl8hUEZuOlM8f145Eb/Q2aUItxIeaQxmMJlERS92wnTkgRE8sgqju5+YvUi4Kn +oTazhI2i81n6jiR3o0EwPzATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL +MAkGB2eBDAEFAgMwEgYJKwYBBAGDmCoBAQH/BAIwADAKBggqhkjOPQQDAgNJADBG +AiEArf8y911gRhZcETxSxAxuQlZzSVGsGTDu/qgqUJI8o5ICIQCZtHYhOZPUtf37 +xv9I9FbmZ+2EqrsYY4MLj3NntIlx7A== +-----END CERTIFICATE----- + diff --git a/v3/testdata/smime/organization_validated_with_lei_role.pem b/v3/testdata/smime/organization_validated_with_lei_role.pem new file mode 100644 index 000000000..9f84b53c7 --- /dev/null +++ b/v3/testdata/smime/organization_validated_with_lei_role.pem @@ -0,0 +1,44 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 27 21:24:08 2024 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:65:5a:40:93:2d:68:a9:f2:bc:25:f1:d5:73:41: + 7e:d1:8b:df:e3:ff:78:c6:35:18:e7:1a:01:18:19: + 87:5f:7e:db:97:6b:73:bd:b2:52:5c:58:87:59:4e: + 6a:2d:8d:4e:ea:7a:c9:84:7e:68:18:61:64:a0:c6: + 35:7d:e0:e4:b8 + 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.2.3 + 1.3.6.1.4.1.52266.2: + 0. + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:45:02:20:74:8e:47:17:c0:68:88:aa:48:2d:bb:e1:ea:5e: + b1:4b:9e:34:52:3d:84:81:64:8d:7f:c0:c7:2c:34:36:a8:8b: + 02:21:00:fe:54:e1:63:17:25:a7:2f:b8:89:d1:19:d8:81:a2: + bc:e6:d1:0b:7a:f7:e0:3b:8a:5e:d3:63:dd:d2:d0:91:8d +-----BEGIN CERTIFICATE----- +MIIBLjCB1aADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjEyNDA4WhgP +OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARlWkCT +LWip8rwl8dVzQX7Ri9/j/3jGNRjnGgEYGYdfftuXa3O9slJcWIdZTmotjU7qesmE +fmgYYWSgxjV94OS4oz4wPDATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL +MAkGB2eBDAEFAgMwDwYJKwYBBAGDmCoCBAIwADAKBggqhkjOPQQDAgNIADBFAiB0 +jkcXwGiIqkgtu+HqXrFLnjRSPYSBZI1/wMcsNDaoiwIhAP5U4WMXJacvuInRGdiB +orzm0Qt69+A7il7TY93S0JGN +-----END CERTIFICATE----- + diff --git a/v3/testdata/smime/sponsor_validated_with_lei_critical.pem b/v3/testdata/smime/sponsor_validated_with_lei_critical.pem new file mode 100644 index 000000000..f70ae20dc --- /dev/null +++ b/v3/testdata/smime/sponsor_validated_with_lei_critical.pem @@ -0,0 +1,44 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 27 20:27:18 2024 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:70:4c:86:07:80:17:0b:2c:db:4d:32:0b:fa:5b: + 2b:7a:90:09:60:f5:d9:10:f9:1f:c7:a9:1d:b2:84: + 91:0c:88:ac:de:c2:85:a3:39:2b:89:70:6d:44:16: + 49:ae:46:92:82:c6:d8:05:7d:3c:16:80:9b:fb:11: + 41:df:03:ee:05 + 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.3.3 + 1.3.6.1.4.1.52266.1: critical + 0. + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:45:02:21:00:a8:1d:cf:1e:5e:8d:ea:40:f2:30:0b:4b:b9: + 11:42:75:de:30:00:7b:31:ba:0f:df:64:83:72:0f:2e:94:a7: + 84:02:20:4d:95:81:58:2a:2b:ab:86:3a:ae:37:25:10:79:56: + 7c:07:01:34:06:5f:4c:f9:cc:40:1d:31:e4:94:48:34:db +-----BEGIN CERTIFICATE----- +MIIBMTCB2KADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjAyNzE4WhgP +OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARwTIYH +gBcLLNtNMgv6Wyt6kAlg9dkQ+R/HqR2yhJEMiKzewoWjOSuJcG1EFkmuRpKCxtgF +fTwWgJv7EUHfA+4Fo0EwPzATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL +MAkGB2eBDAEFAwMwEgYJKwYBBAGDmCoBAQH/BAIwADAKBggqhkjOPQQDAgNIADBF +AiEAqB3PHl6N6kDyMAtLuRFCdd4wAHsxug/fZINyDy6Up4QCIE2VgVgqK6uGOq43 +JRB5VnwHATQGX0z5zEAdMeSUSDTb +-----END CERTIFICATE----- + diff --git a/v3/testdata/smime/sponsor_validated_with_lei_role_critical.pem b/v3/testdata/smime/sponsor_validated_with_lei_role_critical.pem new file mode 100644 index 000000000..e4f0b74ca --- /dev/null +++ b/v3/testdata/smime/sponsor_validated_with_lei_role_critical.pem @@ -0,0 +1,44 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: ecdsa-with-SHA256 + Issuer: + Validity + Not Before: Feb 27 21:27:01 2024 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:38:a5:8d:f4:41:c4:74:b6:f5:81:80:f9:1c:76: + 07:c0:34:44:2f:f1:4c:35:b1:87:d2:c7:50:ca:8d: + df:b9:be:6b:2a:1c:bd:60:f7:1a:5f:2e:df:92:db: + ac:5d:11:74:f0:53:bc:dc:d6:2a:b7:27:f1:4b:1f: + 93:5b:9d:fb:6d + 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.3.3 + 1.3.6.1.4.1.52266.2: critical + 0. + Signature Algorithm: ecdsa-with-SHA256 + Signature Value: + 30:46:02:21:00:89:6f:04:3d:64:d6:98:8f:3e:5d:3c:99:2c: + 67:34:0f:4d:a8:77:d9:41:93:08:d9:72:a7:ed:f1:e5:3d:b9: + 5f:02:21:00:fb:a3:41:a5:94:c6:84:88:9f:8f:ff:cc:52:a6: + a1:ba:cf:a3:87:50:58:5c:63:ff:2c:46:42:98:fc:eb:05:09 +-----BEGIN CERTIFICATE----- +MIIBMjCB2KADAgECAgEDMAoGCCqGSM49BAMCMAAwIBcNMjQwMjI3MjEyNzAxWhgP +OTk5ODExMzAwMDAwMDBaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ4pY30 +QcR0tvWBgPkcdgfANEQv8Uw1sYfSx1DKjd+5vmsqHL1g9xpfLt+S26xdEXTwU7zc +1iq3J/FLH5Nbnftto0EwPzATBgNVHSUEDDAKBggrBgEFBQcDBDAUBgNVHSAEDTAL +MAkGB2eBDAEFAwMwEgYJKwYBBAGDmCoCAQH/BAIwADAKBggqhkjOPQQDAgNJADBG +AiEAiW8EPWTWmI8+XTyZLGc0D02od9lBkwjZcqft8eU9uV8CIQD7o0GllMaEiJ+P +/8xSpqG6z6OHUFhcY/8sRkKY/OsFCQ== +-----END CERTIFICATE----- + diff --git a/v3/util/oid.go b/v3/util/oid.go index bdabb0e73..5ded05d68 100644 --- a/v3/util/oid.go +++ b/v3/util/oid.go @@ -24,33 +24,35 @@ import ( var ( //extension OIDs - AdobeTimeStampOID = asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 9, 1} // Adobe Time-stamp x509 extension - AdobeArchiveRevInfoOID = asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 9, 2} // Adobe Archive Revocation Info x509 extension - AiaOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1} // Authority Information Access - AuthkeyOID = asn1.ObjectIdentifier{2, 5, 29, 35} // Authority Key Identifier - BasicConstOID = asn1.ObjectIdentifier{2, 5, 29, 19} // Basic Constraints - CertPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 32} // Certificate Policies - CrlDistOID = asn1.ObjectIdentifier{2, 5, 29, 31} // CRL Distribution Points - CtPoisonOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} // CT Poison - EkuSynOid = asn1.ObjectIdentifier{2, 5, 29, 37} // Extended Key Usage Syntax - FreshCRLOID = asn1.ObjectIdentifier{2, 5, 29, 46} // Freshest CRL - InhibitAnyPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 54} // Inhibit Any Policy - IssuerAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 18} // Issuer Alt Name - KeyUsageOID = asn1.ObjectIdentifier{2, 5, 29, 15} // Key Usage - LogoTypeOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 12} // Logo Type Ext - NameConstOID = asn1.ObjectIdentifier{2, 5, 29, 30} // Name Constraints - OscpNoCheckOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 5} // OSCP No Check - PolicyConstOID = asn1.ObjectIdentifier{2, 5, 29, 36} // Policy Constraints - PolicyMapOID = asn1.ObjectIdentifier{2, 5, 29, 33} // Policy Mappings - PrivKeyUsageOID = asn1.ObjectIdentifier{2, 5, 29, 16} // Private Key Usage Period - QcStateOid = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3} // QC Statements - TimestampOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} // Signed Certificate Timestamp List - SmimeOID = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 15} // Smime Capabilities - SubjectAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 17} // Subject Alt Name - SubjectDirAttrOID = asn1.ObjectIdentifier{2, 5, 29, 9} // Subject Directory Attributes - SubjectInfoAccessOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11} // Subject Info Access Syntax - SubjectKeyIdentityOID = asn1.ObjectIdentifier{2, 5, 29, 14} // Subject Key Identifier - ReasonCodeOID = asn1.ObjectIdentifier{2, 5, 29, 21} // CRL Reason Code + AdobeTimeStampOID = asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 9, 1} // Adobe Time-stamp x509 extension + AdobeArchiveRevInfoOID = asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 9, 2} // Adobe Archive Revocation Info x509 extension + AiaOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 1} // Authority Information Access + AuthkeyOID = asn1.ObjectIdentifier{2, 5, 29, 35} // Authority Key Identifier + BasicConstOID = asn1.ObjectIdentifier{2, 5, 29, 19} // Basic Constraints + CertPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 32} // Certificate Policies + CrlDistOID = asn1.ObjectIdentifier{2, 5, 29, 31} // CRL Distribution Points + CtPoisonOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3} // CT Poison + EkuSynOid = asn1.ObjectIdentifier{2, 5, 29, 37} // Extended Key Usage Syntax + FreshCRLOID = asn1.ObjectIdentifier{2, 5, 29, 46} // Freshest CRL + InhibitAnyPolicyOID = asn1.ObjectIdentifier{2, 5, 29, 54} // Inhibit Any Policy + IssuerAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 18} // Issuer Alt Name + KeyUsageOID = asn1.ObjectIdentifier{2, 5, 29, 15} // Key Usage + LegalEntityIdentifierOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 52266, 1} // Legal Entity Identifier + LegalEntityIdentifierRoleOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 52266, 2} // Legal Entity Identifier Role + LogoTypeOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 12} // Logo Type Ext + NameConstOID = asn1.ObjectIdentifier{2, 5, 29, 30} // Name Constraints + OscpNoCheckOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 5} // OSCP No Check + PolicyConstOID = asn1.ObjectIdentifier{2, 5, 29, 36} // Policy Constraints + PolicyMapOID = asn1.ObjectIdentifier{2, 5, 29, 33} // Policy Mappings + PrivKeyUsageOID = asn1.ObjectIdentifier{2, 5, 29, 16} // Private Key Usage Period + QcStateOid = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 3} // QC Statements + TimestampOID = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 2} // Signed Certificate Timestamp List + SmimeOID = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 15} // Smime Capabilities + SubjectAlternateNameOID = asn1.ObjectIdentifier{2, 5, 29, 17} // Subject Alt Name + SubjectDirAttrOID = asn1.ObjectIdentifier{2, 5, 29, 9} // Subject Directory Attributes + SubjectInfoAccessOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 11} // Subject Info Access Syntax + SubjectKeyIdentityOID = asn1.ObjectIdentifier{2, 5, 29, 14} // Subject Key Identifier + ReasonCodeOID = asn1.ObjectIdentifier{2, 5, 29, 21} // CRL Reason Code // CA/B reserved policies BRDomainValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1} // CA/B BR Domain-Validated BROrganizationValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 2} // CA/B BR Organization-Validated diff --git a/v3/util/smime_policies.go b/v3/util/smime_policies.go index 763a9fa86..f0f4eb3be 100644 --- a/v3/util/smime_policies.go +++ b/v3/util/smime_policies.go @@ -18,9 +18,13 @@ import ( "github.com/zmap/zcrypto/x509" ) -func IsMailboxValidatedCertificate(c *x509.Certificate) bool { +func IsSMIMEBRCertificate(c *x509.Certificate) bool { + return IsLegacySMIMECertificate(c) || IsMultipurposeSMIMECertificate(c) || IsStrictSMIMECertificate(c) +} + +func IsIndividualValidatedCertificate(c *x509.Certificate) bool { for _, oid := range c.PolicyIdentifiers { - if oid.Equal(SMIMEBRMailboxValidatedLegacyOID) || oid.Equal(SMIMEBRMailboxValidatedMultipurposeOID) || oid.Equal(SMIMEBRMailboxValidatedStrictOID) { + if oid.Equal(SMIMEBRIndividualValidatedLegacyOID) || oid.Equal(SMIMEBRIndividualValidatedMultipurposeOID) || oid.Equal(SMIMEBRIndividualValidatedStrictOID) { return true } } @@ -28,13 +32,9 @@ func IsMailboxValidatedCertificate(c *x509.Certificate) bool { return false } -func IsSMIMEBRCertificate(c *x509.Certificate) bool { - return IsLegacySMIMECertificate(c) || IsMultipurposeSMIMECertificate(c) || IsStrictSMIMECertificate(c) -} - -func IsLegacySMIMECertificate(c *x509.Certificate) bool { +func IsMailboxValidatedCertificate(c *x509.Certificate) bool { for _, oid := range c.PolicyIdentifiers { - if oid.Equal(SMIMEBRMailboxValidatedLegacyOID) || oid.Equal(SMIMEBROrganizationValidatedLegacyOID) || oid.Equal(SMIMEBRSponsorValidatedLegacyOID) || oid.Equal(SMIMEBRIndividualValidatedLegacyOID) { + if oid.Equal(SMIMEBRMailboxValidatedLegacyOID) || oid.Equal(SMIMEBRMailboxValidatedMultipurposeOID) || oid.Equal(SMIMEBRMailboxValidatedStrictOID) { return true } } @@ -62,6 +62,16 @@ func IsSponsorValidatedCertificate(c *x509.Certificate) bool { return false } +func IsLegacySMIMECertificate(c *x509.Certificate) bool { + for _, oid := range c.PolicyIdentifiers { + if oid.Equal(SMIMEBRMailboxValidatedLegacyOID) || oid.Equal(SMIMEBROrganizationValidatedLegacyOID) || oid.Equal(SMIMEBRSponsorValidatedLegacyOID) || oid.Equal(SMIMEBRIndividualValidatedLegacyOID) { + return true + } + } + + return false +} + func IsMultipurposeSMIMECertificate(c *x509.Certificate) bool { for _, oid := range c.PolicyIdentifiers { if oid.Equal(SMIMEBRMailboxValidatedMultipurposeOID) || oid.Equal(SMIMEBROrganizationValidatedMultipurposeOID) || oid.Equal(SMIMEBRSponsorValidatedMultipurposeOID) || oid.Equal(SMIMEBRIndividualValidatedMultipurposeOID) {