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