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
5package x509
6
7import (
8	"bytes"
9	"errors"
10	"fmt"
11	"net"
12	"net/url"
13	"os"
14	"reflect"
15	"runtime"
16	"strings"
17	"time"
18	"unicode/utf8"
19)
20
21// ignoreCN disables interpreting Common Name as a hostname. See issue 24151.
22var ignoreCN = strings.Contains(os.Getenv("GODEBUG"), "x509ignoreCN=1")
23
24type InvalidReason int
25
26const (
27	// NotAuthorizedToSign results when a certificate is signed by another
28	// which isn't marked as a CA certificate.
29	NotAuthorizedToSign InvalidReason = iota
30	// Expired results when a certificate has expired, based on the time
31	// given in the VerifyOptions.
32	Expired
33	// CANotAuthorizedForThisName results when an intermediate or root
34	// certificate has a name constraint which doesn't permit a DNS or
35	// other name (including IP address) in the leaf certificate.
36	CANotAuthorizedForThisName
37	// TooManyIntermediates results when a path length constraint is
38	// violated.
39	TooManyIntermediates
40	// IncompatibleUsage results when the certificate's key usage indicates
41	// that it may only be used for a different purpose.
42	IncompatibleUsage
43	// NameMismatch results when the subject name of a parent certificate
44	// does not match the issuer name in the child.
45	NameMismatch
46	// NameConstraintsWithoutSANs results when a leaf certificate doesn't
47	// contain a Subject Alternative Name extension, but a CA certificate
48	// contains name constraints, and the Common Name can be interpreted as
49	// a hostname.
50	//
51	// You can avoid this error by setting the experimental GODEBUG environment
52	// variable to "x509ignoreCN=1", disabling Common Name matching entirely.
53	// This behavior might become the default in the future.
54	NameConstraintsWithoutSANs
55	// UnconstrainedName results when a CA certificate contains permitted
56	// name constraints, but leaf certificate contains a name of an
57	// unsupported or unconstrained type.
58	UnconstrainedName
59	// TooManyConstraints results when the number of comparison operations
60	// needed to check a certificate exceeds the limit set by
61	// VerifyOptions.MaxConstraintComparisions. This limit exists to
62	// prevent pathological certificates can consuming excessive amounts of
63	// CPU time to verify.
64	TooManyConstraints
65	// CANotAuthorizedForExtKeyUsage results when an intermediate or root
66	// certificate does not permit a requested extended key usage.
67	CANotAuthorizedForExtKeyUsage
68)
69
70// CertificateInvalidError results when an odd error occurs. Users of this
71// library probably want to handle all these errors uniformly.
72type CertificateInvalidError struct {
73	Cert   *Certificate
74	Reason InvalidReason
75	Detail string
76}
77
78func (e CertificateInvalidError) Error() string {
79	switch e.Reason {
80	case NotAuthorizedToSign:
81		return "x509: certificate is not authorized to sign other certificates"
82	case Expired:
83		return "x509: certificate has expired or is not yet valid: " + e.Detail
84	case CANotAuthorizedForThisName:
85		return "x509: a root or intermediate certificate is not authorized to sign for this name: " + e.Detail
86	case CANotAuthorizedForExtKeyUsage:
87		return "x509: a root or intermediate certificate is not authorized for an extended key usage: " + e.Detail
88	case TooManyIntermediates:
89		return "x509: too many intermediates for path length constraint"
90	case IncompatibleUsage:
91		return "x509: certificate specifies an incompatible key usage"
92	case NameMismatch:
93		return "x509: issuer name does not match subject from issuing certificate"
94	case NameConstraintsWithoutSANs:
95		return "x509: issuer has name constraints but leaf doesn't have a SAN extension"
96	case UnconstrainedName:
97		return "x509: issuer has name constraints but leaf contains unknown or unconstrained name: " + e.Detail
98	}
99	return "x509: unknown error"
100}
101
102// HostnameError results when the set of authorized names doesn't match the
103// requested name.
104type HostnameError struct {
105	Certificate *Certificate
106	Host        string
107}
108
109func (h HostnameError) Error() string {
110	c := h.Certificate
111
112	if !c.hasSANExtension() && !validHostname(c.Subject.CommonName) &&
113		matchHostnames(toLowerCaseASCII(c.Subject.CommonName), toLowerCaseASCII(h.Host)) {
114		// This would have validated, if it weren't for the validHostname check on Common Name.
115		return "x509: Common Name is not a valid hostname: " + c.Subject.CommonName
116	}
117
118	var valid string
119	if ip := net.ParseIP(h.Host); ip != nil {
120		// Trying to validate an IP
121		if len(c.IPAddresses) == 0 {
122			return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
123		}
124		for _, san := range c.IPAddresses {
125			if len(valid) > 0 {
126				valid += ", "
127			}
128			valid += san.String()
129		}
130	} else {
131		if c.commonNameAsHostname() {
132			valid = c.Subject.CommonName
133		} else {
134			valid = strings.Join(c.DNSNames, ", ")
135		}
136	}
137
138	if len(valid) == 0 {
139		return "x509: certificate is not valid for any names, but wanted to match " + h.Host
140	}
141	return "x509: certificate is valid for " + valid + ", not " + h.Host
142}
143
144// UnknownAuthorityError results when the certificate issuer is unknown
145type UnknownAuthorityError struct {
146	Cert *Certificate
147	// hintErr contains an error that may be helpful in determining why an
148	// authority wasn't found.
149	hintErr error
150	// hintCert contains a possible authority certificate that was rejected
151	// because of the error in hintErr.
152	hintCert *Certificate
153}
154
155func (e UnknownAuthorityError) Error() string {
156	s := "x509: certificate signed by unknown authority"
157	if e.hintErr != nil {
158		certName := e.hintCert.Subject.CommonName
159		if len(certName) == 0 {
160			if len(e.hintCert.Subject.Organization) > 0 {
161				certName = e.hintCert.Subject.Organization[0]
162			} else {
163				certName = "serial:" + e.hintCert.SerialNumber.String()
164			}
165		}
166		s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
167	}
168	return s
169}
170
171// SystemRootsError results when we fail to load the system root certificates.
172type SystemRootsError struct {
173	Err error
174}
175
176func (se SystemRootsError) Error() string {
177	msg := "x509: failed to load system roots and no roots provided"
178	if se.Err != nil {
179		return msg + "; " + se.Err.Error()
180	}
181	return msg
182}
183
184// errNotParsed is returned when a certificate without ASN.1 contents is
185// verified. Platform-specific verification needs the ASN.1 contents.
186var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
187
188// VerifyOptions contains parameters for Certificate.Verify. It's a structure
189// because other PKIX verification APIs have ended up needing many options.
190type VerifyOptions struct {
191	// DNSName, if set, is checked against the leaf certificate with
192	// Certificate.VerifyHostname or the platform verifier.
193	DNSName string
194
195	// Intermediates is an optional pool of certificates that are not trust
196	// anchors, but can be used to form a chain from the leaf certificate to a
197	// root certificate.
198	Intermediates *CertPool
199	// Roots is the set of trusted root certificates the leaf certificate needs
200	// to chain up to. If nil, the system roots or the platform verifier are used.
201	Roots *CertPool
202
203	// CurrentTime is used to check the validity of all certificates in the
204	// chain. If zero, the current time is used.
205	CurrentTime time.Time
206
207	// KeyUsages specifies which Extended Key Usage values are acceptable. A
208	// chain is accepted if it allows any of the listed values. An empty list
209	// means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny.
210	KeyUsages []ExtKeyUsage
211
212	// MaxConstraintComparisions is the maximum number of comparisons to
213	// perform when checking a given certificate's name constraints. If
214	// zero, a sensible default is used. This limit prevents pathological
215	// certificates from consuming excessive amounts of CPU time when
216	// validating. It does not apply to the platform verifier.
217	MaxConstraintComparisions int
218}
219
220const (
221	leafCertificate = iota
222	intermediateCertificate
223	rootCertificate
224)
225
226// rfc2821Mailbox represents a “mailbox” (which is an email address to most
227// people) by breaking it into the “local” (i.e. before the '@') and “domain”
228// parts.
229type rfc2821Mailbox struct {
230	local, domain string
231}
232
233// parseRFC2821Mailbox parses an email address into local and domain parts,
234// based on the ABNF for a “Mailbox” from RFC 2821. According to RFC 5280,
235// Section 4.2.1.6 that's correct for an rfc822Name from a certificate: “The
236// format of an rfc822Name is a "Mailbox" as defined in RFC 2821, Section 4.1.2”.
237func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
238	if len(in) == 0 {
239		return mailbox, false
240	}
241
242	localPartBytes := make([]byte, 0, len(in)/2)
243
244	if in[0] == '"' {
245		// Quoted-string = DQUOTE *qcontent DQUOTE
246		// non-whitespace-control = %d1-8 / %d11 / %d12 / %d14-31 / %d127
247		// qcontent = qtext / quoted-pair
248		// qtext = non-whitespace-control /
249		//         %d33 / %d35-91 / %d93-126
250		// quoted-pair = ("\" text) / obs-qp
251		// text = %d1-9 / %d11 / %d12 / %d14-127 / obs-text
252		//
253		// (Names beginning with “obs-” are the obsolete syntax from RFC 2822,
254		// Section 4. Since it has been 16 years, we no longer accept that.)
255		in = in[1:]
256	QuotedString:
257		for {
258			if len(in) == 0 {
259				return mailbox, false
260			}
261			c := in[0]
262			in = in[1:]
263
264			switch {
265			case c == '"':
266				break QuotedString
267
268			case c == '\\':
269				// quoted-pair
270				if len(in) == 0 {
271					return mailbox, false
272				}
273				if in[0] == 11 ||
274					in[0] == 12 ||
275					(1 <= in[0] && in[0] <= 9) ||
276					(14 <= in[0] && in[0] <= 127) {
277					localPartBytes = append(localPartBytes, in[0])
278					in = in[1:]
279				} else {
280					return mailbox, false
281				}
282
283			case c == 11 ||
284				c == 12 ||
285				// Space (char 32) is not allowed based on the
286				// BNF, but RFC 3696 gives an example that
287				// assumes that it is. Several “verified”
288				// errata continue to argue about this point.
289				// We choose to accept it.
290				c == 32 ||
291				c == 33 ||
292				c == 127 ||
293				(1 <= c && c <= 8) ||
294				(14 <= c && c <= 31) ||
295				(35 <= c && c <= 91) ||
296				(93 <= c && c <= 126):
297				// qtext
298				localPartBytes = append(localPartBytes, c)
299
300			default:
301				return mailbox, false
302			}
303		}
304	} else {
305		// Atom ("." Atom)*
306	NextChar:
307		for len(in) > 0 {
308			// atext from RFC 2822, Section 3.2.4
309			c := in[0]
310
311			switch {
312			case c == '\\':
313				// Examples given in RFC 3696 suggest that
314				// escaped characters can appear outside of a
315				// quoted string. Several “verified” errata
316				// continue to argue the point. We choose to
317				// accept it.
318				in = in[1:]
319				if len(in) == 0 {
320					return mailbox, false
321				}
322				fallthrough
323
324			case ('0' <= c && c <= '9') ||
325				('a' <= c && c <= 'z') ||
326				('A' <= c && c <= 'Z') ||
327				c == '!' || c == '#' || c == '$' || c == '%' ||
328				c == '&' || c == '\'' || c == '*' || c == '+' ||
329				c == '-' || c == '/' || c == '=' || c == '?' ||
330				c == '^' || c == '_' || c == '`' || c == '{' ||
331				c == '|' || c == '}' || c == '~' || c == '.':
332				localPartBytes = append(localPartBytes, in[0])
333				in = in[1:]
334
335			default:
336				break NextChar
337			}
338		}
339
340		if len(localPartBytes) == 0 {
341			return mailbox, false
342		}
343
344		// From RFC 3696, Section 3:
345		// “period (".") may also appear, but may not be used to start
346		// or end the local part, nor may two or more consecutive
347		// periods appear.”
348		twoDots := []byte{'.', '.'}
349		if localPartBytes[0] == '.' ||
350			localPartBytes[len(localPartBytes)-1] == '.' ||
351			bytes.Contains(localPartBytes, twoDots) {
352			return mailbox, false
353		}
354	}
355
356	if len(in) == 0 || in[0] != '@' {
357		return mailbox, false
358	}
359	in = in[1:]
360
361	// The RFC species a format for domains, but that's known to be
362	// violated in practice so we accept that anything after an '@' is the
363	// domain part.
364	if _, ok := domainToReverseLabels(in); !ok {
365		return mailbox, false
366	}
367
368	mailbox.local = string(localPartBytes)
369	mailbox.domain = in
370	return mailbox, true
371}
372
373// domainToReverseLabels converts a textual domain name like foo.example.com to
374// the list of labels in reverse order, e.g. ["com", "example", "foo"].
375func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
376	for len(domain) > 0 {
377		if i := strings.LastIndexByte(domain, '.'); i == -1 {
378			reverseLabels = append(reverseLabels, domain)
379			domain = ""
380		} else {
381			reverseLabels = append(reverseLabels, domain[i+1:])
382			domain = domain[:i]
383		}
384	}
385
386	if len(reverseLabels) > 0 && len(reverseLabels[0]) == 0 {
387		// An empty label at the end indicates an absolute value.
388		return nil, false
389	}
390
391	for _, label := range reverseLabels {
392		if len(label) == 0 {
393			// Empty labels are otherwise invalid.
394			return nil, false
395		}
396
397		for _, c := range label {
398			if c < 33 || c > 126 {
399				// Invalid character.
400				return nil, false
401			}
402		}
403	}
404
405	return reverseLabels, true
406}
407
408func matchEmailConstraint(mailbox rfc2821Mailbox, constraint string) (bool, error) {
409	// If the constraint contains an @, then it specifies an exact mailbox
410	// name.
411	if strings.Contains(constraint, "@") {
412		constraintMailbox, ok := parseRFC2821Mailbox(constraint)
413		if !ok {
414			return false, fmt.Errorf("x509: internal error: cannot parse constraint %q", constraint)
415		}
416		return mailbox.local == constraintMailbox.local && strings.EqualFold(mailbox.domain, constraintMailbox.domain), nil
417	}
418
419	// Otherwise the constraint is like a DNS constraint of the domain part
420	// of the mailbox.
421	return matchDomainConstraint(mailbox.domain, constraint)
422}
423
424func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
425	// From RFC 5280, Section 4.2.1.10:
426	// “a uniformResourceIdentifier that does not include an authority
427	// component with a host name specified as a fully qualified domain
428	// name (e.g., if the URI either does not include an authority
429	// component or includes an authority component in which the host name
430	// is specified as an IP address), then the application MUST reject the
431	// certificate.”
432
433	host := uri.Host
434	if len(host) == 0 {
435		return false, fmt.Errorf("URI with empty host (%q) cannot be matched against constraints", uri.String())
436	}
437
438	if strings.Contains(host, ":") && !strings.HasSuffix(host, "]") {
439		var err error
440		host, _, err = net.SplitHostPort(uri.Host)
441		if err != nil {
442			return false, err
443		}
444	}
445
446	if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
447		net.ParseIP(host) != nil {
448		return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
449	}
450
451	return matchDomainConstraint(host, constraint)
452}
453
454func matchIPConstraint(ip net.IP, constraint *net.IPNet) (bool, error) {
455	if len(ip) != len(constraint.IP) {
456		return false, nil
457	}
458
459	for i := range ip {
460		if mask := constraint.Mask[i]; ip[i]&mask != constraint.IP[i]&mask {
461			return false, nil
462		}
463	}
464
465	return true, nil
466}
467
468func matchDomainConstraint(domain, constraint string) (bool, error) {
469	// The meaning of zero length constraints is not specified, but this
470	// code follows NSS and accepts them as matching everything.
471	if len(constraint) == 0 {
472		return true, nil
473	}
474
475	domainLabels, ok := domainToReverseLabels(domain)
476	if !ok {
477		return false, fmt.Errorf("x509: internal error: cannot parse domain %q", domain)
478	}
479
480	// RFC 5280 says that a leading period in a domain name means that at
481	// least one label must be prepended, but only for URI and email
482	// constraints, not DNS constraints. The code also supports that
483	// behaviour for DNS constraints.
484
485	mustHaveSubdomains := false
486	if constraint[0] == '.' {
487		mustHaveSubdomains = true
488		constraint = constraint[1:]
489	}
490
491	constraintLabels, ok := domainToReverseLabels(constraint)
492	if !ok {
493		return false, fmt.Errorf("x509: internal error: cannot parse domain %q", constraint)
494	}
495
496	if len(domainLabels) < len(constraintLabels) ||
497		(mustHaveSubdomains && len(domainLabels) == len(constraintLabels)) {
498		return false, nil
499	}
500
501	for i, constraintLabel := range constraintLabels {
502		if !strings.EqualFold(constraintLabel, domainLabels[i]) {
503			return false, nil
504		}
505	}
506
507	return true, nil
508}
509
510// checkNameConstraints checks that c permits a child certificate to claim the
511// given name, of type nameType. The argument parsedName contains the parsed
512// form of name, suitable for passing to the match function. The total number
513// of comparisons is tracked in the given count and should not exceed the given
514// limit.
515func (c *Certificate) checkNameConstraints(count *int,
516	maxConstraintComparisons int,
517	nameType string,
518	name string,
519	parsedName interface{},
520	match func(parsedName, constraint interface{}) (match bool, err error),
521	permitted, excluded interface{}) error {
522
523	excludedValue := reflect.ValueOf(excluded)
524
525	*count += excludedValue.Len()
526	if *count > maxConstraintComparisons {
527		return CertificateInvalidError{c, TooManyConstraints, ""}
528	}
529
530	for i := 0; i < excludedValue.Len(); i++ {
531		constraint := excludedValue.Index(i).Interface()
532		match, err := match(parsedName, constraint)
533		if err != nil {
534			return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
535		}
536
537		if match {
538			return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)}
539		}
540	}
541
542	permittedValue := reflect.ValueOf(permitted)
543
544	*count += permittedValue.Len()
545	if *count > maxConstraintComparisons {
546		return CertificateInvalidError{c, TooManyConstraints, ""}
547	}
548
549	ok := true
550	for i := 0; i < permittedValue.Len(); i++ {
551		constraint := permittedValue.Index(i).Interface()
552
553		var err error
554		if ok, err = match(parsedName, constraint); err != nil {
555			return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
556		}
557
558		if ok {
559			break
560		}
561	}
562
563	if !ok {
564		return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)}
565	}
566
567	return nil
568}
569
570// isValid performs validity checks on c given that it is a candidate to append
571// to the chain in currentChain.
572func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
573	if len(c.UnhandledCriticalExtensions) > 0 {
574		return UnhandledCriticalExtension{}
575	}
576
577	if len(currentChain) > 0 {
578		child := currentChain[len(currentChain)-1]
579		if !bytes.Equal(child.RawIssuer, c.RawSubject) {
580			return CertificateInvalidError{c, NameMismatch, ""}
581		}
582	}
583
584	now := opts.CurrentTime
585	if now.IsZero() {
586		now = time.Now()
587	}
588	if now.Before(c.NotBefore) {
589		return CertificateInvalidError{
590			Cert:   c,
591			Reason: Expired,
592			Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)),
593		}
594	} else if now.After(c.NotAfter) {
595		return CertificateInvalidError{
596			Cert:   c,
597			Reason: Expired,
598			Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)),
599		}
600	}
601
602	maxConstraintComparisons := opts.MaxConstraintComparisions
603	if maxConstraintComparisons == 0 {
604		maxConstraintComparisons = 250000
605	}
606	comparisonCount := 0
607
608	var leaf *Certificate
609	if certType == intermediateCertificate || certType == rootCertificate {
610		if len(currentChain) == 0 {
611			return errors.New("x509: internal error: empty chain when appending CA cert")
612		}
613		leaf = currentChain[0]
614	}
615
616	checkNameConstraints := (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints()
617	if checkNameConstraints && leaf.commonNameAsHostname() {
618		// This is the deprecated, legacy case of depending on the commonName as
619		// a hostname. We don't enforce name constraints against the CN, but
620		// VerifyHostname will look for hostnames in there if there are no SANs.
621		// In order to ensure VerifyHostname will not accept an unchecked name,
622		// return an error here.
623		return CertificateInvalidError{c, NameConstraintsWithoutSANs, ""}
624	} else if checkNameConstraints && leaf.hasSANExtension() {
625		err := forEachSAN(leaf.getSANExtension(), func(tag int, data []byte) error {
626			switch tag {
627			case nameTypeEmail:
628				name := string(data)
629				mailbox, ok := parseRFC2821Mailbox(name)
630				if !ok {
631					return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
632				}
633
634				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
635					func(parsedName, constraint interface{}) (bool, error) {
636						return matchEmailConstraint(parsedName.(rfc2821Mailbox), constraint.(string))
637					}, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil {
638					return err
639				}
640
641			case nameTypeDNS:
642				name := string(data)
643				if _, ok := domainToReverseLabels(name); !ok {
644					return fmt.Errorf("x509: cannot parse dnsName %q", name)
645				}
646
647				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name,
648					func(parsedName, constraint interface{}) (bool, error) {
649						return matchDomainConstraint(parsedName.(string), constraint.(string))
650					}, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil {
651					return err
652				}
653
654			case nameTypeURI:
655				name := string(data)
656				uri, err := url.Parse(name)
657				if err != nil {
658					return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name)
659				}
660
661				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "URI", name, uri,
662					func(parsedName, constraint interface{}) (bool, error) {
663						return matchURIConstraint(parsedName.(*url.URL), constraint.(string))
664					}, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil {
665					return err
666				}
667
668			case nameTypeIP:
669				ip := net.IP(data)
670				if l := len(ip); l != net.IPv4len && l != net.IPv6len {
671					return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data)
672				}
673
674				if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip,
675					func(parsedName, constraint interface{}) (bool, error) {
676						return matchIPConstraint(parsedName.(net.IP), constraint.(*net.IPNet))
677					}, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil {
678					return err
679				}
680
681			default:
682				// Unknown SAN types are ignored.
683			}
684
685			return nil
686		})
687
688		if err != nil {
689			return err
690		}
691	}
692
693	// KeyUsage status flags are ignored. From Engineering Security, Peter
694	// Gutmann: A European government CA marked its signing certificates as
695	// being valid for encryption only, but no-one noticed. Another
696	// European CA marked its signature keys as not being valid for
697	// signatures. A different CA marked its own trusted root certificate
698	// as being invalid for certificate signing. Another national CA
699	// distributed a certificate to be used to encrypt data for the
700	// country’s tax authority that was marked as only being usable for
701	// digital signatures but not for encryption. Yet another CA reversed
702	// the order of the bit flags in the keyUsage due to confusion over
703	// encoding endianness, essentially setting a random keyUsage in
704	// certificates that it issued. Another CA created a self-invalidating
705	// certificate by adding a certificate policy statement stipulating
706	// that the certificate had to be used strictly as specified in the
707	// keyUsage, and a keyUsage containing a flag indicating that the RSA
708	// encryption key could only be used for Diffie-Hellman key agreement.
709
710	if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
711		return CertificateInvalidError{c, NotAuthorizedToSign, ""}
712	}
713
714	if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
715		numIntermediates := len(currentChain) - 1
716		if numIntermediates > c.MaxPathLen {
717			return CertificateInvalidError{c, TooManyIntermediates, ""}
718		}
719	}
720
721	return nil
722}
723
724// Verify attempts to verify c by building one or more chains from c to a
725// certificate in opts.Roots, using certificates in opts.Intermediates if
726// needed. If successful, it returns one or more chains where the first
727// element of the chain is c and the last element is from opts.Roots.
728//
729// If opts.Roots is nil, the platform verifier might be used, and
730// verification details might differ from what is described below. If system
731// roots are unavailable the returned error will be of type SystemRootsError.
732//
733// Name constraints in the intermediates will be applied to all names claimed
734// in the chain, not just opts.DNSName. Thus it is invalid for a leaf to claim
735// example.com if an intermediate doesn't permit it, even if example.com is not
736// the name being validated. Note that DirectoryName constraints are not
737// supported.
738//
739// Extended Key Usage values are enforced nested down a chain, so an intermediate
740// or root that enumerates EKUs prevents a leaf from asserting an EKU not in that
741// list. (While this is not specified, it is common practice in order to limit
742// the types of certificates a CA can issue.)
743//
744// WARNING: this function doesn't do any revocation checking.
745func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
746	// Platform-specific verification needs the ASN.1 contents so
747	// this makes the behavior consistent across platforms.
748	if len(c.Raw) == 0 {
749		return nil, errNotParsed
750	}
751	if opts.Intermediates != nil {
752		for _, intermediate := range opts.Intermediates.certs {
753			if len(intermediate.Raw) == 0 {
754				return nil, errNotParsed
755			}
756		}
757	}
758
759	// Use Windows's own verification and chain building.
760	if opts.Roots == nil && runtime.GOOS == "windows" {
761		return c.systemVerify(&opts)
762	}
763
764	if opts.Roots == nil {
765		opts.Roots = systemRootsPool()
766		if opts.Roots == nil {
767			return nil, SystemRootsError{systemRootsErr}
768		}
769	}
770
771	err = c.isValid(leafCertificate, nil, &opts)
772	if err != nil {
773		return
774	}
775
776	if len(opts.DNSName) > 0 {
777		err = c.VerifyHostname(opts.DNSName)
778		if err != nil {
779			return
780		}
781	}
782
783	var candidateChains [][]*Certificate
784	if opts.Roots.contains(c) {
785		candidateChains = append(candidateChains, []*Certificate{c})
786	} else {
787		if candidateChains, err = c.buildChains(nil, []*Certificate{c}, nil, &opts); err != nil {
788			return nil, err
789		}
790	}
791
792	keyUsages := opts.KeyUsages
793	if len(keyUsages) == 0 {
794		keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
795	}
796
797	// If any key usage is acceptable then we're done.
798	for _, usage := range keyUsages {
799		if usage == ExtKeyUsageAny {
800			return candidateChains, nil
801		}
802	}
803
804	for _, candidate := range candidateChains {
805		if checkChainForKeyUsage(candidate, keyUsages) {
806			chains = append(chains, candidate)
807		}
808	}
809
810	if len(chains) == 0 {
811		return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
812	}
813
814	return chains, nil
815}
816
817func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
818	n := make([]*Certificate, len(chain)+1)
819	copy(n, chain)
820	n[len(chain)] = cert
821	return n
822}
823
824// maxChainSignatureChecks is the maximum number of CheckSignatureFrom calls
825// that an invocation of buildChains will (tranistively) make. Most chains are
826// less than 15 certificates long, so this leaves space for multiple chains and
827// for failed checks due to different intermediates having the same Subject.
828const maxChainSignatureChecks = 100
829
830func (c *Certificate) buildChains(cache map[*Certificate][][]*Certificate, currentChain []*Certificate, sigChecks *int, opts *VerifyOptions) (chains [][]*Certificate, err error) {
831	var (
832		hintErr  error
833		hintCert *Certificate
834	)
835
836	considerCandidate := func(certType int, candidate *Certificate) {
837		for _, cert := range currentChain {
838			if cert.Equal(candidate) {
839				return
840			}
841		}
842
843		if sigChecks == nil {
844			sigChecks = new(int)
845		}
846		*sigChecks++
847		if *sigChecks > maxChainSignatureChecks {
848			err = errors.New("x509: signature check attempts limit reached while verifying certificate chain")
849			return
850		}
851
852		if err := c.CheckSignatureFrom(candidate); err != nil {
853			if hintErr == nil {
854				hintErr = err
855				hintCert = candidate
856			}
857			return
858		}
859
860		err = candidate.isValid(certType, currentChain, opts)
861		if err != nil {
862			return
863		}
864
865		switch certType {
866		case rootCertificate:
867			chains = append(chains, appendToFreshChain(currentChain, candidate))
868		case intermediateCertificate:
869			if cache == nil {
870				cache = make(map[*Certificate][][]*Certificate)
871			}
872			childChains, ok := cache[candidate]
873			if !ok {
874				childChains, err = candidate.buildChains(cache, appendToFreshChain(currentChain, candidate), sigChecks, opts)
875				cache[candidate] = childChains
876			}
877			chains = append(chains, childChains...)
878		}
879	}
880
881	for _, rootNum := range opts.Roots.findPotentialParents(c) {
882		considerCandidate(rootCertificate, opts.Roots.certs[rootNum])
883	}
884	for _, intermediateNum := range opts.Intermediates.findPotentialParents(c) {
885		considerCandidate(intermediateCertificate, opts.Intermediates.certs[intermediateNum])
886	}
887
888	if len(chains) > 0 {
889		err = nil
890	}
891	if len(chains) == 0 && err == nil {
892		err = UnknownAuthorityError{c, hintErr, hintCert}
893	}
894
895	return
896}
897
898// validHostname reports whether host is a valid hostname that can be matched or
899// matched against according to RFC 6125 2.2, with some leniency to accommodate
900// legacy values.
901func validHostname(host string) bool {
902	host = strings.TrimSuffix(host, ".")
903
904	if len(host) == 0 {
905		return false
906	}
907
908	for i, part := range strings.Split(host, ".") {
909		if part == "" {
910			// Empty label.
911			return false
912		}
913		if i == 0 && part == "*" {
914			// Only allow full left-most wildcards, as those are the only ones
915			// we match, and matching literal '*' characters is probably never
916			// the expected behavior.
917			continue
918		}
919		for j, c := range part {
920			if 'a' <= c && c <= 'z' {
921				continue
922			}
923			if '0' <= c && c <= '9' {
924				continue
925			}
926			if 'A' <= c && c <= 'Z' {
927				continue
928			}
929			if c == '-' && j != 0 {
930				continue
931			}
932			if c == '_' || c == ':' {
933				// Not valid characters in hostnames, but commonly
934				// found in deployments outside the WebPKI.
935				continue
936			}
937			return false
938		}
939	}
940
941	return true
942}
943
944// commonNameAsHostname reports whether the Common Name field should be
945// considered the hostname that the certificate is valid for. This is a legacy
946// behavior, disabled if the Subject Alt Name extension is present.
947//
948// It applies the strict validHostname check to the Common Name field, so that
949// certificates without SANs can still be validated against CAs with name
950// constraints if there is no risk the CN would be matched as a hostname.
951// See NameConstraintsWithoutSANs and issue 24151.
952func (c *Certificate) commonNameAsHostname() bool {
953	return !ignoreCN && !c.hasSANExtension() && validHostname(c.Subject.CommonName)
954}
955
956func matchHostnames(pattern, host string) bool {
957	host = strings.TrimSuffix(host, ".")
958	pattern = strings.TrimSuffix(pattern, ".")
959
960	if len(pattern) == 0 || len(host) == 0 {
961		return false
962	}
963
964	patternParts := strings.Split(pattern, ".")
965	hostParts := strings.Split(host, ".")
966
967	if len(patternParts) != len(hostParts) {
968		return false
969	}
970
971	for i, patternPart := range patternParts {
972		if i == 0 && patternPart == "*" {
973			continue
974		}
975		if patternPart != hostParts[i] {
976			return false
977		}
978	}
979
980	return true
981}
982
983// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
984// an explicitly ASCII function to avoid any sharp corners resulting from
985// performing Unicode operations on DNS labels.
986func toLowerCaseASCII(in string) string {
987	// If the string is already lower-case then there's nothing to do.
988	isAlreadyLowerCase := true
989	for _, c := range in {
990		if c == utf8.RuneError {
991			// If we get a UTF-8 error then there might be
992			// upper-case ASCII bytes in the invalid sequence.
993			isAlreadyLowerCase = false
994			break
995		}
996		if 'A' <= c && c <= 'Z' {
997			isAlreadyLowerCase = false
998			break
999		}
1000	}
1001
1002	if isAlreadyLowerCase {
1003		return in
1004	}
1005
1006	out := []byte(in)
1007	for i, c := range out {
1008		if 'A' <= c && c <= 'Z' {
1009			out[i] += 'a' - 'A'
1010		}
1011	}
1012	return string(out)
1013}
1014
1015// VerifyHostname returns nil if c is a valid certificate for the named host.
1016// Otherwise it returns an error describing the mismatch.
1017func (c *Certificate) VerifyHostname(h string) error {
1018	// IP addresses may be written in [ ].
1019	candidateIP := h
1020	if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
1021		candidateIP = h[1 : len(h)-1]
1022	}
1023	if ip := net.ParseIP(candidateIP); ip != nil {
1024		// We only match IP addresses against IP SANs.
1025		// See RFC 6125, Appendix B.2.
1026		for _, candidate := range c.IPAddresses {
1027			if ip.Equal(candidate) {
1028				return nil
1029			}
1030		}
1031		return HostnameError{c, candidateIP}
1032	}
1033
1034	lowered := toLowerCaseASCII(h)
1035
1036	if c.commonNameAsHostname() {
1037		if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
1038			return nil
1039		}
1040	} else {
1041		for _, match := range c.DNSNames {
1042			if matchHostnames(toLowerCaseASCII(match), lowered) {
1043				return nil
1044			}
1045		}
1046	}
1047
1048	return HostnameError{c, h}
1049}
1050
1051func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
1052	usages := make([]ExtKeyUsage, len(keyUsages))
1053	copy(usages, keyUsages)
1054
1055	if len(chain) == 0 {
1056		return false
1057	}
1058
1059	usagesRemaining := len(usages)
1060
1061	// We walk down the list and cross out any usages that aren't supported
1062	// by each certificate. If we cross out all the usages, then the chain
1063	// is unacceptable.
1064
1065NextCert:
1066	for i := len(chain) - 1; i >= 0; i-- {
1067		cert := chain[i]
1068		if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
1069			// The certificate doesn't have any extended key usage specified.
1070			continue
1071		}
1072
1073		for _, usage := range cert.ExtKeyUsage {
1074			if usage == ExtKeyUsageAny {
1075				// The certificate is explicitly good for any usage.
1076				continue NextCert
1077			}
1078		}
1079
1080		const invalidUsage ExtKeyUsage = -1
1081
1082	NextRequestedUsage:
1083		for i, requestedUsage := range usages {
1084			if requestedUsage == invalidUsage {
1085				continue
1086			}
1087
1088			for _, usage := range cert.ExtKeyUsage {
1089				if requestedUsage == usage {
1090					continue NextRequestedUsage
1091				} else if requestedUsage == ExtKeyUsageServerAuth &&
1092					(usage == ExtKeyUsageNetscapeServerGatedCrypto ||
1093						usage == ExtKeyUsageMicrosoftServerGatedCrypto) {
1094					// In order to support COMODO
1095					// certificate chains, we have to
1096					// accept Netscape or Microsoft SGC
1097					// usages as equal to ServerAuth.
1098					continue NextRequestedUsage
1099				}
1100			}
1101
1102			usages[i] = invalidUsage
1103			usagesRemaining--
1104			if usagesRemaining == 0 {
1105				return false
1106			}
1107		}
1108	}
1109
1110	return true
1111}
1112