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