Repository: cloudnative-pg/cloudnative-pg

Issue:
[Feature]: Allow users to control TLS verification mode in inter-pod communication
### Is there an existing issue already for this bug?

- [X] I have searched for an existing issue, and could not find anything. I believe this is a new bug.

### I have read the troubleshooting guide

- [X] I have read the troubleshooting guide and I think this is a new bug.

### I am running a supported version of CloudNativePG

- [X] I have read the troubleshooting guide and I think this is a new bug.

### Contact Details

_No response_

### Version

1.23.2

### What version of Kubernetes are you using?

1.30 (unsupported)

### What is your Kubernetes environment?

Self-managed: kind (evaluation)

### How did you install the operator?

YAML manifest

### What happened?

Currently, internal communication between pods is verified using CA only because it is not guaranteed that the server certificate contains the name of the cluster-rw service.
This should be under the user's control, allowing full verification if the server certificate supports it. 

### Cluster resource

_No response_

### Relevant log output

_No response_

### Code of Conduct

- [X] I agree to follow this project's Code of Conduct

Hints from issue comments:
@mnencia: This is not a bug. It's a feature and should not be backported.@github-actions: This issue is stale because it has been open for 60 days with no activity.@github-actions: This issue was closed because it has been inactive for 14 days since being marked as stale.

Solution patch:
diff --git a/docs/src/certificates.md b/docs/src/certificates.md
index e85052c2..e89ec99e 100644
--- a/docs/src/certificates.md
+++ b/docs/src/certificates.md
@@ -26,6 +26,12 @@ primarily operates in two modes:
 You can also choose a hybrid approach, where only part of the certificates is
 generated outside CNPG.
 
+!!! Note
+    The operator and instances verify server certificates against the CA only,
+    disregarding the DNS name. This approach is due to the typical absence of DNS
+    names in user-provided certificates for the `<cluster>-rw` service used for
+    communication within the cluster.
+
 ## Operator-managed mode
 
 By default, the operator generates a single CA and uses it for both client and
@@ -63,7 +69,7 @@ is passed as `ssl_ca_file` to all the instances so it can verify client
 certificates it signed. The private key is stored in the same secret and used
 to sign client certificates generated by the `kubectl cnpg` plugin.
 
-#### Client `streaming_replica`` certificate
+#### Client `streaming_replica` certificate
 
 The operator uses the generated self-signed CA to sign a client certificate for
 the user `streaming_replica`, storing it in a secret of type
@@ -89,6 +95,12 @@ the following parameters:
     The operator still creates and manages the two secrets related to client
     certificates.
 
+!!! Note
+    The operator and instances verify server certificates against the CA only,
+    disregarding the DNS name. This approach is due to the typical absence of DNS
+    names in user-provided certificates for the `<cluster>-rw` service used for
+    communication within the cluster.
+
 !!! Note
     If you want ConfigMaps and secrets to be reloaded by instances, you can add
     a label with the key `cnpg.io/reload` to it. Otherwise you must reload the
diff --git a/internal/cmd/manager/instance/status/cmd.go b/internal/cmd/manager/instance/status/cmd.go
index 17cf03e4..ceb85bbb 100644
--- a/internal/cmd/manager/instance/status/cmd.go
+++ b/internal/cmd/manager/instance/status/cmd.go
@@ -65,7 +65,6 @@ func statusSubCommand(ctx context.Context) error {
 		ctx,
 		cli,
 		cluster.GetServerCASecretObjectKey(),
-		cluster.GetServiceReadWriteName(),
 	)
 	if err != nil {
 		log.Error(err, "Error while building the TLS context")
diff --git a/internal/controller/backup_controller.go b/internal/controller/backup_controller.go
index b898edf7..995e2dff 100644
--- a/internal/controller/backup_controller.go
+++ b/internal/controller/backup_controller.go
@@ -148,7 +148,6 @@ func (r *BackupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
 		ctx,
 		r.Client,
 		cluster.GetServerCASecretObjectKey(),
-		cluster.GetServiceReadWriteName(),
 	)
 	if err != nil {
 		return ctrl.Result{}, err
diff --git a/internal/controller/cluster_controller.go b/internal/controller/cluster_controller.go
index 24d0a993..4191ee5d 100644
--- a/internal/controller/cluster_controller.go
+++ b/internal/controller/cluster_controller.go
@@ -264,7 +264,6 @@ func (r *ClusterReconciler) reconcile(ctx context.Context, cluster *apiv1.Cluste
 		ctx,
 		r.Client,
 		cluster.GetServerCASecretObjectKey(),
-		cluster.GetServiceReadWriteName(),
 	)
 	if err != nil {
 		return ctrl.Result{}, err
diff --git a/pkg/certs/tls.go b/pkg/certs/tls.go
index 32b1cfdf..eb9c9f87 100644
--- a/pkg/certs/tls.go
+++ b/pkg/certs/tls.go
@@ -32,12 +32,11 @@ type contextKey string
 // contextKeyTLSConfig is the context key holding the TLS configuration
 const contextKeyTLSConfig contextKey = "tlsConfig"
 
-// newTLSConfigFromSecret creates a tls.Config from the given CA secret and serverName pair
+// newTLSConfigFromSecret creates a tls.Config from the given CA secret.
 func newTLSConfigFromSecret(
 	ctx context.Context,
 	cli client.Client,
 	caSecret types.NamespacedName,
-	serverName string,
 ) (*tls.Config, error) {
 	secret := &v1.Secret{}
 	err := cli.Get(ctx, caSecret, secret)
@@ -50,12 +49,45 @@ func newTLSConfigFromSecret(
 		return nil, fmt.Errorf("missing %s entry in secret %s", CACertKey, caSecret.Name)
 	}
 
+	// The operator will verify the certificates only against the CA, ignoring the DNS name.
+	// This behavior is because user-provided certificates could not have the DNS name
+	// for the <cluster>-rw service, which would cause a name verification error.
 	caCertPool := x509.NewCertPool()
 	caCertPool.AppendCertsFromPEM(caCertificate)
 	tlsConfig := tls.Config{
-		MinVersion: tls.VersionTLS13,
-		ServerName: serverName,
-		RootCAs:    caCertPool,
+		MinVersion:         tls.VersionTLS13,
+		RootCAs:            caCertPool,
+		InsecureSkipVerify: true, //#nosec G402 -- we are verifying the certificate ourselves
+		VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
+			// Code adapted from https://go.dev/src/crypto/tls/handshake_client.go#L986
+			if len(rawCerts) == 0 {
+				return fmt.Errorf("no raw certificates provided")
+			}
+
+			certs := make([]*x509.Certificate, len(rawCerts))
+			for i, rawCert := range rawCerts {
+				cert, err := x509.ParseCertificate(rawCert)
+				if err != nil {
+					return fmt.Errorf("failed to parse certificate: %v", err)
+				}
+				certs[i] = cert
+			}
+
+			opts := x509.VerifyOptions{
+				Roots:         caCertPool,
+				Intermediates: x509.NewCertPool(),
+			}
+
+			for _, cert := range certs[1:] {
+				opts.Intermediates.AddCert(cert)
+			}
+			_, err := certs[0].Verify(opts)
+			if err != nil {
+				return &tls.CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
+			}
+
+			return nil
+		},
 	}
 
 	return &tlsConfig, nil
@@ -67,9 +99,8 @@ func NewTLSConfigForContext(
 	ctx context.Context,
 	cli client.Client,
 	caSecret types.NamespacedName,
-	serverName string,
 ) (context.Context, error) {
-	conf, err := newTLSConfigFromSecret(ctx, cli, caSecret, serverName)
+	conf, err := newTLSConfigFromSecret(ctx, cli, caSecret)
 	if err != nil {
 		return nil, err
 	}



Test patch:
diff --git a/pkg/certs/tls_test.go b/pkg/certs/tls_test.go
index 7602e23a..8e998765 100644
--- a/pkg/certs/tls_test.go
+++ b/pkg/certs/tls_test.go
@@ -19,6 +19,8 @@ package certs
 import (
 	"context"
 	"crypto/tls"
+	"encoding/pem"
+	"errors"
 	"fmt"
 
 	v1 "k8s.io/api/core/v1"
@@ -33,44 +35,240 @@ import (
 
 var _ = Describe("newTLSConfigFromSecret", func() {
 	var (
-		ctx        context.Context
-		c          client.Client
-		caSecret   types.NamespacedName
-		serverName string
+		ctx      context.Context
+		c        client.Client
+		caSecret types.NamespacedName
 	)
 
 	BeforeEach(func() {
 		ctx = context.TODO()
 		caSecret = types.NamespacedName{Name: "test-secret", Namespace: "default"}
-		serverName = "test-server"
 	})
 
 	Context("when the secret is found and valid", func() {
 		BeforeEach(func() {
-			secretData := map[string][]byte{
-				CACertKey: []byte(`-----BEGIN CERTIFICATE-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Qe3X7Q6WZpXqlXkq0Bd
-... (rest of the CA certificate) ...
------END CERTIFICATE-----`),
+			caData := map[string][]byte{
+				CACertKey: []byte(`
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            66:10:89:ae:f9:55:99:81:9c:34:cc:ff:1e:86:e8:7e:3c:47:61:34
+        Signature Algorithm: ecdsa-with-SHA256
+        Issuer: CN=CA
+        Validity
+            Not Before: Jun 18 15:36:59 2024 GMT
+            Not After : Jun 16 15:36:59 2034 GMT
+        Subject: CN=CA
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (384 bit)
+                pub:
+                    04:8f:69:ab:43:73:b9:1a:38:03:38:5f:e6:ec:9e:
+                    7f:1e:9a:bd:96:82:7f:aa:3d:f9:1f:63:ae:5a:7a:
+                    a6:c2:c4:38:0a:d2:9e:27:38:9f:ae:51:2d:98:db:
+                    86:32:0f:d5:17:dd:77:73:56:67:08:71:51:5a:bb:
+                    54:48:d7:26:fe:35:b0:d0:04:e5:4d:61:71:86:16:
+                    41:4a:5b:9c:b2:fd:4d:39:9f:8f:60:2b:40:81:62:
+                    a6:b6:4f:92:4d:ae:1e
+                ASN1 OID: secp384r1
+                NIST CURVE: P-384
+        X509v3 extensions:
+            X509v3 Subject Key Identifier:
+                6F:18:E5:45:77:82:87:82:D5:C2:4D:21:18:7B:7D:51:07:F1:60:5F
+            X509v3 Authority Key Identifier:
+                6F:18:E5:45:77:82:87:82:D5:C2:4D:21:18:7B:7D:51:07:F1:60:5F
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+    Signature Algorithm: ecdsa-with-SHA256
+    Signature Value:
+        30:65:02:30:05:da:f0:d9:a9:f0:a1:b0:a7:00:51:7b:ab:eb:
+        42:c6:5d:a8:5c:40:a5:4b:ca:0d:99:3d:98:6e:2c:cd:00:7e:
+        e8:63:19:6d:24:ef:63:c0:30:5e:25:cb:be:a0:ca:40:02:31:
+        00:df:04:a0:53:93:81:52:48:17:90:28:e2:6f:b7:47:3d:71:
+        06:7c:11:0b:37:dc:ae:14:9f:12:86:9b:fb:26:b3:1e:a7:8f:
+        76:75:20:09:b5:76:bf:27:db:ab:76:70:73
+-----BEGIN CERTIFICATE-----
+MIIBrDCCATKgAwIBAgIUZhCJrvlVmYGcNMz/HobofjxHYTQwCgYIKoZIzj0EAwIw
+DTELMAkGA1UEAwwCQ0EwHhcNMjQwNjE4MTUzNjU5WhcNMzQwNjE2MTUzNjU5WjAN
+MQswCQYDVQQDDAJDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABI9pq0NzuRo4Azhf
+5uyefx6avZaCf6o9+R9jrlp6psLEOArSnic4n65RLZjbhjIP1Rfdd3NWZwhxUVq7
+VEjXJv41sNAE5U1hcYYWQUpbnLL9TTmfj2ArQIFiprZPkk2uHqNTMFEwHQYDVR0O
+BBYEFG8Y5UV3goeC1cJNIRh7fVEH8WBfMB8GA1UdIwQYMBaAFG8Y5UV3goeC1cJN
+IRh7fVEH8WBfMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDaAAwZQIwBdrw
+2anwobCnAFF7q+tCxl2oXEClS8oNmT2YbizNAH7oYxltJO9jwDBeJcu+oMpAAjEA
+3wSgU5OBUkgXkCjib7dHPXEGfBELN9yuFJ8Shpv7JrMep492dSAJtXa/J9urdnBz
+-----END CERTIFICATE-----
+`),
 			}
-			secret := &v1.Secret{
+			ca := &v1.Secret{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      caSecret.Name,
 					Namespace: caSecret.Namespace,
 				},
-				Data: secretData,
+				Data: caData,
 			}
-			c = fake.NewClientBuilder().WithObjects(secret).Build()
+			c = fake.NewClientBuilder().WithObjects(ca).Build()
 		})
 
-		It("should return a valid tls.Config", func() {
-			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret, serverName)
+		It("should return a valid tls.Config", func(ctx context.Context) {
+			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret)
 			Expect(err).NotTo(HaveOccurred())
 			Expect(tlsConfig).NotTo(BeNil())
 			Expect(tlsConfig.MinVersion).To(Equal(uint16(tls.VersionTLS13)))
-			Expect(tlsConfig.ServerName).To(Equal(serverName))
 			Expect(tlsConfig.RootCAs).ToNot(BeNil())
 		})
+
+		It("should validate good certificates", func(ctx context.Context) {
+			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret)
+			Expect(err).NotTo(HaveOccurred())
+			serverBlock, _ := pem.Decode([]byte(`
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            79:eb:2b:67:38:42:f3:39:b1:3c:2e:25:28:fb:53:56:b5:9a:4b:e1
+        Signature Algorithm: ecdsa-with-SHA256
+        Issuer: CN=CA
+        Validity
+            Not Before: Jun 18 15:36:59 2024 GMT
+            Not After : Jun 16 15:36:59 2034 GMT
+        Subject: CN=server
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (384 bit)
+                pub:
+                    04:79:7f:27:60:cc:25:b1:cf:d4:4a:06:a6:86:8e:
+                    66:1f:e8:1f:dc:1b:1a:fb:3f:ea:74:ec:3f:ca:c1:
+                    68:ac:b1:e1:e7:68:53:98:f1:f7:35:9a:b1:c5:c5:
+                    b3:9a:9f:1b:8d:ab:2f:06:b4:79:2a:10:af:c5:c6:
+                    e7:22:82:93:81:9c:f1:65:34:69:ba:b9:aa:09:48:
+                    3a:da:dd:a4:52:5b:a1:58:6a:8a:d8:71:b1:eb:78:
+                    9f:88:b3:32:dd:71:b0
+                ASN1 OID: secp384r1
+                NIST CURVE: P-384
+        X509v3 extensions:
+            X509v3 Basic Constraints:
+                CA:FALSE
+            Netscape Cert Type:
+                SSL Server
+            Netscape Comment:
+                OpenSSL Generated Server Certificate
+            X509v3 Subject Key Identifier:
+                CA:71:9F:5C:D0:C4:1C:12:D4:60:5E:9C:05:A3:84:F4:FF:56:E1:1E
+            X509v3 Authority Key Identifier:
+                keyid:6F:18:E5:45:77:82:87:82:D5:C2:4D:21:18:7B:7D:51:07:F1:60:5F
+                DirName:/CN=CA
+                serial:66:10:89:AE:F9:55:99:81:9C:34:CC:FF:1E:86:E8:7E:3C:47:61:34
+            X509v3 Key Usage: critical
+                Digital Signature, Key Encipherment
+            X509v3 Extended Key Usage:
+                TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name:
+                DNS:server.private.tld
+    Signature Algorithm: ecdsa-with-SHA256
+    Signature Value:
+        30:64:02:30:3c:af:af:1f:0c:ed:44:d9:79:92:42:d4:a8:dc:
+        9c:9b:b1:26:5e:fe:e8:0f:1f:8e:a1:dd:66:1f:f2:fc:81:72:
+        89:93:42:f5:74:6a:a2:ea:96:4d:3d:c9:a8:8e:c1:40:02:30:
+        67:18:f5:7f:15:52:99:4c:b5:4c:15:f3:e8:7d:2c:52:fb:45:
+        87:f1:60:6f:ab:f8:a9:43:dd:44:4e:b1:34:9c:37:95:b6:54:
+        67:11:eb:db:15:e4:e4:ea:7f:0b:0e:8e
+-----BEGIN CERTIFICATE-----
+MIICbDCCAfOgAwIBAgIUeesrZzhC8zmxPC4lKPtTVrWaS+EwCgYIKoZIzj0EAwIw
+DTELMAkGA1UEAwwCQ0EwHhcNMjQwNjE4MTUzNjU5WhcNMzQwNjE2MTUzNjU5WjAR
+MQ8wDQYDVQQDDAZzZXJ2ZXIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR5fydgzCWx
+z9RKBqaGjmYf6B/cGxr7P+p07D/KwWisseHnaFOY8fc1mrHFxbOanxuNqy8GtHkq
+EK/FxucigpOBnPFlNGm6uaoJSDra3aRSW6FYaorYcbHreJ+IszLdcbCjggEOMIIB
+CjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYk
+T3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBTK
+cZ9c0MQcEtRgXpwFo4T0/1bhHjBIBgNVHSMEQTA/gBRvGOVFd4KHgtXCTSEYe31R
+B/FgX6ERpA8wDTELMAkGA1UEAwwCQ0GCFGYQia75VZmBnDTM/x6G6H48R2E0MA4G
+A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYD
+VR0RBBYwFIISc2VydmVyLnByaXZhdGUudGxkMAoGCCqGSM49BAMCA2cAMGQCMDyv
+rx8M7UTZeZJC1KjcnJuxJl7+6A8fjqHdZh/y/IFyiZNC9XRqouqWTT3JqI7BQAIw
+Zxj1fxVSmUy1TBXz6H0sUvtFh/Fgb6v4qUPdRE6xNJw3lbZUZxHr2xXk5Op/Cw6O
+-----END CERTIFICATE-----
+`))
+			err = tlsConfig.VerifyPeerCertificate([][]byte{serverBlock.Bytes}, nil)
+			Expect(err).ShouldNot(HaveOccurred())
+		})
+
+		It("should reject bad certificates", func(ctx context.Context) {
+			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret)
+			Expect(err).NotTo(HaveOccurred())
+			badServerBlock, _ := pem.Decode([]byte(`Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            79:eb:2b:67:38:42:f3:39:b1:3c:2e:25:28:fb:53:56:b5:9a:4b:e2
+        Signature Algorithm: ecdsa-with-SHA256
+        Issuer: CN=CA
+        Validity
+            Not Before: Jun 18 16:01:44 2024 GMT
+            Not After : Jun 16 16:01:44 2034 GMT
+        Subject: CN=server
+        Subject Public Key Info:
+            Public Key Algorithm: id-ecPublicKey
+                Public-Key: (384 bit)
+                pub:
+                    04:9a:14:de:61:60:87:c8:de:53:54:29:56:04:db:
+                    5a:0c:7c:45:cf:ef:4e:62:1c:dc:f3:98:45:4d:2e:
+                    f8:34:6b:70:05:ab:06:ff:37:fb:e2:56:3c:b1:f3:
+                    ee:7f:23:32:c0:5b:f2:9c:09:99:e7:d8:d7:7c:84:
+                    c4:d8:4c:01:51:c1:24:9b:ac:d8:cb:b9:97:48:01:
+                    32:1e:0b:16:6c:bb:1a:b1:9d:d3:e2:51:c4:a1:39:
+                    65:61:a2:bf:81:bd:78
+                ASN1 OID: secp384r1
+                NIST CURVE: P-384
+        X509v3 extensions:
+            X509v3 Basic Constraints:
+                CA:FALSE
+            Netscape Cert Type:
+                SSL Server
+            Netscape Comment:
+                OpenSSL Generated Server Certificate
+            X509v3 Subject Key Identifier:
+                5D:53:DE:D3:60:C9:77:C6:E9:48:FF:B9:AA:27:44:DF:DF:73:C7:61
+            X509v3 Authority Key Identifier:
+                keyid:0B:71:A6:BF:D0:1D:23:64:26:24:B2:E3:FA:32:48:A7:F6:81:C1:CA
+                DirName:/CN=CA
+                serial:41:EF:37:0F:BE:78:0B:72:63:75:C5:71:85:44:D8:EC:F3:D7:65:45
+            X509v3 Key Usage: critical
+                Digital Signature, Key Encipherment
+            X509v3 Extended Key Usage:
+                TLS Web Server Authentication, TLS Web Client Authentication
+            X509v3 Subject Alternative Name:
+                DNS:server.private.tld
+    Signature Algorithm: ecdsa-with-SHA256
+    Signature Value:
+        30:66:02:31:00:f7:14:2c:d0:2a:8a:3a:a7:43:1e:f6:82:fe:
+        40:24:e7:8d:e1:47:d8:71:8b:8c:5f:8a:03:fa:ac:c1:a2:a9:
+        99:89:a5:06:e8:7a:9d:76:73:e0:5c:8c:db:0e:c6:43:f6:02:
+        31:00:8a:1a:a2:1d:f9:78:fa:3b:a8:27:a2:2f:71:86:ed:2b:
+        6f:34:a7:32:3a:d4:46:86:b5:bf:67:79:f8:ee:57:b2:c1:3b:
+        2c:6b:49:74:82:ab:77:6a:7b:12:ec:04:e9:d9
+-----BEGIN CERTIFICATE-----
+MIICbjCCAfOgAwIBAgIUeesrZzhC8zmxPC4lKPtTVrWaS+IwCgYIKoZIzj0EAwIw
+DTELMAkGA1UEAwwCQ0EwHhcNMjQwNjE4MTYwMTQ0WhcNMzQwNjE2MTYwMTQ0WjAR
+MQ8wDQYDVQQDDAZzZXJ2ZXIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASaFN5hYIfI
+3lNUKVYE21oMfEXP705iHNzzmEVNLvg0a3AFqwb/N/viVjyx8+5/IzLAW/KcCZnn
+2Nd8hMTYTAFRwSSbrNjLuZdIATIeCxZsuxqxndPiUcShOWVhor+BvXijggEOMIIB
+CjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDAzBglghkgBhvhCAQ0EJhYk
+T3BlblNTTCBHZW5lcmF0ZWQgU2VydmVyIENlcnRpZmljYXRlMB0GA1UdDgQWBBRd
+U97TYMl3xulI/7mqJ0Tf33PHYTBIBgNVHSMEQTA/gBQLcaa/0B0jZCYksuP6Mkin
+9oHByqERpA8wDTELMAkGA1UEAwwCQ0GCFEHvNw++eAtyY3XFcYVE2Ozz12VFMA4G
+A1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYD
+VR0RBBYwFIISc2VydmVyLnByaXZhdGUudGxkMAoGCCqGSM49BAMCA2kAMGYCMQD3
+FCzQKoo6p0Me9oL+QCTnjeFH2HGLjF+KA/qswaKpmYmlBuh6nXZz4FyM2w7GQ/YC
+MQCKGqId+Xj6O6gnoi9xhu0rbzSnMjrURoa1v2d5+O5XssE7LGtJdIKrd2p7EuwE
+6dk=
+-----END CERTIFICATE-----
+`))
+			err = tlsConfig.VerifyPeerCertificate([][]byte{badServerBlock.Bytes}, nil)
+			var certError *tls.CertificateVerificationError
+			Expect(errors.As(err, &certError)).To(BeTrue())
+		})
 	})
 
 	Context("when the secret is not found", func() {
@@ -79,7 +277,7 @@ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Qe3X7Q6WZpXqlXkq0Bd
 		})
 
 		It("should return an error", func() {
-			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret, serverName)
+			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret)
 			Expect(err).To(HaveOccurred())
 			Expect(tlsConfig).To(BeNil())
 			Expect(err.Error()).To(ContainSubstring(fmt.Sprintf("while getting caSecret %s", caSecret.Name)))
@@ -98,7 +296,7 @@ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Qe3X7Q6WZpXqlXkq0Bd
 		})
 
 		It("should return an error", func() {
-			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret, serverName)
+			tlsConfig, err := newTLSConfigFromSecret(ctx, c, caSecret)
 			Expect(err).To(HaveOccurred())
 			Expect(tlsConfig).To(BeNil())
 			Expect(err.Error()).To(ContainSubstring(fmt.Sprintf("missing %s entry in secret %s", CACertKey, caSecret.Name)))