The function buildVerifyFunc is used when users want root cert reloading, and possibly custom verification check. We have to build our own verification function here because current tls module: 1. does not have a good support on root cert reloading. 2. will ignore basic certificate check when settin
(c *advancedTLSCreds, serverName string, rawConn net.Conn, peerVerifiedChains *CertificateChains)
| 510 | // 1. For server it is, client certs + Root ca that the server trusts |
| 511 | // 2. For client it is, server certs + Root ca that the client trusts |
| 512 | func buildVerifyFunc(c *advancedTLSCreds, |
| 513 | serverName string, |
| 514 | rawConn net.Conn, |
| 515 | peerVerifiedChains *CertificateChains) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { |
| 516 | return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { |
| 517 | chains := verifiedChains |
| 518 | var leafCert *x509.Certificate |
| 519 | rawCertList := make([]*x509.Certificate, len(rawCerts)) |
| 520 | for i, asn1Data := range rawCerts { |
| 521 | cert, err := x509.ParseCertificate(asn1Data) |
| 522 | if err != nil { |
| 523 | return err |
| 524 | } |
| 525 | rawCertList[i] = cert |
| 526 | } |
| 527 | if c.verificationType == CertAndHostVerification || c.verificationType == CertVerification { |
| 528 | // perform possible trust credential reloading and certificate check |
| 529 | rootCAs := c.config.RootCAs |
| 530 | if !c.isClient { |
| 531 | rootCAs = c.config.ClientCAs |
| 532 | } |
| 533 | // Reload root CA certs. |
| 534 | if rootCAs == nil && c.getRootCertificates != nil { |
| 535 | results, err := c.getRootCertificates(&ConnectionInfo{ |
| 536 | RawConn: rawConn, |
| 537 | RawCerts: rawCerts, |
| 538 | }) |
| 539 | if err != nil { |
| 540 | return err |
| 541 | } |
| 542 | rootCAs = results.TrustCerts |
| 543 | } |
| 544 | // Verify peers' certificates against RootCAs and get verifiedChains. |
| 545 | keyUsages := []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} |
| 546 | if !c.isClient { |
| 547 | keyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} |
| 548 | } |
| 549 | opts := x509.VerifyOptions{ |
| 550 | Roots: rootCAs, |
| 551 | CurrentTime: time.Now(), |
| 552 | Intermediates: x509.NewCertPool(), |
| 553 | KeyUsages: keyUsages, |
| 554 | } |
| 555 | for _, cert := range rawCertList[1:] { |
| 556 | opts.Intermediates.AddCert(cert) |
| 557 | } |
| 558 | // Perform default hostname check if specified. |
| 559 | if c.isClient && c.verificationType == CertAndHostVerification && serverName != "" { |
| 560 | parsedName, _, err := net.SplitHostPort(serverName) |
| 561 | if err != nil { |
| 562 | // If the serverName had no host port or if the serverName cannot be |
| 563 | // parsed, use it as-is. |
| 564 | parsedName = serverName |
| 565 | } |
| 566 | opts.DNSName = parsedName |
| 567 | } |
| 568 | var err error |
| 569 | chains, err = rawCertList[0].Verify(opts) |
no test coverage detected