From c6fb8df03433aeb97529f55674eefb1a19666527 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Sat, 12 Oct 2024 16:41:17 +0000 Subject: [PATCH] chore(deps): update module github.com/zmap/zlint/v3 to v3.6.4 --- go.mod | 8 +- go.sum | 8 + vendor/github.com/zmap/zlint/v3/lint/base.go | 5 +- .../github.com/zmap/zlint/v3/lint/source.go | 8 +- ...lint_aia_ca_issuers_must_have_http_only.go | 78 +++++++++ ...ia_must_contain_permitted_access_method.go | 113 +++++++++++++ .../lint_aia_ocsp_must_have_http_only.go | 78 +++++++++ .../cabf_br/lint_aia_unique_locations.go | 89 ++++++++++ .../v3/lints/cabf_br/lint_ca_invalid_eku.go | 81 +++++++++ .../lint_cab_dv_subject_invalid_values.go | 77 +++++++++ .../lint_crl_distrib_points_not_http.go | 64 ++++++++ ...nt_crlissuer_must_not_be_present_in_cdp.go | 79 +++++++++ .../lint_dsa_correct_order_in_subgroup.go | 11 +- .../lint_dsa_shorter_than_2048_bits.go | 5 +- .../lint_dsa_unique_correct_representation.go | 11 +- .../cabf_br/lint_duplicate_subject_attribs.go | 99 +++++++++++ .../lints/cabf_br/lint_e_invalid_cps_uri.go | 74 +++++++++ .../v3/lints/cabf_br/lint_eku_critical.go | 52 ++++++ ...y_identifier_not_recommended_subscriber.go | 70 ++++++++ .../cabf_br/lint_invalid_subject_rdn_order.go | 145 ++++++++++++++++ ...nt_sub_cert_aia_contains_internal_names.go | 13 +- ...ert_aia_does_not_contain_issuing_ca_url.go | 8 +- ..._sub_cert_aia_does_not_contain_ocsp_url.go | 11 +- .../lints/cabf_br/lint_sub_cert_eku_check.go | 81 +++++++++ .../cabf_br/lint_sub_cert_eku_extra_values.go | 11 +- ...ert_eku_server_auth_client_auth_missing.go | 11 +- .../cabf_br/lint_subj_orgunit_in_ca_cert.go | 69 ++++++++ .../lint_subject_rdns_correct_encoding.go | 155 ++++++++++++++++++ .../lint_cs_crl_distribution_points.go | 62 +++++++ .../lints/cabf_cs_br/lint_cs_eku_required.go | 87 ++++++++++ .../cabf_cs_br/lint_cs_key_usage_required.go | 79 +++++++++ .../lints/cabf_cs_br/lint_cs_rsa_key_size.go | 58 +++++++ ...t_cabf_org_identifier_psd_vat_has_state.go | 57 +++++++ .../lint_ev_invalid_business_category.go | 69 ++++++++ ...lint_ev_orgid_inconsistent_subj_and_ext.go | 143 ++++++++++++++++ .../lint_authority_key_identifier.go | 85 ++++++++++ .../lint_commonname_mailbox_validated.go | 58 +++++++ .../lint_legal_entity_identifier.go | 83 ++++++++++ .../lint_qc_statements_not_critical.go | 55 +++++++ .../lint_single_email_if_present.go | 39 +++-- .../lint_single_email_subject_if_present.go | 60 +++++++ .../lint_subject_country_name.go | 55 +++++++ .../cabf_smime_br/lint_subject_dir_attr.go | 52 ++++++ ...ribers_crl_distribution_points_are_http.go | 77 +++++++++ .../cabf_smime_br/mailbox_address_from_san.go | 124 ++++++++++++++ .../smime_legacy_multipurpose_eku_check.go | 4 +- .../lint_subj_country_not_uppercase.go | 62 +++++++ .../v3/lints/rfc/lint_cert_ext_invalid_der.go | 119 ++++++++++++++ .../lint_crl_empty_revoked_certificates.go | 101 ++++++++++++ .../lints/rfc/lint_crl_missing_crl_number.go | 62 +++++++ ...nt_crl_revoked_certificates_field_empty.go | 114 +++++++++++++ .../zlint/v3/lints/rfc/lint_empty_sct_list.go | 99 +++++++++++ .../lints/rfc/lint_precert_with_sct_list.go | 59 +++++++ vendor/github.com/zmap/zlint/v3/util/ca.go | 29 ++-- vendor/github.com/zmap/zlint/v3/util/cs.go | 18 ++ .../github.com/zmap/zlint/v3/util/gtld_map.go | 14 +- vendor/github.com/zmap/zlint/v3/util/oid.go | 76 +++++---- vendor/github.com/zmap/zlint/v3/util/san.go | 13 +- .../zmap/zlint/v3/util/smime_policies.go | 26 ++- vendor/github.com/zmap/zlint/v3/util/time.go | 6 + vendor/github.com/zmap/zlint/v3/zlint.go | 1 + .../x/crypto/internal/poly1305/sum_ppc64le.s | 14 +- vendor/golang.org/x/crypto/ocsp/ocsp.go | 13 +- vendor/golang.org/x/sys/unix/aliases.go | 2 +- .../x/sys/unix/syscall_darwin_libSystem.go | 2 +- .../golang.org/x/sys/unix/syscall_freebsd.go | 12 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 99 +++++++++++ .../golang.org/x/sys/unix/zsyscall_linux.go | 10 ++ vendor/golang.org/x/sys/unix/ztypes_linux.go | 60 +++++++ vendor/modules.txt | 9 +- 70 files changed, 3647 insertions(+), 134 deletions(-) create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ca_issuers_must_have_http_only.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_must_contain_permitted_access_method.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ocsp_must_have_http_only.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_unique_locations.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_invalid_eku.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_cab_dv_subject_invalid_values.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crl_distrib_points_not_http.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crlissuer_must_not_be_present_in_cdp.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_duplicate_subject_attribs.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_e_invalid_cps_uri.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_eku_critical.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ext_subject_key_identifier_not_recommended_subscriber.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_invalid_subject_rdn_order.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_check.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subj_orgunit_in_ca_cert.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subject_rdns_correct_encoding.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_crl_distribution_points.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_eku_required.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_key_usage_required.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_rsa_key_size.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_cabf_org_identifier_psd_vat_has_state.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_invalid_business_category.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_orgid_inconsistent_subj_and_ext.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_authority_key_identifier.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_legal_entity_identifier.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_qc_statements_not_critical.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_subject_if_present.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_country_name.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_dir_attr.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subscribers_crl_distribution_points_are_http.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/mailbox_address_from_san.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/community/lint_subj_country_not_uppercase.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/rfc/lint_cert_ext_invalid_der.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_empty_revoked_certificates.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_missing_crl_number.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_revoked_certificates_field_empty.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/rfc/lint_empty_sct_list.go create mode 100644 vendor/github.com/zmap/zlint/v3/lints/rfc/lint_precert_with_sct_list.go create mode 100644 vendor/github.com/zmap/zlint/v3/util/cs.go diff --git a/go.mod b/go.mod index 5d8a79f5..d31f22eb 100644 --- a/go.mod +++ b/go.mod @@ -15,8 +15,8 @@ require ( github.com/mattn/go-sqlite3 v1.14.22 github.com/prometheus/client_golang v1.19.0 github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 - github.com/zmap/zlint/v3 v3.6.1 - golang.org/x/crypto v0.19.0 + github.com/zmap/zlint/v3 v3.6.4 + golang.org/x/crypto v0.21.0 ) require ( @@ -33,8 +33,8 @@ require ( github.com/stretchr/testify v1.8.4 // indirect github.com/weppos/publicsuffix-go v0.30.0 // indirect github.com/ziutek/mymysql v1.5.4 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.17.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.32.0 // indirect k8s.io/klog/v2 v2.100.1 // indirect diff --git a/go.sum b/go.sum index 4b18bc77..41881dc3 100644 --- a/go.sum +++ b/go.sum @@ -377,6 +377,8 @@ github.com/zmap/zlint/v3 v3.5.0 h1:Eh2B5t6VKgVH0DFmTwOqE50POvyDhUaU9T2mJOe1vfQ= github.com/zmap/zlint/v3 v3.5.0/go.mod h1:JkNSrsDJ8F4VRtBZcYUQSvnWFL7utcjDIn+FE64mlBI= github.com/zmap/zlint/v3 v3.6.1 h1:IM1jJ35YFBKFrbBMc8Kq34MGyDYttwRGZjO/qxIYG2Y= github.com/zmap/zlint/v3 v3.6.1/go.mod h1:NVgiIWssgzp0bNl8P4Gz94NHV2ep/4Jyj9V69uTmZyg= +github.com/zmap/zlint/v3 v3.6.4 h1:r2kHfRF7mIsxW0IH4Og2iZnrlpCLTZBFjnXy1x/ZnZI= +github.com/zmap/zlint/v3 v3.6.4/go.mod h1:KQLVUquVaO5YJDl5a4k/7RPIbIW2v66+sRoBPNZusI8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -397,6 +399,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -473,6 +477,8 @@ golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -542,6 +548,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/vendor/github.com/zmap/zlint/v3/lint/base.go b/vendor/github.com/zmap/zlint/v3/lint/base.go index 499810e7..e572b27a 100644 --- a/vendor/github.com/zmap/zlint/v3/lint/base.go +++ b/vendor/github.com/zmap/zlint/v3/lint/base.go @@ -221,7 +221,10 @@ func (l *CertificateLint) Execute(cert *x509.Certificate, config Configuration) if l.Source == CABFBaselineRequirements && !util.IsServerAuthCert(cert) { return &LintResult{Status: NA} } - if l.Source == CABFSMIMEBaselineRequirements && !((util.IsEmailProtectionCert(cert) && util.HasEmailSAN(cert)) || util.IsSMIMEBRCertificate(cert)) { + if l.Source == CABFSMIMEBaselineRequirements && !util.IsEmailProtectionCert(cert) { + return &LintResult{Status: NA} + } + if l.Source == CABFCSBaselineRequirements && !util.IsCodeSigning(cert.PolicyIdentifiers) { return &LintResult{Status: NA} } lint := l.Lint() diff --git a/vendor/github.com/zmap/zlint/v3/lint/source.go b/vendor/github.com/zmap/zlint/v3/lint/source.go index 2486cb0a..3cd0c303 100644 --- a/vendor/github.com/zmap/zlint/v3/lint/source.go +++ b/vendor/github.com/zmap/zlint/v3/lint/source.go @@ -32,8 +32,10 @@ const ( RFC5280 LintSource = "RFC5280" RFC5480 LintSource = "RFC5480" RFC5891 LintSource = "RFC5891" + RFC6962 LintSource = "RFC6962" RFC8813 LintSource = "RFC8813" CABFBaselineRequirements LintSource = "CABF_BR" + CABFCSBaselineRequirements LintSource = "CABF_CS_BR" CABFSMIMEBaselineRequirements LintSource = "CABF_SMIME_BR" CABFEVGuidelines LintSource = "CABF_EV" MozillaRootStorePolicy LintSource = "Mozilla" @@ -51,7 +53,7 @@ func (s *LintSource) UnmarshalJSON(data []byte) error { } switch LintSource(throwAway) { - case RFC5280, RFC5480, RFC5891, CABFBaselineRequirements, CABFEVGuidelines, CABFSMIMEBaselineRequirements, MozillaRootStorePolicy, AppleRootStorePolicy, Community, EtsiEsi: + case RFC8813, RFC5280, RFC5480, RFC5891, CABFBaselineRequirements, CABFEVGuidelines, CABFSMIMEBaselineRequirements, MozillaRootStorePolicy, AppleRootStorePolicy, Community, EtsiEsi, RFC6962: *s = LintSource(throwAway) return nil default: @@ -75,6 +77,8 @@ func (s *LintSource) FromString(src string) { *s = RFC5480 case RFC5891: *s = RFC5891 + case RFC8813: + *s = RFC8813 case CABFBaselineRequirements: *s = CABFBaselineRequirements case CABFEVGuidelines: @@ -87,6 +91,8 @@ func (s *LintSource) FromString(src string) { *s = AppleRootStorePolicy case Community: *s = Community + case RFC6962: + *s = RFC6962 case EtsiEsi: *s = EtsiEsi } diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ca_issuers_must_have_http_only.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ca_issuers_must_have_http_only.go new file mode 100644 index 00000000..08bd9d23 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ca_issuers_must_have_http_only.go @@ -0,0 +1,78 @@ +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 ( + "fmt" + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type bRAIACAIssuersHasHTTPOnly struct{} + +/************************************************************************ +7.1.2.7.7 Subscriber Certificate Authority Information Access +The AuthorityInfoAccessSyntax MUST contain one or more AccessDescriptions. Each +AccessDescription MUST only contain a permitted accessMethod, as detailed below, and +each accessLocation MUST be encoded as the specified GeneralName type. +The AuthorityInfoAccessSyntax MAY contain multiple AccessDescriptions with the +same accessMethod, if permitted for that accessMethod. When multiple +AccessDescriptions are present with the same accessMethod, each accessLocation +MUST be unique, and each AccessDescription MUST be ordered in priority for that +accessMethod, with the most‐preferred accessLocation being the first +AccessDescription. No ordering requirements are given for AccessDescriptions that +contain different accessMethods, provided that previous requirement is satisfied. + +id-ad-caIssuers +1.3.6.1.5.5.7.48.2 uniformResourceIdentifier SHOULD A HTTP URL of the +Issuing CA’s certificate +*************************************************************************/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_aia_ca_issuers_must_have_http_only", + Description: "The id-ad-caIssuers accessMethod must contain an HTTP URL of the Issuing CA’s certificate. Other schemes are not allowed.", + Citation: "BRs: 7.1.2.7.7", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewBRAIACAIssuersHasHTTPOnly, + }) +} + +func NewBRAIACAIssuersHasHTTPOnly() lint.LintInterface { + return &bRAIACAIssuersHasHTTPOnly{} +} + +func (l *bRAIACAIssuersHasHTTPOnly) CheckApplies(c *x509.Certificate) bool { + return len(c.IssuingCertificateURL) > 0 && util.IsSubscriberCert(c) +} + +func (l *bRAIACAIssuersHasHTTPOnly) Execute(c *x509.Certificate) *lint.LintResult { + for _, u := range c.IssuingCertificateURL { + purl, err := url.Parse(u) + if err != nil { + return &lint.LintResult{Status: lint.Error, Details: "Could not parse caIssuers in AIA."} + } + if purl.Scheme != "http" { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Found scheme %s in caIssuers of AIA, which is not allowed.", purl.Scheme)} + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_must_contain_permitted_access_method.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_must_contain_permitted_access_method.go new file mode 100644 index 00000000..ca741240 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_must_contain_permitted_access_method.go @@ -0,0 +1,113 @@ +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 ( + "fmt" + + "github.com/zmap/zcrypto/encoding/asn1" + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type bRAIAAccessMethodAllowed struct{} + +/************************************************************************ +7.1.2.7.7 Subscriber Certificate Authority Information Access +The AuthorityInfoAccessSyntax MUST contain one or more AccessDescriptions. Each +AccessDescription MUST only contain a permitted accessMethod, as detailed below, and +each accessLocation MUST be encoded as the specified GeneralName type. +The AuthorityInfoAccessSyntax MAY contain multiple AccessDescriptions with the +same accessMethod, if permitted for that accessMethod. When multiple +AccessDescriptions are present with the same accessMethod, each accessLocation +MUST be unique, and each AccessDescription MUST be ordered in priority for that +accessMethod, with the most‐preferred accessLocation being the first +AccessDescription. No ordering requirements are given for AccessDescriptions that +contain different accessMethods, provided that previous requirement is satisfied. + +Each AccessDescription MUST only contain a permitted accessMethod, as detailed below, +and each accessLocation MUST be encoded as the specified GeneralName type. + +This lint checks that only the id-ad-ocsp or id-ad-caIssuers accessMethod is present +and that the value is a uniformResourceIdentifier GeneralName. + +GeneralName ::= CHOICE { + otherName [0] AnotherName, + rfc822Name [1] IA5String, + dNSName [2] IA5String, + x400Address [3] ORAddress, + directoryName [4] Name, + ediPartyName [5] EDIPartyName, + uniformResourceIdentifier [6] IA5String, + iPAddress [7] OCTET STRING, + registeredID [8] OBJECT IDENTIFIER } +*************************************************************************/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_aia_must_contain_permitted_access_method", + Description: "The AIA must contain only the id-ad-ocsp or id-ad-caIssuers accessMethod. Others are not allowed. Also, each accessLocation MUST be encoded as uniformResourceIdentifier GeneralName.", + Citation: "BRs: 7.1.2.7.7", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewBRAIAAccessMethodAllowed, + }) +} + +func NewBRAIAAccessMethodAllowed() lint.LintInterface { + return &bRAIAAccessMethodAllowed{} +} + +func (l *bRAIAAccessMethodAllowed) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.AiaOID) +} + +func (l *bRAIAAccessMethodAllowed) Execute(c *x509.Certificate) *lint.LintResult { + + // see x509.go + for _, ext := range c.Extensions { + if ext.Id.Equal(util.AiaOID) { + var aia []authorityInfoAccess + _, err := asn1.Unmarshal(ext.Value, &aia) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + for _, v := range aia { + if v.Location.Tag != 6 { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Certificate has an invalid GeneralName with tag %d in an accessLocation.", v.Location.Tag)} + } + + if !(v.Method.Equal(idAdCaIssuers) || v.Method.Equal(idAdOCSP)) { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Certificate has an invalid accessMethod with OID %s.", v.Method)} + } + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +type authorityInfoAccess struct { + Method asn1.ObjectIdentifier + Location asn1.RawValue +} + +var ( + idAdOCSP = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1} + idAdCaIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2} +) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ocsp_must_have_http_only.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ocsp_must_have_http_only.go new file mode 100644 index 00000000..6b56e177 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_ocsp_must_have_http_only.go @@ -0,0 +1,78 @@ +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 ( + "fmt" + "net/url" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type bRAIAOCSPHasHTTPOnly struct{} + +/************************************************************************ +7.1.2.7.7 Subscriber Certificate Authority Information Access +The AuthorityInfoAccessSyntax MUST contain one or more AccessDescriptions. Each +AccessDescription MUST only contain a permitted accessMethod, as detailed below, and +each accessLocation MUST be encoded as the specified GeneralName type. +The AuthorityInfoAccessSyntax MAY contain multiple AccessDescriptions with the +same accessMethod, if permitted for that accessMethod. When multiple +AccessDescriptions are present with the same accessMethod, each accessLocation +MUST be unique, and each AccessDescription MUST be ordered in priority for that +accessMethod, with the most‐preferred accessLocation being the first +AccessDescription. No ordering requirements are given for AccessDescriptions that +contain different accessMethods, provided that previous requirement is satisfied. + +id-ad-ocsp +1.3.6.1.5.5.7.48.1 uniformResourceIdentifier MUST A HTTP URL of the +Issuing CA’s OCSP responder. +*************************************************************************/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_aia_ocsp_must_have_http_only", + Description: "The id-ad-ocsp accessMethod must contain an HTTP URL of the of the Issuing CA’s OCSP responder. Other schemes are not allowed.", + Citation: "BRs: 7.1.2.7.7", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewBRAIAOCSPHasHTTPOnly, + }) +} + +func NewBRAIAOCSPHasHTTPOnly() lint.LintInterface { + return &bRAIAOCSPHasHTTPOnly{} +} + +func (l *bRAIAOCSPHasHTTPOnly) CheckApplies(c *x509.Certificate) bool { + return len(c.OCSPServer) > 0 && util.IsSubscriberCert(c) +} + +func (l *bRAIAOCSPHasHTTPOnly) Execute(c *x509.Certificate) *lint.LintResult { + for _, u := range c.OCSPServer { + purl, err := url.Parse(u) + if err != nil { + return &lint.LintResult{Status: lint.Error, Details: "Could not parse OCSP URL in AIA."} + } + if purl.Scheme != "http" { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("Found scheme %s in OCSP URL of AIA, which is not allowed.", purl.Scheme)} + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_unique_locations.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_unique_locations.go new file mode 100644 index 00000000..f176d35e --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_aia_unique_locations.go @@ -0,0 +1,89 @@ +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 ( + "fmt" + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type bRAIAAccessLocationUnique struct{} + +/************************************************************************ +7.1.2.7.7 Subscriber Certificate Authority Information Access +The AuthorityInfoAccessSyntax MUST contain one or more AccessDescriptions. Each +AccessDescription MUST only contain a permitted accessMethod, as detailed below, and +each accessLocation MUST be encoded as the specified GeneralName type. +The AuthorityInfoAccessSyntax MAY contain multiple AccessDescriptions with the +same accessMethod, if permitted for that accessMethod. When multiple +AccessDescriptions are present with the same accessMethod, each accessLocation +MUST be unique, and each AccessDescription MUST be ordered in priority for that +accessMethod, with the most‐preferred accessLocation being the first +AccessDescription. No ordering requirements are given for AccessDescriptions that +contain different accessMethods, provided that previous requirement is satisfied. + +When multiple AccessDescriptions are present with the same accessMethod, +each accessLocation MUST be unique. +*************************************************************************/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_aia_unique_access_locations", + Description: "When multiple AccessDescriptions are present with the same accessMethod in the AIA extension, then each accessLocation MUST be unique.", + Citation: "BRs: 7.1.2.7.7", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewBRAIAAccessLocationUnique, + }) +} + +func NewBRAIAAccessLocationUnique() lint.LintInterface { + return &bRAIAAccessLocationUnique{} +} + +func (l *bRAIAAccessLocationUnique) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && (len(c.IssuingCertificateURL) > 0 || len(c.OCSPServer) > 0) +} + +func (l *bRAIAAccessLocationUnique) Execute(c *x509.Certificate) *lint.LintResult { + + ocspURLs := make([]string, 0) + for _, url := range c.OCSPServer { + for _, foundURL := range ocspURLs { + if strings.EqualFold(url, foundURL) { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("accessLocation with URL %s is found more than once in OCSP URLs", url)} + } + } + ocspURLs = append(ocspURLs, url) + } + + issuingCertificateURLs := make([]string, 0) + for _, url := range c.IssuingCertificateURL { + for _, foundURL := range issuingCertificateURLs { + if strings.EqualFold(url, foundURL) { + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("accessLocation with URL %s is found more than once in caIssuers URLs", url)} + } + } + issuingCertificateURLs = append(issuingCertificateURLs, url) + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_invalid_eku.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_invalid_eku.go new file mode 100644 index 00000000..d6b8ddea --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ca_invalid_eku.go @@ -0,0 +1,81 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + */ + +package cabf_br + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "fmt" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_ca_invalid_eku", + Description: "Checks that SubCA certificates do not contain forbidden values in their EKU extension.", + Citation: "CABF BRs §7.1.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_1_7_1_Date, + }, + Lint: NewCaInvalidEKU, + }) +} + +type caInvalidEKU struct{} + +func NewCaInvalidEKU() lint.LintInterface { + return &caInvalidEKU{} +} + +// This lint applies to any SubCA certificate to which the CABF BRs are applicable and which contains +// the EKU extension. Given that the lint source is lint.CABFBaselineRequirements, if we arrive here +// it's been already checked that the certificate falls within the purview of the CABF BRs. +func (l *caInvalidEKU) CheckApplies(c *x509.Certificate) bool { + return util.IsSubCA(c) && len(c.ExtKeyUsage) != 0 +} + +func (l *caInvalidEKU) Execute(c *x509.Certificate) *lint.LintResult { + + // If the EKU contains anyExtendedKeyUsage, it's probably a cross-certicate + // In this case, the EKU must not contain any other value + if util.HasEKU(c, x509.ExtKeyUsageAny) && len(c.ExtKeyUsage) > 1 { + return &lint.LintResult{ + Status: lint.Error, + Details: "anyExtendedKeyUsage MUST NOT be accompanied by any other value in the EKU extension", + } + } + + // If we get here, it is necessarily a SubCA with serverAuth in the EKU + for _, eku := range c.ExtKeyUsage { + if eku == x509.ExtKeyUsageEmailProtection || + eku == x509.ExtKeyUsageCodeSigning || + eku == x509.ExtKeyUsageTimeStamping || + eku == x509.ExtKeyUsageOcspSigning { + + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("%s MUST not be present together with serverAuth in the EKU extension", util.GetEKUString(eku)), + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_cab_dv_subject_invalid_values.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_cab_dv_subject_invalid_values.go new file mode 100644 index 00000000..3563da7f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_cab_dv_subject_invalid_values.go @@ -0,0 +1,77 @@ +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 ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type dvSubjectInvalidValues struct{} + +/************************************************ +7.1.2.7.2 Domain Validated + +The following table details the acceptable AttributeTypes that may appear within the type +field of an AttributeTypeAndValue, as well as the contents permitted within the value field. + +Table 35: Domain Validated subject Attributes + +countryName MAY The two‐letter ISO 3166‐1 country code for the country +associated with the Subject. Section 3.2.2.3 + +commonName NOT RECOMMENDED +If present, MUST contain a value derived from the +subjectAltName extension according to Section +7.1.4.3. + +Any other attribute MUST NOT +************************************************/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_cab_dv_subject_invalid_values", + Description: "If certificate policy 2.23.140.1.2.1 (CA/B BR domain validated) is included, only country and/or common name is allowed in SubjectDN.", + Citation: "BRs: 7.1.2.7.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewDvSubjectInvalidValues, + }) +} + +func NewDvSubjectInvalidValues() lint.LintInterface { + return &dvSubjectInvalidValues{} +} + +func (l *dvSubjectInvalidValues) CheckApplies(cert *x509.Certificate) bool { + return util.SliceContainsOID(cert.PolicyIdentifiers, util.BRDomainValidatedOID) && util.IsSubscriberCert(cert) +} + +func (l *dvSubjectInvalidValues) Execute(cert *x509.Certificate) *lint.LintResult { + names := util.GetTypesInName(&cert.Subject) + for _, n := range names { + if n.Equal(util.CommonNameOID) || n.Equal(util.CountryNameOID) { + continue + } + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("DV certificate contains the invalid attribute type %s", n)} + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crl_distrib_points_not_http.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crl_distrib_points_not_http.go new file mode 100644 index 00000000..54d041a2 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crl_distrib_points_not_http.go @@ -0,0 +1,64 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package cabf_br + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "strings" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_crl_distrib_points_not_http", + Description: "The scheme of each CRL Distribution Point MUST be 'http'", + Citation: "CABF BRs §7.1.2.11.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_2_0_0_Date, + }, + Lint: NewCrlDistribPointsNotHTTP, + }) +} + +type crlDistribPointsNotHTTP struct{} + +func NewCrlDistribPointsNotHTTP() lint.LintInterface { + return &crlDistribPointsNotHTTP{} +} + +func (l *crlDistribPointsNotHTTP) CheckApplies(c *x509.Certificate) bool { + return len(c.CRLDistributionPoints) > 0 +} + +func (l *crlDistribPointsNotHTTP) Execute(c *x509.Certificate) *lint.LintResult { + for _, dp := range c.CRLDistributionPoints { + if !strings.HasPrefix(dp, "http:") { + return &lint.LintResult{ + Status: lint.Error, + Details: "Certificate contains a non-HTTP CRL distribution point", + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crlissuer_must_not_be_present_in_cdp.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crlissuer_must_not_be_present_in_cdp.go new file mode 100644 index 00000000..739ed233 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_crlissuer_must_not_be_present_in_cdp.go @@ -0,0 +1,79 @@ +/* + * 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_br + +import ( + "github.com/zmap/zcrypto/encoding/asn1" + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_crlissuer_must_not_be_present_in_cdp", + Description: "crlIssuer and/or Reason field MUST NOT be present in the CDP extension.", + Citation: "BR Section 7.1.2.11.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewCrlissuerMustNotBePresentInCdp, + }) +} + +type CrlissuerMustNotBePresentInCdp struct{} + +func NewCrlissuerMustNotBePresentInCdp() lint.LintInterface { + return &CrlissuerMustNotBePresentInCdp{} +} + +func (l *CrlissuerMustNotBePresentInCdp) CheckApplies(c *x509.Certificate) bool { + return c.CRLDistributionPoints != nil +} + +func (l *CrlissuerMustNotBePresentInCdp) Execute(c *x509.Certificate) *lint.LintResult { + + for _, ext := range c.Extensions { + if ext.Id.Equal(util.CrlDistOID) { + var cdp []distributionPoint + _, err := asn1.Unmarshal(ext.Value, &cdp) + if err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + for _, dp := range cdp { + if (len(dp.CRLIssuer.Bytes) > 0) || (len(dp.Reason.Bytes) > 0) { + return &lint.LintResult{Status: lint.Error} + } + + } + + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +type distributionPoint struct { + DistributionPoint distributionPointName `asn1:"optional,tag:0"` + Reason asn1.BitString `asn1:"optional,tag:1"` + CRLIssuer asn1.RawValue `asn1:"optional,tag:2"` +} + +type distributionPointName struct { + FullName asn1.RawValue `asn1:"optional,tag:0"` + RelativeName pkix.RDNSequence `asn1:"optional,tag:1"` +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go index db56d3cf..6dc0a0dc 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_correct_order_in_subgroup.go @@ -29,11 +29,12 @@ type dsaSubgroup struct{} func init() { lint.RegisterCertificateLint(&lint.CertificateLint{ LintMetadata: lint.LintMetadata{ - Name: "e_dsa_correct_order_in_subgroup", - Description: "DSA: Public key value has the unique correct representation in the field, and that the key has the correct order in the subgroup", - Citation: "BRs v1.7.0: 6.1.6", - Source: lint.CABFBaselineRequirements, - EffectiveDate: util.CABEffectiveDate, + Name: "e_dsa_correct_order_in_subgroup", + Description: "DSA: Public key value has the unique correct representation in the field, and that the key has the correct order in the subgroup", + Citation: "BRs v1.7.0: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + IneffectiveDate: util.CABFBRs_1_7_1_Date, }, Lint: NewDsaSubgroup, }) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go index 0a56380a..bde8f0ee 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_shorter_than_2048_bits.go @@ -31,8 +31,9 @@ func init() { Description: "DSA modulus size must be at least 2048 bits", Citation: "BRs v1.7.0: 6.1.5", // Refer to BRs: 6.1.5, taking the statement "Before 31 Dec 2010" literally - Source: lint.CABFBaselineRequirements, - EffectiveDate: util.ZeroDate, + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.ZeroDate, + IneffectiveDate: util.CABFBRs_1_7_1_Date, }, Lint: NewDsaTooShort, }) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_unique_correct_representation.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_unique_correct_representation.go index 29afa3f1..cdb5019f 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_unique_correct_representation.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_dsa_unique_correct_representation.go @@ -29,11 +29,12 @@ type dsaUniqueCorrectRepresentation struct{} func init() { lint.RegisterCertificateLint(&lint.CertificateLint{ LintMetadata: lint.LintMetadata{ - Name: "e_dsa_unique_correct_representation", - Description: "DSA: Public key value has the unique correct representation in the field, and that the key has the correct order in the subgroup", - Citation: "BRs v1.7.0: 6.1.6", - Source: lint.CABFBaselineRequirements, - EffectiveDate: util.CABEffectiveDate, + Name: "e_dsa_unique_correct_representation", + Description: "DSA: Public key value has the unique correct representation in the field, and that the key has the correct order in the subgroup", + Citation: "BRs v1.7.0: 6.1.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + IneffectiveDate: util.CABFBRs_1_7_1_Date, }, Lint: NewDsaUniqueCorrectRepresentation, }) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_duplicate_subject_attribs.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_duplicate_subject_attribs.go new file mode 100644 index 00000000..200e8362 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_duplicate_subject_attribs.go @@ -0,0 +1,99 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + */ + +package cabf_br + +import ( + "github.com/zmap/zcrypto/encoding/asn1" + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "fmt" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_duplicate_subject_attribs", + Description: "Each Name MUST NOT contain more than one instance of a given AttributeTypeAndValue across all RDNs", + Citation: "CABF BRs 7.1.4.1", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_2_0_0_Date, + }, + Lint: NewDuplicateSubjectAttribs, + }) +} + +type duplicateSubjectAttribs struct{} + +func NewDuplicateSubjectAttribs() lint.LintInterface { + return &duplicateSubjectAttribs{} +} + +func (l *duplicateSubjectAttribs) CheckApplies(c *x509.Certificate) bool { + return true +} + +// The domainComponent and streetAddress attributes are exempt from +// the single-instance requirement; organizationalUnitName would be too, +// if it weren't for the fact that it has been deprecated. + +var singleInstanceOIDs = map[string]string{ + "1.3.6.1.4.1.311.60.2.1.1": "jurisdictionLocality", + "1.3.6.1.4.1.311.60.2.1.2": "jurisdictionStateOrProvince", + "1.3.6.1.4.1.311.60.2.1.3": "jurisdictionCountry", + "2.5.4.3": "commonName", + "2.5.4.4": "surname", + "2.5.4.5": "serialNumber", + "2.5.4.6": "countryName", + "2.5.4.7": "localityName", + "2.5.4.8": "stateOrProvinceName", + "2.5.4.10": "organizationName", + "2.5.4.15": "businessCategory", + "2.5.4.42": "givenName", + "2.5.4.97": "organizationIdentifier", +} + +func (l *duplicateSubjectAttribs) Execute(c *x509.Certificate) *lint.LintResult { + + var subject pkix.RDNSequence + if _, err := asn1.Unmarshal(c.RawSubject, &subject); err != nil { + return &lint.LintResult{Status: lint.Fatal} + } + + foundOIDs := make(map[string]bool) + + for _, rdn := range subject { + for _, ava := range rdn { + oid := fmt.Sprint(ava.Type) + name, mustBeSingle := singleInstanceOIDs[oid] + _, alreadySeen := foundOIDs[oid] + if mustBeSingle && alreadySeen { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("Multiple instances of '%s' are NOT allowed in the Subject", name), + } + } + foundOIDs[oid] = true + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_e_invalid_cps_uri.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_e_invalid_cps_uri.go new file mode 100644 index 00000000..a2c542d5 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_e_invalid_cps_uri.go @@ -0,0 +1,74 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package cabf_br + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "net/url" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_invalid_cps_uri", + Description: "If the CPS URI policyQualifier is present in a certificate, it MUST contain an HTTP or HTTPS URL", + Citation: "CABF BR 7.1.2 (several subsections thereof)", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_2_0_0_Date, + }, + Lint: NewInvalidCPSUri, + }) +} + +type invalidCPSUri struct{} + +func NewInvalidCPSUri() lint.LintInterface { + return &invalidCPSUri{} +} + +func (l *invalidCPSUri) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CertPolicyOID) +} + +func isValidHttpOrHttpsURL(input string) bool { + parsedURL, err := url.Parse(input) + if err != nil { + return false + } + + scheme := parsedURL.Scheme + return scheme == "http" || scheme == "https" +} + +func (l *invalidCPSUri) Execute(c *x509.Certificate) *lint.LintResult { + // There should normally be just one CPS URI, but one never knows... + for _, pol := range c.CPSuri { + for _, uri := range pol { + if !isValidHttpOrHttpsURL(uri) { + return &lint.LintResult{Status: lint.Error} + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_eku_critical.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_eku_critical.go new file mode 100644 index 00000000..43a2f139 --- /dev/null +++ b/vendor/github.com/zmap/zlint/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/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ext_subject_key_identifier_not_recommended_subscriber.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ext_subject_key_identifier_not_recommended_subscriber.go new file mode 100644 index 00000000..73d0d24c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_ext_subject_key_identifier_not_recommended_subscriber.go @@ -0,0 +1,70 @@ +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 subjectKeyIdNotRecommendedSubscriber struct{} + +/********************************************************************** +RFC5280 suggested the addition of SKI extension, but CABF BR SC62 +marked the extension as NOT RECOMMENDED for subscriber certificates + +Warning: +Users of zlint will trigger either +`w_ext_subject_key_identifier_not_recommended_subscriber` (this lint) +or `w_ext_subject_key_identifier_missing_sub_cert` the one enforcing +RFC5280's behavior. + +Users are expected to specifically ignore one or the other lint +depending on which one apply to them. + +See: + - https://github.com/zmap/zlint/issues/749 + - https://github.com/zmap/zlint/issues/762 +**********************************************************************/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "w_ext_subject_key_identifier_not_recommended_subscriber", + Description: "Subscriber certificates use of Subject Key Identifier is NOT RECOMMENDED", + Citation: "BRs v2: 7.1.2.7.6", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewSubjectKeyIdNotRecommendedSubscriber, + }) +} + +func NewSubjectKeyIdNotRecommendedSubscriber() lint.LintInterface { + return &subjectKeyIdNotRecommendedSubscriber{} +} + +func (l *subjectKeyIdNotRecommendedSubscriber) CheckApplies(cert *x509.Certificate) bool { + return util.IsSubscriberCert(cert) +} + +func (l *subjectKeyIdNotRecommendedSubscriber) Execute(cert *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(cert, util.SubjectKeyIdentityOID) { + return &lint.LintResult{Status: lint.Warn} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_invalid_subject_rdn_order.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_invalid_subject_rdn_order.go new file mode 100644 index 00000000..b4710e20 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_invalid_subject_rdn_order.go @@ -0,0 +1,145 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package cabf_br + +import ( + "crypto/x509/pkix" + "encoding/asn1" + + "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_invalid_subject_rdn_order", + Description: "Subject field attributes (RDNs) SHALL be encoded in a specific order", + Citation: "BRs: 7.1.4.2", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_2_0_0_Date, + }, + Lint: NewInvalidSubjectRDNOrder, + }) +} + +type invalidSubjectRDNOrder struct{} + +func NewInvalidSubjectRDNOrder() lint.LintInterface { + return &invalidSubjectRDNOrder{} +} + +func (l *invalidSubjectRDNOrder) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func getShortOIDName(oid string) string { + switch oid { + case "0.9.2342.19200300.100.1.25": + return "DC" + case "2.5.4.6": + return "C" + case "2.5.4.8": + return "ST" + case "2.5.4.7": + return "L" + case "2.5.4.17": + return "postalCode" + case "2.5.4.9": + return "street" + case "2.5.4.10": + return "O" + case "2.5.4.4": + return "SN" + case "2.5.4.42": + return "givenName" + case "2.5.4.11": + return "OU" + case "2.5.4.3": + return "CN" + default: + return "" + } +} + +func findElement(arr []string, target string) (int, bool) { + for i, value := range arr { + if value == target { + return i, true + } + } + return -1, false +} + +func checkOrder(actualOrder []string, expectedOrder []string) bool { + var prevPosition int + prevPosition = 0 + + for _, targetElement := range actualOrder { + position, found := findElement(expectedOrder, targetElement) + if found { + if position < prevPosition { + return false + } + prevPosition = position + } + } + return true +} + +func checkSubjectRDNOrder(cert *x509.Certificate) bool { + + rawSubject := cert.RawSubject + + var rdnSequence pkix.RDNSequence + _, err := asn1.Unmarshal(rawSubject, &rdnSequence) + if err != nil { + return false + } + + var rdnOrder []string + + for _, rdn := range rdnSequence { + for _, atv := range rdn { + rdnShortName := getShortOIDName(atv.Type.String()) + if rdnShortName != "" { + rdnOrder = append(rdnOrder, rdnShortName) + } + } + } + + // Expected order of RDNs as per CABF BR section 7.1.4.2 + expectedRDNOrder := []string{"DC", "C", "ST", "L", "postalCode", "street", "O", "SN", "givenName", "OU", "CN"} + + return checkOrder(rdnOrder, expectedRDNOrder) +} + +func (l *invalidSubjectRDNOrder) Execute(c *x509.Certificate) *lint.LintResult { + + var out lint.LintResult + + if checkSubjectRDNOrder(c) { + out.Status = lint.Pass + } else { + out.Status = lint.Error + } + return &out +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_contains_internal_names.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_contains_internal_names.go index 7c2a27b5..837f925d 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_contains_internal_names.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_contains_internal_names.go @@ -15,6 +15,7 @@ package cabf_br */ import ( + "net" "net/url" "time" @@ -53,7 +54,7 @@ func NewSubCertAIAInternalName() lint.LintInterface { } func (l *subCertAIAInternalName) CheckApplies(c *x509.Certificate) bool { - return util.IsSubscriberCert(c) + return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.AiaOID) } func (l *subCertAIAInternalName) Execute(c *x509.Certificate) *lint.LintResult { @@ -62,6 +63,11 @@ func (l *subCertAIAInternalName) Execute(c *x509.Certificate) *lint.LintResult { if err != nil { return &lint.LintResult{Status: lint.Error} } + + if net.ParseIP(purl.Host) != nil { + continue + } + if !util.HasValidTLD(purl.Hostname(), time.Now()) { return &lint.LintResult{Status: lint.Warn} } @@ -71,6 +77,11 @@ func (l *subCertAIAInternalName) Execute(c *x509.Certificate) *lint.LintResult { if err != nil { return &lint.LintResult{Status: lint.Error} } + + if net.ParseIP(purl.Host) != nil { + continue + } + if !util.HasValidTLD(purl.Hostname(), time.Now()) { return &lint.LintResult{Status: lint.Warn} } diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go index 9447ab92..3fa1f12c 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_issuing_ca_url.go @@ -26,9 +26,11 @@ type subCertIssuerUrl struct{} /************************************************************************ BRs: 7.1.2.3 -cRLDistributionPoints -This extension MAY be present. If present, it MUST NOT be marked critical, and it MUST contain the -HTTP URL of the CA’s CRL service. +authorityInformationAccess +This extension MUST be present. It MUST NOT be marked critical, and it MUST contain +the HTTP URL of the Issuing CA’s OCSP responder (accessMethod = 1.3.6.1.5.5.7.48.1). +It SHOULD also contain the HTTP URL of the Issuing CA’s certificate (accessMethod = +1.3.6.1.5.5.7.48.2). *************************************************************************/ func init() { diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go index d007651d..e97335a9 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_aia_does_not_contain_ocsp_url.go @@ -36,11 +36,12 @@ It SHOULD also contain the HTTP URL of the Issuing CA’s certificate (accessMet func init() { lint.RegisterCertificateLint(&lint.CertificateLint{ LintMetadata: lint.LintMetadata{ - Name: "e_sub_cert_aia_does_not_contain_ocsp_url", - Description: "Subscriber Certificate: authorityInformationAccess MUST contain the HTTP URL of the Issuing CA's OSCP responder.", - Citation: "BRs: 7.1.2.3", - Source: lint.CABFBaselineRequirements, - EffectiveDate: util.CABEffectiveDate, + Name: "e_sub_cert_aia_does_not_contain_ocsp_url", + Description: "Subscriber Certificate: authorityInformationAccess MUST contain the HTTP URL of the Issuing CA's OSCP responder.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + IneffectiveDate: util.CABFBRs_2_0_0_Date, }, Lint: NewSubCertOcspUrl, }) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_check.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_check.go new file mode 100644 index 00000000..c5ef84c3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_check.go @@ -0,0 +1,81 @@ +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 ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type subExtKeyUsageCheck struct{} + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_sub_cert_eku_check", + Description: "Subscriber certificates MUST have id-kp-serverAuth and MAY have id-kp-clientAuth present in extKeyUsage", + Citation: "BRs: 7.1.2.7.10 Subscriber Certificate Extended Key Usage", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_2_0_0_Date, + }, + Lint: NewSubExtKeyUsageCheck, + }) +} + +func NewSubExtKeyUsageCheck() lint.LintInterface { + return &subExtKeyUsageCheck{} +} + +func (l *subExtKeyUsageCheck) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.EkuSynOid) +} + +func (l *subExtKeyUsageCheck) Execute(c *x509.Certificate) *lint.LintResult { + var hasClientAuthEKU, hasServerAuthEKU bool + + for _, eku := range c.ExtKeyUsage { + switch eku { + case x509.ExtKeyUsageServerAuth: + hasServerAuthEKU = true + + case x509.ExtKeyUsageClientAuth: + hasClientAuthEKU = true + + case x509.ExtKeyUsageAny, x509.ExtKeyUsageCodeSigning, x509.ExtKeyUsageTimeStamping, + x509.ExtKeyUsageOcspSigning, x509.ExtKeyUsageEmailProtection: + + return &lint.LintResult{Status: lint.Error, Details: fmt.Sprintf("%s MUST NOT be present", util.GetEKUString(eku))} + } + } + + if !hasServerAuthEKU { + return &lint.LintResult{Status: lint.Error, Details: "id-kp-serverAuth MUST be present"} + } + + for _, eku := range c.UnknownExtKeyUsage { + if eku.Equal(util.PreCertificateSigningCertificateEKU) { + return &lint.LintResult{Status: lint.Error, Details: "Precertificate Signing Certificate extKeyUsage MUST NOT be present"} + } + } + + if (len(c.ExtKeyUsage) > 2 && !hasClientAuthEKU) || len(c.UnknownExtKeyUsage) > 0 { + return &lint.LintResult{Status: lint.Warn, Details: "any other value than id-kp-serverAuth and id-kp-clientAuth is NOT RECOMMENDED"} + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_extra_values.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_extra_values.go index 2febde6f..c7d1f182 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_extra_values.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_extra_values.go @@ -34,11 +34,12 @@ present. func init() { lint.RegisterCertificateLint(&lint.CertificateLint{ LintMetadata: lint.LintMetadata{ - Name: "w_sub_cert_eku_extra_values", - Description: "Subscriber Certificate: extKeyUsage values other than id-kp-serverAuth, id-kp-clientAuth, and id-kp-emailProtection SHOULD NOT be present.", - Citation: "BRs: 7.1.2.3", - Source: lint.CABFBaselineRequirements, - EffectiveDate: util.CABEffectiveDate, + Name: "w_sub_cert_eku_extra_values", + Description: "Subscriber Certificate: extKeyUsage values other than id-kp-serverAuth, id-kp-clientAuth, and id-kp-emailProtection SHOULD NOT be present.", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + IneffectiveDate: util.CABFBRs_2_0_0_Date, }, Lint: NewSubExtKeyUsageLegalUsage, }) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go index 3ef75c2b..adb67b4d 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_sub_cert_eku_server_auth_client_auth_missing.go @@ -34,11 +34,12 @@ present. func init() { lint.RegisterCertificateLint(&lint.CertificateLint{ LintMetadata: lint.LintMetadata{ - Name: "e_sub_cert_eku_server_auth_client_auth_missing", - Description: "Subscriber certificates MUST have either id-kp-serverAuth or id-kp-clientAuth or both present in extKeyUsage", - Citation: "BRs: 7.1.2.3", - Source: lint.CABFBaselineRequirements, - EffectiveDate: util.CABEffectiveDate, + Name: "e_sub_cert_eku_server_auth_client_auth_missing", + Description: "Subscriber certificates MUST have either id-kp-serverAuth or id-kp-clientAuth or both present in extKeyUsage", + Citation: "BRs: 7.1.2.3", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABEffectiveDate, + IneffectiveDate: util.CABFBRs_2_0_0_Date, }, Lint: NewSubExtKeyUsageClientOrServer, }) diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subj_orgunit_in_ca_cert.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subj_orgunit_in_ca_cert.go new file mode 100644 index 00000000..c9aebb23 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subj_orgunit_in_ca_cert.go @@ -0,0 +1,69 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + */ + +package cabf_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_subj_orgunit_in_ca_cert", + Description: "The organizationalUnitName MUST NOT be included in Root CA certs or TLS Subordinate CA certs. organizationalUnitName is allowed for cross signed certificates, although not recommended. This lint may be configured to signify that the target is a cross signed certificate.", + Citation: "CABF BR §7.1.2.10.2 (CA Certificate Naming)", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.CABFBRs_2_0_0_Date, + }, + Lint: NewSubjectOrgUnitInCACert, + }) +} + +type subjectOrgUnitInCACert struct { + CrossCert bool `comment:"Set this to true if the certificate to be linted is a cross-certificate"` +} + +func NewSubjectOrgUnitInCACert() lint.LintInterface { + return &subjectOrgUnitInCACert{ + CrossCert: false, + } +} + +func (l *subjectOrgUnitInCACert) Configure() interface{} { + return l +} + +func (l *subjectOrgUnitInCACert) CheckApplies(c *x509.Certificate) bool { + return util.IsCACert(c) +} + +func (l *subjectOrgUnitInCACert) Execute(c *x509.Certificate) *lint.LintResult { + if c.Subject.OrganizationalUnit != nil { + if !l.CrossCert { + return &lint.LintResult{ + Status: lint.Error, + Details: "The OU attribute in the Subject is prohibited in Root and TLS CA certificates", + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subject_rdns_correct_encoding.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subject_rdns_correct_encoding.go new file mode 100644 index 00000000..26b286ea --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_br/lint_subject_rdns_correct_encoding.go @@ -0,0 +1,155 @@ +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 ( + "fmt" + + "github.com/zmap/zcrypto/encoding/asn1" + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type subjectRdnsCorrectEncoding struct{} + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_subject_rdns_correct_encoding", + Description: "CAs that include attributes in the Certificate subject field that are listed in the Tables 77 and 78 of BR 2.0.0 SHALL follow the specified encoding requirements for the attribute", + Citation: "BRs 2.0.0: 7.1.4.2, Table 77 and Table 78", + Source: lint.CABFBaselineRequirements, + EffectiveDate: util.SC62EffectiveDate, + }, + Lint: NewSubjectRdnsCorrectEncoding, + }) +} + +func NewSubjectRdnsCorrectEncoding() lint.LintInterface { + return &subjectRdnsCorrectEncoding{} +} + +func (l *subjectRdnsCorrectEncoding) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectRdnsCorrectEncoding) Execute(c *x509.Certificate) *lint.LintResult { + rdnSequence := util.RawRDNSequence{} + if rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence); err != nil || len(rest) > 0 { + return &lint.LintResult{Status: lint.Fatal} + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + oid := attrTypeAndValue.Type.String() + tag := attrTypeAndValue.Value.Tag + + errors := []string{} + + result := isIA5String("0.9.2342.19200300.100.1.25", oid, tag, "domainComponent") + errors = append(errors, result) + result = isPrintable("2.5.4.6", oid, tag, "countryName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.8", oid, tag, "stateOrProvinceName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.7", oid, tag, "localityName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.17", oid, tag, "postalCode") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.9", oid, tag, "streetAddress") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.10", oid, tag, "organizationName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.4", oid, tag, "surname") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.42", oid, tag, "givenName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.11", oid, tag, "organizationalUnitName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.3", oid, tag, "commonName") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.15", oid, tag, "businessCategory") + errors = append(errors, result) + result = isPrintable("1.3.6.1.4.1.311.60.2.1.3", oid, tag, "jurisdictionCountry") + errors = append(errors, result) + result = isPrintableOrUTF8("1.3.6.1.4.1.311.60.2.1.2", oid, tag, "jurisdictionStateOrProvince") + errors = append(errors, result) + result = isPrintableOrUTF8("1.3.6.1.4.1.311.60.2.1.1", oid, tag, "jurisdictionLocality") + errors = append(errors, result) + result = isPrintable("2.5.4.5", oid, tag, "serialNumber") + errors = append(errors, result) + result = isPrintableOrUTF8("2.5.4.97", oid, tag, "organizationIdentifier") + errors = append(errors, result) + + for _, encodingError := range errors { + if encodingError != "" { + return &lint.LintResult{Status: lint.Error, Details: encodingError} + } + } + + } + } + return &lint.LintResult{Status: lint.Pass} +} + +func isPrintableOrUTF8(referenceOid string, oid string, tag int, attributeName string) string { + if referenceOid == oid && tag != 19 && tag != 12 { + return fmt.Sprintf("Attribute %s in subjectDN has the wrong encoding %s.", attributeName, getEncodingName(tag)) + } + return "" +} + +func isPrintable(referenceOid string, oid string, tag int, attributeName string) string { + if referenceOid == oid && tag != 19 { + return fmt.Sprintf("Attribute %s in subjectDN has the wrong encoding %s.", attributeName, getEncodingName(tag)) + } + return "" +} +func isIA5String(referenceOid string, oid string, tag int, attributeName string) string { + if referenceOid == oid && tag != 22 { + return fmt.Sprintf("Attribute %s in subjectDN has the wrong encoding %s.", attributeName, getEncodingName(tag)) + } + return "" +} + +//Tag BMPString: 0x1e = 30 +//Tag UTF8String: 0x0c = 12 +//Tag TeletexString: 0x14 = 20 +//Tag UniversalString: 0x1c = 28 +//Tag PrintableString: 0x13 = 19 +//Tag IA5String: 0x16 = 22 + +func getEncodingName(tag int) string { + if tag == 12 { + return "UTF8String" + } + if tag == 19 { + return "PrintableString" + } + if tag == 20 { + return "TeletexString" + } + if tag == 22 { + return "IA5String" + } + if tag == 28 { + return "UniversalString" + } + if tag == 30 { + return "BMPString" + } + return "Unknown" +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_crl_distribution_points.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_crl_distribution_points.go new file mode 100644 index 00000000..dfda904f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_crl_distribution_points.go @@ -0,0 +1,62 @@ +package cabf_cs_br + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +/*7.1.2.3 b. cRLDistributionPoints +This extension MUST be present. It MUST NOT be marked critical, and it MUST contain the +HTTP URL of the CA’s CRL service*/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_cs_crl_distribution_points", + Description: "This extension MUST be present. It MUST NOT be marked critical. It MUST contain the HTTP URL of the CA's CRL service", + Citation: "CABF CS BRs 7.1.2.3.b", + Source: lint.CABFCSBaselineRequirements, + EffectiveDate: util.CABF_CS_BRs_1_2_Date, + }, + Lint: NewCrlDistributionPoints, + }) +} + +type crlDistributionPoints struct{} + +func NewCrlDistributionPoints() lint.LintInterface { + return &crlDistributionPoints{} +} + +func (l *crlDistributionPoints) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) || util.IsSubCA(c) +} + +func (l *crlDistributionPoints) Execute(c *x509.Certificate) *lint.LintResult { + cdp := util.GetExtFromCert(c, util.CrlDistOID) + if cdp == nil { + return &lint.LintResult{ + Status: lint.Error, + Details: "The cRLDistributionPoints extension MUST be present."} + } + + if cdp.Critical { + return &lint.LintResult{ + Status: lint.Error, + Details: "The cRLDistributionPoints MUST NOT be marked critical."} + } + + // MUST contain the HTTP URL of the CA’s CRL service + for _, uri := range c.CRLDistributionPoints { + if !strings.HasPrefix(uri, "http://") { + return &lint.LintResult{Status: lint.Error, Details: "cRLDistributionPoints MUST contain the HTTP URL of the CA's CRL service"} + } + } + + return &lint.LintResult{ + Status: lint.Pass, + } +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_eku_required.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_eku_required.go new file mode 100644 index 00000000..91ac6701 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_eku_required.go @@ -0,0 +1,87 @@ +package cabf_cs_br + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +/* 7.1.2.3 Code signing and Timestamp Certificate +f. extKeyUsage +If the Certificate is a Code Signing Certificate, then id-kp-codeSigning MUST be present +and the following EKUs MAY be present: + • Lifetime Signing OID (1.3.6.1.4.1.311.10.3.13) + • id-kp-emailProtection + • Document Signing (1.3.6.1.4.1.311.3.10.3.12) + +If the Certificate is a Timestamp Certificate, then id-kp-timeStamping MUST be present +and MUST be marked critical. +Additionally, the following EKUs MUST NOT be present: + • anyExtendedKeyUsage + • id-kp-serverAuth + +Other values SHOULD NOT be present. If any other value is present, the CA MUST have a +business agreement with a Platform vendor requiring that EKU in order to issue a +Platform‐specific code signing certificate with that EKU. +*/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_cs_eku_required", + Description: "If the Certificate is a Code Signing Certificate, then id-kp-codeSigning MUST be present. anyExtendedKeyUsage and id-kp-serverAuth MUST NOT be present.", + Citation: "CABF CS BRs 7.1.2.3.f", + Source: lint.CABFCSBaselineRequirements, + EffectiveDate: util.CABF_CS_BRs_1_2_Date, + }, + Lint: NewCsEKURequired, + }) +} + +type csEKURequired struct{} + +func NewCsEKURequired() lint.LintInterface { + return &csEKURequired{} +} + +func (l *csEKURequired) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) || util.IsSubCA(c) +} + +func (l *csEKURequired) Execute(c *x509.Certificate) *lint.LintResult { + prohibitedEKUs := map[x509.ExtKeyUsage]struct{}{ + x509.ExtKeyUsageAny: {}, + x509.ExtKeyUsageServerAuth: {}, + } + + if util.IsSubCA(c) { + prohibitedEKUs[x509.ExtKeyUsageEmailProtection] = struct{}{} + } + + hasCodeSigningEKU := false + + for _, eku := range c.ExtKeyUsage { + if eku == x509.ExtKeyUsageCodeSigning { + hasCodeSigningEKU = true + } + + if _, isProhibited := prohibitedEKUs[eku]; isProhibited { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("Code Signing certificate includes prohibited EKU: %v", eku), + } + } + } + + if !hasCodeSigningEKU { + return &lint.LintResult{ + Status: lint.Error, + Details: "Code Signing certificate missing required Code Signing EKU", + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_key_usage_required.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_key_usage_required.go new file mode 100644 index 00000000..686b4405 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_key_usage_required.go @@ -0,0 +1,79 @@ +package cabf_cs_br + +import ( + "github.com/zmap/zcrypto/x509" + + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +/* 7.1.2.3 Code signing and Timestamp Certificate +e. keyUsage +This extension MUST be present and MUST be marked critical. +The bit position for digitalSignature MUST be set. Bit positions for keyCertSign and +cRLSign MUST NOT be set. All other bit positions SHOULD NOT be set. +*/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_cs_key_usage_required", + Description: "This extension MUST be present and MUST be marked critical. The bit position for digitalSignature MUST be set. The bit positions for keyCertSign and cRLSign MUST NOT be set. All other bit positions SHOULD NOT be set.", + Citation: "CABF CS BRs 7.1.2.3e", + Source: lint.CABFCSBaselineRequirements, + EffectiveDate: util.CABF_CS_BRs_1_2_Date, + }, + Lint: NewCsKeyUsageRequired, + }) +} + +type csKeyUsageRequired struct{} + +func NewCsKeyUsageRequired() lint.LintInterface { + return &csKeyUsageRequired{} +} + +func (l *csKeyUsageRequired) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *csKeyUsageRequired) Execute(c *x509.Certificate) *lint.LintResult { + ku := util.GetExtFromCert(c, util.KeyUsageOID) + if ku == nil { + return &lint.LintResult{ + Status: lint.Error, + Details: "Key usage extension MUST be present.", + } + } + + if !ku.Critical { + return &lint.LintResult{ + Status: lint.Error, + Details: "Key usage extension MUST be marked critical", + } + } + + if (c.KeyUsage & x509.KeyUsageDigitalSignature) == 0 { + return &lint.LintResult{ + Status: lint.Error, + Details: "Code Signing certificate must have digitalSignature key usage", + } + } + + // keyCertSign and cRLSign bits MUST NOT be set. + if (c.KeyUsage & (x509.KeyUsageCertSign | x509.KeyUsageCRLSign)) != 0 { + return &lint.LintResult{ + Status: lint.Error, + Details: "keyCertSign and cRLSign key usages MUST NOT be set", + } + } + + // All other bit positions SHOULD NOT be set. + if c.KeyUsage & ^x509.KeyUsageDigitalSignature != 0 { + return &lint.LintResult{ + Status: lint.Warn, + Details: "Only digitalSignature key usage is recommended. Other key usages SHOULD NOT be set."} + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_rsa_key_size.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_rsa_key_size.go new file mode 100644 index 00000000..493e3793 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_cs_br/lint_cs_rsa_key_size.go @@ -0,0 +1,58 @@ +package cabf_cs_br + +import ( + "crypto/rsa" + + "github.com/zmap/zcrypto/x509" + + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +/*6.1.5.2 Code signing Certificate and Timestamp Authority key sizes +For Keys corresponding to Subscriber code signing and Timestamp Authority Certificates: +• If the Key is RSA, then the modulus MUST be at least 3072 bits in length. +• If the Key is ECDSA, then the curve MUST be one of NIST P‐256, P‐384, or P‐521. +• If the Key is DSA, then one of the following key parameter options MUST be used: +• Key length (L) of 2048 bits and modulus length (N) of 224 bits +• Key length (L) of 2048 bits and modulus length (N) of 256 bits*/ + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_cs_rsa_key_size", + Description: "If the Key is RSA, then the modulus MUST be at least 3072 bits in length", + Citation: "CABF CS BRs 6.1.5.2", + Source: lint.CABFCSBaselineRequirements, + EffectiveDate: util.CABF_CS_BRs_1_2_Date, + }, + Lint: NewCsRsaKeySize, + }) +} + +type csRsaKeySize struct{} + +func NewCsRsaKeySize() lint.CertificateLintInterface { + return &csRsaKeySize{} +} + +func (l *csRsaKeySize) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) +} + +func (l *csRsaKeySize) Execute(c *x509.Certificate) *lint.LintResult { + rsaKey, ok := c.PublicKey.(*rsa.PublicKey) + if !ok { + return &lint.LintResult{Status: lint.NA} + } + + // If the Key is RSA, then the modulus MUST be at least 3072 bits in length. + if rsaKey.N.BitLen() < 3072 { + return &lint.LintResult{ + Status: lint.Error, + Details: "Code Signing RSA key modulus MUST be at least 3072 bits in length.", + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_cabf_org_identifier_psd_vat_has_state.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_cabf_org_identifier_psd_vat_has_state.go new file mode 100644 index 00000000..1830f14f --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_cabf_org_identifier_psd_vat_has_state.go @@ -0,0 +1,57 @@ +/* + * 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_ev + +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_cabf_org_identifier_psd_vat_has_state", + Description: "The cabfOrganizationIdentifier field for PSD org VAT Registration Schemes cannot include the referenceStateOrProvince field.", + Citation: "9.2.8", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.SC17EffectiveDate, + }, + Lint: NewCabfOrgIdentifierPsdVatHasState, + }) +} + +type CabfOrgIdentifierPsdVatHasState struct{} + +func NewCabfOrgIdentifierPsdVatHasState() lint.LintInterface { + return &CabfOrgIdentifierPsdVatHasState{} +} + +func (l *CabfOrgIdentifierPsdVatHasState) CheckApplies(c *x509.Certificate) bool { + for _, ext := range c.Extensions { + if ext.Id.Equal(util.CabfExtensionOrganizationIdentifier) && (c.CABFOrganizationIdentifier.Scheme == "PSD" || c.CABFOrganizationIdentifier.Scheme == "VAT") { + return true + } + } + return false +} + +func (l *CabfOrgIdentifierPsdVatHasState) Execute(c *x509.Certificate) *lint.LintResult { + if c.CABFOrganizationIdentifier.State == "" { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_invalid_business_category.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_invalid_business_category.go new file mode 100644 index 00000000..9e57c207 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_invalid_business_category.go @@ -0,0 +1,69 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package cabf_ev + +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_ev_invalid_business_category", + Description: "Checks that businessCategory contains a valid value as per EV Guidelines 7.1.4.2.3", + Citation: "EVGs 7.1.4.2.3", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.ZeroDate, + }, + Lint: NewInvalidBusinessCategory, + }) +} + +type invalidBusinessCategory struct{} + +func NewInvalidBusinessCategory() lint.LintInterface { + return &invalidBusinessCategory{} +} + +func (l *invalidBusinessCategory) CheckApplies(c *x509.Certificate) bool { + return util.IsEV(c.PolicyIdentifiers) && util.IsSubscriberCert(c) +} + +func (l *invalidBusinessCategory) Execute(c *x509.Certificate) *lint.LintResult { + + for _, v := range c.Subject.Names { + if util.BusinessOID.Equal(v.Type) { + businessCategory := v.Value + if (businessCategory == "Private Organization") || + (businessCategory == "Government Entity") || + (businessCategory == "Business Entity") || + (businessCategory == "Non-Commercial Entity") { + return &lint.LintResult{Status: lint.Pass} + } else { + return &lint.LintResult{Status: lint.Error} + } + } + } + + // businessCategory missing: that's an error, but is not this lint's business + return &lint.LintResult{Status: lint.NA} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_orgid_inconsistent_subj_and_ext.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_orgid_inconsistent_subj_and_ext.go new file mode 100644 index 00000000..d22312ea --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_ev/lint_ev_orgid_inconsistent_subj_and_ext.go @@ -0,0 +1,143 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package cabf_ev + +import ( + "fmt" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "regexp" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_ev_orgid_inconsistent_subj_and_ext", + Description: "Checks that the organizationIdentifier Subject attribute and the CABFOrganizationIdentifier extension are consistent", + Citation: "EVGs 9.2.8 and 9.8.2", + Source: lint.CABFEVGuidelines, + EffectiveDate: util.CABFEV_Sec9_2_8_Date, + }, + Lint: NewOrgIdInconsistentSubjAndExt, + }) +} + +// According to EVGs 9.2.8 +type OrganizationIdentifier struct { + ParseAsPSD bool + Scheme string + Country string + State string + Reference string +} + +func (o OrganizationIdentifier) Parse(orgId string) (OrganizationIdentifier, error) { + re := o.regexForOrgID() + if !re.MatchString(orgId) { + return o, fmt.Errorf("Cannot parse organizationIdentifier ('%s'): it is probably invalid", orgId) + } + names := re.SubexpNames() + match := re.FindStringSubmatch(orgId) + // Initialize a map to hold group names and values + result := make(map[string]string) + // Populate the map + for i, name := range names { + if i != 0 && name != "" { // Skip the whole match and unnamed groups + result[name] = match[i] + } + } + o.Scheme = result["scheme"] + o.Country = result["country"] + o.State = result["state"] + o.Reference = result["reference"] + return o, nil +} + +func (o OrganizationIdentifier) regexForOrgID() *regexp.Regexp { + // This is according to the EVG (stricter than ETSI EN 319 412-1) + const OrgIdPattern = `^(?P[A-Z]{3})(?P[A-Z]{2})(?:\+(?P[A-Z]{2}))?\-(?P.+)$` + const PsdOrgIdPattern = `^(?P[A-Z]{3})(?P[A-Z]{2})(?:\+(?P[A-Z]{2}))?\-(?P[A-Z]*)\-(?P.+)$` + var pattern string + if o.ParseAsPSD { + pattern = PsdOrgIdPattern + } else { + pattern = OrgIdPattern + } + return regexp.MustCompile(pattern) +} + +type orgIdInconsistentSubjAndExt struct{} + +func NewOrgIdInconsistentSubjAndExt() lint.LintInterface { + return &orgIdInconsistentSubjAndExt{} +} + +func (l *orgIdInconsistentSubjAndExt) CheckApplies(c *x509.Certificate) bool { + // It is actually mandatory that, if orgId is present, cabfOrgId be present as well, + // however this is already checked by another lint + return util.IsEV(c.PolicyIdentifiers) && (len(c.Subject.OrganizationIDs) > 0) && + util.IsExtInCert(c, util.CabfExtensionOrganizationIdentifier) +} + +func (l *orgIdInconsistentSubjAndExt) Execute(c *x509.Certificate) *lint.LintResult { + // It should be safe to assume there is only one element in OrganizationIDs + orgId, err := OrganizationIdentifier{ParseAsPSD: false}.Parse(c.Subject.OrganizationIDs[0]) + if err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: "the organizationIdentifier Subject attribute probably has an invalid value"} + } + + if (c.CABFOrganizationIdentifier.Scheme != orgId.Scheme) || + (c.CABFOrganizationIdentifier.Country != orgId.Country) || + (c.CABFOrganizationIdentifier.State != orgId.State) || + (c.CABFOrganizationIdentifier.Reference != orgId.Reference) { + + if orgId.Scheme != "PSD" { + + return &lint.LintResult{ + Status: lint.Error, + Details: "CABFOrganizationIdentifier is NOT consistent with organizationIdentifier"} + } + + psdOrgId, err := OrganizationIdentifier{ParseAsPSD: true}.Parse(c.Subject.OrganizationIDs[0]) + if err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: "the organizationIdentifier Subject attribute probably has an invalid value"} + } + + if (c.CABFOrganizationIdentifier.Scheme != psdOrgId.Scheme) || + (c.CABFOrganizationIdentifier.Country != psdOrgId.Country) || + (c.CABFOrganizationIdentifier.State != psdOrgId.State) || + (c.CABFOrganizationIdentifier.Reference != psdOrgId.Reference) { + + return &lint.LintResult{ + Status: lint.Error, + Details: "CABFOrganizationIdentifier is NOT consistent with organizationIdentifier"} + } + + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_authority_key_identifier.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_authority_key_identifier.go new file mode 100644 index 00000000..a8c3835b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_authority_key_identifier.go @@ -0,0 +1,85 @@ +package cabf_smime_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 ( + "fmt" + + "github.com/zmap/zcrypto/encoding/asn1" + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +type keyIdentifier struct { + KeyIdentifier asn1.RawValue `asn1:"optional,tag:0"` + AuthorityCertIssuer asn1.RawValue `asn1:"optional,tag:1"` + AuthorityCertSerialNumber asn1.RawValue `asn1:"optional,tag:2"` +} + +type authorityKeyIdentifierCorrect struct{} + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_authority_key_identifier_correct", + Description: "authorityKeyIdentifier SHALL be present. This extension SHALL NOT be marked critical. The keyIdentifier field SHALL be present. authorityCertIssuer and authorityCertSerialNumber fields SHALL NOT be present.", + Citation: "7.1.2.3.g", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewAuthorityKeyIdentifierCorrect, + }) +} + +func NewAuthorityKeyIdentifierCorrect() lint.LintInterface { + return &authorityKeyIdentifierCorrect{} +} + +func (l *authorityKeyIdentifierCorrect) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsSMIMEBRCertificate(c) +} + +func (l *authorityKeyIdentifierCorrect) Execute(c *x509.Certificate) *lint.LintResult { + ext := util.GetExtFromCert(c, util.AuthkeyOID) + if ext == nil { + return &lint.LintResult{Status: lint.Error, Details: "missing authorityKeyIdentifier"} + } + if ext.Critical { + return &lint.LintResult{Status: lint.Error, Details: "authorityKeyIdentifier is critical"} + } + + var keyID keyIdentifier + if _, err := asn1.Unmarshal(ext.Value, &keyID); err != nil { + return &lint.LintResult{ + Status: lint.Fatal, + Details: fmt.Sprintf("error unmarshalling authority key identifier extension: %v", err), + } + } + + hasKeyID := len(keyID.KeyIdentifier.Bytes) > 0 + hasCertIssuer := len(keyID.AuthorityCertIssuer.Bytes) > 0 + hasCertSerial := len(keyID.AuthorityCertSerialNumber.Bytes) > 0 + if !hasKeyID { + return &lint.LintResult{Status: lint.Error, Details: "keyIdentifier not present"} + } + if hasCertIssuer { + return &lint.LintResult{Status: lint.Error, Details: "authorityCertIssuer is present"} + } + if hasCertSerial { + return &lint.LintResult{Status: lint.Error, Details: "authorityCertSerialNumber is present"} + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go new file mode 100644 index 00000000..b68a66d6 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_commonname_mailbox_validated.go @@ -0,0 +1,58 @@ +/* + * 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) && util.IsSubscriberCert(c) +} + +func (l *commonNameMailboxValidated) Execute(c *x509.Certificate) *lint.LintResult { + var commonNames []string + if c.Subject.CommonName != "" { + commonNames = append(commonNames, 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/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_legal_entity_identifier.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_legal_entity_identifier.go new file mode 100644 index 00000000..0cd6b6bb --- /dev/null +++ b/vendor/github.com/zmap/zlint/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/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_qc_statements_not_critical.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_qc_statements_not_critical.go new file mode 100644 index 00000000..da37a90b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_qc_statements_not_critical.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_smime_qc_statements_must_not_be_critical", + Description: "This extension MAY be present and SHALL NOT be marked critical.", + Citation: "7.1.2.3.k", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewQCStatementNotCritical, + }) +} + +type qcStatementNotCritical struct{} + +func NewQCStatementNotCritical() lint.LintInterface { + return &qcStatementNotCritical{} +} + +func (l *qcStatementNotCritical) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsExtInCert(c, util.QcStateOid) && util.IsSMIMEBRCertificate(c) +} + +func (l *qcStatementNotCritical) Execute(c *x509.Certificate) *lint.LintResult { + san := util.GetExtFromCert(c, util.QcStateOid) + if san.Critical { + return &lint.LintResult{ + Status: lint.Error, + Details: "qc statements extension is marked critical", + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_if_present.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_if_present.go index a5373ec9..d9731d55 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_if_present.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_if_present.go @@ -23,16 +23,33 @@ import ( "github.com/zmap/zlint/v3/util" ) +/************************************************************************* +7.1.4.2.1 Subject alternative name extension + +All Mailbox Addresses in the subject field or entries of type dirName of this extension SHALL be +repeated as rfc822Name or otherName values of type id-on-SmtpUTF8Mailbox in this +extension. + +7.1.4.2.2 Subject distinguished name fields + +h. Certificate Field: subject:emailAddress (1.2.840.113549.1.9.1) Contents: If present, the +subject:emailAddress SHALL contain a single Mailbox Address as verified under +Section 3.2.2. + +Combining these requirements, this lint checks for malformed email addresses in SAN entries +covering the case of a non-single Mailbox Address. +*************************************************************************/ + func init() { lint.RegisterCertificateLint(&lint.CertificateLint{ LintMetadata: lint.LintMetadata{ Name: "e_single_email_if_present", - Description: "If present, the subject:emailAddress SHALL contain a single Mailbox Address", - Citation: "7.1.4.2.h", + Description: "If present, the subject:emailAddress SHALL contain a single Mailbox Address. All Mailbox Addresses in the subject field SHALL be repeated as rfc822Name or otherName values of type id-on-SmtpUTF8Mailbox in SAN extension.", + Citation: "7.1.4.2.1 and 7.1.4.2.2.h", Source: lint.CABFSMIMEBaselineRequirements, EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, }, - Lint: func() lint.LintInterface { return &singleEmailIfPresent{} }, + Lint: NewSingleEmailIfPresent, }) } @@ -43,22 +60,18 @@ func NewSingleEmailIfPresent() lint.LintInterface { } func (l *singleEmailIfPresent) CheckApplies(c *x509.Certificate) bool { - return util.IsSubscriberCert(c) && c.EmailAddresses != nil && len(c.EmailAddresses) != 0 && util.IsSMIMEBRCertificate(c) + addresses := c.EmailAddresses + return util.IsSubscriberCert(c) && addresses != nil && len(addresses) != 0 && util.IsSMIMEBRCertificate(c) } func (l *singleEmailIfPresent) Execute(c *x509.Certificate) *lint.LintResult { for _, email := range c.EmailAddresses { - _, err := mail.ParseAddress(email) - if err != nil { + if _, err := mail.ParseAddress(email); err != nil { return &lint.LintResult{ - Status: lint.Error, - Details: fmt.Sprintf("subject:emailAddress was present and contained an invalid email address (%s)", email), - LintMetadata: lint.LintMetadata{}, + Status: lint.Error, + Details: fmt.Sprintf("san:emailAddress was present and contained an invalid email address (%s)", email), } } } - - return &lint.LintResult{ - Status: lint.Pass, - } + return &lint.LintResult{Status: lint.Pass} } diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_subject_if_present.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_subject_if_present.go new file mode 100644 index 00000000..1958a95d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_single_email_subject_if_present.go @@ -0,0 +1,60 @@ +/* + * 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 ( + "fmt" + "net/mail" + + "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_single_email_subject_if_present", + Description: "If present, the subject:emailAddress SHALL contain a single Mailbox Address", + Citation: "7.1.4.2.2.h", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewSingleEmailSubjectIfPresent, + }) +} + +type singleEmailSubjectIfPresent struct{} + +func NewSingleEmailSubjectIfPresent() lint.LintInterface { + return &singleEmailSubjectIfPresent{} +} + +func (l *singleEmailSubjectIfPresent) CheckApplies(c *x509.Certificate) bool { + emailAddress := c.Subject.EmailAddress + return util.IsSubscriberCert(c) && emailAddress != nil && len(emailAddress) != 0 && util.IsSMIMEBRCertificate(c) +} + +func (l *singleEmailSubjectIfPresent) Execute(c *x509.Certificate) *lint.LintResult { + for _, email := range c.Subject.EmailAddress { + if _, err := mail.ParseAddress(email); err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("subject:emailAddress was present and contained an invalid email address (%s)", email), + } + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_country_name.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_country_name.go new file mode 100644 index 00000000..07a7dfd0 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_country_name.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 ( + "strings" + + "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_subject_country_name", + Description: "If present, the subject:countryName SHALL contain the two‐letter ISO 3166‐1 country code associated with the location of the Subject", + Citation: "S/MIME BRs: 7.1.4.2.2n", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewSubjectCountryName, + }) +} + +type subjectCountryName struct{} + +func NewSubjectCountryName() lint.LintInterface { + return &subjectCountryName{} +} + +func (l *subjectCountryName) CheckApplies(c *x509.Certificate) bool { + return util.IsMailboxValidatedCertificate(c) +} + +func (l *subjectCountryName) Execute(c *x509.Certificate) *lint.LintResult { + for _, cc := range c.Subject.Country { + if !util.IsISOCountryCode(cc) && strings.ToUpper(cc) != "XX" { + return &lint.LintResult{Status: lint.Error} + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_dir_attr.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_dir_attr.go new file mode 100644 index 00000000..13215469 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subject_dir_attr.go @@ -0,0 +1,52 @@ +package cabf_smime_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 subDirAttr struct{} + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_strict_multipurpose_smime_ext_subject_directory_attr", + Description: "SMIME Strict and Multipurpose certificates cannot have Subject Directory Attributes", + Citation: "BRs: 7.1.2.3j", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewSubDirAttr, + }) +} + +func NewSubDirAttr() lint.LintInterface { + return &subDirAttr{} +} + +func (l *subDirAttr) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && (util.IsStrictSMIMECertificate(c) || util.IsMultipurposeSMIMECertificate(c)) +} + +func (l *subDirAttr) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.SubjectDirAttrOID) { + return &lint.LintResult{Status: lint.Error} + } else { + return &lint.LintResult{Status: lint.Pass} + } +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subscribers_crl_distribution_points_are_http.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subscribers_crl_distribution_points_are_http.go new file mode 100644 index 00000000..3333e36b --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/lint_subscribers_crl_distribution_points_are_http.go @@ -0,0 +1,77 @@ +/* + * 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. + */ + +package cabf_smime_br + +import ( + "net/url" + + "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_subscribers_crl_distribution_points_are_http", + Description: "cRLDistributionPoints SHALL have URI scheme HTTP.", + Citation: "7.1.2.3.b", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + }, + Lint: NewSubscriberCrlDistributionPointsHTTP, + }) +} + +type subscriberCrlDistributionPointsHTTP struct{} + +func NewSubscriberCrlDistributionPointsHTTP() lint.LintInterface { + return &subscriberCrlDistributionPointsHTTP{} +} + +func (l *subscriberCrlDistributionPointsHTTP) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && util.IsSMIMEBRCertificate(c) +} + +func (l *subscriberCrlDistributionPointsHTTP) Execute(c *x509.Certificate) *lint.LintResult { + httpCount := 0 + for _, dp := range c.CRLDistributionPoints { + parsed, err := url.Parse(dp) + if err != nil { + return &lint.LintResult{ + Status: lint.Error, + Details: "SMIME certificate contains invalid CRL distribution point", + } + } + if parsed.Scheme == "http" { + httpCount++ + } + } + + if (util.IsMultipurposeSMIMECertificate(c) || util.IsStrictSMIMECertificate(c)) && httpCount != len(c.CRLDistributionPoints) { + return &lint.LintResult{ + Status: lint.Error, + Details: "SMIME certificate contains invalid URI scheme in CRL distribution point", + } + } + if util.IsLegacySMIMECertificate(c) && httpCount == 0 { + return &lint.LintResult{ + Status: lint.Error, + Details: "SMIME certificate contains no HTTP URI schemes as CRL distribution points", + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/mailbox_address_from_san.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/mailbox_address_from_san.go new file mode 100644 index 00000000..139b051d --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/mailbox_address_from_san.go @@ -0,0 +1,124 @@ +package cabf_smime_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/encoding/asn1" + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zcrypto/x509/pkix" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +// MailboxAddressFromSAN - linter to enforce MAY/SHALL NOT requirements for SMIME certificates +type MailboxAddressFromSAN struct { +} + +func init() { + lint.RegisterLint(&lint.Lint{ + Name: "e_mailbox_address_shall_contain_an_rfc822_name", + Description: "All Mailbox Addresses in the subject field or entries of type dirName of this extension SHALL be repeated as rfc822Name or otherName values of type id-on-SmtpUTF8Mailbox in this extension", + Citation: "SMIME BRs: 7.1.4.2.1", + Source: lint.CABFSMIMEBaselineRequirements, + EffectiveDate: util.CABF_SMIME_BRs_1_0_0_Date, + Lint: NewMailboxAddressFromSAN, + }) +} + +// NewMailboxAddressFromSAN creates a new linter to enforce the requirement that all Mailbox Addresses in SMIME BR certificates must be copied from the SAN +func NewMailboxAddressFromSAN() lint.LintInterface { + return &MailboxAddressFromSAN{} +} + +// CheckApplies is returns true if the certificate's policies assert that it conforms to the SMIME BRs +func (l *MailboxAddressFromSAN) CheckApplies(c *x509.Certificate) bool { + + if !(util.IsSMIMEBRCertificate(c) && util.IsSubscriberCert(c)) { + return false + } + + toFindMailboxAddresses := getMailboxAddressesFromDistinguishedName(c.Subject, util.IsMailboxValidatedCertificate(c)) + + for _, dirName := range c.DirectoryNames { + toFindMailboxAddresses = append(toFindMailboxAddresses, getMailboxAddressesFromDistinguishedName(dirName, false)...) + } + + return len(toFindMailboxAddresses) > 0 + +} + +// Execute checks all the places where Mailbox Addresses may be found in an SMIME certificate and confirms that they are present in the SAN rfc822Name or SAN otherName +func (l *MailboxAddressFromSAN) Execute(c *x509.Certificate) *lint.LintResult { + lintErr := &lint.LintResult{ + Status: lint.Error, + Details: "all certificate mailbox addresses must be present in san:emailAddresses or san:otherNames in addition to any other field they may appear", + } + + // build list of Mailbox addresses from subject:commonName, subject:emailAddress, dirName + + toFindMailboxAddresses := getMailboxAddressesFromDistinguishedName(c.Subject, util.IsMailboxValidatedCertificate(c)) + + for _, dirName := range c.DirectoryNames { + toFindMailboxAddresses = append(toFindMailboxAddresses, getMailboxAddressesFromDistinguishedName(dirName, false)...) + } + + sanNames := map[string]bool{} + for _, rfc822Name := range c.EmailAddresses { + sanNames[rfc822Name] = true + } + + for _, otherName := range c.OtherNames { + if otherName.TypeID.Equal(util.OidIdOnSmtpUtf8Mailbox) { + // The otherName needs to be specially unmarshalled since it is + // stored as a UTF-8 string rather than what the asn1 package + // describes as a PrintableString. + var otherNameValue string + rest, err := asn1.UnmarshalWithParams(otherName.Value.Bytes, &otherNameValue, "utf8") + if len(rest) > 0 || err != nil { + return lintErr + } + + sanNames[otherNameValue] = true + } + } + + for _, mailboxAddress := range toFindMailboxAddresses { + if _, found := sanNames[mailboxAddress]; !found { + return lintErr + } + } + + return &lint.LintResult{Status: lint.Pass} +} + +func getMailboxAddressesFromDistinguishedName(name pkix.Name, includeCN bool) []string { + mailboxAddresses := []string{} + + if includeCN { + for _, commonName := range name.CommonNames { + if util.IsMailboxAddress(commonName) { + mailboxAddresses = append(mailboxAddresses, commonName) + } + } + } + + for _, emailAddress := range name.EmailAddress { + if util.IsMailboxAddress(emailAddress) { + mailboxAddresses = append(mailboxAddresses, emailAddress) + } + } + + return mailboxAddresses +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/smime_legacy_multipurpose_eku_check.go b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/smime_legacy_multipurpose_eku_check.go index 24fc44b0..8f3ac35e 100644 --- a/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/smime_legacy_multipurpose_eku_check.go +++ b/vendor/github.com/zmap/zlint/v3/lints/cabf_smime_br/smime_legacy_multipurpose_eku_check.go @@ -20,7 +20,7 @@ import ( "github.com/zmap/zlint/v3/util" ) -// shallHaveCrlDistributionPoints - linter to enforce requirement that SMIME certificates SHALL contain emailProtecton EKU +// legacyMultipurposeEKUCheck - linter to enforce requirement that SMIME certificates SHALL contain emailProtecton EKU type legacyMultipurposeEKUCheck struct { } @@ -37,7 +37,7 @@ func init() { }) } -// NewShallHaveCrlDistributionPoints creates a new linter to enforce MAY/SHALL NOT field requirements for mailbox validated SMIME certs +// NewLegacyMultipurposeEKUCheck creates a new linter to enforce MAY/SHALL NOT field requirements for mailbox validated SMIME certs func NewLegacyMultipurposeEKUCheck() lint.CertificateLintInterface { return &legacyMultipurposeEKUCheck{} } diff --git a/vendor/github.com/zmap/zlint/v3/lints/community/lint_subj_country_not_uppercase.go b/vendor/github.com/zmap/zlint/v3/lints/community/lint_subj_country_not_uppercase.go new file mode 100644 index 00000000..2c3ccbe8 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/community/lint_subj_country_not_uppercase.go @@ -0,0 +1,62 @@ +/* + * 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 community + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "regexp" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_subj_country_not_uppercase", + Description: "Alpha-2 country codes shall consist of LATIN CAPITAL LETTER A through LATIN CAPITAL LETTER Z", + Citation: "ISO 3166-2:2020(E) section 5.1", + Source: lint.Community, + EffectiveDate: util.ZeroDate, + }, + Lint: NewSubjCountryNotUppercase, + }) +} + +type subjCountryNotUppercase struct{} + +func NewSubjCountryNotUppercase() lint.LintInterface { + return &subjCountryNotUppercase{} +} + +func (l *subjCountryNotUppercase) CheckApplies(c *x509.Certificate) bool { + return true +} + +var re = regexp.MustCompile("^[A-Z]+$") + +func (l *subjCountryNotUppercase) Execute(c *x509.Certificate) *lint.LintResult { + // There should be only one countryName attribute in the Subject, normally, + // but checking this is not our business here, so let's scan them all + for _, cc := range c.Subject.Country { + if !re.MatchString(cc) { + return &lint.LintResult{ + Status: lint.Error, + Details: "Country codes must be comprised of uppercase A-Z letters", + } + } + } + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_cert_ext_invalid_der.go b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_cert_ext_invalid_der.go new file mode 100644 index 00000000..578444af --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_cert_ext_invalid_der.go @@ -0,0 +1,119 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + */ + +package rfc + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "crypto/x509/pkix" + "encoding/asn1" + "fmt" + "math/big" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_cert_ext_invalid_der", + Description: "Checks that the 'critical' flag of extensions is not FALSE when present (as per DER encoding)", + Citation: "RFC 5280 $4.2", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + }, + Lint: NewCertExtensionInvalidDER, + }) +} + +type certExtensionInvalidDER struct{} + +/* + * Modified syntax w/respect to RFC 5280, so we can detect whether + * the critical field is actually present in the DER encoding + */ +type Extension struct { + Id asn1.ObjectIdentifier + // This is either the 'critical' or the 'extnValue' field (see RFC 5280 section 4.1) + // We can discriminate based on tag, since the two fields are of different ASN.1 types + Field2 asn1.RawValue + // If this is present, it can only be the 'extnValue' field + // We need to be able to capture it, but we do not deal with it + Field3 asn1.RawValue `asn1:"optional"` +} + +// This is just plain RFC 5280 +type Certificate struct { + TbsCertificate TBSCertificate + SignatureAlgorithm pkix.AlgorithmIdentifier + SignatureValue asn1.BitString +} + +// Simplified with respect to RFC 5280, as we are not interested in most fields here +type TBSCertificate struct { + Version int `asn1:"optional,explicit,default:0,tag:0"` + SerialNumber *big.Int + SignatureAlgo pkix.AlgorithmIdentifier + Issuer asn1.RawValue + Validity asn1.RawValue + Subject asn1.RawValue + PublicKey asn1.RawValue + IssuerUniqueId asn1.BitString `asn1:"optional,tag:1"` + SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"` + Extensions []Extension `asn1:"omitempty,optional,explicit,tag:3"` +} + +func NewCertExtensionInvalidDER() lint.LintInterface { + return &certExtensionInvalidDER{} +} + +func (l *certExtensionInvalidDER) CheckApplies(c *x509.Certificate) bool { + // This lint applies to any kind of certificate + return true +} + +func (l *certExtensionInvalidDER) Execute(c *x509.Certificate) *lint.LintResult { + + // Re-decode certificate based on an ad-hoc target struct + var cert Certificate + _, err := asn1.Unmarshal(c.Raw, &cert) + + // This should never happen + if err != nil { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "Failed to decode certificate", + } + } + + for _, ext := range cert.TbsCertificate.Extensions { + if ext.Field2.Tag == asn1.TagBoolean { + // This is the 'critical' flag + if ext.Field2.Bytes[0] == 0 { + // This a BOOLEAN FALSE + return &lint.LintResult{ + Status: lint.Error, + Details: fmt.Sprintf("The %v extension is not properly DER-encoded ('critical' must be absent when FALSE)", ext.Id), + } + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_empty_revoked_certificates.go b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_empty_revoked_certificates.go new file mode 100644 index 00000000..fec36bc4 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_empty_revoked_certificates.go @@ -0,0 +1,101 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package rfc + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "crypto/x509/pkix" + "encoding/asn1" + "math/big" + "time" +) + +func init() { + lint.RegisterRevocationListLint(&lint.RevocationListLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_crl_empty_revoked_certificates", + Description: "When there are no revoked certificates, the revoked certificates list MUST be absent", + Citation: "RFC5280 §5.1.2.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + }, + Lint: NewEmptyRevokedCertificates, + }) +} + +type emptyRevokedCertificates struct{} + +type RevokedCertificate struct { + UserCertificate *big.Int + RevocationDate time.Time + CrlEntryExtensions asn1.RawValue `asn1:"optional"` +} + +type TBSCertList struct { + Version int `asn1:"optional"` + Signature pkix.AlgorithmIdentifier + Issuer asn1.RawValue + ThisUpdate time.Time + NextUpdate time.Time `asn1:"optional"` + RevokedCertificates []RevokedCertificate `asn1:"optional"` + CrlExtensions asn1.RawValue `asn1:"tag:0,optional"` +} + +type CertificateList struct { + TbsCertList TBSCertList + SignatureAlgorithm pkix.AlgorithmIdentifier + SignatureValue asn1.BitString +} + +func NewEmptyRevokedCertificates() lint.RevocationListLintInterface { + return &emptyRevokedCertificates{} +} + +func (l *emptyRevokedCertificates) CheckApplies(c *x509.RevocationList) bool { + return true +} + +func (l *emptyRevokedCertificates) Execute(c *x509.RevocationList) *lint.LintResult { + + // We have to re-unmarshal the CRL in our own way, as x.509 RevocationList + // does not allow the verification we want to do here + var certList CertificateList + _, err := asn1.Unmarshal(c.Raw, &certList) + if err != nil { + return &lint.LintResult{ + Status: lint.Fatal, + Details: "Failed to decode CRL", + } + } + + if certList.TbsCertList.RevokedCertificates != nil { + if len(certList.TbsCertList.RevokedCertificates) == 0 { + return &lint.LintResult{ + Status: lint.Error, + Details: "CRL contains an empty revokedCertificates element", + } + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_missing_crl_number.go b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_missing_crl_number.go new file mode 100644 index 00000000..cbe28b23 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_missing_crl_number.go @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + * of ACTALIS S.p.A. (www.actalis.com). + */ + +package rfc + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" +) + +func init() { + lint.RegisterRevocationListLint(&lint.RevocationListLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_crl_missing_crl_number", + Description: "CRL issuers conforming to this profile MUST include this extension in all CRLs", + Citation: "RFC5280 §5.2.3", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + }, + Lint: NewMissingCRLNumber, + }) +} + +type missingCRLNumber struct{} + +func NewMissingCRLNumber() lint.RevocationListLintInterface { + return &missingCRLNumber{} +} + +func (l *missingCRLNumber) CheckApplies(c *x509.RevocationList) bool { + return true +} + +func (l *missingCRLNumber) Execute(c *x509.RevocationList) *lint.LintResult { + for _, e := range c.Extensions { + if e.Id.Equal(util.CRLNumberOID) { + return &lint.LintResult{Status: lint.Pass} + } + } + + return &lint.LintResult{ + Status: lint.Error, + Details: "This CRL lacks the mandatory CRL Number extension", + } +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_revoked_certificates_field_empty.go b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_revoked_certificates_field_empty.go new file mode 100644 index 00000000..4ab576d3 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_crl_revoked_certificates_field_empty.go @@ -0,0 +1,114 @@ +package rfc + +/* + * 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" + "golang.org/x/crypto/cryptobyte" + cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" +) + +type revokedCertificates struct{} + +/* +RFC 5280: 5.1.2.6 + + When there are no revoked certificates, the revoked certificates list + MUST be absent. +*/ +func init() { + lint.RegisterRevocationListLint(&lint.RevocationListLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_crl_revoked_certificates_field_must_be_empty", + Description: "When the revokedCertificates field is empty, it MUST be absent from the DER-encoded ASN.1 data structure.", + Citation: "RFC 5280: 5.1.2.6", + Source: lint.RFC5280, + EffectiveDate: util.RFC5280Date, + }, + Lint: NewEmptyRevokedCerts, + }) +} + +func NewEmptyRevokedCerts() lint.RevocationListLintInterface { + return &revokedCertificates{} +} + +func (l *revokedCertificates) CheckApplies(c *x509.RevocationList) bool { + // This lint is to verify that the TBSCertList.revokedCertificates field, + // when empty, is indeed missing from the DER-encoded ASN.1 bytes. + if c != nil && len(c.RevokedCertificates) == 0 { + return true + } + + return false +} + +func (l *revokedCertificates) Execute(c *x509.RevocationList) *lint.LintResult { + // This is a modified version of x509.ParseRevocationList that extracts the + // raw DER-encoded bytes that comprise a CRL and parses away layers until + // the optional `revokedCertificates` field of a TBSCertList is either found + // or confirmed to be missing from the ASN.1 data structure. + input := cryptobyte.String(c.Raw) + + // Extract the CertificateList + if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "malformed CRL"} + } + + var tbs cryptobyte.String + // Extract the TBSCertList from the CertificateList + if !input.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Fatal, Details: "malformed TBS CRL"} + } + + // Skip optional version + tbs.SkipOptionalASN1(cryptobyte_asn1.INTEGER) + + // Skip the signature + tbs.SkipASN1(cryptobyte_asn1.SEQUENCE) + + // Skip the issuer + tbs.SkipASN1(cryptobyte_asn1.SEQUENCE) + + // SkipOptionalASN1 is identical to SkipASN1 except that it also does a + // peek. We'll handle the non-optional thisUpdate with these double peeks + // because there's no harm doing so. + skipTime := func(s *cryptobyte.String) { + switch { + case s.PeekASN1Tag(cryptobyte_asn1.UTCTime): + s.SkipOptionalASN1(cryptobyte_asn1.UTCTime) + case s.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime): + s.SkipOptionalASN1(cryptobyte_asn1.GeneralizedTime) + } + } + + // Skip thisUpdate + skipTime(&tbs) + + // Skip optional nextUpdate + skipTime(&tbs) + + // Finally, the field which we care about: revokedCertificates. This will + // not trigger on the next field `crlExtensions` because that has + // context-specific tag [0] and EXPLICIT encoding, not `SEQUENCE` and is + // therefore a safe place to end this venture. + if tbs.PeekASN1Tag(cryptobyte_asn1.SEQUENCE) { + return &lint.LintResult{Status: lint.Error, Details: "When there are no revoked certificates, the revoked certificates list MUST be absent."} + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_empty_sct_list.go b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_empty_sct_list.go new file mode 100644 index 00000000..d6f47a2c --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_empty_sct_list.go @@ -0,0 +1,99 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + */ + +package rfc + +import ( + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/v3/lint" + "github.com/zmap/zlint/v3/util" + + "encoding/asn1" +) + +func init() { + lint.RegisterCertificateLint(&lint.CertificateLint{ + LintMetadata: lint.LintMetadata{ + Name: "e_empty_sct_list", + Description: "At least one SCT MUST be included in the SignedCertificateTimestampList extension", + Citation: "RFC 6962 section 3.3", + Source: lint.RFC6962, + EffectiveDate: util.RFC6962Date, + }, + Lint: NewEmptySCTList, + }) +} + +type emptySCTList struct{} + +func NewEmptySCTList() lint.LintInterface { + return &emptySCTList{} +} + +// CheckApplies returns true for any subscriber certificates that are not precertificates +// (i.e. that do not have the CT poison extension defined in RFC 6962) +func (l *emptySCTList) CheckApplies(c *x509.Certificate) bool { + return util.IsSubscriberCert(c) && !util.IsExtInCert(c, util.CtPoisonOID) +} + +func (l *emptySCTList) Execute(c *x509.Certificate) *lint.LintResult { + + var sctListExtValue []byte + + for _, e := range c.Extensions { + if e.Id.Equal(util.TimestampOID) { + sctListExtValue = e.Value + break + } + } + + // SCT extension not found, so there is nothing to check + if sctListExtValue == nil { + return &lint.LintResult{Status: lint.Pass} + } + + var octetString []byte + + _, err := asn1.Unmarshal(sctListExtValue, &octetString) + if err != nil { + // This will probably never happen, as at this point the extension has already been parsed by an upper Zlint layer + return &lint.LintResult{ + Status: lint.Fatal, + Details: "Error decoding the SignedCertificateTimestampList extension", + } + } + + // Per RFC 5246, the SCT list must begin with a two-bytes length field + if len(octetString) < 2 { + // This will probably never happen, as at this point the extension has already been parsed by an upper Zlint layer + return &lint.LintResult{ + Status: lint.Fatal, + Details: "Invalid SCT list encoding (missing length field)", + } + } + + // If the SCT list length (first two bytes) is zero, then it's an invalid SCT list per RFC 6962 + if octetString[0] == 0 && octetString[1] == 0 { + return &lint.LintResult{ + Status: lint.Error, + Details: "At least one SCT MUST be included in the SignedCertificateTimestampList extension", + } + } + + return &lint.LintResult{Status: lint.Pass} +} diff --git a/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_precert_with_sct_list.go b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_precert_with_sct_list.go new file mode 100644 index 00000000..a84b7a41 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/lints/rfc/lint_precert_with_sct_list.go @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/* + * Contributed by Adriano Santoni + */ + +package rfc + +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_precert_with_sct_list", + Description: "SCTs must be embedded in the final certificate, not in a precertificate", + Citation: "RFC 6962 §3.3", + Source: lint.RFC6962, + EffectiveDate: util.RFC6962Date, + }, + Lint: NewPreCertWithSCTList, + }) +} + +type preCertWithSCTList struct{} + +func NewPreCertWithSCTList() lint.LintInterface { + return &preCertWithSCTList{} +} + +func (l *preCertWithSCTList) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.CtPoisonOID) +} + +func (l *preCertWithSCTList) Execute(c *x509.Certificate) *lint.LintResult { + if util.IsExtInCert(c, util.TimestampOID) { + return &lint.LintResult{ + Status: lint.Error, + Details: "Precertificates must not contain the SignedCertificateTimestampList extension", + } + } else { + return &lint.LintResult{Status: lint.Pass} + } +} diff --git a/vendor/github.com/zmap/zlint/v3/util/ca.go b/vendor/github.com/zmap/zlint/v3/util/ca.go index c5cac2a5..c6242114 100644 --- a/vendor/github.com/zmap/zlint/v3/util/ca.go +++ b/vendor/github.com/zmap/zlint/v3/util/ca.go @@ -52,7 +52,7 @@ func IsDelegatedOCSPResponderCert(cert *x509.Certificate) bool { } func IsServerAuthCert(cert *x509.Certificate) bool { - if len(cert.ExtKeyUsage) == 0 { + if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 { return true } for _, eku := range cert.ExtKeyUsage { @@ -60,21 +60,30 @@ func IsServerAuthCert(cert *x509.Certificate) bool { return true } } + for _, policy := range cert.PolicyIdentifiers { + if policy.Equal(BRDomainValidatedOID) || policy.Equal(BROrganizationValidatedOID) || + policy.Equal(BRIndividualValidatedOID) || policy.Equal(BRExtendedValidatedOID) { + return true + } + } return false } // IsEmailProtectionCert returns true if the certificate presented is for use protecting emails. -// A certificate is for use protecting emails if it contains the Any Purpose or emailProtection -// EKUs or if the certificate contains no EKUs. This last point is a way of being overly cautious -// and choosing to prefer false positives over false negatives. +// The S/MIME BRs say the certificate can be identified by an EKU for id-kp-emailProtection +// and the inclusion of a rfc822Name SAN or an otherName of type id-on-SmtpUTF8Mailbox. +// As a way of being overly cautious and choosing to prefer false positives over false negatives, +// also include certificates that have no EKUs, the any purpose EKU, or one of the policy OIDs. func IsEmailProtectionCert(cert *x509.Certificate) bool { - if len(cert.ExtKeyUsage) == 0 { - return true - } - for _, eku := range cert.ExtKeyUsage { - if eku == x509.ExtKeyUsageAny || eku == x509.ExtKeyUsageEmailProtection { + if HasEmailSAN(cert) { + if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 { return true } + for _, eku := range cert.ExtKeyUsage { + if eku == x509.ExtKeyUsageAny || eku == x509.ExtKeyUsageEmailProtection { + return true + } + } } - return false + return IsSMIMEBRCertificate(cert) } diff --git a/vendor/github.com/zmap/zlint/v3/util/cs.go b/vendor/github.com/zmap/zlint/v3/util/cs.go new file mode 100644 index 00000000..5191ba28 --- /dev/null +++ b/vendor/github.com/zmap/zlint/v3/util/cs.go @@ -0,0 +1,18 @@ +package util + +import "github.com/zmap/zcrypto/encoding/asn1" + +const ( + evCodeSigningPolicy = "2.23.140.1.3" + codeSigningPolicy = "2.23.140.1.4.1" +) + +func IsCodeSigning(policies []asn1.ObjectIdentifier) bool { + for _, policy := range policies { + if policy.String() == evCodeSigningPolicy || policy.String() == codeSigningPolicy { + return true + } + } + + return false +} diff --git a/vendor/github.com/zmap/zlint/v3/util/gtld_map.go b/vendor/github.com/zmap/zlint/v3/util/gtld_map.go index 454d1518..ab5244a5 100644 --- a/vendor/github.com/zmap/zlint/v3/util/gtld_map.go +++ b/vendor/github.com/zmap/zlint/v3/util/gtld_map.go @@ -481,7 +481,7 @@ var tldMap = map[string]GTLDPeriod{ "avianca": { GTLD: "avianca", DelegationDate: "2016-03-09", - RemovalDate: "", + RemovalDate: "2024-03-27", }, "aw": { GTLD: "aw", @@ -1426,7 +1426,7 @@ var tldMap = map[string]GTLDPeriod{ "comcast": { GTLD: "comcast", DelegationDate: "2016-07-07", - RemovalDate: "", + RemovalDate: "2024-02-06", }, "commbank": { GTLD: "commbank", @@ -1631,7 +1631,7 @@ var tldMap = map[string]GTLDPeriod{ "dabur": { GTLD: "dabur", DelegationDate: "2015-01-24", - RemovalDate: "", + RemovalDate: "2024-09-25", }, "dad": { GTLD: "dad", @@ -2771,7 +2771,7 @@ var tldMap = map[string]GTLDPeriod{ "guardian": { GTLD: "guardian", DelegationDate: "2016-05-13", - RemovalDate: "", + RemovalDate: "2024-03-05", }, "gucci": { GTLD: "gucci", @@ -4416,7 +4416,7 @@ var tldMap = map[string]GTLDPeriod{ "natura": { GTLD: "natura", DelegationDate: "2016-02-11", - RemovalDate: "", + RemovalDate: "2024-06-12", }, "navy": { GTLD: "navy", @@ -5701,7 +5701,7 @@ var tldMap = map[string]GTLDPeriod{ "shaw": { GTLD: "shaw", DelegationDate: "2016-03-22", - RemovalDate: "", + RemovalDate: "2024-07-09", }, "shell": { GTLD: "shell", @@ -6956,7 +6956,7 @@ var tldMap = map[string]GTLDPeriod{ "xfinity": { GTLD: "xfinity", DelegationDate: "2016-07-07", - RemovalDate: "", + RemovalDate: "2024-02-06", }, "xihuan": { GTLD: "xihuan", diff --git a/vendor/github.com/zmap/zlint/v3/util/oid.go b/vendor/github.com/zmap/zlint/v3/util/oid.go index 75d8a8ee..ec81a904 100644 --- a/vendor/github.com/zmap/zlint/v3/util/oid.go +++ b/vendor/github.com/zmap/zlint/v3/util/oid.go @@ -24,37 +24,43 @@ 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 - // 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 - BRIndividualValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 3} // CA/B BR Individual-Validated + 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 + CRLNumberOID = asn1.ObjectIdentifier{2, 5, 29, 20} // CRL Number + // Extended Key Usage OIDs + PreCertificateSigningCertificateEKU = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 4} + // CA/B Reserved Certificate Policy Identifiers + BRExtendedValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 1} // CA/B BR Reserved Certificate Policy Identifiers - Extended Validation + BRDomainValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1} // CA/B BR Reserved Certificate Policy Identifiers - Domain-Validated + BROrganizationValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 2} // CA/B BR Reserved Certificate Policy Identifiers - Organization-Validated + BRIndividualValidatedOID = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 3} // CA/B BR Reserved Certificate Policy Identifiers - Individual-Validated BRTorServiceDescriptor = asn1.ObjectIdentifier{2, 23, 140, 1, 31} // CA/B BR Tor Service Descriptor CabfExtensionOrganizationIdentifier = asn1.ObjectIdentifier{2, 23, 140, 3, 1} // CA/B EV 9.8.2 cabfOrganizationIdentifier SMIMEBRMailboxValidatedLegacyOID = asn1.ObjectIdentifier{2, 23, 140, 1, 5, 1, 1} // CA/B SMIME BR Mailbox Validated, Legacy @@ -158,6 +164,14 @@ func TypeInName(name *pkix.Name, oid asn1.ObjectIdentifier) bool { return false } +func GetTypesInName(name *pkix.Name) []asn1.ObjectIdentifier { + types := make([]asn1.ObjectIdentifier, 0) + for _, name := range name.Names { + types = append(types, name.Type) + } + return types +} + // helper function to parse policyMapping extensions, returns slices of CertPolicyIds separated by domain func GetMappedPolicies(polMap *pkix.Extension) ([][2]asn1.ObjectIdentifier, error) { if polMap == nil { diff --git a/vendor/github.com/zmap/zlint/v3/util/san.go b/vendor/github.com/zmap/zlint/v3/util/san.go index d1f2f551..a22bda71 100644 --- a/vendor/github.com/zmap/zlint/v3/util/san.go +++ b/vendor/github.com/zmap/zlint/v3/util/san.go @@ -1,6 +1,10 @@ package util -import "github.com/zmap/zcrypto/x509" +import ( + "net/mail" + + "github.com/zmap/zcrypto/x509" +) func HasEmailSAN(c *x509.Certificate) bool { for _, san := range c.EmailAddresses { @@ -17,3 +21,10 @@ func HasEmailSAN(c *x509.Certificate) bool { return false } + +// IsMailboxAddress returns true if the passed in string resembles an RFC 5322 +// mailbox address. +func IsMailboxAddress(address string) bool { + validAddress, err := mail.ParseAddress(address) + return err == nil && validAddress.Address == address +} diff --git a/vendor/github.com/zmap/zlint/v3/util/smime_policies.go b/vendor/github.com/zmap/zlint/v3/util/smime_policies.go index 763a9fa8..f0f4eb3b 100644 --- a/vendor/github.com/zmap/zlint/v3/util/smime_policies.go +++ b/vendor/github.com/zmap/zlint/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) { diff --git a/vendor/github.com/zmap/zlint/v3/util/time.go b/vendor/github.com/zmap/zlint/v3/util/time.go index cd740a95..c0c9ee3e 100644 --- a/vendor/github.com/zmap/zlint/v3/util/time.go +++ b/vendor/github.com/zmap/zlint/v3/util/time.go @@ -37,6 +37,7 @@ var ( RFC4630Date = time.Date(2006, time.August, 1, 0, 0, 0, 0, time.UTC) RFC5280Date = time.Date(2008, time.May, 1, 0, 0, 0, 0, time.UTC) RFC6818Date = time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC) + RFC6962Date = time.Date(2013, time.June, 1, 0, 0, 0, 0, time.UTC) RFC8813Date = time.Date(2020, time.August, 1, 0, 0, 0, 0, time.UTC) CABEffectiveDate = time.Date(2012, time.July, 1, 0, 0, 0, 0, time.UTC) CABReservedIPDate = time.Date(2016, time.October, 1, 0, 0, 0, 0, time.UTC) @@ -74,13 +75,18 @@ var ( AppleReducedLifetimeDate = time.Date(2020, time.September, 1, 0, 0, 0, 0, time.UTC) CABFBRs_1_7_9_Date = time.Date(2021, time.August, 16, 0, 0, 0, 0, time.UTC) CABFBRs_1_8_0_Date = time.Date(2021, time.August, 25, 0, 0, 0, 0, time.UTC) + CABFBRs_2_0_0_Date = time.Date(2023, time.September, 15, 0, 0, 0, 0, time.UTC) NoReservedDomainLabelsDate = time.Date(2021, time.October, 1, 0, 0, 0, 0, time.UTC) CABFBRs_OU_Prohibited_Date = time.Date(2022, time.September, 1, 0, 0, 0, 0, time.UTC) + SC17EffectiveDate = time.Date(2019, time.June, 21, 0, 0, 0, 0, time.UTC) 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) + // Date when section 9.2.8 of CABF EVG became effective + CABFEV_Sec9_2_8_Date = time.Date(2020, time.January, 31, 0, 0, 0, 0, time.UTC) + CABF_CS_BRs_1_2_Date = time.Date(2019, time.August, 13, 0, 0, 0, 0, time.UTC) ) var ( diff --git a/vendor/github.com/zmap/zlint/v3/zlint.go b/vendor/github.com/zmap/zlint/v3/zlint.go index c94bcb6c..93c7a2e1 100644 --- a/vendor/github.com/zmap/zlint/v3/zlint.go +++ b/vendor/github.com/zmap/zlint/v3/zlint.go @@ -23,6 +23,7 @@ import ( "github.com/zmap/zlint/v3/lint" _ "github.com/zmap/zlint/v3/lints/apple" _ "github.com/zmap/zlint/v3/lints/cabf_br" + _ "github.com/zmap/zlint/v3/lints/cabf_cs_br" _ "github.com/zmap/zlint/v3/lints/cabf_ev" _ "github.com/zmap/zlint/v3/lints/cabf_smime_br" _ "github.com/zmap/zlint/v3/lints/community" diff --git a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s index d2ca5dee..b3c1699b 100644 --- a/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s +++ b/vendor/golang.org/x/crypto/internal/poly1305/sum_ppc64le.s @@ -19,15 +19,14 @@ #define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \ MULLD r0, h0, t0; \ - MULLD r0, h1, t4; \ MULHDU r0, h0, t1; \ + MULLD r0, h1, t4; \ MULHDU r0, h1, t5; \ ADDC t4, t1, t1; \ MULLD r0, h2, t2; \ - ADDZE t5; \ MULHDU r1, h0, t4; \ MULLD r1, h0, h0; \ - ADD t5, t2, t2; \ + ADDE t5, t2, t2; \ ADDC h0, t1, t1; \ MULLD h2, r1, t3; \ ADDZE t4, h0; \ @@ -37,13 +36,11 @@ ADDE t5, t3, t3; \ ADDC h0, t2, t2; \ MOVD $-4, t4; \ - MOVD t0, h0; \ - MOVD t1, h1; \ ADDZE t3; \ - ANDCC $3, t2, h2; \ - AND t2, t4, t0; \ + RLDICL $0, t2, $62, h2; \ + AND t2, t4, h0; \ ADDC t0, h0, h0; \ - ADDE t3, h1, h1; \ + ADDE t3, t1, h1; \ SLD $62, t3, t4; \ SRD $2, t2; \ ADDZE h2; \ @@ -75,6 +72,7 @@ TEXT ·update(SB), $0-32 loop: POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22) + PCALIGN $16 multiply: POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21) ADD $-16, R5 diff --git a/vendor/golang.org/x/crypto/ocsp/ocsp.go b/vendor/golang.org/x/crypto/ocsp/ocsp.go index 4269ed11..bf225953 100644 --- a/vendor/golang.org/x/crypto/ocsp/ocsp.go +++ b/vendor/golang.org/x/crypto/ocsp/ocsp.go @@ -279,21 +279,22 @@ func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier { // This is the exposed reflection of the internal OCSP structures. -// The status values that can be expressed in OCSP. See RFC 6960. +// The status values that can be expressed in OCSP. See RFC 6960. +// These are used for the Response.Status field. const ( // Good means that the certificate is valid. - Good = iota + Good = 0 // Revoked means that the certificate has been deliberately revoked. - Revoked + Revoked = 1 // Unknown means that the OCSP responder doesn't know about the certificate. - Unknown + Unknown = 2 // ServerFailed is unused and was never used (see // https://go-review.googlesource.com/#/c/18944). ParseResponse will // return a ResponseError when an error response is parsed. - ServerFailed + ServerFailed = 3 ) -// The enumerated reasons for revoking a certificate. See RFC 5280. +// The enumerated reasons for revoking a certificate. See RFC 5280. const ( Unspecified = 0 KeyCompromise = 1 diff --git a/vendor/golang.org/x/sys/unix/aliases.go b/vendor/golang.org/x/sys/unix/aliases.go index e7d3df4b..b0e41985 100644 --- a/vendor/golang.org/x/sys/unix/aliases.go +++ b/vendor/golang.org/x/sys/unix/aliases.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9 +//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go index 16dc6993..2f0fa76e 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_libSystem.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build darwin && go1.12 +//go:build darwin package unix diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index 64d1bb4d..2b57e0f7 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -13,6 +13,7 @@ package unix import ( + "errors" "sync" "unsafe" ) @@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) { func Uname(uname *Utsname) error { mib := []_C_int{CTL_KERN, KERN_OSTYPE} n := unsafe.Sizeof(uname.Sysname) - if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil { + // Suppress ENOMEM errors to be compatible with the C library __xuname() implementation. + if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_HOSTNAME} n = unsafe.Sizeof(uname.Nodename) - if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_OSRELEASE} n = unsafe.Sizeof(uname.Release) - if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } mib = []_C_int{CTL_KERN, KERN_VERSION} n = unsafe.Sizeof(uname.Version) - if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } @@ -205,7 +207,7 @@ func Uname(uname *Utsname) error { mib = []_C_int{CTL_HW, HW_MACHINE} n = unsafe.Sizeof(uname.Machine) - if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil { + if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) { return err } diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0f85e29e..5682e262 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error { //sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error) //sys Fsopen(fsName string, flags int) (fd int, err error) //sys Fspick(dirfd int, pathName string, flags int) (fd int, err error) + +//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) + +func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) { + var keyp *byte + if keyp, err = BytePtrFromString(key); err != nil { + return + } + return fsconfig(fd, cmd, keyp, value, aux) +} + +// FsconfigSetFlag is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FLAG. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +func FsconfigSetFlag(fd int, key string) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0) +} + +// FsconfigSetString is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_STRING. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetString(fd int, key string, value string) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(value); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0) +} + +// FsconfigSetBinary is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_BINARY. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is the parameter value to set. +func FsconfigSetBinary(fd int, key string, value []byte) (err error) { + if len(value) == 0 { + return EINVAL + } + return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value)) +} + +// FsconfigSetPath is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// path is a non-empty path for specified key. +// atfd is a file descriptor at which to start lookup from or AT_FDCWD. +func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd) +} + +// FsconfigSetPathEmpty is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as +// FconfigSetPath but with AT_PATH_EMPTY implied. +func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) { + var valuep *byte + if valuep, err = BytePtrFromString(path); err != nil { + return + } + return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd) +} + +// FsconfigSetFd is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_SET_FD. +// +// fd is the filesystem context to act upon. +// key the parameter key to set. +// value is a file descriptor to be assigned to specified key. +func FsconfigSetFd(fd int, key string, value int) (err error) { + return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value) +} + +// FsconfigCreate is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_CREATE. +// +// fd is the filesystem context to act upon. +func FsconfigCreate(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0) +} + +// FsconfigReconfigure is equivalent to fsconfig(2) called +// with cmd == FSCONFIG_CMD_RECONFIGURE. +// +// fd is the filesystem context to act upon. +func FsconfigReconfigure(fd int) (err error) { + return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0) +} + //sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64 //sysnb Getpgid(pid int) (pgid int, err error) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 1488d271..87d8612a 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) { + _, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func Getdents(fd int, buf []byte) (n int, err error) { var _p0 unsafe.Pointer if len(buf) > 0 { diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index dc0c955e..eff6bcde 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -836,6 +836,15 @@ const ( FSPICK_EMPTY_PATH = 0x8 FSMOUNT_CLOEXEC = 0x1 + + FSCONFIG_SET_FLAG = 0x0 + FSCONFIG_SET_STRING = 0x1 + FSCONFIG_SET_BINARY = 0x2 + FSCONFIG_SET_PATH = 0x3 + FSCONFIG_SET_PATH_EMPTY = 0x4 + FSCONFIG_SET_FD = 0x5 + FSCONFIG_CMD_CREATE = 0x6 + FSCONFIG_CMD_RECONFIGURE = 0x7 ) type OpenHow struct { @@ -1550,6 +1559,7 @@ const ( IFLA_DEVLINK_PORT = 0x3e IFLA_GSO_IPV4_MAX_SIZE = 0x3f IFLA_GRO_IPV4_MAX_SIZE = 0x40 + IFLA_DPLL_PIN = 0x41 IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0 IFLA_PROTO_DOWN_REASON_MASK = 0x1 IFLA_PROTO_DOWN_REASON_VALUE = 0x2 @@ -1565,6 +1575,7 @@ const ( IFLA_INET6_ICMP6STATS = 0x6 IFLA_INET6_TOKEN = 0x7 IFLA_INET6_ADDR_GEN_MODE = 0x8 + IFLA_INET6_RA_MTU = 0x9 IFLA_BR_UNSPEC = 0x0 IFLA_BR_FORWARD_DELAY = 0x1 IFLA_BR_HELLO_TIME = 0x2 @@ -1612,6 +1623,9 @@ const ( IFLA_BR_MCAST_MLD_VERSION = 0x2c IFLA_BR_VLAN_STATS_PER_PORT = 0x2d IFLA_BR_MULTI_BOOLOPT = 0x2e + IFLA_BR_MCAST_QUERIER_STATE = 0x2f + IFLA_BR_FDB_N_LEARNED = 0x30 + IFLA_BR_FDB_MAX_LEARNED = 0x31 IFLA_BRPORT_UNSPEC = 0x0 IFLA_BRPORT_STATE = 0x1 IFLA_BRPORT_PRIORITY = 0x2 @@ -1649,6 +1663,14 @@ const ( IFLA_BRPORT_BACKUP_PORT = 0x22 IFLA_BRPORT_MRP_RING_OPEN = 0x23 IFLA_BRPORT_MRP_IN_OPEN = 0x24 + IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25 + IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26 + IFLA_BRPORT_LOCKED = 0x27 + IFLA_BRPORT_MAB = 0x28 + IFLA_BRPORT_MCAST_N_GROUPS = 0x29 + IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a + IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b + IFLA_BRPORT_BACKUP_NHID = 0x2c IFLA_INFO_UNSPEC = 0x0 IFLA_INFO_KIND = 0x1 IFLA_INFO_DATA = 0x2 @@ -1670,6 +1692,9 @@ const ( IFLA_MACVLAN_MACADDR = 0x4 IFLA_MACVLAN_MACADDR_DATA = 0x5 IFLA_MACVLAN_MACADDR_COUNT = 0x6 + IFLA_MACVLAN_BC_QUEUE_LEN = 0x7 + IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8 + IFLA_MACVLAN_BC_CUTOFF = 0x9 IFLA_VRF_UNSPEC = 0x0 IFLA_VRF_TABLE = 0x1 IFLA_VRF_PORT_UNSPEC = 0x0 @@ -1693,9 +1718,22 @@ const ( IFLA_XFRM_UNSPEC = 0x0 IFLA_XFRM_LINK = 0x1 IFLA_XFRM_IF_ID = 0x2 + IFLA_XFRM_COLLECT_METADATA = 0x3 IFLA_IPVLAN_UNSPEC = 0x0 IFLA_IPVLAN_MODE = 0x1 IFLA_IPVLAN_FLAGS = 0x2 + NETKIT_NEXT = -0x1 + NETKIT_PASS = 0x0 + NETKIT_DROP = 0x2 + NETKIT_REDIRECT = 0x7 + NETKIT_L2 = 0x0 + NETKIT_L3 = 0x1 + IFLA_NETKIT_UNSPEC = 0x0 + IFLA_NETKIT_PEER_INFO = 0x1 + IFLA_NETKIT_PRIMARY = 0x2 + IFLA_NETKIT_POLICY = 0x3 + IFLA_NETKIT_PEER_POLICY = 0x4 + IFLA_NETKIT_MODE = 0x5 IFLA_VXLAN_UNSPEC = 0x0 IFLA_VXLAN_ID = 0x1 IFLA_VXLAN_GROUP = 0x2 @@ -1726,6 +1764,8 @@ const ( IFLA_VXLAN_GPE = 0x1b IFLA_VXLAN_TTL_INHERIT = 0x1c IFLA_VXLAN_DF = 0x1d + IFLA_VXLAN_VNIFILTER = 0x1e + IFLA_VXLAN_LOCALBYPASS = 0x1f IFLA_GENEVE_UNSPEC = 0x0 IFLA_GENEVE_ID = 0x1 IFLA_GENEVE_REMOTE = 0x2 @@ -1740,6 +1780,7 @@ const ( IFLA_GENEVE_LABEL = 0xb IFLA_GENEVE_TTL_INHERIT = 0xc IFLA_GENEVE_DF = 0xd + IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe IFLA_BAREUDP_UNSPEC = 0x0 IFLA_BAREUDP_PORT = 0x1 IFLA_BAREUDP_ETHERTYPE = 0x2 @@ -1752,6 +1793,8 @@ const ( IFLA_GTP_FD1 = 0x2 IFLA_GTP_PDP_HASHSIZE = 0x3 IFLA_GTP_ROLE = 0x4 + IFLA_GTP_CREATE_SOCKETS = 0x5 + IFLA_GTP_RESTART_COUNT = 0x6 IFLA_BOND_UNSPEC = 0x0 IFLA_BOND_MODE = 0x1 IFLA_BOND_ACTIVE_SLAVE = 0x2 @@ -1781,6 +1824,9 @@ const ( IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a IFLA_BOND_TLB_DYNAMIC_LB = 0x1b IFLA_BOND_PEER_NOTIF_DELAY = 0x1c + IFLA_BOND_AD_LACP_ACTIVE = 0x1d + IFLA_BOND_MISSED_MAX = 0x1e + IFLA_BOND_NS_IP6_TARGET = 0x1f IFLA_BOND_AD_INFO_UNSPEC = 0x0 IFLA_BOND_AD_INFO_AGGREGATOR = 0x1 IFLA_BOND_AD_INFO_NUM_PORTS = 0x2 @@ -1796,6 +1842,7 @@ const ( IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6 IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7 IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8 + IFLA_BOND_SLAVE_PRIO = 0x9 IFLA_VF_INFO_UNSPEC = 0x0 IFLA_VF_INFO = 0x1 IFLA_VF_UNSPEC = 0x0 @@ -1854,8 +1901,16 @@ const ( IFLA_STATS_LINK_XSTATS_SLAVE = 0x3 IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4 IFLA_STATS_AF_SPEC = 0x5 + IFLA_STATS_GETSET_UNSPEC = 0x0 + IFLA_STATS_GET_FILTERS = 0x1 + IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2 IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0 IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2 + IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1 + IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2 IFLA_XDP_UNSPEC = 0x0 IFLA_XDP_FD = 0x1 IFLA_XDP_ATTACHED = 0x2 @@ -1885,6 +1940,11 @@ const ( IFLA_RMNET_UNSPEC = 0x0 IFLA_RMNET_MUX_ID = 0x1 IFLA_RMNET_FLAGS = 0x2 + IFLA_MCTP_UNSPEC = 0x0 + IFLA_MCTP_NET = 0x1 + IFLA_DSA_UNSPEC = 0x0 + IFLA_DSA_CONDUIT = 0x1 + IFLA_DSA_MASTER = 0x1 ) const ( diff --git a/vendor/modules.txt b/vendor/modules.txt index 60692974..9fe221b6 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -117,12 +117,13 @@ github.com/zmap/zcrypto/util github.com/zmap/zcrypto/x509 github.com/zmap/zcrypto/x509/ct github.com/zmap/zcrypto/x509/pkix -# github.com/zmap/zlint/v3 v3.6.1 +# github.com/zmap/zlint/v3 v3.6.4 ## explicit; go 1.18 github.com/zmap/zlint/v3 github.com/zmap/zlint/v3/lint github.com/zmap/zlint/v3/lints/apple github.com/zmap/zlint/v3/lints/cabf_br +github.com/zmap/zlint/v3/lints/cabf_cs_br github.com/zmap/zlint/v3/lints/cabf_ev github.com/zmap/zlint/v3/lints/cabf_smime_br github.com/zmap/zlint/v3/lints/community @@ -130,7 +131,7 @@ github.com/zmap/zlint/v3/lints/etsi github.com/zmap/zlint/v3/lints/mozilla github.com/zmap/zlint/v3/lints/rfc github.com/zmap/zlint/v3/util -# golang.org/x/crypto v0.19.0 +# golang.org/x/crypto v0.21.0 ## explicit; go 1.18 golang.org/x/crypto/blowfish golang.org/x/crypto/chacha20 @@ -148,11 +149,11 @@ golang.org/x/crypto/pkcs12/internal/rc2 golang.org/x/crypto/scrypt golang.org/x/crypto/ssh golang.org/x/crypto/ssh/internal/bcrypt_pbkdf -# golang.org/x/net v0.20.0 +# golang.org/x/net v0.23.0 ## explicit; go 1.18 golang.org/x/net/context/ctxhttp golang.org/x/net/idna -# golang.org/x/sys v0.17.0 +# golang.org/x/sys v0.18.0 ## explicit; go 1.18 golang.org/x/sys/cpu golang.org/x/sys/unix