cherry-pick commits to 1.34.x (#4229)

Co-authored-by: Easwar Swaminathan <easwars@google.com>

This is a cherry pick of 
- encoding/proto: do not panic when types do not match (#4218)
- xds: add env var protection for client-side security (#4247)
diff --git a/encoding/proto/proto.go b/encoding/proto/proto.go
index e1230fd..3009b35 100644
--- a/encoding/proto/proto.go
+++ b/encoding/proto/proto.go
@@ -21,6 +21,8 @@
 package proto
 
 import (
+	"fmt"
+
 	"github.com/golang/protobuf/proto"
 	"google.golang.org/grpc/encoding"
 )
@@ -36,11 +38,19 @@
 type codec struct{}
 
 func (codec) Marshal(v interface{}) ([]byte, error) {
-	return proto.Marshal(v.(proto.Message))
+	vv, ok := v.(proto.Message)
+	if !ok {
+		return nil, fmt.Errorf("failed to marshal, message is %T, want proto.Message", v)
+	}
+	return proto.Marshal(vv)
 }
 
 func (codec) Unmarshal(data []byte, v interface{}) error {
-	return proto.Unmarshal(data, v.(proto.Message))
+	vv, ok := v.(proto.Message)
+	if !ok {
+		return fmt.Errorf("failed to unmarshal, message is %T, want proto.Message", v)
+	}
+	return proto.Unmarshal(data, vv)
 }
 
 func (codec) Name() string {
diff --git a/vet.sh b/vet.sh
index b41df6d..4012b05 100755
--- a/vet.sh
+++ b/vet.sh
@@ -28,7 +28,7 @@
 }
 trap cleanup EXIT
 
-PATH="${GOPATH}/bin:${GOROOT}/bin:${PATH}"
+PATH="${HOME}/go/bin:${GOROOT}/bin:${PATH}"
 
 if [[ "$1" = "-install" ]]; then
   # Check for module support
diff --git a/xds/internal/client/client_cds_test.go b/xds/internal/client/client_cds_test.go
index 6cba7ef..a8ec411 100644
--- a/xds/internal/client/client_cds_test.go
+++ b/xds/internal/client/client_cds_test.go
@@ -31,6 +31,7 @@
 	anypb "github.com/golang/protobuf/ptypes/any"
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
+	"google.golang.org/grpc/xds/internal/env"
 	"google.golang.org/grpc/xds/internal/version"
 )
 
@@ -184,7 +185,65 @@
 	}
 }
 
+func (s) TestValidateClusterWithSecurityConfig_EnvVarOff(t *testing.T) {
+	// Turn off the env var protection for client-side security.
+	origClientSideSecurityEnvVar := env.ClientSideSecuritySupport
+	env.ClientSideSecuritySupport = false
+	defer func() { env.ClientSideSecuritySupport = origClientSideSecurityEnvVar }()
+
+	cluster := &v3clusterpb.Cluster{
+		ClusterDiscoveryType: &v3clusterpb.Cluster_Type{Type: v3clusterpb.Cluster_EDS},
+		EdsClusterConfig: &v3clusterpb.Cluster_EdsClusterConfig{
+			EdsConfig: &v3corepb.ConfigSource{
+				ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{
+					Ads: &v3corepb.AggregatedConfigSource{},
+				},
+			},
+			ServiceName: serviceName,
+		},
+		LbPolicy: v3clusterpb.Cluster_ROUND_ROBIN,
+		TransportSocket: &v3corepb.TransportSocket{
+			Name: "envoy.transport_sockets.tls",
+			ConfigType: &v3corepb.TransportSocket_TypedConfig{
+				TypedConfig: &anypb.Any{
+					TypeUrl: version.V3UpstreamTLSContextURL,
+					Value: func() []byte {
+						tls := &v3tlspb.UpstreamTlsContext{
+							CommonTlsContext: &v3tlspb.CommonTlsContext{
+								ValidationContextType: &v3tlspb.CommonTlsContext_ValidationContextCertificateProviderInstance{
+									ValidationContextCertificateProviderInstance: &v3tlspb.CommonTlsContext_CertificateProviderInstance{
+										InstanceName:    "rootInstance",
+										CertificateName: "rootCert",
+									},
+								},
+							},
+						}
+						mtls, _ := proto.Marshal(tls)
+						return mtls
+					}(),
+				},
+			},
+		},
+	}
+	wantUpdate := ClusterUpdate{
+		ServiceName: serviceName,
+		EnableLRS:   false,
+	}
+	gotUpdate, err := validateCluster(cluster)
+	if err != nil {
+		t.Errorf("validateCluster() failed: %v", err)
+	}
+	if diff := cmp.Diff(wantUpdate, gotUpdate); diff != "" {
+		t.Errorf("validateCluster() returned unexpected diff (-want, got):\n%s", diff)
+	}
+}
+
 func (s) TestValidateClusterWithSecurityConfig(t *testing.T) {
+	// Turn on the env var protection for client-side security.
+	origClientSideSecurityEnvVar := env.ClientSideSecuritySupport
+	env.ClientSideSecuritySupport = true
+	defer func() { env.ClientSideSecuritySupport = origClientSideSecurityEnvVar }()
+
 	const (
 		identityPluginInstance = "identityPluginInstance"
 		identityCertName       = "identityCert"
diff --git a/xds/internal/client/client_xds.go b/xds/internal/client/client_xds.go
index af25ce2..0d36a50 100644
--- a/xds/internal/client/client_xds.go
+++ b/xds/internal/client/client_xds.go
@@ -33,6 +33,7 @@
 	v3typepb "github.com/envoyproxy/go-control-plane/envoy/type/v3"
 	"github.com/golang/protobuf/proto"
 	anypb "github.com/golang/protobuf/ptypes/any"
+	"google.golang.org/grpc/xds/internal/env"
 
 	"google.golang.org/grpc/internal/grpclog"
 	"google.golang.org/grpc/xds/internal"
@@ -305,9 +306,14 @@
 		return emptyUpdate, fmt.Errorf("xds: unexpected lbPolicy %v in response: %+v", cluster.GetLbPolicy(), cluster)
 	}
 
-	sc, err := securityConfigFromCluster(cluster)
-	if err != nil {
-		return emptyUpdate, err
+	// Process security configuration received from the control plane iff the
+	// corresponding environment variable is set.
+	var sc *SecurityConfig
+	if env.ClientSideSecuritySupport {
+		var err error
+		if sc, err = securityConfigFromCluster(cluster); err != nil {
+			return emptyUpdate, err
+		}
 	}
 	return ClusterUpdate{
 		ServiceName: cluster.GetEdsClusterConfig().GetServiceName(),
diff --git a/xds/internal/env/env.go b/xds/internal/env/env.go
index 3b338ea..26b97ec 100644
--- a/xds/internal/env/env.go
+++ b/xds/internal/env/env.go
@@ -26,8 +26,9 @@
 )
 
 const (
-	bootstrapFileNameEnv = "GRPC_XDS_BOOTSTRAP"
-	xdsV3SupportEnv      = "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT"
+	bootstrapFileNameEnv         = "GRPC_XDS_BOOTSTRAP"
+	xdsV3SupportEnv              = "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT"
+	clientSideSecuritySupportEnv = "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT"
 )
 
 var (
@@ -39,4 +40,11 @@
 	// done by setting the environment variable
 	// "GRPC_XDS_EXPERIMENTAL_V3_SUPPORT" to "true".
 	V3Support = strings.EqualFold(os.Getenv(xdsV3SupportEnv), "true")
+	// ClientSideSecuritySupport is used to control processing of security
+	// configuration on the client-side.
+	//
+	// Note that there is no env var protection for the server-side because we
+	// have a brand new API on the server-side and users explicitly need to use
+	// the new API to get security integration on the server.
+	ClientSideSecuritySupport = strings.EqualFold(os.Getenv(clientSideSecuritySupportEnv), "true")
 )