Repository: traefik/traefik
File: pkg/tls/tlsmanager.go (Go)

Code before:
	}

	tlsConfig.GetCertificate = func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
		domainToCheck := types.CanonicalDomain(clientHello.ServerName)

		if isACMETLS(clientHello) {
			certificate := acmeTLSStore.GetBestCertificate(clientHello)
			if certificate == nil {
				log.WithoutContext().Debugf("TLS: no certificate for TLSALPN challenge: %s", domainToCheck)
				// Let crypto/tls determine the appropriate error and the TLS alert.
				// https://cs.opensource.google/go/go/+/dev.boringcrypto.go1.17:src/crypto/tls/common.go;l=1058
				return nil, nil
			}

			return certificate, nil
		}

		bestCertificate := store.GetBestCertificate(clientHello)
		if bestCertificate != nil {
			return bestCertificate, nil
		}

		if sniStrict {
			log.WithoutContext().Debugf("TLS: strict SNI enabled - No certificate found for domain: %q, closing connection", domainToCheck)
			// Let crypto/tls determine the appropriate error and the TLS alert.
			// https://cs.opensource.google/go/go/+/dev.boringcrypto.go1.17:src/crypto/tls/common.go;l=1058
			return nil, nil
		}

		log.WithoutContext().Debugf("Serving default certificate for request: %q", domainToCheck)
		return store.DefaultCertificate, nil
	}

	return tlsConfig, err
}

// GetCertificates returns all stored certificates.
func (m *Manager) GetCertificates() []*x509.Certificate {
	var certificates []*x509.Certificate

	// We iterate over all the certificates.
	for _, store := range m.stores {
		if store.DynamicCerts != nil && store.DynamicCerts.Get() != nil {
			for _, cert := range store.DynamicCerts.Get().(map[string]*tls.Certificate) {
				x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
				if err != nil {
					continue
				}

				certificates = append(certificates, x509Cert)
			}

Review comment (suggestion):
```suggestion
			// Same comment as above, as in the isACMETLS case.
```

Code after:
	}

	tlsConfig.GetCertificate = func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
		domainToCheck := types.CanonicalDomain(clientHello.ServerName)

		if isACMETLS(clientHello) {
			certificate := acmeTLSStore.GetBestCertificate(clientHello)
			if certificate == nil {
				log.WithoutContext().Debugf("TLS: no certificate for TLSALPN challenge: %s", domainToCheck)
				// We want the user to eventually get the (alertUnrecognizedName) "unrecognized
				// name" error.
				// Unfortunately, if we returned an error here, since we can't use
				// the unexported error (errNoCertificates) that our caller (config.getCertificate
				// in crypto/tls) uses as a sentinel, it would report an (alertInternalError)
				// "internal error" instead of an alertUnrecognizedName.
				// Which is why we return no error, and we let the caller detect that there's
				// actually no certificate, and fall back into the flow that will report
				// the desired error.
				// https://cs.opensource.google/go/go/+/dev.boringcrypto.go1.17:src/crypto/tls/common.go;l=1058
				return nil, nil
			}

			return certificate, nil
		}

		bestCertificate := store.GetBestCertificate(clientHello)
		if bestCertificate != nil {
			return bestCertificate, nil
		}

		if sniStrict {
			log.WithoutContext().Debugf("TLS: strict SNI enabled - No certificate found for domain: %q, closing connection", domainToCheck)
			// Same comment as above, as in the isACMETLS case.
			return nil, nil
		}

		log.WithoutContext().Debugf("Serving default certificate for request: %q", domainToCheck)
		return store.DefaultCertificate, nil
	}

	return tlsConfig, err
}

// GetCertificates returns all stored certificates.
func (m *Manager) GetCertificates() []*x509.Certificate {
	var certificates []*x509.Certificate

	// We iterate over all the certificates.
	for _, store := range m.stores {
		if store.DynamicCerts != nil && store.DynamicCerts.Get() != nil {
			for _, cert := range store.DynamicCerts.Get().(map[string]*tls.Certificate) {