Giter Club home page Giter Club logo

zlint's Introduction

ZMap: The Internet Scanner

Build Status

ZMap is a fast single packet network scanner designed for Internet-wide network surveys. On a typical desktop computer with a gigabit Ethernet connection, ZMap is capable scanning the entire public IPv4 address space on a single port in under 45 minutes. With a 10gigE connection and netmap or PF_RING, ZMap can scan the IPv4 address space in under 5 minutes.

ZMap operates on GNU/Linux, Mac OS, and BSD. ZMap currently has fully implemented probe modules for TCP SYN scans, ICMP, DNS queries, UPnP, BACNET, and can send a large number of UDP probes. If you are looking to do more involved scans (e.g., banner grab or TLS handshake), take a look at ZGrab 2, ZMap's sister project that performs stateful application-layer handshakes.

Using ZMap

If you haven't used ZMap before, we have a step-by-step Getting Started Guide that details how to perform basic scans. Documentation about all of ZMap's options and more advanced functionality can be found in our Wiki.

If you have questions, please first check our FAQ. Still have questions? Ask the community in Github Discussions. Please do not create an Issue for usage or support questions.

Installation

The latest stable release of ZMap is version 4.1.1 and supports Linux, macOS, and BSD.

Instructions on building ZMap from source can be found in INSTALL.

Architecture

More information about ZMap's architecture and a comparison with other tools can be found in these two research papers:

If you use ZMap for published research, please cite the original research paper:

@inproceedings{durumeric2013zmap,
  title={{ZMap}: Fast Internet-wide scanning and its security applications},
  author={Durumeric, Zakir and Wustrow, Eric and Halderman, J Alex},
  booktitle={22nd USENIX Security Symposium},
  year={2013}
}

Citing the ZMap paper helps us to track ZMap usage within the research community and to pursue funding for continued development.

License and Copyright

ZMap 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 LICENSE for the specific language governing permissions and limitations under the License.

zlint's People

Contributors

aaomidi avatar aarongable avatar bitlux avatar cardonator avatar cbonnell avatar christopher-henderson avatar cpu avatar dadrian avatar defacto64 avatar dependabot[bot] avatar github-actions[bot] avatar jdkasten avatar jsha avatar justinbastress avatar mtgag avatar richsalz avatar robplee avatar rufusjwb avatar sleevi avatar szank avatar tadukurow avatar thoom avatar titanous avatar tld-update-bot avatar toddgaunt-gs avatar vanbroup avatar xolphinmartijn avatar zakird avatar zhengping12 avatar zsofiatomicsko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zlint's Issues

Document creating test certificates

We need to document the process we're following to create zlint test certificates.

Do we have any scripts that we're using, or if we have a process, what it is.

e_sub_ca_eku_name_constraints should be removed

Subordinate CA: If includes id-kp-serverAuth EKU, then it MUST include Name constraints w/ constraints on DNSName, IPAddress, and DirectoryName

I don't see any justification for this lint.

The logic is correct if the CA intends the intermediate cert to be regarded as "Technically Constrained". However, there are plenty of cases where this is not the CA's intent.

Consider these two examples of intermediate certs that contain EKU=id-kp-serverAuth but don't contain the Name Constraints extension:
https://crt.sh/?id=250864699&opt=zlint
https://crt.sh/?id=5779800&opt=zlint
In both cases, the CA's intent is to restrict the type of leaf cert that can be issued/verified. e.g., code signing leaf certs can't be issued, but Server Authentication leaf certs can be issued to any domain.

Note that the Microsoft Trusted Root Program actually requires CAs to use the EKU extension like this for "unconstrained" intermediates!
https://technet.microsoft.com/en-gb/library/cc751157.aspx
Rollover root certificates, or certificates which are intended to replace previously enrolled but expired certificates, will not be accepted if they combine server authentication with code signing uses unless the uses are separated by application of Extended Key Uses (“EKU”s) at the intermediate CA certificate level that are reflected in the whole certificate chain.

Decide how to handle non-server certificates

Consider the following example certs:
https://crt.sh/?id=204352566&opt=zlint (a Client Authentication certificate)
https://crt.sh/?id=201186679&opt=zlint (an OCSP Signing certificate)
https://crt.sh/?id=122792187&opt=zlint (a Code Signing certificate)
https://crt.sh/?id=158872566&opt=zlint (an EV Code Signing certificate)

Currently ZLint "checks for consistency with RFC 5280 and the CA/Browser Forum Baseline Requirements (v.1.4.8)", so it's unsurprising that various warnings/errors/fatals are triggered for these certs that aren't intended to comply with the CABForum BRs.

Should ZLint be enhanced to somehow detect the certificate type and only run CABForum BR lints on certs that are actually expected to be CABForum BR compliant? Should ZLint even be further enhanced to check for consistency with other standards (e.g., the EV Code Signing Guidelines, the Code Signing BRs published by CASC, the Google S/MIME profile, the various browser root program policies, etc).

Or, should it be up to the user/caller (e.g., crt.sh) to make sure that ZLint is only used/called for certs that are expected to be CABForum BR compliant?

Fix the Execute API

We need to fix the ZLint api to actually use the Execute function properly and not throw errors.

RFC5280 email address length is 255

The ASN.1 modules in Appendix A are unchanged from RFC 3280, except
that ub-emailaddress-length was changed from 128 to 255 in order to
align with PKCS #9 [RFC2985].

ub-emailaddress-length INTEGER ::= 255

.onion lint

The EV Guidelines require certificates issued for .onion include the cabf-TorServiceDescriptor extension, defined in the EV Guidelines, as part of these certificates. This is required by Section 11.7.1 (1) of the EV Guidelines, reading: "For a Certificate issued to a Domain Name with .onion in the right-most label of the Domain Name, the CA SHALL confirm that, as of the date the Certificate was issued, the Applicant’s control over the .onion Domain Name in accordance with Appendix F."

All lints need tests

We should have a meta-test, that enforces that any lint file has an associated test file.

Data races when used concurrently

I ran zlint in a tool that runs multiple lints concurrently, with Go's race detector turned on, and it found data races. I'm assuming zlint isn't currently meant to be concurrency-safe. Is that accurate? If so, it should be documented. Thanks!

WARNING: DATA RACE
Write at 0x00c420376420 by goroutine 34:
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*generalizedNotZulu).CheckApplies()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/lint_generalized_time_not_in_zulu.go:47 +0x205
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*Lint).Execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/base.go:106 +0x86
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.(*ResultSet).execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:44 +0x1a2
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.LintCertificate()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:83 +0x69
  main.(*certChecker).checkCert()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:199 +0x1d0
  main.(*certChecker).processCerts()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:169 +0x140
  main.main.func2()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:380 +0xac

Previous write at 0x00c420376420 by goroutine 33:
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*generalizedNotZulu).CheckApplies()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/lint_generalized_time_not_in_zulu.go:47 +0x205
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*Lint).Execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/base.go:106 +0x86
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.(*ResultSet).execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:44 +0x1a2
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.LintCertificate()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:83 +0x69
  main.(*certChecker).checkCert()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:199 +0x1d0
  main.(*certChecker).processCerts()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:169 +0x140
  main.main.func2()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:380 +0xac

Goroutine 34 (running) created at:
  main.main()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:378 +0x1143

Goroutine 33 (running) created at:
  main.main()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:378 +0x1143
==================
==================
WARNING: DATA RACE
Write at 0x00c420376422 by goroutine 32:
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*utcNoSecond).CheckApplies()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/lint_utc_time_does_not_include_seconds.go:52 +0x205
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*Lint).Execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/base.go:106 +0x86
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.(*ResultSet).execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:44 +0x1a2
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.LintCertificate()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:83 +0x69
  main.(*certChecker).checkCert()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:199 +0x1d0
  main.(*certChecker).processCerts()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:169 +0x140
  main.main.func2()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:380 +0xac

Previous write at 0x00c420376422 by goroutine 34:
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*utcNoSecond).CheckApplies()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/lint_utc_time_does_not_include_seconds.go:52 +0x205
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints.(*Lint).Execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/lints/base.go:106 +0x86
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.(*ResultSet).execute()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:44 +0x1a2
  github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint.LintCertificate()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/vendor/github.com/zmap/zlint/zlint.go:83 +0x69
  main.(*certChecker).checkCert()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:199 +0x1d0
  main.(*certChecker).processCerts()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:169 +0x140
  main.main.func2()
      /home/jsha/gopkg/src/github.com/letsencrypt/boulder/cmd/cert-checker/main.go:380 +0xac

Speeding up the slowest lints

Hi, I was intending to use zlint as a library, and ran some benchmarks to see how it fares.
It turns out that there are five lints (w_dnsname_underscore_in_trd, e_dnsname_underscore_in_sld, e_dnsname_hyphen_in_sld, w_dnsname_wildcard_left_of_public_suffix, w_san_iana_pub_suffix_empty) that slow down the linter tremendously. Without them the linter runs ~70x faster on my laptop. The current performance is too low for my needs.

The mentioned linters are so slow, because they all call util.ICANNPublicSuffixParse on CommonName and SAN DNS names.

I'd like to propose a meta linter, that first parses the strings with util.ICANNPublicSuffixParse and then performs all the checks, on already parsed values.

This way you could sped up the linter ~5x.
It would also require Linter interface change, from
Execute(c *x509.Certificate) *LintResult to Execute(c *x509.Certificate) []LintResult

Otherwise, the parsed domain names could be cached in the zcrypto's x509 certificate.
I am hoping to start a discussion on how to make the zlint faster, and I'd be happy to write a PR for that if I get a green light.

"providence" isn't a good term

And "provenance" isn't that much better. :) Perhaps just the simple "from"?
providence shows up in the json output format.

Generating certificates for unit tests

Hi guys, I wanted to add few more lints and need to generate certificates that would fail those lints.
Are there any guidelines on how to generate them?
I can see that the subject/issuer are similar in most of them. Shall I reuse those?
Are you using self signed certs? Any easy way to generate ones? If not, I could write a tool that would create a self signed cert from a template and put it in the repo also.

E: EV certificates must include localityName in subject - only true if stateOrProvinceName is absent

This shouldn't be an error since localtyName is optional when stateOrProvinceName is present (since EV ver 1.6.4 and ballot 191)

E.g., https://crt.sh/?id=466655384&opt=zlint

BR: 7.1.4.2.2 (e)
Certificate Field: subject:localityName (OID: 2.5.4.7)
Required if the subject:organizationName field, subject:givenName field, or subject:surname field are present and the subject:stateOrProvinceName field is absent.
Optional if the subject:stateOrProvinceName field and the subject:organizationName field, subject:givenName field, or subject:surname field are present.
Prohibited if the subject:organizationName field, subject:givenName, and subject:surname field are absent.

Correctly deal with IV Subject names

https://crt.sh/?id=204117585&opt=zlint
"ERROR: The postal code MUST NOT be included without an organization name
ERROR: The 'Street Address' field MUST NOT be included without an organization name"

As described in issue #157, some of the "Prohibited" clauses in BR 7.1.4.2.2 are badly written, but looking at the "Optional" clauses helps to determine the intent.

Subject:postalCode is (emphasis mine) "Optional if the subject:organizationName, subject:givenName field, or subject:surname fields are present." Ditto for subject:streetAddress.

ZLint should be able to output its coverage of the BR's

ZLint should be able to output what Sections of the BR's it thinks it covers. We should then compare this to the BR's, and ensure that we are covering all rules regarding certificates.

Furthermore, it may make sense to maintain our model of the sections of the BR's, and which are relevant to ZLint, as some sort of declarative structure / code, that can be easily compared to the BR's themselves (e.g. if a new section is added). As much of this should be automated as possible, but at the end of the day we have a legal-ish document that humans need to interpret. We should just try to automate away as much as possible to avoid human mistakes.

meta_lint.py should enforce naming conventions

Right now, lints/meta_lint.py enforces that the Lint Name matches the report field being updated if you .replace("_", "").lower(). It should further match that the name of the report field matches the field that would be generated by the protobuf compiler.

OCSP Protocol Lint

ERROR: BR certificates must include an HTTP URL of the OCSP responder

-----BEGIN CERTIFICATE-----
MIIF+zCCBOOgAwIBAgIQQAFa+ZCcrQwwll1N+hLvdzANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSAwHgYDVQQLExdJZGVu
VHJ1c3QgUHVibGljIFNlY3RvcjEcMBoGA1UEAxMTSWRlblRydXN0IEFDRVMgQ0Eg
MjAeFw0xNzAzMjMwNTA4MDhaFw0xOTAzMDgwNjA4MDhaMHoxCzAJBgNVBAYTAlVT
MRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDjAMBgNVBAgTBVRleGFzMRAwDgYD
VQQHEwdIb3VzdG9uMRMwEQYDVQQLEwpNVURJQU0gSW5jMRowGAYDVQQDExF3d3cu
TXVkaWFtSW5jLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALK4
tFl5uRAhZ8NY08EE1gTxVNWM124Wjcfh1oAdqvccGST/n8kn85kjXL7Uoxm62+/5
RzJ/WVaenpVUUkAkMXPybHG+/uoLxe2xPrHo23JKL7Qek86NNEZ5xEUQ2l3FPAsL
uxPoTxx4aA20hR6slK5/lueDlA1IcHcOykBlStmfz9ZvbGDJkMhTuhrYUWgpNr9+
I33REpCVQ10rU6dDngxXTznInfZ2lCZ3pkMgTt4hH4wydtJcSUic8zeyw+UAA75J
9q5CefPFs5bGRbV6D9h5A2cnxRBdBt8FeSwEiYBiUidteGKZkuhDu9rDRjU1s8NY
PRlyTVHnAhBcn4jiAfUCAwEAAaOCApQwggKQMA4GA1UdDwEB/wQEAwIFoDB6Bggr
BgEFBQcBAQRuMGwwPQYIKwYBBQUHMAKGMWh0dHA6Ly92YWxpZGF0aW9uLmlkZW50
cnVzdC5jb20vY2VydHMvYWNlc2NhMi5wN2MwKwYIKwYBBQUHMAGGH2h0dHBzOi8v
YWNlcy5vY3NwLmlkZW50cnVzdC5jb20wHwYDVR0jBBgwFoAUBs0otOUcXb+6P68S
CUODnXn87DIwggFBBgNVHSAEggE4MIIBNDCCATAGCmCGSAFlAwIBAQUwggEgMEwG
CCsGAQUFBwIBFkBodHRwczovL3NlY3VyZS5pZGVudHJ1c3QuY29tL2NlcnRpZmlj
YXRlcy9wb2xpY3kvYWNlcy9pbmRleC5odG1sMIHPBggrBgEFBQcCAjCBwhqBv0Nl
cnRpZmljYXRlIHVzZSByZXN0cmljdGVkIHRvIFJlbHlpbmcgUGFydHkocykgaW4g
YWNjb3JkYW5jZSB3aXRoIEFDRVMgQ1AgKHNlZSBodHRwczovL3NlY3VyZS5pZGVu
dHJ1c3QuY29tL2NlcnRpZmljYXRlcy9wb2xpY3kvYWNlcy9pbmRleC5odG1sKS4g
SWRlblRydXN0IEFDRVMgQ1BTIGluY29ycG9yYXRlZCBieSByZWZlcmVuY2UuMEAG
A1UdHwQ5MDcwNaAzoDGGL2h0dHA6Ly92YWxpZGF0aW9uLmlkZW50cnVzdC5jb20v
Y3JsL2FjZXNjYTIuY3JsMBwGA1UdEQQVMBOCEXd3dy5NdWRpYW1JbmMuY29tMB0G
A1UdDgQWBBRLS6xGdcYQlEu4FKLxPAdPyl3grTAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBALIF00gs9j+nMWMuC1XriAOL
+w5YDtcPUdGjOHTbpM/7BaKG4TVgjI3iK9VpBuiWgUZN1SJOsGSrivnuM6+1jj9I
IHvIE5VR5UsTwFA7UYRST9xjHD1O76/KYgrQSfky/qCq15IdqvIXiRJdsdc4/JpO
1NFx8RbzU6UJ1/PHody2b85A9VI19HPtzeMyLP4xAfNDMXf/iRhOgPO4hPK5MgY5
xI1VJ1FL4YPti7M2BzvHnmrmCkRbM9unNdHR+D6aRYk+j0z436Kqi0M2hGHqOdpx
JRsAW7JgdDckXHY3sTF6gQrBlgOu9rTUlRjZVM3zVwG1kpifeOGzeDO1UDrCm5g=
-----END CERTIFICATE-----

Postal code prohibited check is incorrect

Some of the "Prohibited" clauses in BR 7.1.4.2.2 are badly written. For example (emphasis mine):

  • subject:localityName is prohibited "if the subject:organizationName field, subject:givenName, and subject:surname field are absent".
  • subject:stateOrProvinceName is prohibited "if the subject:organizationName field, subject:givenName field, or subject:surname field are absent"
  • subject:postalCode is prohibited "if the subject:organizationName field, subject:givenName field, or subject:surname field are absent"

I'm sure the intent for all of the above is that the prohibition applies only if all of the mentioned fields (organizationName, givenName and surname) are absent. That's the approach ZLint seems to take for all Subject fields except for subject:postalCode.

https://github.com/zmap/zlint/blob/master/lints/lint_sub_cert_postal_code_prohibited.go#L19 needs &&s instead of ||s.

False error on CRLdp does not contain url

I believe there may be a bug in Zlint. If you look at this certificate:
https://censys.io/certificates/6ef0debdfc2d9af68c5174c2b88ccfabde9540a1b6b96e2526b59e6a9ab09b10

You will see it has a zlint error, specifically, it is:

sub cert crl distribution points does not contain url

And if you look at the CRLdp in the CenSys user interface it shows a single ldap URI:
image

But if you look at the same certificate under OpenSSL you see:
image

Upon inspection of the lint code, it seems it is doing the right things:
https://github.com/zmap/zlint/blob/master/lints/lint_sub_cert_crl_distribution_points_does_not_contain_url.go#L43

So I guess the X.509 decoder is only returning a single CRLdp?

Incorrect warning on multiple attributes in one RDN

In your code you have this warning on having "multiple attributes in one RDN" in one certificate. In fact I do not understand the warning and why you made it.

As from initial type definition we have this:

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
		
RelativeDistinguishedName ::=
SET SIZE (1..MAX) OF AttributeTypeAndValue

And nothing stops us from having multiple AttributeTypeAndValue - could be (1..MAX) values inside one RelativeDistinguishedName.

So, could you describe why you made the warning in zlint?

Creating a new lint is error prone

The current steps to add a new lint are incredibly tedious. There are too many places where we're storing lint information and all of this should be built in a script.

stdin certificate in cmd mode

running cmd

zlint -
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----

Seems to not respond.

While the same is working for zcertificate

zcertificate -
-----BEGIN CERTIFICATE-----
MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
-----END CERTIFICATE-----

{"raw":"MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw56wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=","parsed":{"version":3,"serial_number":"1","signature_algorithm":{"name":"SHA1WithRSA","oid":"1.2.840.113549.1.1.5"},"issuer":{"common_name":["AddTrust External CA Root"],"country":["SE"],"organization":["AddTrust AB"],"organizational_unit":["AddTrust External TTP Network"]},"issuer_dn":"C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root","validity":{"start":"2000-05-30T10:48:38Z","end":"2020-05-30T10:48:38Z","length":631152000},"subject":{"common_name":["AddTrust External CA Root"],"country":["SE"],"organization":["AddTrust AB"],"organizational_unit":["AddTrust External TTP Network"]},"subject_dn":"C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root","subject_key_info":{"key_algorithm":{"name":"RSA"},"rsa_public_key":{"exponent":65537,"modulus":"t/caM+byAAQtOeBOW+0fvGwPzbX6I7bO3psRM5ekKUx9k5+9SryT7QMa44/P5W1QWtaXKZRagLBJetsulf24yr83OC0ePpFBrXBWx/BPP+gynnTKyJBU6cZfD3idmkA8Dqxhql4Uj56HoWpQ3NeaTq8Fs6ZxlJxxs1BgCscTnTgHhgKo6ahpJhiQq0ywTyOrOk+E2N/On+Fpb7vXQtdrROTHre5tQV9yWnEIN7N5ZaRZoJQ39wAvDcKSctrQOHLbFKhFxF0qfbe01sTurM0TRLfJK91DACX6YblpalgjEbenM49WdVn1zSnXRrcKK2W200JvFbK4e/vv6V1T1TRaJw==","length":2048},"fingerprint_sha256":"942a6916a6e4ae527711c5450247a2a74fb8e156a8254ca66e739a11493bb445"},"extensions":{"key_usage":{"certificate_sign":true,"crl_sign":true,"value":96},"basic_constraints":{"is_ca":true},"authority_key_id":"adbd987a34b426f7fac42654ef03bde024cb541a","subject_key_id":"adbd987a34b426f7fac42654ef03bde024cb541a"},"signature":{"signature_algorithm":{"name":"SHA1WithRSA","oid":"1.2.840.113549.1.1.5"},"value":"sJvghSXC1iPiD5YGkp1BmJzZhHmB2R5bFAcjNmWPsNh3u6xBbEdgg1Gw+TI95/z2JhPHgBalv1r8h894eYkhmuJMBwqGNbzy3lHE0pa33H5O7nD9HDnrDAJRFC2OvRbgwd9Gdeckrez0QrSFk3AQZ7qdBjVKGNMresxRQqF6Y9Hmu6HFK8I2vhMN5r1jfnl7pwkNQKtq3Y+Kw/b2jBpCBVHURfWfp2IhaBUgQzyZ53y9JNipkRdziD9WGzE4GLRxD5rNyA6eji4b4YyYg8sfMfFETMYEc0l2YA/H+L0XgGsu6cxMDlqaeQ8gCi7VnmMmHlWSlNiCF1p70LzHj06GBA==","valid":false,"self_signed":true},"fingerprint_md5":"1d3554048578b03f42424dbf20730a3f","fingerprint_sha1":"02faf3e291435468607857694df5e45b68851868","fingerprint_sha256":"687fa451382278fff0c8b11f8d43d576671c6eb2bceab413fb83d965d06d2ff2","tbs_noct_fingerprint":"32e1783f2384bc17836c03850527b18de7901a6909de7cf6b7d9d46659895d6c","spki_subject_fingerprint":"4df410fbf6761bcf75fe2a45e15fcab3640bf5e5d1300d0eeb5927152432179c","tbs_fingerprint":"32e1783f2384bc17836c03850527b18de7901a6909de7cf6b7d9d46659895d6c","validation_level":"unknown","redacted":false},"zlint":{"version":3,"timestamp":1520593396,"lints":{"e_basic_constraints_not_critical":{"result":"pass"},"e_ca_common_name_missing":{"result":"NE"},"e_ca_country_name_invalid":{"result":"NE"},"e_ca_country_name_missing":{"result":"NE"},"e_ca_crl_sign_not_set":{"result":"NE"},"e_ca_is_ca":{"result":"NE"},"e_ca_key_cert_sign_not_set":{"result":"NE"},"e_ca_key_usage_missing":{"result":"NE"},"e_ca_key_usage_not_critical":{"result":"NE"},"e_ca_organization_name_missing":{"result":"NE"},"e_ca_subject_field_empty":{"result":"pass"},"e_cab_dv_conflicts_with_locality":{"result":"NA"},"e_cab_dv_conflicts_with_org":{"result":"NA"},"e_cab_dv_conflicts_with_postal":{"result":"NA"},"e_cab_dv_conflicts_with_province":{"result":"NA"},"e_cab_dv_conflicts_with_street":{"result":"NA"},"e_cab_iv_requires_personal_name":{"result":"NA"},"e_cab_ov_requires_org":{"result":"NA"},"e_cert_contains_unique_identifier":{"result":"NE"},"e_cert_extensions_version_not_3":{"result":"pass"},"e_cert_policy_iv_requires_country":{"result":"NA"},"e_cert_policy_iv_requires_province_or_locality":{"result":"NA"},"e_cert_policy_ov_requires_country":{"result":"NA"},"e_cert_policy_ov_requires_province_or_locality":{"result":"NA"},"e_cert_unique_identifier_version_not_2_or_3":{"result":"NA"},"e_distribution_point_incomplete":{"result":"NA"},"e_dnsname_bad_character_in_label":{"result":"NA"},"e_dnsname_contains_bare_iana_suffix":{"result":"NA"},"e_dnsname_empty_label":{"result":"NA"},"e_dnsname_hyphen_in_sld":{"result":"NA"},"e_dnsname_label_too_long":{"result":"NA"},"e_dnsname_left_label_wildcard_correct":{"result":"NE"},"e_dnsname_not_valid_tld":{"result":"NA"},"e_dnsname_underscore_in_sld":{"result":"NA"},"e_dnsname_wildcard_only_in_left_label":{"result":"NE"},"e_dsa_correct_order_in_subgroup":{"result":"NA"},"e_dsa_improper_modulus_or_divisor_size":{"result":"NA"},"e_dsa_params_missing":{"result":"NA"},"e_dsa_shorter_than_2048_bits":{"result":"NA"},"e_dsa_unique_correct_representation":{"result":"NA"},"e_ec_improper_curves":{"result":"NA"},"e_ev_business_category_missing":{"result":"NA"},"e_ev_country_name_missing":{"result":"NA"},"e_ev_locality_name_missing":{"result":"NA"},"e_ev_organization_name_missing":{"result":"NA"},"e_ev_serial_number_missing":{"result":"NA"},"e_ev_valid_time_too_long":{"result":"NA"},"e_ext_aia_marked_critical":{"result":"NA"},"e_ext_authority_key_identifier_critical":{"result":"pass"},"e_ext_authority_key_identifier_missing":{"result":"NA"},"e_ext_authority_key_identifier_no_key_identifier":{"result":"pass"},"e_ext_cert_policy_disallowed_any_policy_qualifier":{"result":"NA"},"e_ext_cert_policy_duplicate":{"result":"NA"},"e_ext_cert_policy_explicit_text_ia5_string":{"result":"NA"},"e_ext_cert_policy_explicit_text_too_long":{"result":"NA"},"e_ext_duplicate_extension":{"result":"pass"},"e_ext_freshest_crl_marked_critical":{"result":"NA"},"e_ext_ian_dns_not_ia5_string":{"result":"NA"},"e_ext_ian_empty_name":{"result":"NA"},"e_ext_ian_no_entries":{"result":"NA"},"e_ext_ian_rfc822_format_invalid":{"result":"NA"},"e_ext_ian_space_dns_name":{"result":"NA"},"e_ext_ian_uri_format_invalid":{"result":"NA"},"e_ext_ian_uri_host_not_fqdn_or_ip":{"result":"NA"},"e_ext_ian_uri_not_ia5":{"result":"NA"},"e_ext_ian_uri_relative":{"result":"NA"},"e_ext_key_usage_cert_sign_without_ca":{"result":"NE"},"e_ext_key_usage_without_bits":{"result":"NE"},"e_ext_name_constraints_not_critical":{"result":"NA"},"e_ext_name_constraints_not_in_ca":{"result":"NA"},"e_ext_policy_constraints_empty":{"result":"NA"},"e_ext_policy_constraints_not_critical":{"result":"NA"},"e_ext_policy_map_any_policy":{"result":"NA"},"e_ext_san_contains_reserved_ip":{"result":"NE"},"e_ext_san_directory_name_present":{"result":"NA"},"e_ext_san_dns_name_too_long":{"result":"NA"},"e_ext_san_dns_not_ia5_string":{"result":"NA"},"e_ext_san_edi_party_name_present":{"result":"NA"},"e_ext_san_empty_name":{"result":"NA"},"e_ext_san_missing":{"result":"NA"},"e_ext_san_no_entries":{"result":"NA"},"e_ext_san_not_critical_without_subject":{"result":"NA"},"e_ext_san_other_name_present":{"result":"NA"},"e_ext_san_registered_id_present":{"result":"NA"},"e_ext_san_rfc822_format_invalid":{"result":"NA"},"e_ext_san_rfc822_name_present":{"result":"NA"},"e_ext_san_space_dns_name":{"result":"NA"},"e_ext_san_uniform_resource_identifier_present":{"result":"NA"},"e_ext_san_uri_format_invalid":{"result":"NA"},"e_ext_san_uri_host_not_fqdn_or_ip":{"result":"NA"},"e_ext_san_uri_not_ia5":{"result":"NA"},"e_ext_san_uri_relative":{"result":"NA"},"e_ext_subject_directory_attr_critical":{"result":"NA"},"e_ext_subject_key_identifier_critical":{"result":"pass"},"e_ext_subject_key_identifier_missing_ca":{"result":"pass"},"e_generalized_time_does_not_include_seconds":{"result":"NA"},"e_generalized_time_includes_fraction_seconds":{"result":"NA"},"e_generalized_time_not_in_zulu":{"result":"NA"},"e_ian_bare_wildcard":{"result":"NA"},"e_ian_dns_name_includes_null_char":{"result":"NA"},"e_ian_dns_name_starts_with_period":{"result":"NA"},"e_ian_wildcard_not_first":{"result":"NA"},"e_inhibit_any_policy_not_critical":{"result":"NA"},"e_international_dns_name_not_nfkc":{"result":"NA"},"e_international_dns_name_not_unicode":{"result":"NA"},"e_invalid_certificate_version":{"result":"NE"},"e_issuer_dn_country_not_printable_string":{"result":"pass"},"e_issuer_field_empty":{"result":"pass"},"e_name_constraint_empty":{"result":"NA"},"e_name_constraint_maximum_not_absent":{"result":"NA"},"e_name_constraint_minimum_non_zero":{"result":"NA"},"e_old_root_ca_rsa_mod_less_than_2048_bits":{"result":"pass"},"e_old_sub_ca_rsa_mod_less_than_1024_bits":{"result":"NA"},"e_old_sub_cert_rsa_mod_less_than_1024_bits":{"result":"NA"},"e_path_len_constraint_improperly_included":{"result":"NE"},"e_path_len_constraint_zero_or_less":{"result":"pass"},"e_public_key_type_not_allowed":{"result":"NE"},"e_root_ca_extended_key_usage_present":{"result":"NE"},"e_root_ca_key_usage_must_be_critical":{"result":"error"},"e_root_ca_key_usage_present":{"result":"pass"},"e_rsa_exp_negative":{"result":"pass"},"e_rsa_mod_less_than_2048_bits":{"result":"pass"},"e_rsa_no_public_key":{"result":"pass"},"e_rsa_public_exponent_not_odd":{"result":"NE"},"e_rsa_public_exponent_too_small":{"result":"NE"},"e_san_bare_wildcard":{"result":"NA"},"e_san_dns_name_includes_null_char":{"result":"NA"},"e_san_dns_name_starts_with_period":{"result":"NA"},"e_san_wildcard_not_first":{"result":"NA"},"e_serial_number_longer_than_20_octets":{"result":"NE"},"e_serial_number_not_positive":{"result":"NE"},"e_signature_algorithm_not_supported":{"result":"pass"},"e_sub_ca_aia_does_not_contain_ocsp_url":{"result":"NA"},"e_sub_ca_aia_marked_critical":{"result":"NA"},"e_sub_ca_aia_missing":{"result":"NA"},"e_sub_ca_certificate_policies_missing":{"result":"NA"},"e_sub_ca_crl_distribution_points_does_not_contain_url":{"result":"NA"},"e_sub_ca_crl_distribution_points_marked_critical":{"result":"NA"},"e_sub_ca_crl_distribution_points_missing":{"result":"NA"},"e_sub_cert_aia_does_not_contain_ocsp_url":{"result":"NA"},"e_sub_cert_aia_marked_critical":{"result":"NA"},"e_sub_cert_aia_missing":{"result":"NA"},"e_sub_cert_cert_policy_empty":{"result":"NA"},"e_sub_cert_certificate_policies_missing":{"result":"NA"},"e_sub_cert_country_name_must_appear":{"result":"NA"},"e_sub_cert_crl_distribution_points_does_not_contain_url":{"result":"NA"},"e_sub_cert_crl_distribution_points_marked_critical":{"result":"NA"},"e_sub_cert_eku_missing":{"result":"NA"},"e_sub_cert_eku_server_auth_client_auth_missing":{"result":"NA"},"e_sub_cert_given_name_surname_contains_correct_policy":{"result":"NA"},"e_sub_cert_key_usage_cert_sign_bit_set":{"result":"NA"},"e_sub_cert_key_usage_crl_sign_bit_set":{"result":"NA"},"e_sub_cert_locality_name_must_appear":{"result":"NA"},"e_sub_cert_locality_name_must_not_appear":{"result":"NA"},"e_sub_cert_not_is_ca":{"result":"NA"},"e_sub_cert_or_sub_ca_using_sha1":{"result":"NE"},"e_sub_cert_postal_code_must_not_appear":{"result":"NA"},"e_sub_cert_province_must_appear":{"result":"NA"},"e_sub_cert_province_must_not_appear":{"result":"NA"},"e_sub_cert_street_address_should_not_exist":{"result":"NA"},"e_sub_cert_valid_time_longer_than_39_months":{"result":"NA"},"e_sub_cert_valid_time_longer_than_825_days":{"result":"NA"},"e_subject_common_name_max_length":{"result":"pass"},"e_subject_common_name_not_from_san":{"result":"NA"},"e_subject_contains_noninformational_value":{"result":"NE"},"e_subject_contains_reserved_ip":{"result":"NE"},"e_subject_country_not_iso":{"result":"NE"},"e_subject_dn_country_not_printable_string":{"result":"pass"},"e_subject_dn_serial_number_max_length":{"result":"NA"},"e_subject_dn_serial_number_not_printable_string":{"result":"NA"},"e_subject_email_max_length":{"result":"pass"},"e_subject_empty_without_san":{"result":"pass"},"e_subject_given_name_max_length":{"result":"pass"},"e_subject_info_access_marked_critical":{"result":"NA"},"e_subject_locality_name_max_length":{"result":"pass"},"e_subject_not_dn":{"result":"pass"},"e_subject_organization_name_max_length":{"result":"pass"},"e_subject_organizational_unit_name_max_length":{"result":"pass"},"e_subject_postal_code_max_length":{"result":"pass"},"e_subject_state_name_max_length":{"result":"pass"},"e_subject_street_address_max_length":{"result":"pass"},"e_subject_surname_max_length":{"result":"pass"},"e_utc_time_does_not_include_seconds":{"result":"pass"},"e_utc_time_not_in_zulu":{"result":"pass"},"e_validity_time_not_positive":{"result":"pass"},"e_wrong_time_format_pre2050":{"result":"pass"},"n_ca_digital_signature_not_set":{"result":"NE"},"n_contains_redacted_dnsname":{"result":"NA"},"n_sub_ca_eku_missing":{"result":"NA"},"n_sub_ca_eku_not_technically_constrained":{"result":"NA"},"n_subject_common_name_included":{"result":"NA"},"w_distribution_point_missing_ldap_or_uri":{"result":"NA"},"w_dnsname_underscore_in_trd":{"result":"NA"},"w_dnsname_wildcard_left_of_public_suffix":{"result":"NA"},"w_eku_critical_improperly":{"result":"NA"},"w_ext_aia_access_location_missing":{"result":"NA"},"w_ext_cert_policy_contains_noticeref":{"result":"NA"},"w_ext_cert_policy_explicit_text_includes_control":{"result":"NA"},"w_ext_cert_policy_explicit_text_not_nfc":{"result":"NA"},"w_ext_cert_policy_explicit_text_not_utf8":{"result":"NA"},"w_ext_crl_distribution_marked_critical":{"result":"NA"},"w_ext_ian_critical":{"result":"NA"},"w_ext_key_usage_not_critical":{"result":"warn"},"w_ext_policy_map_not_critical":{"result":"NA"},"w_ext_policy_map_not_in_cert_policy":{"result":"NA"},"w_ext_san_critical_with_subject_dn":{"result":"NA"},"w_ext_subject_key_identifier_missing_sub_cert":{"result":"NA"},"w_ian_iana_pub_suffix_empty":{"result":"NA"},"w_issuer_dn_leading_whitespace":{"result":"pass"},"w_issuer_dn_trailing_whitespace":{"result":"pass"},"w_multiple_issuer_rdn":{"result":"pass"},"w_multiple_subject_rdn":{"result":"pass"},"w_name_constraint_on_edi_party_name":{"result":"NA"},"w_name_constraint_on_registered_id":{"result":"NA"},"w_name_constraint_on_x400":{"result":"NA"},"w_root_ca_basic_constraints_path_len_constraint_field_present":{"result":"NE"},"w_root_ca_contains_cert_policy":{"result":"NE"},"w_rsa_mod_factors_smaller_than_752":{"result":"NE"},"w_rsa_mod_not_odd":{"result":"NE"},"w_rsa_public_exponent_not_in_range":{"result":"NE"},"w_san_iana_pub_suffix_empty":{"result":"NA"},"w_serial_number_low_entropy":{"result":"NE"},"w_sub_ca_aia_does_not_contain_issuing_ca_url":{"result":"NA"},"w_sub_ca_certificate_policies_marked_critical":{"result":"NA"},"w_sub_ca_eku_critical":{"result":"NA"},"w_sub_ca_name_constraints_not_critical":{"result":"NA"},"w_sub_cert_aia_does_not_contain_issuing_ca_url":{"result":"NA"},"w_sub_cert_certificate_policies_marked_critical":{"result":"NA"},"w_sub_cert_eku_extra_values":{"result":"NA"},"w_sub_cert_sha1_expiration_too_long":{"result":"NA"},"w_subject_dn_leading_whitespace":{"result":"pass"},"w_subject_dn_trailing_whitespace":{"result":"pass"}},"notices_present":false,"warnings_present":true,"errors_present":true,"fatals_present":false}}

Lint "e_subject_dn_country_not_printable_string" is too strict

Hi, this is a bit embarrassing, but I've had another read through the RFC 5280 (https://tools.ietf.org/html/rfc5280#section-4.1.2.4)
and it states that for both Issuer and Subject the RDN fields can be either PrintableString or UTF8String.

The DirectoryString type is defined as a choice of PrintableString,
   TeletexString, BMPString, UTF8String, and UniversalString.  CAs
   conforming to this profile MUST use either the PrintableString or
   UTF8String encoding of DirectoryString, with two exceptions.  When
   CAs have previously issued certificates with issuer fields with
   attributes encoded using TeletexString, BMPString, or
   UniversalString, then the CA MAY continue to use these encodings of
   the DirectoryString to preserve backward compatibility.  Also, new
   CAs that are added to a domain where existing CAs issue certificates
   with issuer fields with attributes encoded using TeletexString,
   BMPString, or UniversalString MAY encode attributes that they share
   with the existing CAs using the same encodings as the existing CAs
   use.

The Appendix A that is used as the citation for the lint is wrong, or at least inconsistent. Also, I think that this should be a warning, given the allowed exceptions.

All Lint tests need review

We need to ensure that the current tests actually test what we think they do. This will require manual inspection.

TestSANEDIPartyMissing failing

Running unittests on master with go version go1.10 linux/amd64:

asn1: structure error: explicitly tagged member didn't match
--- FAIL: TestSANEDIPartyMissing (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x530 pc=0x6a2855]

goroutine 262 [running]:
testing.tRunner.func1(0xc4202e93b0)
        /home/jsha/go1.10/src/testing/testing.go:742 +0x29d
panic(0x76d1e0, 0xa73cb0)
        /home/jsha/go1.10/src/runtime/panic.go:505 +0x229
github.com/zmap/zlint/util.IsServerAuthCert(0x0, 0x785ac0)
        /home/jsha/gopkg/src/github.com/zmap/zlint/util/ca.go:48 +0x5
github.com/zmap/zlint/lints.(*Lint).Execute(0xc4202cf500, 0x0, 0x8060a3)
        /home/jsha/gopkg/src/github.com/zmap/zlint/lints/base.go:103 +0x117
github.com/zmap/zlint/lints.TestSANEDIPartyMissing(0xc4202e93b0)
        /home/jsha/gopkg/src/github.com/zmap/zlint/lints/lint_ext_san_edi_party_name_present_test.go:33 +0x9e
testing.tRunner(0xc4202e93b0, 0x81e750)
        /home/jsha/go1.10/src/testing/testing.go:777 +0xd0
created by testing.(*T).Run
        /home/jsha/go1.10/src/testing/testing.go:824 +0x2e0
FAIL    github.com/zmap/zlint/lints     0.060s

Godoc for lints package malformed

On https://godoc.org/github.com/zmap/zlint/lints, it looks like some of the comments are being turned into godoc in unexpected ways:

lint_rsa_no_public_key.go

lint_sub_cert_certificate_policies_marked_critical.go ***************************************************************************** BRs: 7.1.2.3 certificatePolicies This extension MUST be present and SHOULD NOT be marked critical. *****************************************************************************

CA Certs verified under BRs 7.1.6.1 use 7.1.4.2.2

BRs 7.1.6.1 states that OV certificates (with policy identifer 2.23.140.1.2.2) must include the localityName to the extent such a field is required under Section 7.1.4.2.2.

Section 7.1.4.2.2 is only applicable to Subscriber Certificates. zlint is currently enforcing this check on CA certificates.
Example: https://censys.io/certificates/95c074e35902a14abd9d19afb6e7f80e669ff8e2363270539d963613f04aaa21/zlint

It also looks like problems exists with 2.23.140.1.2.3 (EV) certificates as well. I have only analyzed code related to 7.1.6.1.

Potential fix:
It seems like it would be as simple as adding a cert.IsCA check to the affected code.

if util.TypeInName(&cert.Subject, util.LocalityNameOID) || util.TypeInName(&cert.Subject, util.StateOrProvinceNameOID) {

if util.TypeInName(&cert.Subject, util.LocalityNameOID) || util.TypeInName(&cert.Subject, util.StateOrProvinceNameOID) {

Reference:
https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.5.6.pdf

Lint e_ext_san_uri_host_not_fqdn_or_ip returning an error on valid uris

Hi, this lint doesn't work like intended. Given a valid URI, for example sip:[email protected] it returns an error.

Problem is in the util.GetHost() method, fortunately as far as I can tell it is not used elsewhere:
lint_ext_san_uri_host_not_fqdn_or_ip_test.go:

if uri != "" {
			host := util.GetHost(uri)
			if !util.AuthIsFQDNOrIP(host) {
				return &LintResult{Status: Error}
			}
		}

Given the input mentioned before, util.GetHost(uri) returns an empty string.
The problem is compounded by the bad test data in the testlint/testCerts/SANURIHostWildcardFQDN.pem certificate.

X509v3 Subject Alternative Name: 
                DNS:*.example.com, URI:test//user@*.example.com:1337/test

The uri in this cert doesn't have colon after the scheme, this is not a valid URI in the first place.
I suspect that the test data have been generated first and then the util.GetHost() have been created to work with the test input.
Given a valid URI like sip:[email protected] or test://user@*.example.com:1337/test the linter fails.

Notice for `arpa` domains

From my reading, it's not strictly against the rules to have a certificate for .arpa (e.g., *.0.0.b.c.0.0.4.2.ip6.arpa), but it's a somewhat odd case. It'd be nice to have a notice that checks for this.

Certs with CN containing capital letters flagged by `e_subject_common_name_not_from_san` false positive

Example:
https://crt.sh/?id=276876975&opt=cablint,x509lint,zlint

No other linters in crt.sh are flagging this cert, and as far as I can tell, DNS names should be normalised before parsing/validation. Either way pasting Tours.AlliedTT.com to chrome works, as the dns name is automatically converted to lowercase (possibly by the IDNA engine)

The e_subject_common_name_not_from_san should perform ToLower on the common name before comparing it with SAN DNS names IMHO. Any objections?

e_sub_ca_must_not_contain_any_policy should be removed

Subordinate CA: MUST NOT contain the anyPolicy identifier (2.5.29.32.0)

This is only true when the Subordinate CA "is not an Affiliate of the Issuing CA". I think evaluating legal relationships is out of scope for ZLint!

Here are two examples of intermediate certs where the Issuing CA and the Subordinate CA are affiliated, and so this error is a false positive:
https://crt.sh/?id=250864699&opt=zlint
https://crt.sh/?id=5779800&opt=zlint

I propose that this lint should be removed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.