{"id":13582378,"url":"https://github.com/zmap/zlint","last_synced_at":"2025-05-14T23:07:41.627Z","repository":{"id":37549724,"uuid":"75216133","full_name":"zmap/zlint","owner":"zmap","description":"X.509 Certificate Linter focused on Web PKI standards and requirements.","archived":false,"fork":false,"pushed_at":"2025-05-04T14:07:45.000Z","size":31177,"stargazers_count":393,"open_issues_count":86,"forks_count":116,"subscribers_count":54,"default_branch":"master","last_synced_at":"2025-05-04T14:36:10.893Z","etag":null,"topics":["linter","x509"],"latest_commit_sha":null,"homepage":"https://zmap.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zmap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-11-30T18:42:16.000Z","updated_at":"2025-05-04T14:07:48.000Z","dependencies_parsed_at":"2023-01-31T15:45:47.445Z","dependency_job_id":"7a160734-2ceb-4f96-91c9-afe3afc1399b","html_url":"https://github.com/zmap/zlint","commit_stats":{"total_commits":451,"total_committers":57,"mean_commits":7.912280701754386,"dds":0.8603104212860311,"last_synced_commit":"997ad5143216f4a3f461545f277be7e20bdcb557"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmap%2Fzlint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmap%2Fzlint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmap%2Fzlint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zmap%2Fzlint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zmap","download_url":"https://codeload.github.com/zmap/zlint/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243362,"owners_count":22038046,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linter","x509"],"created_at":"2024-08-01T15:02:39.547Z","updated_at":"2025-05-14T23:07:36.616Z","avatar_url":"https://github.com/zmap.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"ZLint\n=====\n\n[![CI Status](https://github.com/zmap/zlint/workflows/Go/badge.svg)](https://github.com/zmap/zlint/actions?query=workflow%3AGo)\n[![Integration Tests](https://github.com/zmap/zlint/workflows/integration-test/badge.svg)](https://github.com/zmap/zlint/actions?query=workflow%3Aintegration-test)\n[![Lint Status](https://github.com/zmap/zlint/workflows/golangci-lint/badge.svg)](https://github.com/zmap/zlint/actions?query=workflow%3Agolangci-lint)\n[![Go Report Card](https://goreportcard.com/badge/github.com/zmap/zlint)](https://goreportcard.com/report/github.com/zmap/zlint)\n\nZLint is a X.509 certificate linter written in Go that checks for consistency\nwith standards (e.g. [RFC 5280]) and other relevant PKI requirements (e.g.\n[CA/Browser Forum Baseline Requirements][BR v1.4.8]).\n\nIt can be used as a command line tool or as a library integrated into CA\nsoftware.\n\n[RFC 5280]: https://www.ietf.org/rfc/rfc5280.txt\n[BR v1.4.8]: https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.4.8.pdf\n\nRequirements\n------------\n\nZLint requires [Go 1.16.x or newer](https://golang.org/doc/install) be\ninstalled. The command line setup instructions assume the `go` command is in\nyour `$PATH`.\n\nLint Sources\n------------\n\nHistorically ZLint was focused on only [RFC 5280] and [v1.4.8][BR v1.4.8] of the\n[CA/Browser Forum baseline requirements][BRs]. A detailed list of the original\nBR coverage can be found [in this spreadsheet][Coverage Spreadsheet].\n\nMore recently ZLint has been restructured to make it easier to add lints based\non other sources. While not complete, presently ZLint has lints sourced from:\n\n* [CA/Browser Forum EV SSL Certificate Guidelines][CABF EV]\n* [ETSI ESI]\n* [Mozilla's PKI policy][MozPolicy]\n* [Apple's CT policy][AppleCT]\n* Various RFCs (e.g. [RFC 6818], [RFC 4055], [RFC 8399])\n\nBy default ZLint will apply applicable lints from all sources but consumers may\nalso customize which lints are used by including/exclduing specific sources.\n\n[BRs]: https://cabforum.org/baseline-requirements-documents/\n[Coverage Spreadsheet]: https://docs.google.com/spreadsheets/d/1ywp0op9mkTaggigpdF2YMTubepowJ50KQBhc_b00e-Y\n[CABF EV]: https://cabforum.org/extended-validation/\n[MozPolicy]: https://github.com/mozilla/pkipolicy\n[ETSI ESI]: https://www.etsi.org/technologies/digital-signature\n[AppleCT]: https://support.apple.com/en-us/HT205280\n[RFC 6818]: https://www.ietf.org/rfc/rfc6818.txt\n[RFC 4055]: https://www.ietf.org/rfc/rfc4055.txt\n[RFC 8399]: https://www.ietf.org/rfc/rfc8399.txt\n\n\nVersioning and Releases\n-----------------------\n\nZLint aims to follow [semantic versioning](https://semver.org/). The addition of\nnew lints will generally result in a MINOR version revision. Since downstream\nprojects depend on lint results and names for policy decisions changes of this\nnature will result in MAJOR version revision.\n\nWhere possible we will try to make available a release candidate (RC) a week\nbefore finalizing a production ready release tag. We encourage users to test RC\nreleases to provide feedback early enough for bugs to be addressed before the\nfinal release is made available.\n\nPlease subscribe to the [ZLint Announcements][zlint-announce] mailing list to\nreceive notifications of new releases/release candidates. This low-volumne\nannouncements mailing list is only used for new ZLint releases and major\nproject announcements, not questions/support/bug reports.\n\n[zlint-announce]:  https://groups.google.com/forum/#!forum/zlint-announcements\n\n\nCommand Line Usage\n------------------\n\nZLint can be used on the command-line through a simple bundled executable\n_ZLint_ as well as through\n[ZCertificate](https://github.com/zmap/zcertificate), a more full-fledged\ncommand-line certificate parser that links against ZLint.\n\nExample ZLint CLI usage:\n\n\tgo get github.com/zmap/zlint/v3/cmd/zlint\n\techo \"Lint mycert.pem with all applicable lints\"\n\tzlint mycert.pem\n\n\techo \"Lint mycert.pem with just the two named lints\"\n\tzlint -includeNames=e_mp_exponent_cannot_be_one,e_mp_modulus_must_be_divisible_by_8 mycert.pem\n\n\techo \"List available lint sources\"\n\tzlint -list-lints-source\n\n\techo \"Lint mycert.pem with all of the lints except for ETSI ESI sourced lints\"\n\tzlint -excludeSources=ETSI_ESI mycert.pem\n\n\techo \"Receive a copy of the full (default) configuration for all configurable lints\"\n\tzlint -exampleConfig\n\n\techo \"Lint mycert.pem using a custom configuration for any configurable lints\"\n\tzlint -config configFile.toml mycert.pem\n\n\techo \"List available lint profiles. A profile is a pre-defined collection of lints.\"\n\tzlint -list-profiles\n\nSee `zlint -h` for all available command line options.\n\n### Linting Certificate Revocation Lists\nNo 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.\n\nThe following is an example of a parseable CRL PEM file.\n```\n-----BEGIN X509 CRL-----\nMIIBnjCBhwIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDEw1BbWlyIHdhcyBI\nZXJlFw0yMzAzMTMwNTUyNTVaFw0yMzAzMTQwNTUyNTVaoDswOTArBgNVHSMEJDAi\ngCAywvCJz28KsE/6Wf9E1nuiihBFWlUyq7X/RDgn5SllIDAKBgNVHRQEAwIBATAN\nBgkqhkiG9w0BAQsFAAOCAQEAakioBhLs31svWHGmolDhUg6O1daN6zXSAz/avgzl\n38aTKfRSNQ+vM7qgrvCoRojnamziJgXe1hz+/dc8H0/+WEBwVgp1rBzr8f25dSZC\nlXBHT1cNI5RL+wU0pFMouUiwWqwUg8o9iGYkqvhuko4AQIcpAoBuf0OggjCuj48r\nFX7UN7Kz4pc/4ufengKGkf7EeEQffY3zlS0DAtWv+exoQ6Dt+otDr0PbINJZg+46\nTJ/+0w6RsLGoe4Sh/PYPfaCngMyezENUgJgR1+vF6hbVUweeOB+4nFRNxvHMup0G\nGEA4yfzQtHWL8rizWUCyuqXEMPZLzyJT0rv5cLgoOvs+8Q==\n-----END X509 CRL-----\n```\n\nLibrary Usage\n-------------\n\nZLint can also be used as a library. To lint a certificate with all applicable\nlints is as simple as using `zlint.LintCertificate` with a parsed certificate:\n\n```go\nimport (\n\t\"github.com/zmap/zcrypto/x509\"\n\t\"github.com/zmap/zlint/v3\"\n)\n\nvar certDER []byte = ...\nparsed, err := x509.ParseCertificate(certDER)\nif err != nil {\n\t// If x509.ParseCertificate fails, the certificate is too broken to lint.\n\t// This should be treated as ZLint rejecting the certificate\n\tlog.Fatal(\"unable to parse certificate:\", err)\n}\nzlintResultSet := zlint.LintCertificate(parsed)\n```\n\nTo lint a certificate with a subset of lints (e.g. based on lint source, or\nname) filter the global lint registry and use it with `zlint.LintCertificateEx`:\n\n```go\nimport (\n\t\"github.com/zmap/zcrypto/x509\"\n\t\"github.com/zmap/zlint/v3\"\n\t\"github.com/zmap/zlint/v3/lint\"\n)\n\nvar certDER []byte = ...\nparsed, err := x509.ParseCertificate(certDER)\nif err != nil {\n\t// If x509.ParseCertificate fails, the certificate is too broken to lint.\n\t// This should be treated as ZLint rejecting the certificate\n\tlog.Fatal(\"unable to parse certificate:\", err)\n}\n\nregistry, err := lint.GlobalRegistry().Filter(lint.FilterOptions{\n  ExcludeSources: []lint.LintSource{lint.EtsiEsi},\n})\nif err != nil {\n\tlog.Fatal(\"lint registry filter failed to apply:\", err)\n}\nzlintResultSet := zlint.LintCertificateEx(parsed, registry)\n```\n\nTo 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.\n\nA `Configuration` may be constructed using any of the following functions:\n\n* `lint.NewConfig(r io.Reader) (Configuration, error)`\n* `lint.NewConfigFromFile(path string) (Configuration, error)`\n* `lint.NewConfigFromString(config string) (Configuration, error)`\n\nThe contents of the input to all three constructors must be a valid TOML document.\n\n```go\nimport (\n\t\"github.com/zmap/zcrypto/x509\"\n\t\"github.com/zmap/zlint/v3\"\n)\n\nvar certDER []byte = ...\nparsed, err := x509.ParseCertificate(certDER)\nif err != nil {\n\t// If x509.ParseCertificate fails, the certificate is too broken to lint.\n\t// This should be treated as ZLint rejecting the certificate\n\tlog.Fatal(\"unable to parse certificate:\", err)\n}\nconfiguration, err := lint.NewConfigFromString(`\n        [some_configurable_lint]\n        IsWebPki = true\n        NumIterations = 42\n        \n        [some_configurable_lint.AnySubMapping]\n        something = \"else\"\n        anything = \"at all\"\n`)\nif err != nil {\n\tlog.Fatal(\"unable to parse configuration:\", err)\n}\nlint.GlobalRegistry().SetConfigutration(configuration)\nzlintResultSet := zlint.LintCertificate(parsed)\n```\n\nSee [the `zlint` command][zlint cmd]'s source code for an example.\n\n[zlint cmd]: https://github.com/zmap/zlint/blob/master/v3/cmd/zlint/main.go\n\n\nExtending ZLint\n----------------\n\nFor information on extending ZLint with new lints see [CONTRIBUTING.md]\n\n[CONTRIBUTING.md]: https://github.com/zmap/zlint/blob/master/CONTRIBUTING.md\n\n\nZlint Users/Integrations\n-------------------------\n\nPre-issuance linting is **strongly recommended** by the [Mozilla root\nprogram](https://wiki.allizom.org/CA/Required_or_Recommended_Practices#Pre-Issuance_Linting).\nHere are some projects/CAs known to integrate with ZLint in some fashion:\n\n* [Actalis](https://www.actalis.it/en/home.aspx)\n* [ANF AC](https://www.anf.es/)\n* [Camerfirma](https://www.camerfirma.com/)\n* [CFSSL](https://github.com/cloudflare/cfssl)\n* [Digicert](https://www.digicert.com/)\n* [EJBCA](https://download.primekey.com/docs/EJBCA-Enterprise/6_11_1/adminguide.html#Post%20Processing%20Validators%20(Pre-Certificate%20or%20Certificate%20Validation))\n* [Entrust](https://www.entrust.com/)\n* [Globalsign](https://www.globalsign.com/en/)\n* [GoDaddy](https://www.godaddy.com)\n* [Google Trust Services](https://pki.goog/)\n* [Government of Spain, FNMT](http://www.fnmt.es/)\n* [Izenpe](https://www.izenpe.eus/)\n* [Let's Encrypt](https://letsencrypt.org) and [Boulder](https://github.com/letsencrypt/boulder)\n* [Microsec](https://www.microsec.com/)\n* [Microsoft](https://www.microsoft.com)\n* [Nexus Certificate Manager](https://doc.nexusgroup.com/display/PUB/Smart+ID+Certificate+Manager)\n* [QuoVadis](https://www.quovadisglobal.com/)\n* [Sectigo](https://sectigo.com/), [crt.sh](https://crt.sh/), and [pkimetal](https://github.com/pkimetal/pkimetal)\n* [Siemens](https://siemens.com/pki)\n* [SSL.com](https://www.ssl.com/)\n* [PKI Insights](https://www.codegic.com/pki-insights-health-monitoring-for-microsoft-ca/)\n* [NETLOCK](https://www.netlock.hu/)\n* [Disig](https://eidas.disig.sk/en/)\n\nPlease submit a pull request to update the README if you are aware of\nanother CA/project that uses zlint.\n\n\nLicense and Copyright\n---------------------\n\nZMap Copyright 2024 Regents of the University of Michigan\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\nthis file except in compliance with the License. You may obtain a copy of the\nLicense at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed\nunder the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR\nCONDITIONS OF ANY KIND, either express or implied. See LICENSE for the specific\nlanguage governing permissions and limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmap%2Fzlint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzmap%2Fzlint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzmap%2Fzlint/lists"}