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