]> 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 any,
509         match func(parsedName, constraint any) (match bool, err error),
510         permitted, excluded any) 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 any) (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 any) (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 any) (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 any) (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 // Certificates that use SHA1WithRSA and ECDSAWithSHA1 signatures are not supported,
740 // and will not be used to build chains.
741 //
742 // WARNING: this function doesn't do any revocation checking.
743 func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
744         // Platform-specific verification needs the ASN.1 contents so
745         // this makes the behavior consistent across platforms.
746         if len(c.Raw) == 0 {
747                 return nil, errNotParsed
748         }
749         for i := 0; i < opts.Intermediates.len(); i++ {
750                 c, err := opts.Intermediates.cert(i)
751                 if err != nil {
752                         return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", err)
753                 }
754                 if len(c.Raw) == 0 {
755                         return nil, errNotParsed
756                 }
757         }
758
759         // Use platform verifiers, where available, if Roots is from SystemCertPool.
760         if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
761                 if opts.Roots == nil {
762                         return c.systemVerify(&opts)
763                 }
764                 if opts.Roots != nil && opts.Roots.systemPool {
765                         platformChains, err := c.systemVerify(&opts)
766                         // If the platform verifier succeeded, or there are no additional
767                         // roots, return the platform verifier result. Otherwise, continue
768                         // with the Go verifier.
769                         if err == nil || opts.Roots.len() == 0 {
770                                 return platformChains, err
771                         }
772                 }
773         }
774
775         if opts.Roots == nil {
776                 opts.Roots = systemRootsPool()
777                 if opts.Roots == nil {
778                         return nil, SystemRootsError{systemRootsErr}
779                 }
780         }
781
782         err = c.isValid(leafCertificate, nil, &opts)
783         if err != nil {
784                 return
785         }
786
787         if len(opts.DNSName) > 0 {
788                 err = c.VerifyHostname(opts.DNSName)
789                 if err != nil {
790                         return
791                 }
792         }
793
794         var candidateChains [][]*Certificate
795         if opts.Roots.contains(c) {
796                 candidateChains = append(candidateChains, []*Certificate{c})
797         } else {
798                 if candidateChains, err = c.buildChains(nil, []*Certificate{c}, nil, &opts); err != nil {
799                         return nil, err
800                 }
801         }
802
803         keyUsages := opts.KeyUsages
804         if len(keyUsages) == 0 {
805                 keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
806         }
807
808         // If any key usage is acceptable then we're done.
809         for _, usage := range keyUsages {
810                 if usage == ExtKeyUsageAny {
811                         return candidateChains, nil
812                 }
813         }
814
815         for _, candidate := range candidateChains {
816                 if checkChainForKeyUsage(candidate, keyUsages) {
817                         chains = append(chains, candidate)
818                 }
819         }
820
821         if len(chains) == 0 {
822                 return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
823         }
824
825         return chains, nil
826 }
827
828 func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
829         n := make([]*Certificate, len(chain)+1)
830         copy(n, chain)
831         n[len(chain)] = cert
832         return n
833 }
834
835 // maxChainSignatureChecks is the maximum number of CheckSignatureFrom calls
836 // that an invocation of buildChains will (transitively) make. Most chains are
837 // less than 15 certificates long, so this leaves space for multiple chains and
838 // for failed checks due to different intermediates having the same Subject.
839 const maxChainSignatureChecks = 100
840
841 func (c *Certificate) buildChains(cache map[*Certificate][][]*Certificate, currentChain []*Certificate, sigChecks *int, opts *VerifyOptions) (chains [][]*Certificate, err error) {
842         var (
843                 hintErr  error
844                 hintCert *Certificate
845         )
846
847         considerCandidate := func(certType int, candidate *Certificate) {
848                 for _, cert := range currentChain {
849                         if cert.Equal(candidate) {
850                                 return
851                         }
852                 }
853
854                 if sigChecks == nil {
855                         sigChecks = new(int)
856                 }
857                 *sigChecks++
858                 if *sigChecks > maxChainSignatureChecks {
859                         err = errors.New("x509: signature check attempts limit reached while verifying certificate chain")
860                         return
861                 }
862
863                 if err := c.CheckSignatureFrom(candidate); err != nil {
864                         if hintErr == nil {
865                                 hintErr = err
866                                 hintCert = candidate
867                         }
868                         return
869                 }
870
871                 err = candidate.isValid(certType, currentChain, opts)
872                 if err != nil {
873                         return
874                 }
875
876                 switch certType {
877                 case rootCertificate:
878                         chains = append(chains, appendToFreshChain(currentChain, candidate))
879                 case intermediateCertificate:
880                         if cache == nil {
881                                 cache = make(map[*Certificate][][]*Certificate)
882                         }
883                         childChains, ok := cache[candidate]
884                         if !ok {
885                                 childChains, err = candidate.buildChains(cache, appendToFreshChain(currentChain, candidate), sigChecks, opts)
886                                 cache[candidate] = childChains
887                         }
888                         chains = append(chains, childChains...)
889                 }
890         }
891
892         for _, root := range opts.Roots.findPotentialParents(c) {
893                 considerCandidate(rootCertificate, root)
894         }
895         for _, intermediate := range opts.Intermediates.findPotentialParents(c) {
896                 considerCandidate(intermediateCertificate, intermediate)
897         }
898
899         if len(chains) > 0 {
900                 err = nil
901         }
902         if len(chains) == 0 && err == nil {
903                 err = UnknownAuthorityError{c, hintErr, hintCert}
904         }
905
906         return
907 }
908
909 func validHostnamePattern(host string) bool { return validHostname(host, true) }
910 func validHostnameInput(host string) bool   { return validHostname(host, false) }
911
912 // validHostname reports whether host is a valid hostname that can be matched or
913 // matched against according to RFC 6125 2.2, with some leniency to accommodate
914 // legacy values.
915 func validHostname(host string, isPattern bool) bool {
916         if !isPattern {
917                 host = strings.TrimSuffix(host, ".")
918         }
919         if len(host) == 0 {
920                 return false
921         }
922
923         for i, part := range strings.Split(host, ".") {
924                 if part == "" {
925                         // Empty label.
926                         return false
927                 }
928                 if isPattern && i == 0 && part == "*" {
929                         // Only allow full left-most wildcards, as those are the only ones
930                         // we match, and matching literal '*' characters is probably never
931                         // the expected behavior.
932                         continue
933                 }
934                 for j, c := range part {
935                         if 'a' <= c && c <= 'z' {
936                                 continue
937                         }
938                         if '0' <= c && c <= '9' {
939                                 continue
940                         }
941                         if 'A' <= c && c <= 'Z' {
942                                 continue
943                         }
944                         if c == '-' && j != 0 {
945                                 continue
946                         }
947                         if c == '_' {
948                                 // Not a valid character in hostnames, but commonly
949                                 // found in deployments outside the WebPKI.
950                                 continue
951                         }
952                         return false
953                 }
954         }
955
956         return true
957 }
958
959 func matchExactly(hostA, hostB string) bool {
960         if hostA == "" || hostA == "." || hostB == "" || hostB == "." {
961                 return false
962         }
963         return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB)
964 }
965
966 func matchHostnames(pattern, host string) bool {
967         pattern = toLowerCaseASCII(pattern)
968         host = toLowerCaseASCII(strings.TrimSuffix(host, "."))
969
970         if len(pattern) == 0 || len(host) == 0 {
971                 return false
972         }
973
974         patternParts := strings.Split(pattern, ".")
975         hostParts := strings.Split(host, ".")
976
977         if len(patternParts) != len(hostParts) {
978                 return false
979         }
980
981         for i, patternPart := range patternParts {
982                 if i == 0 && patternPart == "*" {
983                         continue
984                 }
985                 if patternPart != hostParts[i] {
986                         return false
987                 }
988         }
989
990         return true
991 }
992
993 // toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
994 // an explicitly ASCII function to avoid any sharp corners resulting from
995 // performing Unicode operations on DNS labels.
996 func toLowerCaseASCII(in string) string {
997         // If the string is already lower-case then there's nothing to do.
998         isAlreadyLowerCase := true
999         for _, c := range in {
1000                 if c == utf8.RuneError {
1001                         // If we get a UTF-8 error then there might be
1002                         // upper-case ASCII bytes in the invalid sequence.
1003                         isAlreadyLowerCase = false
1004                         break
1005                 }
1006                 if 'A' <= c && c <= 'Z' {
1007                         isAlreadyLowerCase = false
1008                         break
1009                 }
1010         }
1011
1012         if isAlreadyLowerCase {
1013                 return in
1014         }
1015
1016         out := []byte(in)
1017         for i, c := range out {
1018                 if 'A' <= c && c <= 'Z' {
1019                         out[i] += 'a' - 'A'
1020                 }
1021         }
1022         return string(out)
1023 }
1024
1025 // VerifyHostname returns nil if c is a valid certificate for the named host.
1026 // Otherwise it returns an error describing the mismatch.
1027 //
1028 // IP addresses can be optionally enclosed in square brackets and are checked
1029 // against the IPAddresses field. Other names are checked case insensitively
1030 // against the DNSNames field. If the names are valid hostnames, the certificate
1031 // fields can have a wildcard as the left-most label.
1032 //
1033 // Note that the legacy Common Name field is ignored.
1034 func (c *Certificate) VerifyHostname(h string) error {
1035         // IP addresses may be written in [ ].
1036         candidateIP := h
1037         if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
1038                 candidateIP = h[1 : len(h)-1]
1039         }
1040         if ip := net.ParseIP(candidateIP); ip != nil {
1041                 // We only match IP addresses against IP SANs.
1042                 // See RFC 6125, Appendix B.2.
1043                 for _, candidate := range c.IPAddresses {
1044                         if ip.Equal(candidate) {
1045                                 return nil
1046                         }
1047                 }
1048                 return HostnameError{c, candidateIP}
1049         }
1050
1051         candidateName := toLowerCaseASCII(h) // Save allocations inside the loop.
1052         validCandidateName := validHostnameInput(candidateName)
1053
1054         for _, match := range c.DNSNames {
1055                 // Ideally, we'd only match valid hostnames according to RFC 6125 like
1056                 // browsers (more or less) do, but in practice Go is used in a wider
1057                 // array of contexts and can't even assume DNS resolution. Instead,
1058                 // always allow perfect matches, and only apply wildcard and trailing
1059                 // dot processing to valid hostnames.
1060                 if validCandidateName && validHostnamePattern(match) {
1061                         if matchHostnames(match, candidateName) {
1062                                 return nil
1063                         }
1064                 } else {
1065                         if matchExactly(match, candidateName) {
1066                                 return nil
1067                         }
1068                 }
1069         }
1070
1071         return HostnameError{c, h}
1072 }
1073
1074 func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
1075         usages := make([]ExtKeyUsage, len(keyUsages))
1076         copy(usages, keyUsages)
1077
1078         if len(chain) == 0 {
1079                 return false
1080         }
1081
1082         usagesRemaining := len(usages)
1083
1084         // We walk down the list and cross out any usages that aren't supported
1085         // by each certificate. If we cross out all the usages, then the chain
1086         // is unacceptable.
1087
1088 NextCert:
1089         for i := len(chain) - 1; i >= 0; i-- {
1090                 cert := chain[i]
1091                 if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
1092                         // The certificate doesn't have any extended key usage specified.
1093                         continue
1094                 }
1095
1096                 for _, usage := range cert.ExtKeyUsage {
1097                         if usage == ExtKeyUsageAny {
1098                                 // The certificate is explicitly good for any usage.
1099                                 continue NextCert
1100                         }
1101                 }
1102
1103                 const invalidUsage ExtKeyUsage = -1
1104
1105         NextRequestedUsage:
1106                 for i, requestedUsage := range usages {
1107                         if requestedUsage == invalidUsage {
1108                                 continue
1109                         }
1110
1111                         for _, usage := range cert.ExtKeyUsage {
1112                                 if requestedUsage == usage {
1113                                         continue NextRequestedUsage
1114                                 }
1115                         }
1116
1117                         usages[i] = invalidUsage
1118                         usagesRemaining--
1119                         if usagesRemaining == 0 {
1120                                 return false
1121                         }
1122                 }
1123         }
1124
1125         return true
1126 }