diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 552ac8d..cfc4974 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -14,5 +14,5 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@v2 with: - version: v1.39 + version: v1.47.2 only-new-issues: true \ No newline at end of file diff --git a/README.md b/README.md index 610b0b1..193217a 100644 --- a/README.md +++ b/README.md @@ -236,7 +236,7 @@ Advanced examples on how to combine JSON output with [jq](https://stedolan.githu ``` # Find certificates that have linter warnings -certigo dump --json $INPUT | jq '.certificates[] | select(.warnings != [])' +certigo dump --json $INPUT | jq '.certificates[] | select(.lints != [])' # Find certificates that are signed with SHA1-RSA certigo dump --json $INPUT | jq '.certificates[] | select(.signature_algorithm == "SHA1-RSA")' diff --git a/go.mod b/go.mod index 07ef7a5..e7903ec 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,8 @@ require ( github.com/mattn/go-colorable v0.1.12 github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 github.com/stretchr/testify v1.8.0 + github.com/zmap/zcrypto v0.0.0-20220402174210-599ec18ecbac + github.com/zmap/zlint/v3 v3.3.1 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/asn1-ber.v1 v1.0.0-20170511165959-379148ca0225 diff --git a/go.sum b/go.sum index 12a0ce8..8406af7 100644 --- a/go.sum +++ b/go.sum @@ -591,6 +591,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mreiferson/go-httpclient v0.0.0-20160630210159-31f0106b4474/go.mod h1:OQA4XLvDbMgS8P0CevmM4m9Q3Jq4phKUzcocxuGJ5m8= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-http-dialer v0.0.0-20161116154839-378f744fb2b8 h1:BhQQWYKJwXPtAhm12d4gQU4LKS9Yov22yOrDc2QA7ho= @@ -723,10 +724,12 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= @@ -800,6 +803,8 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.7 h1:aXiFAgRugfJ27UFDsGJ9DB2FvTC73hlVXFSqq5bo9eU= github.com/urfave/cli v1.22.7/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236 h1:vMJBP3PQViZsF6cOINtvyMC8ptpLsyJ4EwyFnzuWNxc= +github.com/weppos/publicsuffix-go v0.15.1-0.20220329081811-9a40b608a236/go.mod h1:HYux0V0Zi04bHNwOHy4cXJVz/TQjYonnF6aoYhj+3QE= github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= @@ -812,6 +817,12 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zmap/rc2 v0.0.0-20131011165748-24b9757f5521/go.mod h1:3YZ9o3WnatTIZhuOtot4IcUfzoKVjUHqu6WALIyI0nE= +github.com/zmap/zcertificate v0.0.0-20180516150559-0e3d58b1bac4/go.mod h1:5iU54tB79AMBcySS0R2XIyZBAVmeHranShAFELYx7is= +github.com/zmap/zcrypto v0.0.0-20220402174210-599ec18ecbac h1:+nr36qrZEH0RIYNjcUEnOrCUdcSG3om2ANaFA6iSVWA= +github.com/zmap/zcrypto v0.0.0-20220402174210-599ec18ecbac/go.mod h1:egdRkzUylATvPkWMpebZbXhv0FMEMJGX/ur0D3Csk2s= +github.com/zmap/zlint/v3 v3.3.1 h1:IrIY2Qd2Wr9ZHhdQ3mszehSydz+x6OROClztMEK+2bU= +github.com/zmap/zlint/v3 v3.3.1/go.mod h1:fPCW5acxhqw4HU1Vm0t9oFEPo1/uH9hI0sci/Z++hEI= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= @@ -926,6 +937,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= @@ -1163,6 +1175,7 @@ golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/lib/display.go b/lib/display.go index 3e7caa9..7c74e63 100644 --- a/lib/display.go +++ b/lib/display.go @@ -138,7 +138,7 @@ Signed Certificate Timestamp: Signature: {{.SignatureAlgorithm | highlightAlgorithm}} {{- end}} {{- if .Warnings}} -Warnings: +Lints: {{- range .Warnings}} {{. | redify}} {{- end}} @@ -165,7 +165,7 @@ URI Names: Email Addresses: {{wrapWith .Width "\n\t" (join ", " .EmailAddresses)}}{{end}} {{- if .Warnings}} -Warnings:{{range .Warnings}} +Lints:{{range .Warnings}} {{. | redify}}{{end}}{{end}}` // EncodeX509ToJSON encodes an X.509 certificate into a JSON string. diff --git a/lib/encoder.go b/lib/encoder.go index 4ab8d52..f1322cd 100644 --- a/lib/encoder.go +++ b/lib/encoder.go @@ -28,10 +28,18 @@ import ( "encoding/json" "encoding/pem" "fmt" + "log" "net" + "sort" "strconv" "strings" + "sync" "time" + + zx509 "github.com/zmap/zcrypto/x509" + + "github.com/zmap/zlint/v3" + "github.com/zmap/zlint/v3/lint" ) var keyUsages = []x509.KeyUsage{ @@ -202,7 +210,7 @@ type simpleCertificate struct { URINames []string `json:"uri_names,omitempty"` EmailAddresses []string `json:"email_addresses,omitempty"` SCTList []*simpleSCT `json:"sct_list,omitempty"` - Warnings []string `json:"warnings,omitempty"` + Warnings []string `json:"lints,omitempty"` PEM string `json:"pem,omitempty"` // Internal fields for text display. Set - to skip serialize. @@ -258,7 +266,7 @@ func createSimpleCertificate(name string, cert *x509.Certificate) simpleCertific out.URINames = append(out.URINames, uri.String()) } - out.Warnings = certWarnings(cert, out.URINames) + out.Warnings = certLints(cert, out.URINames) if cert.BasicConstraintsValid { out.BasicConstraints = &basicConstraints{ @@ -386,67 +394,36 @@ func decodeKey(publicKey interface{}) (string, int) { } } -// certWarnings prints a list of warnings to show common mistakes in certs. -func certWarnings(cert *x509.Certificate, uriNames []string) (warnings []string) { - if cert.SerialNumber.Sign() != 1 { - warnings = append(warnings, "Serial number in cert appears to be zero/negative") +var lintRegistryOnce sync.Once +var lintRegistry lint.Registry + +// certLints prints a list of lints to show common mistakes in certs. +func certLints(cert *x509.Certificate, uriNames []string) (lints []string) { + parsed, err := zx509.ParseCertificate(cert.Raw) + if err != nil { + lints = append(lints, fmt.Sprintf("Failed to parse certificate: %v", err)) + return } - if cert.SerialNumber.BitLen() > 160 { - warnings = append(warnings, "Serial number too long; should be 20 bytes or less") - } + lintRegistryOnce.Do(func() { + registry, err := lint.GlobalRegistry().Filter(lint.FilterOptions{ + IncludeSources: []lint.LintSource{lint.RFC5280, lint.Community}, + }) + if err != nil { + log.Fatalf("Failed to filter lint registry: %v", err) + } + lintRegistry = registry + }) - if cert.KeyUsage&x509.KeyUsageCertSign != 0 && !cert.IsCA { - warnings = append(warnings, "Key usage 'cert sign' is set, but is not a CA cert") - } - - if cert.KeyUsage&x509.KeyUsageCertSign == 0 && cert.IsCA { - warnings = append(warnings, "Certificate is a CA cert, but key usage 'cert sign' missing") - } - - if cert.Version < 2 { - warnings = append(warnings, fmt.Sprintf("Certificate is not in X509v3 format (version is %d)", cert.Version+1)) - } - - if len(cert.DNSNames) == 0 && len(cert.IPAddresses) == 0 && len(uriNames) == 0 && !cert.IsCA { - warnings = append(warnings, "Certificate doesn't have any valid DNS/URI names or IP addresses set") - } - - if len(cert.UnhandledCriticalExtensions) > 0 { - warnings = append(warnings, "Certificate has unhandled critical extensions") - } - - warnings = append(warnings, algWarnings(cert)...) - - return -} - -// algWarnings checks key sizes, signature algorithms. -func algWarnings(cert *x509.Certificate) (warnings []string) { - alg, size := decodeKey(cert.PublicKey) - if (alg == "RSA" || alg == "DSA") && size < 2048 { - warnings = append(warnings, fmt.Sprintf("Size of %s key should be at least 2048 bits", alg)) - } - if alg == "ECDSA" && size < 224 { - warnings = append(warnings, fmt.Sprintf("Size of %s key should be at least 224 bits", alg)) - } - - for _, alg := range badSignatureAlgorithms { - if cert.SignatureAlgorithm == alg { - warnings = append(warnings, fmt.Sprintf("Signed with %s, which is an outdated signature algorithm", algString(alg))) + zLints := zlint.LintCertificateEx(parsed, lintRegistry) + for lintName, lintResult := range zLints.Results { + if lintResult.Status >= lint.Warn { + lint := lintRegistry.ByName(lintName) + lints = append(lints, fmt.Sprintf("%s: [%s] %s", strings.ToUpper(lintResult.Status.String()), + lint.Source, lint.Description)) } } - - if alg == "RSA" { - key := cert.PublicKey.(*rsa.PublicKey) - if key.E < 3 { - warnings = append(warnings, "Public key exponent in RSA key is less than 3") - } - if key.N.Sign() != 1 { - warnings = append(warnings, "Public key modulus in RSA key appears to be zero/negative") - } - } - + sort.Strings(lints) return } diff --git a/tests/dump-cert-chain-to-text.t b/tests/dump-cert-chain-to-text.t index 6477bee..4ce36ef 100644 --- a/tests/dump-cert-chain-to-text.t +++ b/tests/dump-cert-chain-to-text.t @@ -226,4 +226,4 @@ Dump a live cert chain (squareup-chain.crt) Key Usage: \tCert Sign (esc) \tCRL Sign (esc) - + \ No newline at end of file diff --git a/tests/dump-leaf-to-json.t b/tests/dump-leaf-to-json.t index b4eeadb..f356c3d 100644 --- a/tests/dump-leaf-to-json.t +++ b/tests/dump-leaf-to-json.t @@ -27,4 +27,4 @@ Set up test data. Dump an example certificate (example-leaf.crt) to JSON output $ certigo dump --json example-leaf.crt - {"certificates":[{"serial":"15384458167827828543","not_before":"2016-06-10T22:14:11Z","not_after":"2023-04-15T22:14:11Z","signature_algorithm":"SHA256-RSA","is_self_signed":false,"subject":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"issuer":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"extended_key_usage":["Client Auth","Server Auth"],"dns_names":["localhost"],"ip_addresses":["127.0.0.1","::1"],"pem":"-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV\nBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMH\nZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoX\nDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxl\nLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3\nv34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69\nw8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhR\npPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84c\nzKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF\n5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2\nNp6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAs\nBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJ\nKoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sM\nlM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7\nLstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7d\nvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeL\nFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2Xl\niJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=\n-----END CERTIFICATE-----\n"}]} + {"certificates":[{"serial":"15384458167827828543","not_before":"2016-06-10T22:14:11Z","not_after":"2023-04-15T22:14:11Z","signature_algorithm":"SHA256-RSA","is_self_signed":false,"subject":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"issuer":{"common_name":"example-leaf","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"extended_key_usage":["Client Auth","Server Auth"],"dns_names":["localhost"],"ip_addresses":["127.0.0.1","::1"],"lints":["WARN: [RFC5280] Sub certificates SHOULD include Subject Key Identifier in end entity certs"],"pem":"-----BEGIN CERTIFICATE-----\nMIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV\nBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMH\nZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoX\nDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxl\nLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3\nv34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69\nw8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhR\npPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84c\nzKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF\n5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2\nNp6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAs\nBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJ\nKoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sM\nlM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7\nLstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7d\nvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeL\nFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2Xl\niJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=\n-----END CERTIFICATE-----\n"}]} diff --git a/tests/dump-leaf-to-not-verbose.t b/tests/dump-leaf-to-not-verbose.t index 06cefe8..ea50bf8 100644 --- a/tests/dump-leaf-to-not-verbose.t +++ b/tests/dump-leaf-to-not-verbose.t @@ -38,4 +38,6 @@ Dump an example certificate (example-leaf.crt) \tlocalhost (esc) IP Addresses: \t127.0.0.1, ::1 (esc) + Lints: + \tWARN: [RFC5280] Sub certificates SHOULD include Subject Key Identifier in end entity certs (esc) diff --git a/tests/dump-leaf-to-text.t b/tests/dump-leaf-to-text.t index a47a1cc..f49d6be 100644 --- a/tests/dump-leaf-to-text.t +++ b/tests/dump-leaf-to-text.t @@ -51,4 +51,6 @@ Dump an example certificate (example-leaf.crt) \tlocalhost (esc) IP Addresses: \t127.0.0.1, ::1 (esc) - + Lints: + \tWARN: [RFC5280] Sub certificates SHOULD include Subject Key Identifier in end entity certs (esc) + \ No newline at end of file diff --git a/tests/dump-name-constraints-to-text.t b/tests/dump-name-constraints-to-text.t index c6175d9..373658a 100644 --- a/tests/dump-name-constraints-to-text.t +++ b/tests/dump-name-constraints-to-text.t @@ -62,4 +62,7 @@ Dump an example certificate with name constraints (example-name-constraints.crt) \t10.10.0.0/16 (esc) Key Usage: \tCert Sign (esc) - + Lints: + \tERROR: [RFC5280] CAs MUST include a Subject Key Identifier in all CA certificates (esc) + \tERROR: [RFC5280] If it is included, conforming CAs MUST mark the name constraints extension as critical (esc) + \ No newline at end of file diff --git a/tests/dump-small-key-to-json.t b/tests/dump-small-key-to-json.t index 5441523..b156b23 100644 --- a/tests/dump-small-key-to-json.t +++ b/tests/dump-small-key-to-json.t @@ -20,4 +20,4 @@ Set up test data. Dump an example certificate (example-leaf.crt) to JSON output $ certigo dump --json example-small-key.crt - {"certificates":[{"serial":"14381893493177441266","not_before":"2016-06-10T22:14:12Z","not_after":"2023-04-15T22:14:12Z","signature_algorithm":"SHA256-RSA","is_self_signed":true,"subject":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"issuer":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"warnings":["Certificate is not in X509v3 format (version is 2)","Certificate doesn't have any valid DNS/URI names or IP addresses set","Size of RSA key should be at least 2048 bits"],"pem":"-----BEGIN CERTIFICATE-----\nMIICKzCCAZQCCQDHlr/u+lfb8jANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExEDAOBgNVBAoTB2NlcnRpZ28xEDAOBgNVBAsTB2V4YW1w\nbGUxGjAYBgNVBAMTEWV4YW1wbGUtc21hbGwta2V5MB4XDTE2MDYxMDIyMTQxMloX\nDTIzMDQxNTIyMTQxMlowWjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRowGAYDVQQDExFleGFtcGxl\nLXNtYWxsLWtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAlzyCIeP1T87k\n1rHVMtbaGXIWpK/VQuvuXwig+e3ct1ajA4bw0BAInXZ37FEGGSCUix0k/CjH2Nlt\nGREtwbahE0k5oTkVbA5XS4xkNs0M0poAFN5OiFKEAqZ014hqhvKnEUQ2oTe9SVOR\nWw49mLNg36AIEE2Fu2KQb/VT90cwwD0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQBV\nsJ4Vb2L1ywLVeAxNqY0PZqS7a8Q2GLhNr5V+3hOoWn7bwqQ7L06UJGSrcLOPZeIH\nIWM20aOFHSTWbocd4f+m6s3llyXwBBlK2BPZbWv0OeAHgjN9AVav4flAZ4oD2GxA\naJkGAXmR9QzZNJLai5mv3L/B/p/NxeU3UGfaySxVvw==\n-----END CERTIFICATE-----\n"}]} + {"certificates":[{"serial":"14381893493177441266","not_before":"2016-06-10T22:14:12Z","not_after":"2023-04-15T22:14:12Z","signature_algorithm":"SHA256-RSA","is_self_signed":true,"subject":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"issuer":{"common_name":"example-small-key","country":["US"],"organization":["certigo"],"organizational_unit":["example"],"province":["CA"]},"lints":["WARN: [RFC5280] Sub certificates SHOULD include Subject Key Identifier in end entity certs"],"pem":"-----BEGIN CERTIFICATE-----\nMIICKzCCAZQCCQDHlr/u+lfb8jANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExEDAOBgNVBAoTB2NlcnRpZ28xEDAOBgNVBAsTB2V4YW1w\nbGUxGjAYBgNVBAMTEWV4YW1wbGUtc21hbGwta2V5MB4XDTE2MDYxMDIyMTQxMloX\nDTIzMDQxNTIyMTQxMlowWjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYD\nVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRowGAYDVQQDExFleGFtcGxl\nLXNtYWxsLWtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAlzyCIeP1T87k\n1rHVMtbaGXIWpK/VQuvuXwig+e3ct1ajA4bw0BAInXZ37FEGGSCUix0k/CjH2Nlt\nGREtwbahE0k5oTkVbA5XS4xkNs0M0poAFN5OiFKEAqZ014hqhvKnEUQ2oTe9SVOR\nWw49mLNg36AIEE2Fu2KQb/VT90cwwD0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQBV\nsJ4Vb2L1ywLVeAxNqY0PZqS7a8Q2GLhNr5V+3hOoWn7bwqQ7L06UJGSrcLOPZeIH\nIWM20aOFHSTWbocd4f+m6s3llyXwBBlK2BPZbWv0OeAHgjN9AVav4flAZ4oD2GxA\naJkGAXmR9QzZNJLai5mv3L/B/p/NxeU3UGfaySxVvw==\n-----END CERTIFICATE-----\n"}]} diff --git a/tests/dump-small-key-to-text.t b/tests/dump-small-key-to-text.t index 05d95be..a5f26d5 100644 --- a/tests/dump-small-key-to-text.t +++ b/tests/dump-small-key-to-text.t @@ -37,8 +37,6 @@ Dump an example certificate (example-leaf.crt) \tOrganization: certigo (esc) \tOrganizational Unit: example (esc) \tCommonName: example-small-key (esc) - Warnings: - \tCertificate is not in X509v3 format (version is 2) (esc) - \tCertificate doesn't have any valid DNS/URI names or IP addresses set (esc) - \tSize of RSA key should be at least 2048 bits (esc) - + Lints: + \tWARN: [RFC5280] Sub certificates SHOULD include Subject Key Identifier in end entity certs (esc) + \ No newline at end of file diff --git a/tests/dump-spiffe-cert-to-text.t b/tests/dump-spiffe-cert-to-text.t index 2318740..1ee567a 100644 --- a/tests/dump-spiffe-cert-to-text.t +++ b/tests/dump-spiffe-cert-to-text.t @@ -58,4 +58,4 @@ Dump a SPIFFE example certificate (example-spiffe.crt) \tServer Auth (esc) URI Names: \tspiffe://dev.acme.com/path/service (esc) - + \ No newline at end of file