From 29a7f96d18c4621ccfdc90add992dd1ddf997526 Mon Sep 17 00:00:00 2001 From: Daniel McCarney Date: Mon, 11 Feb 2019 13:47:29 -0500 Subject: [PATCH] Godeps: Bump zlint to bb32118 (#4045) The vendored copy of `github.com/zmap/zlint` is updated to bb32118 - the tip of master at the time of writing. This pulls in an updated `gtld_map.go` and a few new lints. Unit tests are confirmed to pass: ``` $ go test ./... ok github.com/zmap/zlint (cached) ? github.com/zmap/zlint/cmd/zlint [no test files] ? github.com/zmap/zlint/cmd/zlint-gtld-update [no test files] ok github.com/zmap/zlint/lints (cached) ok github.com/zmap/zlint/util (cached) ``` --- Godeps/Godeps.json | 6 +- vendor/github.com/zmap/zlint/.travis.yml | 2 +- ..._ext_cert_policy_explicit_text_too_long.go | 13 +++- .../lints/lint_san_dns_name_duplicate.go | 57 +++++++++++++++ .../lint_subject_common_name_not_from_san.go | 4 +- ...int_subject_dn_not_printable_characters.go | 73 +++++++++++++++++++ vendor/github.com/zmap/zlint/template | 9 +-- .../github.com/zmap/zlint/util/encodings.go | 19 +++++ vendor/github.com/zmap/zlint/util/gtld.go | 2 +- vendor/github.com/zmap/zlint/util/gtld_map.go | 16 +++- vendor/github.com/zmap/zlint/util/ip.go | 20 ++--- 11 files changed, 196 insertions(+), 25 deletions(-) create mode 100644 vendor/github.com/zmap/zlint/lints/lint_san_dns_name_duplicate.go create mode 100644 vendor/github.com/zmap/zlint/lints/lint_subject_dn_not_printable_characters.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 2e66365c3..579ca8975 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -350,15 +350,15 @@ }, { "ImportPath": "github.com/zmap/zlint", - "Rev": "34b7be2e59081f4bbe6970785e021e6bf0741f2a" + "Rev": "bb32118ad3ab29c4d9a697aa1d8faa71c07e7500" }, { "ImportPath": "github.com/zmap/zlint/lints", - "Rev": "34b7be2e59081f4bbe6970785e021e6bf0741f2a" + "Rev": "bb32118ad3ab29c4d9a697aa1d8faa71c07e7500" }, { "ImportPath": "github.com/zmap/zlint/util", - "Rev": "34b7be2e59081f4bbe6970785e021e6bf0741f2a" + "Rev": "bb32118ad3ab29c4d9a697aa1d8faa71c07e7500" }, { "ImportPath": "golang.org/x/crypto/cryptobyte", diff --git a/vendor/github.com/zmap/zlint/.travis.yml b/vendor/github.com/zmap/zlint/.travis.yml index ceb65b6fd..1c4a56fbc 100644 --- a/vendor/github.com/zmap/zlint/.travis.yml +++ b/vendor/github.com/zmap/zlint/.travis.yml @@ -1,7 +1,7 @@ language: go dist: trusty go: -- 1.9 +- "1.11" before_install: - go get ./... - go get -t ./... diff --git a/vendor/github.com/zmap/zlint/lints/lint_ext_cert_policy_explicit_text_too_long.go b/vendor/github.com/zmap/zlint/lints/lint_ext_cert_policy_explicit_text_too_long.go index a6a30d9ec..6d7879e7f 100644 --- a/vendor/github.com/zmap/zlint/lints/lint_ext_cert_policy_explicit_text_too_long.go +++ b/vendor/github.com/zmap/zlint/lints/lint_ext_cert_policy_explicit_text_too_long.go @@ -34,6 +34,8 @@ import ( type explicitTextTooLong struct{} +const tagBMPString int = 30 + func (l *explicitTextTooLong) Initialize() error { return nil } @@ -50,7 +52,16 @@ func (l *explicitTextTooLong) CheckApplies(c *x509.Certificate) bool { func (l *explicitTextTooLong) Execute(c *x509.Certificate) *LintResult { for _, firstLvl := range c.ExplicitTexts { for _, text := range firstLvl { - if len(text.Bytes) > 200 { + var runes string + // If the field is a BMPString, we need to parse the bytes out into + // UTF-16-BE runes in order to check their length accurately + // The `Bytes` attribute here is the raw representation of the userNotice + if text.Tag == tagBMPString { + runes, _ = util.ParseBMPString(text.Bytes) + } else { + runes = string(text.Bytes) + } + if len(runes) > 200 { return &LintResult{Status: Error} } } diff --git a/vendor/github.com/zmap/zlint/lints/lint_san_dns_name_duplicate.go b/vendor/github.com/zmap/zlint/lints/lint_san_dns_name_duplicate.go new file mode 100644 index 000000000..40577c9a7 --- /dev/null +++ b/vendor/github.com/zmap/zlint/lints/lint_san_dns_name_duplicate.go @@ -0,0 +1,57 @@ +/* + * ZLint Copyright 2017 Regents of the University of Michigan + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package lints + +import ( + "strings" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/util" +) + +type SANDNSDuplicate struct{} + +func (l *SANDNSDuplicate) Initialize() error { + return nil +} + +func (l *SANDNSDuplicate) CheckApplies(c *x509.Certificate) bool { + return util.IsExtInCert(c, util.SubjectAlternateNameOID) +} + +func (l *SANDNSDuplicate) Execute(c *x509.Certificate) *LintResult { + checkedDNSNames := map[string]struct{}{} + for _, dns := range c.DNSNames { + normalizedDNSName := strings.ToLower(dns) + if _, isPresent := checkedDNSNames[normalizedDNSName]; isPresent { + return &LintResult{Status: Notice} + } + + checkedDNSNames[normalizedDNSName] = struct{}{} + } + + return &LintResult{Status: Pass} +} + +func init() { + RegisterLint(&Lint{ + Name: "n_san_dns_name_duplicate", + Description: "SAN DNSName contains duplicate values", + Citation: "awslabs certlint", + Source: AWSLabs, + EffectiveDate: util.ZeroDate, + Lint: &SANDNSDuplicate{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/lints/lint_subject_common_name_not_from_san.go b/vendor/github.com/zmap/zlint/lints/lint_subject_common_name_not_from_san.go index 5bf3b0e36..106b51727 100644 --- a/vendor/github.com/zmap/zlint/lints/lint_subject_common_name_not_from_san.go +++ b/vendor/github.com/zmap/zlint/lints/lint_subject_common_name_not_from_san.go @@ -22,6 +22,8 @@ contained in the Certificate’s subjectAltName extension (see Section 7.1.4.2.1 ************************************************/ import ( + "strings" + "github.com/zmap/zcrypto/x509" "github.com/zmap/zlint/util" ) @@ -40,7 +42,7 @@ func (l *subjectCommonNameNotFromSAN) Execute(c *x509.Certificate) *LintResult { cn := c.Subject.CommonName for _, dn := range c.DNSNames { - if cn == dn { + if strings.EqualFold(cn, dn) { return &LintResult{Status: Pass} } } diff --git a/vendor/github.com/zmap/zlint/lints/lint_subject_dn_not_printable_characters.go b/vendor/github.com/zmap/zlint/lints/lint_subject_dn_not_printable_characters.go new file mode 100644 index 000000000..7d7b75afe --- /dev/null +++ b/vendor/github.com/zmap/zlint/lints/lint_subject_dn_not_printable_characters.go @@ -0,0 +1,73 @@ +/* + * ZLint Copyright 2017 Regents of the University of Michigan + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package lints + +import ( + "encoding/asn1" + "unicode/utf8" + + "github.com/zmap/zcrypto/x509" + "github.com/zmap/zlint/util" +) + +type subjectDNNotPrintableCharacters struct{} + +func (l *subjectDNNotPrintableCharacters) Initialize() error { + return nil +} + +func (l *subjectDNNotPrintableCharacters) CheckApplies(c *x509.Certificate) bool { + return true +} + +func (l *subjectDNNotPrintableCharacters) Execute(c *x509.Certificate) *LintResult { + rdnSequence := util.RawRDNSequence{} + rest, err := asn1.Unmarshal(c.RawSubject, &rdnSequence) + if err != nil { + return &LintResult{Status: Fatal} + } + if len(rest) > 0 { + return &LintResult{Status: Fatal} + } + + for _, attrTypeAndValueSet := range rdnSequence { + for _, attrTypeAndValue := range attrTypeAndValueSet { + bytes := attrTypeAndValue.Value.Bytes + for len(bytes) > 0 { + r, size := utf8.DecodeRune(bytes) + if r < 0x20 { + return &LintResult{Status: Error} + } + if r >= 0x7F && r <= 0x9F { + return &LintResult{Status: Error} + } + bytes = bytes[size:] + } + } + } + + return &LintResult{Status: Pass} +} + +func init() { + RegisterLint(&Lint{ + Name: "e_subject_dn_not_printable_characters", + Description: "X520 Subject fields MUST only contain printable control characters", + Citation: "RFC 5280: Appendix A", + Source: RFC5280, + EffectiveDate: util.ZeroDate, + Lint: &subjectDNNotPrintableCharacters{}, + }) +} diff --git a/vendor/github.com/zmap/zlint/template b/vendor/github.com/zmap/zlint/template index ff57a0c3a..0eac12c88 100644 --- a/vendor/github.com/zmap/zlint/template +++ b/vendor/github.com/zmap/zlint/template @@ -16,7 +16,6 @@ package lints import ( "github.com/zmap/zcrypto/x509" - "github.com/zmap/zlint/util" ) type SUBST struct{} @@ -29,17 +28,17 @@ func (l *SUBST) CheckApplies(c *x509.Certificate) bool { // Add conditions for application here } -func (l *SUBST) RunTest(c *x509.Certificate) (ResultStruct, error) { +func (l *SUBST) Execute(c *x509.Certificate) *LintResult { // Add actual lint here } func init() { - registerLint(&Lint{ + RegisterLint(&Lint{ Name: "SUBTEST", Description: "Fill this in...", Citation: "Fill this in...", - Source: UnknownLintSource, + Source: UnknownLintSource, EffectiveDate: "Change this...", - Test: &SUBST{}, + Lint: &SUBST{}, }) } diff --git a/vendor/github.com/zmap/zlint/util/encodings.go b/vendor/github.com/zmap/zlint/util/encodings.go index 3fe4e6ae8..92a30d261 100644 --- a/vendor/github.com/zmap/zlint/util/encodings.go +++ b/vendor/github.com/zmap/zlint/util/encodings.go @@ -17,9 +17,11 @@ package util import ( "bytes" "encoding/asn1" + "errors" "regexp" "strings" "unicode" + "unicode/utf16" "github.com/zmap/zcrypto/x509/pkix" ) @@ -115,3 +117,20 @@ var emptyASN1Sequence = []byte{0x30, 0x00} func IsEmptyASN1Sequence(input []byte) bool { return len(input) < 2 || bytes.Equal(input, emptyASN1Sequence) } + +// ParseBMPString returns a uint16 encoded string following the specification for a BMPString type +func ParseBMPString(bmpString []byte) (string, error) { + if len(bmpString)%2 != 0 { + return "", errors.New("odd-length BMP string") + } + // strip terminator if present + if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 { + bmpString = bmpString[:l-2] + } + s := make([]uint16, 0, len(bmpString)/2) + for len(bmpString) > 0 { + s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1])) + bmpString = bmpString[2:] + } + return string(utf16.Decode(s)), nil +} diff --git a/vendor/github.com/zmap/zlint/util/gtld.go b/vendor/github.com/zmap/zlint/util/gtld.go index b9e454d0a..cdaac95f8 100644 --- a/vendor/github.com/zmap/zlint/util/gtld.go +++ b/vendor/github.com/zmap/zlint/util/gtld.go @@ -71,7 +71,7 @@ func (p GTLDPeriod) Valid(when time.Time) error { // HasValidTLD checks that a domain ends in a valid TLD that was delegated in // the root DNS at the time specified. func HasValidTLD(domain string, when time.Time) bool { - labels := strings.Split(domain, ".") + labels := strings.Split(strings.ToLower(domain), ".") rightLabel := labels[len(labels)-1] // if the rightmost label is not present in the tldMap, it isn't valid and // never was. diff --git a/vendor/github.com/zmap/zlint/util/gtld_map.go b/vendor/github.com/zmap/zlint/util/gtld_map.go index ddc24d7b6..93c908eab 100644 --- a/vendor/github.com/zmap/zlint/util/gtld_map.go +++ b/vendor/github.com/zmap/zlint/util/gtld_map.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// This file was generated by zlint-gtld-update at 2018-09-21 11:44 +// This file was generated by zlint-gtld-update at 2019-02-04 10:01 /* * ZLint Copyright 2018 Regents of the University of Michigan @@ -5876,7 +5876,7 @@ var tldMap = map[string]GTLDPeriod{ "spiegel": { GTLD: "spiegel", DelegationDate: "2014-07-18", - RemovalDate: "", + RemovalDate: "2018-12-15", }, "sport": { GTLD: "sport", @@ -5908,6 +5908,11 @@ var tldMap = map[string]GTLDPeriod{ DelegationDate: "2016-07-28", RemovalDate: "", }, + "ss": { + GTLD: "ss", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, "st": { GTLD: "st", DelegationDate: "1985-01-01", @@ -5946,7 +5951,7 @@ var tldMap = map[string]GTLDPeriod{ "statoil": { GTLD: "statoil", DelegationDate: "2015-06-19", - RemovalDate: "", + RemovalDate: "2018-10-03", }, "stc": { GTLD: "stc", @@ -7388,6 +7393,11 @@ var tldMap = map[string]GTLDPeriod{ DelegationDate: "2014-02-18", RemovalDate: "", }, + "xn--mgbah1a3hjkrd": { + GTLD: "xn--mgbah1a3hjkrd", + DelegationDate: "1985-01-01", + RemovalDate: "", + }, "xn--mgbai9azgqp6j": { GTLD: "xn--mgbai9azgqp6j", DelegationDate: "1985-01-01", diff --git a/vendor/github.com/zmap/zlint/util/ip.go b/vendor/github.com/zmap/zlint/util/ip.go index dd58de2c0..153dc0fdc 100644 --- a/vendor/github.com/zmap/zlint/util/ip.go +++ b/vendor/github.com/zmap/zlint/util/ip.go @@ -75,16 +75,16 @@ func IsIANAReserved(ip net.IP) bool { func init() { var networks = map[subnetCategory][]string{ - privateUse: {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, - sharedAddressSpace: {"100.64.0.0/10"}, - benchmarking: {"198.18.0.0/15", "2001:2::/48"}, - documentation: {"192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24", "2001:db8::/32"}, - reserved: {"240.0.0.0/4", "0400::/6", "0800::/5", "1000::/4", "4000::/3", "6000::/3", "8000::/3", "a000::/3", "c000::/3", "e000::/4", "f000::/5", "f800::/6", "fe00::/9"}, // https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml - protocolAssignment: {"192.0.0.0/24", "2001::/23"}, // 192.0.0.0/24 contains 192.0.0.0/29 - IPv4 Service Continuity Prefix - as112: {"192.31.196.0/24", "192.175.48.0/24", "2001:4:112::/48", "2620:4f:8000::/48"}, - amt: {"192.52.193.0/24", "2001:3::/32"}, - orchidV2: {"2001:20::/28"}, - lisp: {"2001:5::/32"}, // TODO: this could expire at 2019-09. Please check https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml for updates + privateUse: {"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}, + sharedAddressSpace: {"100.64.0.0/10"}, + benchmarking: {"198.18.0.0/15", "2001:2::/48"}, + documentation: {"192.0.2.0/24", "198.51.100.0/24", "203.0.113.0/24", "2001:db8::/32"}, + reserved: {"240.0.0.0/4", "0400::/6", "0800::/5", "1000::/4", "4000::/3", "6000::/3", "8000::/3", "a000::/3", "c000::/3", "e000::/4", "f000::/5", "f800::/6", "fe00::/9"}, // https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml + protocolAssignment: {"192.0.0.0/24", "2001::/23"}, // 192.0.0.0/24 contains 192.0.0.0/29 - IPv4 Service Continuity Prefix + as112: {"192.31.196.0/24", "192.175.48.0/24", "2001:4:112::/48", "2620:4f:8000::/48"}, + amt: {"192.52.193.0/24", "2001:3::/32"}, + orchidV2: {"2001:20::/28"}, + lisp: {"2001:5::/32"}, // TODO: this could expire at 2019-09. Please check https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml for updates thisHostOnThisNetwork: {"0.0.0.0/8"}, translatableAddress4to6: {"2002::/16"}, translatableAddress6to4: {"64:ff9b::/96", "64:ff9b:1::/48"},