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 comparision 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 pathalogical 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 // ekuPermittedBy returns true iff the given extended key usage is permitted by 547 // the given EKU from a certificate. Normally, this would be a simple 548 // comparison plus a special case for the any EKU. But, in order to support 549 // existing certificates, some exceptions are made. 550 func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool { 551 if certEKU == ExtKeyUsageAny || eku == certEKU { 552 return true 553 } 554 555 // Some exceptions are made to support existing certificates. Firstly, 556 // the ServerAuth and SGC EKUs are treated as a group. 557 mapServerAuthEKUs := func(eku ExtKeyUsage) ExtKeyUsage { 558 if eku == ExtKeyUsageNetscapeServerGatedCrypto || eku == ExtKeyUsageMicrosoftServerGatedCrypto { 559 return ExtKeyUsageServerAuth 560 } 561 return eku 562 } 563 564 eku = mapServerAuthEKUs(eku) 565 certEKU = mapServerAuthEKUs(certEKU) 566 567 if eku == certEKU || 568 // ServerAuth in a CA permits ClientAuth in the leaf. 569 (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) || 570 // Any CA may issue an OCSP responder certificate. 571 eku == ExtKeyUsageOCSPSigning || 572 // Code-signing CAs can use Microsoft's commercial and 573 // kernel-mode EKUs. 574 ((eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning) { 575 return true 576 } 577 578 return false 579 } 580 581 // isValid performs validity checks on c given that it is a candidate to append 582 // to the chain in currentChain. 583 func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error { 584 if len(c.UnhandledCriticalExtensions) > 0 { 585 return UnhandledCriticalExtension{} 586 } 587 588 if len(currentChain) > 0 { 589 child := currentChain[len(currentChain)-1] 590 if !bytes.Equal(child.RawIssuer, c.RawSubject) { 591 return CertificateInvalidError{c, NameMismatch, ""} 592 } 593 } 594 595 now := opts.CurrentTime 596 if now.IsZero() { 597 now = time.Now() 598 } 599 if now.Before(c.NotBefore) || now.After(c.NotAfter) { 600 return CertificateInvalidError{c, Expired, ""} 601 } 602 603 maxConstraintComparisons := opts.MaxConstraintComparisions 604 if maxConstraintComparisons == 0 { 605 maxConstraintComparisons = 250000 606 } 607 comparisonCount := 0 608 609 var leaf *Certificate 610 if certType == intermediateCertificate || certType == rootCertificate { 611 if len(currentChain) == 0 { 612 return errors.New("x509: internal error: empty chain when appending CA cert") 613 } 614 leaf = currentChain[0] 615 } 616 617 if (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() { 618 sanExtension, ok := leaf.getSANExtension() 619 if !ok { 620 // This is the deprecated, legacy case of depending on 621 // the CN as a hostname. Chains modern enough to be 622 // using name constraints should not be depending on 623 // CNs. 624 return CertificateInvalidError{c, NameConstraintsWithoutSANs, ""} 625 } 626 627 err := forEachSAN(sanExtension, func(tag int, data []byte) error { 628 switch tag { 629 case nameTypeEmail: 630 name := string(data) 631 mailbox, ok := parseRFC2821Mailbox(name) 632 if !ok { 633 // This certificate should not have parsed. 634 return errors.New("x509: internal error: rfc822Name SAN failed to parse") 635 } 636 637 if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox, 638 func(parsedName, constraint interface{}) (bool, error) { 639 return matchEmailConstraint(parsedName.(rfc2821Mailbox), constraint.(string)) 640 }, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil { 641 return err 642 } 643 644 case nameTypeDNS: 645 name := string(data) 646 if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name, 647 func(parsedName, constraint interface{}) (bool, error) { 648 return matchDomainConstraint(parsedName.(string), constraint.(string)) 649 }, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil { 650 return err 651 } 652 653 case nameTypeURI: 654 name := string(data) 655 uri, err := url.Parse(name) 656 if err != nil { 657 return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name) 658 } 659 660 if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "URI", name, uri, 661 func(parsedName, constraint interface{}) (bool, error) { 662 return matchURIConstraint(parsedName.(*url.URL), constraint.(string)) 663 }, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil { 664 return err 665 } 666 667 case nameTypeIP: 668 ip := net.IP(data) 669 if l := len(ip); l != net.IPv4len && l != net.IPv6len { 670 return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data) 671 } 672 673 if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip, 674 func(parsedName, constraint interface{}) (bool, error) { 675 return matchIPConstraint(parsedName.(net.IP), constraint.(*net.IPNet)) 676 }, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil { 677 return err 678 } 679 680 default: 681 // Unknown SAN types are ignored. 682 } 683 684 return nil 685 }) 686 687 if err != nil { 688 return err 689 } 690 } 691 692 checkEKUs := certType == intermediateCertificate 693 694 // If no extended key usages are specified, then all are acceptable. 695 if checkEKUs && (len(c.ExtKeyUsage) == 0 && len(c.UnknownExtKeyUsage) == 0) { 696 checkEKUs = false 697 } 698 699 // If the any key usage is permitted, then no more checks are needed. 700 if checkEKUs { 701 for _, caEKU := range c.ExtKeyUsage { 702 comparisonCount++ 703 if caEKU == ExtKeyUsageAny { 704 checkEKUs = false 705 break 706 } 707 } 708 } 709 710 if checkEKUs { 711 NextEKU: 712 for _, eku := range leaf.ExtKeyUsage { 713 if comparisonCount > maxConstraintComparisons { 714 return CertificateInvalidError{c, TooManyConstraints, ""} 715 } 716 717 for _, caEKU := range c.ExtKeyUsage { 718 comparisonCount++ 719 if ekuPermittedBy(eku, caEKU) { 720 continue NextEKU 721 } 722 } 723 724 oid, _ := oidFromExtKeyUsage(eku) 725 return CertificateInvalidError{c, CANotAuthorizedForExtKeyUsage, fmt.Sprintf("EKU not permitted: %#v", oid)} 726 } 727 728 NextUnknownEKU: 729 for _, eku := range leaf.UnknownExtKeyUsage { 730 if comparisonCount > maxConstraintComparisons { 731 return CertificateInvalidError{c, TooManyConstraints, ""} 732 } 733 734 for _, caEKU := range c.UnknownExtKeyUsage { 735 comparisonCount++ 736 if caEKU.Equal(eku) { 737 continue NextUnknownEKU 738 } 739 } 740 741 return CertificateInvalidError{c, CANotAuthorizedForExtKeyUsage, fmt.Sprintf("EKU not permitted: %#v", eku)} 742 } 743 } 744 745 // KeyUsage status flags are ignored. From Engineering Security, Peter 746 // Gutmann: A European government CA marked its signing certificates as 747 // being valid for encryption only, but no-one noticed. Another 748 // European CA marked its signature keys as not being valid for 749 // signatures. A different CA marked its own trusted root certificate 750 // as being invalid for certificate signing. Another national CA 751 // distributed a certificate to be used to encrypt data for the 752 // countrys tax authority that was marked as only being usable for 753 // digital signatures but not for encryption. Yet another CA reversed 754 // the order of the bit flags in the keyUsage due to confusion over 755 // encoding endianness, essentially setting a random keyUsage in 756 // certificates that it issued. Another CA created a self-invalidating 757 // certificate by adding a certificate policy statement stipulating 758 // that the certificate had to be used strictly as specified in the 759 // keyUsage, and a keyUsage containing a flag indicating that the RSA 760 // encryption key could only be used for Diffie-Hellman key agreement. 761 762 if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) { 763 return CertificateInvalidError{c, NotAuthorizedToSign, ""} 764 } 765 766 if c.BasicConstraintsValid && c.MaxPathLen >= 0 { 767 numIntermediates := len(currentChain) - 1 768 if numIntermediates > c.MaxPathLen { 769 return CertificateInvalidError{c, TooManyIntermediates, ""} 770 } 771 } 772 773 return nil 774 } 775 776 // Verify attempts to verify c by building one or more chains from c to a 777 // certificate in opts.Roots, using certificates in opts.Intermediates if 778 // needed. If successful, it returns one or more chains where the first 779 // element of the chain is c and the last element is from opts.Roots. 780 // 781 // If opts.Roots is nil and system roots are unavailable the returned error 782 // will be of type SystemRootsError. 783 // 784 // Name constraints in the intermediates will be applied to all names claimed 785 // in the chain, not just opts.DNSName. Thus it is invalid for a leaf to claim 786 // example.com if an intermediate doesn't permit it, even if example.com is not 787 // the name being validated. Note that DirectoryName constraints are not 788 // supported. 789 // 790 // Extended Key Usage values are enforced down a chain, so an intermediate or 791 // root that enumerates EKUs prevents a leaf from asserting an EKU not in that 792 // list. 793 // 794 // WARNING: this function doesn't do any revocation checking. 795 func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) { 796 // Platform-specific verification needs the ASN.1 contents so 797 // this makes the behavior consistent across platforms. 798 if len(c.Raw) == 0 { 799 return nil, errNotParsed 800 } 801 if opts.Intermediates != nil { 802 for _, intermediate := range opts.Intermediates.certs { 803 if len(intermediate.Raw) == 0 { 804 return nil, errNotParsed 805 } 806 } 807 } 808 809 // Use Windows's own verification and chain building. 810 if opts.Roots == nil && runtime.GOOS == "windows" { 811 return c.systemVerify(&opts) 812 } 813 814 if opts.Roots == nil { 815 opts.Roots = systemRootsPool() 816 if opts.Roots == nil { 817 return nil, SystemRootsError{systemRootsErr} 818 } 819 } 820 821 err = c.isValid(leafCertificate, nil, &opts) 822 if err != nil { 823 return 824 } 825 826 if len(opts.DNSName) > 0 { 827 err = c.VerifyHostname(opts.DNSName) 828 if err != nil { 829 return 830 } 831 } 832 833 requestedKeyUsages := make([]ExtKeyUsage, len(opts.KeyUsages)) 834 copy(requestedKeyUsages, opts.KeyUsages) 835 if len(requestedKeyUsages) == 0 { 836 requestedKeyUsages = append(requestedKeyUsages, ExtKeyUsageServerAuth) 837 } 838 839 // If no key usages are specified, then any are acceptable. 840 checkEKU := len(c.ExtKeyUsage) > 0 841 842 for _, eku := range requestedKeyUsages { 843 if eku == ExtKeyUsageAny { 844 checkEKU = false 845 break 846 } 847 } 848 849 if checkEKU { 850 NextUsage: 851 for _, eku := range requestedKeyUsages { 852 for _, leafEKU := range c.ExtKeyUsage { 853 if ekuPermittedBy(eku, leafEKU) { 854 continue NextUsage 855 } 856 } 857 858 oid, _ := oidFromExtKeyUsage(eku) 859 return nil, CertificateInvalidError{c, IncompatibleUsage, fmt.Sprintf("%#v", oid)} 860 } 861 } 862 863 var candidateChains [][]*Certificate 864 if opts.Roots.contains(c) { 865 candidateChains = append(candidateChains, []*Certificate{c}) 866 } else { 867 if candidateChains, err = c.buildChains(make(map[int][][]*Certificate), []*Certificate{c}, &opts); err != nil { 868 return nil, err 869 } 870 } 871 872 return candidateChains, nil 873 } 874 875 func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate { 876 n := make([]*Certificate, len(chain)+1) 877 copy(n, chain) 878 n[len(chain)] = cert 879 return n 880 } 881 882 func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) { 883 possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c) 884 nextRoot: 885 for _, rootNum := range possibleRoots { 886 root := opts.Roots.certs[rootNum] 887 888 for _, cert := range currentChain { 889 if cert.Equal(root) { 890 continue nextRoot 891 } 892 } 893 894 err = root.isValid(rootCertificate, currentChain, opts) 895 if err != nil { 896 continue 897 } 898 chains = append(chains, appendToFreshChain(currentChain, root)) 899 } 900 901 possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c) 902 nextIntermediate: 903 for _, intermediateNum := range possibleIntermediates { 904 intermediate := opts.Intermediates.certs[intermediateNum] 905 for _, cert := range currentChain { 906 if cert.Equal(intermediate) { 907 continue nextIntermediate 908 } 909 } 910 err = intermediate.isValid(intermediateCertificate, currentChain, opts) 911 if err != nil { 912 continue 913 } 914 var childChains [][]*Certificate 915 childChains, ok := cache[intermediateNum] 916 if !ok { 917 childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts) 918 cache[intermediateNum] = childChains 919 } 920 chains = append(chains, childChains...) 921 } 922 923 if len(chains) > 0 { 924 err = nil 925 } 926 927 if len(chains) == 0 && err == nil { 928 hintErr := rootErr 929 hintCert := failedRoot 930 if hintErr == nil { 931 hintErr = intermediateErr 932 hintCert = failedIntermediate 933 } 934 err = UnknownAuthorityError{c, hintErr, hintCert} 935 } 936 937 return 938 } 939 940 func matchHostnames(pattern, host string) bool { 941 host = strings.TrimSuffix(host, ".") 942 pattern = strings.TrimSuffix(pattern, ".") 943 944 if len(pattern) == 0 || len(host) == 0 { 945 return false 946 } 947 948 patternParts := strings.Split(pattern, ".") 949 hostParts := strings.Split(host, ".") 950 951 if len(patternParts) != len(hostParts) { 952 return false 953 } 954 955 for i, patternPart := range patternParts { 956 if i == 0 && patternPart == "*" { 957 continue 958 } 959 if patternPart != hostParts[i] { 960 return false 961 } 962 } 963 964 return true 965 } 966 967 // toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use 968 // an explicitly ASCII function to avoid any sharp corners resulting from 969 // performing Unicode operations on DNS labels. 970 func toLowerCaseASCII(in string) string { 971 // If the string is already lower-case then there's nothing to do. 972 isAlreadyLowerCase := true 973 for _, c := range in { 974 if c == utf8.RuneError { 975 // If we get a UTF-8 error then there might be 976 // upper-case ASCII bytes in the invalid sequence. 977 isAlreadyLowerCase = false 978 break 979 } 980 if 'A' <= c && c <= 'Z' { 981 isAlreadyLowerCase = false 982 break 983 } 984 } 985 986 if isAlreadyLowerCase { 987 return in 988 } 989 990 out := []byte(in) 991 for i, c := range out { 992 if 'A' <= c && c <= 'Z' { 993 out[i] += 'a' - 'A' 994 } 995 } 996 return string(out) 997 } 998 999 // VerifyHostname returns nil if c is a valid certificate for the named host. 1000 // Otherwise it returns an error describing the mismatch. 1001 func (c *Certificate) VerifyHostname(h string) error { 1002 // IP addresses may be written in [ ]. 1003 candidateIP := h 1004 if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' { 1005 candidateIP = h[1 : len(h)-1] 1006 } 1007 if ip := net.ParseIP(candidateIP); ip != nil { 1008 // We only match IP addresses against IP SANs. 1009 // https://tools.ietf.org/html/rfc6125#appendix-B.2 1010 for _, candidate := range c.IPAddresses { 1011 if ip.Equal(candidate) { 1012 return nil 1013 } 1014 } 1015 return HostnameError{c, candidateIP} 1016 } 1017 1018 lowered := toLowerCaseASCII(h) 1019 1020 if c.hasSANExtension() { 1021 for _, match := range c.DNSNames { 1022 if matchHostnames(toLowerCaseASCII(match), lowered) { 1023 return nil 1024 } 1025 } 1026 // If Subject Alt Name is given, we ignore the common name. 1027 } else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) { 1028 return nil 1029 } 1030 1031 return HostnameError{c, h} 1032 } 1033