Repository: caddyserver/caddy
File: modules/caddyhttp/reverseproxy/httptransport.go (Go)

Code before:
			caCert, err := decodeBase64DERCert(encodedCACert)
			if err != nil {
				return nil, fmt.Errorf("parsing CA certificate: %v", err)
			}
			rootPool.AddCert(caCert)
		}
		for _, pemFile := range t.RootCAPEMFiles {
			pemData, err := os.ReadFile(pemFile)
			if err != nil {
				return nil, fmt.Errorf("failed reading ca cert: %v", err)
			}
			rootPool.AppendCertsFromPEM(pemData)
		}
		cfg.RootCAs = rootPool
	}

	if t.CARaw != nil {
		caRaw, err := ctx.LoadModule(t, "CARaw")
		if err != nil {
			return nil, fmt.Errorf("failed to load ca module: %v", err)
		}
		ca, ok := caRaw.(caddytls.CA)
		if !ok {
			return nil, fmt.Errorf("CARaw module '%s' is not a certificate pool provider", ca)
		}
		cfg.ClientCAs = ca.CertPool()
	}

	// Renegotiation
	switch t.Renegotiation {
	case "never", "":
		cfg.Renegotiation = tls.RenegotiateNever
	case "once":
		cfg.Renegotiation = tls.RenegotiateOnceAsClient
	case "freely":
		cfg.Renegotiation = tls.RenegotiateFreelyAsClient
	default:
		return nil, fmt.Errorf("invalid TLS renegotiation level: %v", t.Renegotiation)
	}

	// override for the server name used verify the TLS handshake
	cfg.ServerName = t.ServerName

	// throw all security out the window
	cfg.InsecureSkipVerify = t.InsecureSkipVerify

	curvesAdded := make(map[tls.CurveID]struct{})
	for _, curveName := range t.Curves {
		curveID := caddytls.SupportedCurves[curveName]
		if _, ok := curvesAdded[curveID]; !ok {
			curvesAdded[curveID] = struct{}{}

Review comment (suggestion):
The `ClientCAs` field is for servers who are validating incoming client connections. In reverse-proxy transport, we're doing the opposite. We need the block above to be edited, i.e. modifying the source of root certificates.

Code after:
		ctx.Logger().Warn("root_ca_pool and root_ca_pem_files are deprecated. Use one of the tls.ca_pool.source modules instead")
		rootPool := x509.NewCertPool()
		for _, encodedCACert := range t.RootCAPool {
			caCert, err := decodeBase64DERCert(encodedCACert)
			if err != nil {
				return nil, fmt.Errorf("parsing CA certificate: %v", err)
			}
			rootPool.AddCert(caCert)
		}
		for _, pemFile := range t.RootCAPEMFiles {
			pemData, err := os.ReadFile(pemFile)
			if err != nil {
				return nil, fmt.Errorf("failed reading ca cert: %v", err)
			}
			rootPool.AppendCertsFromPEM(pemData)
		}
		cfg.RootCAs = rootPool
	}

	if t.CARaw != nil {
		if len(t.RootCAPool) > 0 || len(t.RootCAPEMFiles) > 0 {
			return nil, fmt.Errorf("conflicting config for Root CA pool")
		}
		caRaw, err := ctx.LoadModule(t, "CARaw")
		if err != nil {
			return nil, fmt.Errorf("failed to load ca module: %v", err)
		}
		ca, ok := caRaw.(caddytls.CA)
		if !ok {
			return nil, fmt.Errorf("CA module '%s' is not a certificate pool provider", ca)
		}
		cfg.RootCAs = ca.CertPool()
	}

	// Renegotiation
	switch t.Renegotiation {
	case "never", "":
		cfg.Renegotiation = tls.RenegotiateNever
	case "once":
		cfg.Renegotiation = tls.RenegotiateOnceAsClient
	case "freely":
		cfg.Renegotiation = tls.RenegotiateFreelyAsClient
	default:
		return nil, fmt.Errorf("invalid TLS renegotiation level: %v", t.Renegotiation)
	}

	// override for the server name used verify the TLS handshake
	cfg.ServerName = t.ServerName

	// throw all security out the window
	cfg.InsecureSkipVerify = t.InsecureSkipVerify