• Stars
    star
    356
  • Rank 119,446 (Top 3 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 8 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

X.509 Certificate Linter focused on Web PKI standards and requirements.

ZLint

CI Status Integration Tests Lint Status Go Report Card

ZLint is a X.509 certificate linter written in Go that checks for consistency with standards (e.g. RFC 5280) and other relevant PKI requirements (e.g. CA/Browser Forum Baseline Requirements).

It can be used as a command line tool or as a library integrated into CA software.

Requirements

ZLint requires Go 1.16.x or newer be installed. The command line setup instructions assume the go command is in your $PATH.

Lint Sources

Historically ZLint was focused on only RFC 5280 and v1.4.8 of the CA/Browser Forum baseline requirements. A detailed list of the original BR coverage can be found in this spreadsheet.

More recently ZLint has been restructured to make it easier to add lints based on other sources. While not complete, presently ZLint has lints sourced from:

By default ZLint will apply applicable lints from all sources but consumers may also customize which lints are used by including/exclduing specific sources.

Versioning and Releases

ZLint aims to follow semantic versioning. The addition of new lints will generally result in a MINOR version revision. Since downstream projects depend on lint results and names for policy decisions changes of this nature will result in MAJOR version revision.

Where possible we will try to make available a release candidate (RC) a week before finalizing a production ready release tag. We encourage users to test RC releases to provide feedback early enough for bugs to be addressed before the final release is made available.

Please subscribe to the ZLint Announcements mailing list to receive notifications of new releases/release candidates. This low-volumne announcements mailing list is only used for new ZLint releases and major project announcements, not questions/support/bug reports.

Command Line Usage

ZLint can be used on the command-line through a simple bundled executable ZLint as well as through ZCertificate, a more full-fledged command-line certificate parser that links against ZLint.

Example ZLint CLI usage:

go get github.com/zmap/zlint/v3/cmd/zlint
echo "Lint mycert.pem with all applicable lints"
zlint mycert.pem

echo "Lint mycert.pem with just the two named lints"
zlint -includeNames=e_mp_exponent_cannot_be_one,e_mp_modulus_must_be_divisible_by_8 mycert.pem

echo "List available lint sources"
zlint -list-lints-source

echo "Lint mycert.pem with all of the lints except for ETSI ESI sourced lints"
zlint -excludeSources=ETSI_ESI mycert.pem

echo "Receive a copy of the full (default) configuration for all configurable lints"
zlint -exampleConfig

echo "Lint mycert.pem using a custom configuration for any configurable lints"
zlint -config configFile.toml mycert.pem

echo "List available lint profiles. A profile is a pre-defined collection of lints."
zlint -list-profiles

See zlint -h for all available command line options.

Linting Certificate Revocation Lists

No special flags are necessary when running lints against a certificate revocation list. However, the CRL in question MUST be a PEM encoded ASN.1 with the X509 CRL PEM armor.

The following is an example of a parseable CRL PEM file.

-----BEGIN X509 CRL-----
MIIBnjCBhwIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDEw1BbWlyIHdhcyBI
ZXJlFw0yMzAzMTMwNTUyNTVaFw0yMzAzMTQwNTUyNTVaoDswOTArBgNVHSMEJDAi
gCAywvCJz28KsE/6Wf9E1nuiihBFWlUyq7X/RDgn5SllIDAKBgNVHRQEAwIBATAN
BgkqhkiG9w0BAQsFAAOCAQEAakioBhLs31svWHGmolDhUg6O1daN6zXSAz/avgzl
38aTKfRSNQ+vM7qgrvCoRojnamziJgXe1hz+/dc8H0/+WEBwVgp1rBzr8f25dSZC
lXBHT1cNI5RL+wU0pFMouUiwWqwUg8o9iGYkqvhuko4AQIcpAoBuf0OggjCuj48r
FX7UN7Kz4pc/4ufengKGkf7EeEQffY3zlS0DAtWv+exoQ6Dt+otDr0PbINJZg+46
TJ/+0w6RsLGoe4Sh/PYPfaCngMyezENUgJgR1+vF6hbVUweeOB+4nFRNxvHMup0G
GEA4yfzQtHWL8rizWUCyuqXEMPZLzyJT0rv5cLgoOvs+8Q==
-----END X509 CRL-----

Library Usage

ZLint can also be used as a library. To lint a certificate with all applicable lints is as simple as using zlint.LintCertificate with a parsed certificate:

import (
	"github.com/zmap/zcrypto/x509"
	"github.com/zmap/zlint/v3"
)

var certDER []byte = ...
parsed, err := x509.ParseCertificate(certDER)
if err != nil {
	// If x509.ParseCertificate fails, the certificate is too broken to lint.
	// This should be treated as ZLint rejecting the certificate
	log.Fatal("unable to parse certificate:", err)
}
zlintResultSet := zlint.LintCertificate(parsed)

To lint a certificate with a subset of lints (e.g. based on lint source, or name) filter the global lint registry and use it with zlint.LintCertificateEx:

import (
	"github.com/zmap/zcrypto/x509"
	"github.com/zmap/zlint/v3"
	"github.com/zmap/zlint/v3/lint"
)

var certDER []byte = ...
parsed, err := x509.ParseCertificate(certDER)
if err != nil {
	// If x509.ParseCertificate fails, the certificate is too broken to lint.
	// This should be treated as ZLint rejecting the certificate
	log.Fatal("unable to parse certificate:", err)
}

registry, err := lint.GlobalRegistry().Filter(lint.FilterOptions{
  ExcludeSources: []lint.LintSource{lint.EtsiEsi},
})
if err != nil {
	log.Fatal("lint registry filter failed to apply:", err)
}
zlintResultSet := zlint.LintCertificateEx(parsed, registry)

To lint a certificate in the presence of a particular configuration file, you must first construct the configuration and then make a call to SetConfiguration in the Registry interface.

A Configuration may be constructed using any of the following functions:

  • lint.NewConfig(r io.Reader) (Configuration, error)
  • lint.NewConfigFromFile(path string) (Configuration, error)
  • lint.NewConfigFromString(config string) (Configuration, error)

The contents of the input to all three constructors must be a valid TOML document.

import (
	"github.com/zmap/zcrypto/x509"
	"github.com/zmap/zlint/v3"
)

var certDER []byte = ...
parsed, err := x509.ParseCertificate(certDER)
if err != nil {
	// If x509.ParseCertificate fails, the certificate is too broken to lint.
	// This should be treated as ZLint rejecting the certificate
	log.Fatal("unable to parse certificate:", err)
}
configuration, err := lint.NewConfigFromString(`
        [some_configurable_lint]
        IsWebPki = true
        NumIterations = 42
        
        [some_configurable_lint.AnySubMapping]
        something = "else"
        anything = "at all"
`)
if err != nil {
	log.Fatal("unable to parse configuration:", err)
}
lint.GlobalRegistry().SetConfigutration(configuration)
zlintResultSet := zlint.LintCertificate(parsed)

See the zlint command's source code for an example.

Extending ZLint

For information on extending ZLint with new lints see CONTRIBUTING.md

Zlint Users/Integrations

Pre-issuance linting is strongly recommended by the Mozilla root program. Here are some projects/CAs known to integrate with ZLint in some fashion:

Please submit a pull request to update the README if you are aware of another CA/project that uses zlint.

License and Copyright

ZMap Copyright 2021 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.

More Repositories

1

zmap

ZMap is a fast single packet network scanner designed for Internet-wide network surveys.
C
5,453
star
2

zgrab2

Fast Go Application Scanner
Go
1,726
star
3

zdns

Fast DNS Lookup Library and CLI Tool
Go
920
star
4

zgrab

**DEPRECATED** This project has been replaced by https://github.com/zmap/zgrab2
Go
748
star
5

zcrypto

Liberal Go TLS + X.509 Library for Research
Go
134
star
6

celerybeat-mongo

A Celery Beat Scheduler that uses MongoDB to store both schedule definitions and status information
Python
126
star
7

go-iptree

GoLang IP Radix Tree
Go
113
star
8

ztag

Tagging and annotation framework for scan data
Python
101
star
9

zannotate

Utility for annotating Internet datasets with contextual metadata (e.g., origin AS, MaxMind GeoIP2, reverse DNS, and WHOIS)
Go
94
star
10

zbrowse

Headless Chrome-based browser
JavaScript
60
star
11

zcertificate

Command line utility for parsing certificates
Go
59
star
12

zschema

A schema language for JSON documents that allows validation and compilation into various database engines
Python
40
star
13

pybulkwhois

Python framework for manipulating bulk WHOIS data from RIRs
Python
19
star
14

iptree

A space-optimized binary tree for storing IP addresses
C++
13
star
15

constants

Repository of constants used in TLS and X509 parsing
12
star
16

rootfetch

Python egg for fetching common certificate root stores
Python
9
star
17

cachehash

An efficient C hash-table like data structure with static size that evicts LRU object on insertion
C
9
star
18

zson

A python library that allows easily encoding and decoding objects into JSON
Python
7
star
19

zflags

go command line option parser http://godoc.org/github.com/jessevdk/…
Go
6
star
20

website

ZMap's Public Website
HTML
5
star
21

zdb

[deprecated] Backend database for Internet-wide scans
C++
4
star
22

zlint-test-corpus

Test certificates for ZLint CI tests
2
star
23

homebrew-formula

Dependencies not included in standard Homebrew taps
Ruby
1
star