Skip to content

Commit

Permalink
Add support for SHA256 thumbprint based vCenter authentication
Browse files Browse the repository at this point in the history
vSphere in general is moving from SHA1 to SHA256 based TLS certificate thumbprints.
This change allows use of SHA256 thumbprint when connecting to vCenter.

govc: the about.cert command '-thumbprint' flag now outputs SHA256 instead of SHA1
  • Loading branch information
dougm committed Mar 12, 2024
1 parent edf70dc commit 2799634
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 17 deletions.
2 changes: 1 addition & 1 deletion govc/about/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (r *certResult) Write(w io.Writer) error {

if r.cmd.thumbprint {
u := r.cmd.Session.URL
_, err := fmt.Fprintf(w, "%s %s\n", u.Host, r.info.ThumbprintSHA1)
_, err := fmt.Fprintf(w, "%s %s\n", u.Host, r.info.ThumbprintSHA256)
return err
}

Expand Down
8 changes: 7 additions & 1 deletion govc/test/cli.bats
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ load test_helper
run govc about.cert -show
assert_success

# with -k=true we get thumbprint output and exit 0
# with -k=true we get sha256 thumbprint output and exit 0
thumbprint=$(govc about.cert -k=true -thumbprint)

# with -k=true we get thumbprint output and exit 60
Expand All @@ -77,6 +77,12 @@ load test_helper

run govc about -k=false -tls-known-hosts <(echo "nope nope")
assert_failure

# sha1 backwards compatibility
host=$(awk '{print $1}'<<<"$thumbprint")
sha1=$(govc about.cert -k=true -json | jq -r .thumbprintSHA1)
run govc about -k=false -tls-known-hosts <(echo "$host $sha1")
assert_success
}

@test "version" {
Expand Down
10 changes: 1 addition & 9 deletions object/host_certificate_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package object

import (
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
Expand Down Expand Up @@ -58,14 +57,7 @@ func (info *HostCertificateInfo) FromCertificate(cert *x509.Certificate) *HostCe
info.Subject = info.fromName(info.subjectName)

info.ThumbprintSHA1 = soap.ThumbprintSHA1(cert)

// SHA-256 for info purposes only, API fields all use SHA-1
sum := sha256.Sum256(cert.Raw)
hex := make([]string, len(sum))
for i, b := range sum {
hex[i] = fmt.Sprintf("%02X", b)
}
info.ThumbprintSHA256 = strings.Join(hex, ":")
info.ThumbprintSHA256 = soap.ThumbprintSHA256(cert)

if info.Status == "" {
info.Status = string(types.HostCertificateManagerCertificateInfoCertificateStatusUnknown)
Expand Down
26 changes: 20 additions & 6 deletions vim25/soap/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"bytes"
"context"
"crypto/sha1"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/json"
Expand Down Expand Up @@ -387,6 +388,20 @@ func ThumbprintSHA1(cert *x509.Certificate) string {
return strings.Join(hex, ":")
}

// ThumbprintSHA256 returns the sha256 thumbprint of the given cert.
func ThumbprintSHA256(cert *x509.Certificate) string {
sum := sha256.Sum256(cert.Raw)
hex := make([]string, len(sum))
for i, b := range sum {
hex[i] = fmt.Sprintf("%02X", b)
}
return strings.Join(hex, ":")
}

func thumbprintMatches(thumbprint string, cert *x509.Certificate) bool {
return thumbprint == ThumbprintSHA256(cert) || thumbprint == ThumbprintSHA1(cert)
}

func (c *Client) dialTLSContext(
ctx context.Context,
network, addr string) (net.Conn, error) {
Expand Down Expand Up @@ -418,14 +433,13 @@ func (c *Client) dialTLSContext(
}

cert := conn.ConnectionState().PeerCertificates[0]
peer := ThumbprintSHA1(cert)
if thumbprint != peer {
_ = conn.Close()

return nil, fmt.Errorf("host %q thumbprint does not match %q", addr, thumbprint)
if thumbprintMatches(thumbprint, cert) {
return conn, nil
}

return conn, nil
_ = conn.Close()

return nil, fmt.Errorf("host %q thumbprint does not match %q", addr, thumbprint)
}

// splitHostPort is similar to net.SplitHostPort,
Expand Down

0 comments on commit 2799634

Please sign in to comment.