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