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