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