chore: update vendor

This commit is contained in:
Mikaël Cluseau
2018-07-03 18:25:07 +11:00
parent ecb3e9c868
commit f91ae88876
211 changed files with 18789 additions and 46221 deletions

View File

@ -12,9 +12,12 @@ import (
"net/url"
"reflect"
"runtime"
"strconv"
"strings"
"time"
"unicode/utf8"
"github.com/google/certificate-transparency-go/asn1"
)
type InvalidReason int
@ -174,19 +177,29 @@ var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificat
// VerifyOptions contains parameters for Certificate.Verify. It's a structure
// because other PKIX verification APIs have ended up needing many options.
type VerifyOptions struct {
DNSName string
Intermediates *CertPool
Roots *CertPool // if nil, the system roots are used
CurrentTime time.Time // if zero, the current time is used
DisableTimeChecks bool
// KeyUsage specifies which Extended Key Usage values are acceptable.
// An empty list means ExtKeyUsageServerAuth. Key usage is considered a
// constraint down the chain which mirrors Windows CryptoAPI behavior,
// but not the spec. To accept any key usage, include ExtKeyUsageAny.
DNSName string
Intermediates *CertPool
Roots *CertPool // if nil, the system roots are used
CurrentTime time.Time // if zero, the current time is used
// Options to disable various verification checks.
DisableTimeChecks bool
DisableCriticalExtensionChecks bool
DisableNameChecks bool
DisableEKUChecks bool
DisablePathLenChecks bool
DisableNameConstraintChecks bool
// KeyUsage specifies which Extended Key Usage values are acceptable. A leaf
// certificate is accepted if it contains any of the listed values. An empty
// list means ExtKeyUsageServerAuth. To accept any key usage, include
// ExtKeyUsageAny.
//
// Certificate chains are required to nest extended key usage values,
// irrespective of this value. This matches the Windows CryptoAPI behavior,
// but not the spec.
KeyUsages []ExtKeyUsage
// MaxConstraintComparisions is the maximum number of comparisons to
// perform when checking a given certificate's name constraints. If
// zero, a sensible default is used. This limit prevents pathalogical
// zero, a sensible default is used. This limit prevents pathological
// certificates from consuming excessive amounts of CPU time when
// validating.
MaxConstraintComparisions int
@ -544,11 +557,16 @@ func (c *Certificate) checkNameConstraints(count *int,
return nil
}
const (
checkingAgainstIssuerCert = iota
checkingAgainstLeafCert
)
// ekuPermittedBy returns true iff the given extended key usage is permitted by
// the given EKU from a certificate. Normally, this would be a simple
// comparison plus a special case for the “any” EKU. But, in order to support
// existing certificates, some exceptions are made.
func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool {
func ekuPermittedBy(eku, certEKU ExtKeyUsage, context int) bool {
if certEKU == ExtKeyUsageAny || eku == certEKU {
return true
}
@ -565,28 +583,33 @@ func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool {
eku = mapServerAuthEKUs(eku)
certEKU = mapServerAuthEKUs(certEKU)
if eku == certEKU ||
// ServerAuth in a CA permits ClientAuth in the leaf.
(eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) ||
if eku == certEKU {
return true
}
// If checking a requested EKU against the list in a leaf certificate there
// are fewer exceptions.
if context == checkingAgainstLeafCert {
return false
}
// ServerAuth in a CA permits ClientAuth in the leaf.
return (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) ||
// Any CA may issue an OCSP responder certificate.
eku == ExtKeyUsageOCSPSigning ||
// Code-signing CAs can use Microsoft's commercial and
// kernel-mode EKUs.
((eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning) {
return true
}
return false
(eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning
}
// isValid performs validity checks on c given that it is a candidate to append
// to the chain in currentChain.
func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
if len(c.UnhandledCriticalExtensions) > 0 {
if !opts.DisableCriticalExtensionChecks && len(c.UnhandledCriticalExtensions) > 0 {
return UnhandledCriticalExtension{ID: c.UnhandledCriticalExtensions[0]}
}
if len(currentChain) > 0 {
if !opts.DisableNameChecks && len(currentChain) > 0 {
child := currentChain[len(currentChain)-1]
if !bytes.Equal(child.RawIssuer, c.RawSubject) {
return CertificateInvalidError{c, NameMismatch, ""}
@ -617,7 +640,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
leaf = currentChain[0]
}
if (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() {
if !opts.DisableNameConstraintChecks && (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() {
sanExtension, ok := leaf.getSANExtension()
if !ok {
// This is the deprecated, legacy case of depending on
@ -633,8 +656,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
name := string(data)
mailbox, ok := parseRFC2821Mailbox(name)
if !ok {
// This certificate should not have parsed.
return errors.New("x509: internal error: rfc822Name SAN failed to parse")
return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
}
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
@ -646,6 +668,10 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
case nameTypeDNS:
name := string(data)
if _, ok := domainToReverseLabels(name); !ok {
return fmt.Errorf("x509: cannot parse dnsName %q", name)
}
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name,
func(parsedName, constraint interface{}) (bool, error) {
return matchDomainConstraint(parsedName.(string), constraint.(string))
@ -692,7 +718,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
}
}
checkEKUs := certType == intermediateCertificate
checkEKUs := !opts.DisableEKUChecks && certType == intermediateCertificate
// If no extended key usages are specified, then all are acceptable.
if checkEKUs && (len(c.ExtKeyUsage) == 0 && len(c.UnknownExtKeyUsage) == 0) {
@ -719,7 +745,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
for _, caEKU := range c.ExtKeyUsage {
comparisonCount++
if ekuPermittedBy(eku, caEKU) {
if ekuPermittedBy(eku, caEKU, checkingAgainstIssuerCert) {
continue NextEKU
}
}
@ -766,7 +792,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return CertificateInvalidError{c, NotAuthorizedToSign, ""}
}
if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
if !opts.DisablePathLenChecks && c.BasicConstraintsValid && c.MaxPathLen >= 0 {
numIntermediates := len(currentChain) - 1
if numIntermediates > c.MaxPathLen {
return CertificateInvalidError{c, TooManyIntermediates, ""}
@ -776,6 +802,18 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
return nil
}
// formatOID formats an ASN.1 OBJECT IDENTIFER in the common, dotted style.
func formatOID(oid asn1.ObjectIdentifier) string {
ret := ""
for i, v := range oid {
if i > 0 {
ret += "."
}
ret += strconv.Itoa(v)
}
return ret
}
// Verify attempts to verify c by building one or more chains from c to a
// certificate in opts.Roots, using certificates in opts.Intermediates if
// needed. If successful, it returns one or more chains where the first
@ -840,7 +878,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
}
// If no key usages are specified, then any are acceptable.
checkEKU := len(c.ExtKeyUsage) > 0
checkEKU := !opts.DisableEKUChecks && len(c.ExtKeyUsage) > 0
for _, eku := range requestedKeyUsages {
if eku == ExtKeyUsageAny {
@ -850,16 +888,33 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
}
if checkEKU {
foundMatch := false
NextUsage:
for _, eku := range requestedKeyUsages {
for _, leafEKU := range c.ExtKeyUsage {
if ekuPermittedBy(eku, leafEKU) {
continue NextUsage
if ekuPermittedBy(eku, leafEKU, checkingAgainstLeafCert) {
foundMatch = true
break NextUsage
}
}
}
oid, _ := oidFromExtKeyUsage(eku)
return nil, CertificateInvalidError{c, IncompatibleUsage, fmt.Sprintf("%#v", oid)}
if !foundMatch {
msg := "leaf contains the following, recognized EKUs: "
for i, leafEKU := range c.ExtKeyUsage {
oid, ok := oidFromExtKeyUsage(leafEKU)
if !ok {
continue
}
if i > 0 {
msg += ", "
}
msg += formatOID(oid)
}
return nil, CertificateInvalidError{c, IncompatibleUsage, msg}
}
}