func getTLSConfig()

in registry/registry.go [251:331]


func getTLSConfig(ctx context.Context, config configuration.TLS, http2Disabled bool) (*tls.Config, error) {
	if config.Certificate == "" && config.LetsEncrypt.CacheFile == "" {
		return nil, errSkipTLSConfig
	}

	tlsMinVersion, ok := tlsLookup[config.MinimumTLS]
	if !ok {
		return nil, fmt.Errorf("unknown minimum TLS level %q specified for http.tls.minimumtls", config.MinimumTLS)
	}

	if config.MinimumTLS != "" {
		dcontext.GetLogger(ctx).WithFields(log.Fields{"minimum_tls": config.MinimumTLS}).Info("restricting minimum TLS version")
	}

	var tlsCipherSuites []uint16
	// configuring cipher suites are no longer supported after the tls1.3.
	if tlsMinVersion > tls.VersionTLS12 {
		dcontext.GetLogger(ctx).Warnf("ignoring configured TLS cipher suites as they are not configurable in %s", config.MinimumTLS)
	} else {
		tlsCipherSuites, err := getCipherSuites(config.CipherSuites)
		if err != nil {
			return nil, fmt.Errorf("parsing cipher suites: %w", err)
		}
		dcontext.GetLogger(ctx).Infof("restricting TLS cipher suites to: %s", strings.Join(getCipherSuiteNames(tlsCipherSuites), ","))
	}

	// nolint gosec,G402
	tlsConf := &tls.Config{
		ClientAuth:               tls.NoClientCert,
		NextProtos:               nextProtos(http2Disabled),
		MinVersion:               tlsMinVersion,
		PreferServerCipherSuites: true,
		CipherSuites:             tlsCipherSuites,
	}

	if config.LetsEncrypt.CacheFile != "" {
		if config.Certificate != "" {
			return nil, fmt.Errorf("cannot specify both certificate and Let's Encrypt")
		}
		m := &autocert.Manager{
			HostPolicy: autocert.HostWhitelist(config.LetsEncrypt.Hosts...),
			Cache:      autocert.DirCache(config.LetsEncrypt.CacheFile),
			Email:      config.LetsEncrypt.Email,
			Prompt:     autocert.AcceptTOS,
		}
		tlsConf.GetCertificate = m.GetCertificate
		tlsConf.NextProtos = append(tlsConf.NextProtos, acme.ALPNProto)
	} else {
		var err error
		tlsConf.Certificates = make([]tls.Certificate, 1)
		tlsConf.Certificates[0], err = tls.LoadX509KeyPair(config.Certificate, config.Key)
		if err != nil {
			return nil, err
		}
	}

	if len(config.ClientCAs) != 0 {
		pool := x509.NewCertPool()

		for _, ca := range config.ClientCAs {
			// nolint: gosec
			caPem, err := os.ReadFile(ca)
			if err != nil {
				return nil, err
			}

			if ok := pool.AppendCertsFromPEM(caPem); !ok {
				return nil, fmt.Errorf("could not add CA to pool")
			}
		}

		for _, subj := range pool.Subjects() {
			dcontext.GetLogger(ctx).WithFields(log.Fields{"ca_subject": string(subj)}).Debug("client CA subject")
		}

		tlsConf.ClientAuth = tls.RequireAndVerifyClientCert
		tlsConf.ClientCAs = pool
	}

	return tlsConf, nil
}