Skip to content

Commit

Permalink
Explicitly set ServerName in TLS config for WCP (vmware-tanzu#465) (v…
Browse files Browse the repository at this point in the history
…mware-tanzu#466)

This change sets ServerName in TLS config in case a leaf cert is set as
ca_file. This will effectively bypass hostname verification, as required
in WCP NSX-VC registration. The rest of the cert will still be checked
as-is.

Signed-off-by: Shawn Wang <[email protected]>
  • Loading branch information
wsquan171 authored Jan 4, 2024
1 parent fee54ef commit 4233623
Show file tree
Hide file tree
Showing 3 changed files with 228 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pkg/nsx/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ func (cluster *Cluster) createTransport(idle time.Duration) *Transport {
RootCAs: certPool,
}

// Bypass CN / SAN verification by setting tls config ServerName to the one in cert
if cn, err := util.GetCommonNameFromLeafCert(caCert); err == nil {
log.Info("pinned common name for manager", "cn", cn, "addr", addr)
config.ServerName = cn
}
} else {
thumbprint := cluster.getThumbprint(addr)
tpCount := len(cluster.config.Thumbprint)
Expand Down
31 changes: 31 additions & 0 deletions pkg/nsx/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ package util
import (
"crypto/sha1"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -389,3 +391,32 @@ func VerifyNsxCertWithThumbprint(der []byte, thumbprint string) error {
log.Error(err, "verify thumbprint", "server", tbFromCert, "local", tbRaw)
return err
}

// GetCommonNameFromLeafCert returns the common name of the first (leaf) cert of
// provided pemCerts. If CA cert is passed, empty CN will be returned.
// Error is returned if pem invalid or not a certificate.
func GetCommonNameFromLeafCert(pemCerts []byte) (string, error) {
block, _ := pem.Decode(pemCerts)
if block == nil {
err := errors.New("decode ca file fail")
log.Error(err, "failed to get CN from cert", "pem", pemCerts)
return "", err
}
if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
err := errors.New("pem not certificate or header not found")
log.Error(err, "failed to get CN from cert", "pem", pemCerts)
return "", err
}

cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
log.Error(err, "failed to get CN from cert", "pem", pemCerts)
return "", err
}

if cert.IsCA {
return "", nil
}

return cert.Subject.CommonName, nil
}
192 changes: 192 additions & 0 deletions pkg/nsx/util/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,195 @@ func TestVerifyNsxCertWithThumbprint(t *testing.T) {
})
}
}

func TestGetCommonNameFromCert(t *testing.T) {
tests := []struct {
name string
pem []byte
cn string
wantErr bool
}{
{
name: "One cert",
pem: []byte(`
-----BEGIN CERTIFICATE-----
MIID5DCCAsygAwIBAgIJAIJaVMN4AJHVMA0GCSqGSIb3DQEBCwUAMIGIMTQwMgYD
VQQDDCtuc3htYW5hZ2VyLW9iLTIyOTQ1MzY4LTEtZGV2LWludGVnLW5zeC05Mzg5
MQwwCgYDVQQLDANOU1gxFDASBgNVBAoMC1ZNd2FyZSBJbmMuMRIwEAYDVQQHDAlQ
YWxvIEFsdG8xCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzAeFw0yNDAxMDIxNjMw
NDVaFw0yNjA0MDYxNjMwNDVaMIGIMTQwMgYDVQQDDCtuc3htYW5hZ2VyLW9iLTIy
OTQ1MzY4LTEtZGV2LWludGVnLW5zeC05Mzg5MQwwCgYDVQQLDANOU1gxFDASBgNV
BAoMC1ZNd2FyZSBJbmMuMRIwEAYDVQQHDAlQYWxvIEFsdG8xCzAJBgNVBAgMAkNB
MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu8
y0kFT2knFi0TVDD344n3QQWx/8y+Y0wKE3oo6jSXlL8h7JQId7Zp4sdgemunt3nL
rjXFjujgMQzDiBILiYvrO4sWbht7v71sOLjj00RofC4vAPM+Xl3vhn4VCRRix99w
f0IDphOPfbVgNajHUIe3Gt3U69ZngUBfXXbpGVK8cCEo6C2JZ7bVj95zNj0n6Tuw
SjMdVfZh4iCqqacnZWqZScRbuyg/t7Gog2GN9XBePkklsmhNlbXwWggZsYosTs/u
U1zo2O92OZ4wnZXLBtAbv77FyLfV7zq7K42QfkG+RcHDbK9ygVsuadXoW+X2FRcc
hYod4nPS/MNxkCUqcF0CAwEAAaNPME0wEwYDVR0lBAwwCgYIKwYBBQUHAwEwNgYD
VR0RBC8wLYIrbnN4bWFuYWdlci1vYi0yMjk0NTM2OC0xLWRldi1pbnRlZy1uc3gt
OTM4OTANBgkqhkiG9w0BAQsFAAOCAQEAfFMmJiIHrpIzLzrCSq2o+6SCyhedZSUF
xnXwrdgPPFiceWBWGN8rMvu1qq1RCG/xxQkxo5KyaAUSWxwPltpPCLQOedn9VUkY
MY2o/ZVAMwp8QoJqHz4RvSeWXEaymh22SKhN4lOnTITSalP8NSxK9G1DM8T828hj
dvHtRf4o3AyJwWRwyLM7qn8s5C1O/JJfyZ/P17nD4yn1HU9StAwWJUvLKVXeFq+Q
XkMSQJYdYDsUkiu98jNxh+oT8Cqdruwtg73pw8pP17EPltBABlHkYOEznw3dgDH3
jSy6ts7e8AND6YWulG9jLmrI1xWwjbVqAoapxJQeSRYQ6Wb/KODPlg==
-----END CERTIFICATE-----
`),
cn: "nsxmanager-ob-22945368-1-dev-integ-nsx-9389",
wantErr: false,
},
{
name: "Cert chain",
pem: []byte(`
-----BEGIN CERTIFICATE-----
MIIGuzCCBaOgAwIBAgIQdL+xbvFsTSlVxSEtNypPzzANBgkqhkiG9w0BAQsFADCB
ujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsT
H1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAy
MDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEuMCwG
A1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEwxSzAeFw0y
MzExMjkxMTU5MDZaFw0yNDExMjgxMTU5MDVaMIGDMQswCQYDVQQGEwJVUzETMBEG
A1UECBMKQ2FsaWZvcm5pYTESMBAGA1UEBxMJUGFsbyBBbHRvMRQwEgYDVQQKEwtW
TXdhcmUsIEluYzE1MDMGA1UEAxMsbnN4TWFuYWdlci5zZGRjLTEwLTIxNS0yMDgt
MjUwLnZtd2FyZXZtYy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDeIz8U7Pgkl6NKnqu7kqtwDjBMUN4fxdC54jTqaKr4zDG7d67DwivcPfMl3S1m
CXKaJr4Ma+Yw0ZCJTwJNv1lGR2R9D+ZgWrvzlPk2ZpfQTuBGHgQnRu960XnsQ31f
u4jDZsNTlhU99KrycFQEJ7RJh+yFaCgiO3OZDHr11vDuunaixswGUIUiCjE4tHRu
/p6ZCItxClgqKTkCkc2s69f21l1CsyM6+PEAIOQ0xfgh8OKBMjbEhrhNdWRluFeW
FJ9LwBNDVBcYM0csflwfVLp4Bz8xZYg7EOfwTU13tDvf2Haekhs6JAftFbeY3BoO
DiOck8hs/TtTyEkVm3RQSM6rAgMBAAGjggLwMIIC7DAMBgNVHRMBAf8EAjAAMB0G
A1UdDgQWBBROPMWy5jA5THUuB9g0O4aFqNllWjAfBgNVHSMEGDAWgBSConB03bxT
P8971PfNf6dgxgpMvzBoBggrBgEFBQcBAQRcMFowIwYIKwYBBQUHMAGGF2h0dHA6
Ly9vY3NwLmVudHJ1c3QubmV0MDMGCCsGAQUFBzAChidodHRwOi8vYWlhLmVudHJ1
c3QubmV0L2wxay1jaGFpbjI1Ni5jZXIwMwYDVR0fBCwwKjAooCagJIYiaHR0cDov
L2NybC5lbnRydXN0Lm5ldC9sZXZlbDFrLmNybDA3BgNVHREEMDAugixuc3hNYW5h
Z2VyLnNkZGMtMTAtMjE1LTIwOC0yNTAudm13YXJldm1jLmNvbTAOBgNVHQ8BAf8E
BAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBMGA1UdIAQMMAow
CAYGZ4EMAQICMIIBfgYKKwYBBAHWeQIEAgSCAW4EggFqAWgAdgA/F0tP1yJHWJQd
ZRyEvg0S7ZA3fx+FauvBvyiF7PhkbgAAAYwa8nZuAAAEAwBHMEUCIQCg2ui4od8a
O8yY5PtUZqTAt6joqU18H26ei+50IDFgpQIgY3QovIXCUvO/KxCuaoBCLyP4N9bX
PkbJ34+udBcn0LoAdgBVgdTCFpA2AUrqC5tXPFPwwOQ4eHAlCBcvo6odBxPTDAAA
AYwa8naOAAAEAwBHMEUCIQD6VTtewFcapQcv8o0Kt2PEy2vp6D3EW1Ewb0op1fTP
FQIgb9TOwY0Mu1xNyuCcwhrtBhJfiq0wpGabPufrg/yXYosAdgDuzdBk1dsazsVc
t520zROiModGfLzs3sNRSFlGcR+1mwAAAYwa8naeAAAEAwBHMEUCIQDUfeW1yQqL
m/ECwaEGK/FIUM8ecofKHt1SE57sbCAbnAIgW7SOcSFSXR8t2rnkQx2YlvS0MV5g
qzxN5NjPODJPc7IwDQYJKoZIhvcNAQELBQADggEBAAvgvh1vJlyUewvUgWmOuVim
bXVnMu2nsqhE3tU5yDVyfG48IWAe6L/YMOSCjGfRPHKOLU0YbgLVTkoIDZqIdphQ
uXfDOmJb542/EyKq+0DYLj4WOfxvL85ALxpwt1w1YXxO68+eDJmGDSHkoGYlCx56
TZizCvI/Dpvv2SAjX8RwO+DJ/etTYmdpu5DC2yY7ucxcM6SelSGcGP/kSNZjZ2Q9
k3HQdLg+sEm+YBCm5FInysatHz5HLgzOOKtNttGnR4E+AxAnL7yig6ZjTQFMu5B3
JkRniwg2hfDP088aI5f+5vCePx7ai6R9MHEvpgHkExeWDXX/Z6RyXfQzESPWA6M=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw
CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl
IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg
RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD
EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x
NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG
A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l
dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt
IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ
jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK
m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT
JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt
LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F
ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/
BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG
AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah
hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE
VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd
BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe
733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw
y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS
BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC
k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv
c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1
exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u
Lcw=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
-----END CERTIFICATE-----
`),
cn: "nsxManager.sddc-10-215-208-250.vmwarevmc.com",
wantErr: false,
},
{
name: "ca cert",
pem: []byte(`
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw
CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl
IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg
RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD
EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x
NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG
A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l
dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt
IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp
ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ
jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK
m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT
JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt
LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F
ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/
BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG
AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah
hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE
VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd
BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe
733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw
y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS
BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC
k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv
c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1
exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u
Lcw=
-----END CERTIFICATE-----
`),
cn: "",
wantErr: false,
},
{
name: "malformed pem",
pem: []byte("MIID5DCCAsygAwIBAgIJAIJaVMN4AJHVMA0GCSqGSIb3DQEBCwUAMIGIMTQwMgYD"),
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cn, err := GetCommonNameFromLeafCert(tt.pem)
if tt.wantErr {
assert.Error(t, err, "GetCommonNameFromCert expected err returned")
} else {
assert.Equal(t, tt.cn, cn)
}
})
}
}

0 comments on commit 4233623

Please sign in to comment.