Black Lives Matter. Support the Equal Justice Initiative.

Source file src/crypto/x509/verify.go

Documentation: crypto/x509

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package x509
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"fmt"
    11  	"net"
    12  	"net/url"
    13  	"reflect"
    14  	"runtime"
    15  	"strings"
    16  	"time"
    17  	"unicode/utf8"
    18  )
    19  
    20  type InvalidReason int
    21  
    22  const (
    23  	// NotAuthorizedToSign results when a certificate is signed by another
    24  	// which isn't marked as a CA certificate.
    25  	NotAuthorizedToSign InvalidReason = iota
    26  	// Expired results when a certificate has expired, based on the time
    27  	// given in the VerifyOptions.
    28  	Expired
    29  	// CANotAuthorizedForThisName results when an intermediate or root
    30  	// certificate has a name constraint which doesn't permit a DNS or
    31  	// other name (including IP address) in the leaf certificate.
    32  	CANotAuthorizedForThisName
    33  	// TooManyIntermediates results when a path length constraint is
    34  	// violated.
    35  	TooManyIntermediates
    36  	// IncompatibleUsage results when the certificate's key usage indicates
    37  	// that it may only be used for a different purpose.
    38  	IncompatibleUsage
    39  	// NameMismatch results when the subject name of a parent certificate
    40  	// does not match the issuer name in the child.
    41  	NameMismatch
    42  	// NameConstraintsWithoutSANs is a legacy error and is no longer returned.
    43  	NameConstraintsWithoutSANs
    44  	// UnconstrainedName results when a CA certificate contains permitted
    45  	// name constraints, but leaf certificate contains a name of an
    46  	// unsupported or unconstrained type.
    47  	UnconstrainedName
    48  	// TooManyConstraints results when the number of comparison operations
    49  	// needed to check a certificate exceeds the limit set by
    50  	// VerifyOptions.MaxConstraintComparisions. This limit exists to
    51  	// prevent pathological certificates can consuming excessive amounts of
    52  	// CPU time to verify.
    53  	TooManyConstraints
    54  	// CANotAuthorizedForExtKeyUsage results when an intermediate or root
    55  	// certificate does not permit a requested extended key usage.
    56  	CANotAuthorizedForExtKeyUsage
    57  )
    58  
    59  // CertificateInvalidError results when an odd error occurs. Users of this
    60  // library probably want to handle all these errors uniformly.
    61  type CertificateInvalidError struct {
    62  	Cert   *Certificate
    63  	Reason InvalidReason
    64  	Detail string
    65  }
    66  
    67  func (e CertificateInvalidError) Error() string {
    68  	switch e.Reason {
    69  	case NotAuthorizedToSign:
    70  		return "x509: certificate is not authorized to sign other certificates"
    71  	case Expired:
    72  		return "x509: certificate has expired or is not yet valid: " + e.Detail
    73  	case CANotAuthorizedForThisName:
    74  		return "x509: a root or intermediate certificate is not authorized to sign for this name: " + e.Detail
    75  	case CANotAuthorizedForExtKeyUsage:
    76  		return "x509: a root or intermediate certificate is not authorized for an extended key usage: " + e.Detail
    77  	case TooManyIntermediates:
    78  		return "x509: too many intermediates for path length constraint"
    79  	case IncompatibleUsage:
    80  		return "x509: certificate specifies an incompatible key usage"
    81  	case NameMismatch:
    82  		return "x509: issuer name does not match subject from issuing certificate"
    83  	case NameConstraintsWithoutSANs:
    84  		return "x509: issuer has name constraints but leaf doesn't have a SAN extension"
    85  	case UnconstrainedName:
    86  		return "x509: issuer has name constraints but leaf contains unknown or unconstrained name: " + e.Detail
    87  	}
    88  	return "x509: unknown error"
    89  }
    90  
    91  // HostnameError results when the set of authorized names doesn't match the
    92  // requested name.
    93  type HostnameError struct {
    94  	Certificate *Certificate
    95  	Host        string
    96  }
    97  
    98  func (h HostnameError) Error() string {
    99  	c := h.Certificate
   100  
   101  	if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) {
   102  		return "x509: certificate relies on legacy Common Name field, use SANs instead"
   103  	}
   104  
   105  	var valid string
   106  	if ip := net.ParseIP(h.Host); ip != nil {
   107  		// Trying to validate an IP
   108  		if len(c.IPAddresses) == 0 {
   109  			return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
   110  		}
   111  		for _, san := range c.IPAddresses {
   112  			if len(valid) > 0 {
   113  				valid += ", "
   114  			}
   115  			valid += san.String()
   116  		}
   117  	} else {
   118  		valid = strings.Join(c.DNSNames, ", ")
   119  	}
   120  
   121  	if len(valid) == 0 {
   122  		return "x509: certificate is not valid for any names, but wanted to match " + h.Host
   123  	}
   124  	return "x509: certificate is valid for " + valid + ", not " + h.Host
   125  }
   126  
   127  // UnknownAuthorityError results when the certificate issuer is unknown
   128  type UnknownAuthorityError struct {
   129  	Cert *Certificate
   130  	// hintErr contains an error that may be helpful in determining why an
   131  	// authority wasn't found.
   132  	hintErr error
   133  	// hintCert contains a possible authority certificate that was rejected
   134  	// because of the error in hintErr.
   135  	hintCert *Certificate
   136  }
   137  
   138  func (e UnknownAuthorityError) Error() string {
   139  	s := "x509: certificate signed by unknown authority"
   140  	if e.hintErr != nil {
   141  		certName := e.hintCert.Subject.CommonName
   142  		if len(certName) == 0 {
   143  			if len(e.hintCert.Subject.Organization) > 0 {
   144  				certName = e.hintCert.Subject.Organization[0]
   145  			} else {
   146  				certName = "serial:" + e.hintCert.SerialNumber.String()
   147  			}
   148  		}
   149  		s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
   150  	}
   151  	return s
   152  }
   153  
   154  // SystemRootsError results when we fail to load the system root certificates.
   155  type SystemRootsError struct {
   156  	Err error
   157  }
   158  
   159  func (se SystemRootsError) Error() string {
   160  	msg := "x509: failed to load system roots and no roots provided"
   161  	if se.Err != nil {
   162  		return msg + "; " + se.Err.Error()
   163  	}
   164  	return msg
   165  }
   166  
   167  func (se SystemRootsError) Unwrap() error { return se.Err }
   168  
   169  // errNotParsed is returned when a certificate without ASN.1 contents is
   170  // verified. Platform-specific verification needs the ASN.1 contents.
   171  var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
   172  
   173  // VerifyOptions contains parameters for Certificate.Verify.
   174  type VerifyOptions struct {
   175  	// DNSName, if set, is checked against the leaf certificate with
   176  	// Certificate.VerifyHostname or the platform verifier.
   177  	DNSName string
   178  
   179  	// Intermediates is an optional pool of certificates that are not trust
   180  	// anchors, but can be used to form a chain from the leaf certificate to a
   181  	// root certificate.
   182  	Intermediates *CertPool
   183  	// Roots is the set of trusted root certificates the leaf certificate needs
   184  	// to chain up to. If nil, the system roots or the platform verifier are used.
   185  	Roots *CertPool
   186  
   187  	// CurrentTime is used to check the validity of all certificates in the
   188  	// chain. If zero, the current time is used.
   189  	CurrentTime time.Time
   190  
   191  	// KeyUsages specifies which Extended Key Usage values are acceptable. A
   192  	// chain is accepted if it allows any of the listed values. An empty list
   193  	// means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny.
   194  	KeyUsages []ExtKeyUsage
   195  
   196  	// MaxConstraintComparisions is the maximum number of comparisons to
   197  	// perform when checking a given certificate's name constraints. If
   198  	// zero, a sensible default is used. This limit prevents pathological
   199  	// certificates from consuming excessive amounts of CPU time when
   200  	// validating. It does not apply to the platform verifier.
   201  	MaxConstraintComparisions int
   202  }
   203  
   204  const (
   205  	leafCertificate = iota
   206  	intermediateCertificate
   207  	rootCertificate
   208  )
   209  
   210  //