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