Skip to content

Commit 1e8b828

Browse files
arampriceclaude
andcommitted
bosh-nats-sync: use code.cloudfoundry.org/tlsconfig instead of hand-rolled tls.Config
Address item 1 in PR review comment #2746 (comment): authprovider and userssync both built their director/UAA TLS client by hand (manual tls.Config{MinVersion}, x509.NewCertPool(), AppendCertsFromPEM). CF already ships code.cloudfoundry.org/tlsconfig as the standard helper for exactly this, and the reviewer noted the hand-rolled config was actually *less* hardened than the org-standard one (no MaxVersion, no cipher-suite pinning). Deliberately does NOT touch items 2/3 from the same comment (reusing bosh-cli's director/uaa packages for the director API and UAA calls) per explicit instruction to avoid a github.com/cloudfoundry/bosh-cli dependency; that remains a footprint-vs-reuse tradeoff for a future PR, not something to pull in incidentally here. pkg/authprovider/auth_provider.go: - buildHTTPClient now builds its *tls.Config via tlsconfig.Build(tlsconfig.WithExternalServiceDefaults()).Client(...), applying tlsconfig.WithAuthorityFromFile(caCertPath) only when CAFilePath() resolves to a file with non-empty content. WithExternalServiceDefaults() pins MinVersion/MaxVersion to TLS 1.2-1.3 and a curated Mozilla-Intermediate cipher-suite list, in place of the previous MinVersion-only config. - Preserves existing behavior exactly: a configured-but-unreadable CA file is still a hard error, an empty file still falls back to the system trust store, and a malformed (but present/non-empty) cert is still a hard error. pkg/userssync/users_sync.go: - buildHTTPClient now uses the same tlsconfig.Build(...).Client(...) pattern for the director API client. Replaced directorCACertPool (manual x509.CertPool + AppendCertsFromPEM) with a small usableCACertContent(path) predicate that gates whether tlsconfig.WithAuthorityFromFile is applied. - Preserves existing behavior: director_ca_cert missing/unreadable/empty falls back to the system trust store (no error, matching Ruby's usable_director_ca_cert?), while a configured-but-unparseable cert is a hard error rather than a silent fallback. pkg/userssync/export_test.go: - Replaced the removed DirectorCACertPool test hook with BuildDirectorTLSConfig, which builds the real *http.Client via buildHTTPClient and returns its *tls.Config, so tests assert against the actual TLS configuration (RootCAs, MinVersion) rather than an internal CertPool-returning helper that no longer exists. pkg/userssync/users_sync_test.go: - Rewrote the "directorCACertPool" spec block against BuildDirectorTLSConfig: same four cases (not configured / missing file / whitespace-only file / unparseable content) now assert on tlsCfg.RootCAs and the error message, plus a new case asserting MinVersion is pinned to TLS 1.2 via WithExternalServiceDefaults. Dependency footprint: go.mod/go.sum/vendor pick up code.cloudfoundry.org/tlsconfig v0.61.0 and a matching golang.org/x/sys patch bump (v0.44.0 -> v0.46.0, already an existing indirect dependency). tlsconfig's own test-only dependencies (certstrap, go.step.sm/crypto, golang.org/x/crypto, etc.) appear in go.sum for module-graph completeness but are not imported by any non-test file, so `go mod vendor` does not pull them into vendor/ or the build. Verified `go build`, `go vet`, and `go test -race ./...` all pass with both the default module resolution and explicit `-mod=vendor` (matching how packages/nats/packaging invokes go build); gofmt and golangci-lint are clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 0899a20 commit 1e8b828

83 files changed

Lines changed: 2635 additions & 831 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/bosh-nats-sync/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module bosh-nats-sync
33
go 1.26.3
44

55
require (
6+
code.cloudfoundry.org/tlsconfig v0.61.0
67
github.com/onsi/ginkgo/v2 v2.28.1
78
github.com/onsi/gomega v1.39.1
89
golang.org/x/oauth2 v0.36.0
@@ -19,7 +20,7 @@ require (
1920
golang.org/x/mod v0.34.0 // indirect
2021
golang.org/x/net v0.53.0 // indirect
2122
golang.org/x/sync v0.20.0 // indirect
22-
golang.org/x/sys v0.44.0 // indirect
23+
golang.org/x/sys v0.46.0 // indirect
2324
golang.org/x/text v0.36.0 // indirect
2425
golang.org/x/tools v0.43.0 // indirect
2526
)

src/bosh-nats-sync/go.sum

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
code.cloudfoundry.org/tlsconfig v0.61.0 h1:3qP/E7g9ZiYnl1oypzL4BlzM9hLIIOewz/jr2LdtQeQ=
2+
code.cloudfoundry.org/tlsconfig v0.61.0/go.mod h1:teqTAz1XYQdNhDEc67uy3Zu1h5ujiPqnXE1v9tffTnE=
3+
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
4+
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
15
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
26
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
37
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -32,10 +36,14 @@ github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI
3236
github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
3337
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
3438
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
39+
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
40+
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
3541
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3642
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
3743
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
3844
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
45+
github.com/square/certstrap v1.3.0 h1:N9P0ZRA+DjT8pq5fGDj0z3FjafRKnBDypP0QHpMlaAk=
46+
github.com/square/certstrap v1.3.0/go.mod h1:wGZo9eE1B7WX2GKBn0htJ+B3OuRl2UsdCFySNooy9hU=
3947
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
4048
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
4149
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
@@ -46,8 +54,12 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
4654
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
4755
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
4856
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
57+
go.step.sm/crypto v0.84.1 h1:i0JNkcLT7LcXef00TNpckjoTTH0QP6REHcAvnY3qrNY=
58+
go.step.sm/crypto v0.84.1/go.mod h1:T54MIdw42uZnz3+mjOIOpJbsbTZF+O3IOLhvU9lBoJk=
4959
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
5060
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
61+
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
62+
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
5163
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
5264
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
5365
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
@@ -56,8 +68,8 @@ golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
5668
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
5769
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
5870
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
59-
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
60-
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
71+
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
72+
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
6173
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
6274
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
6375
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=

src/bosh-nats-sync/pkg/authprovider/auth_provider.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package authprovider
22

33
import (
44
"context"
5-
"crypto/tls"
6-
"crypto/x509"
75
"encoding/base64"
86
"encoding/json"
97
"fmt"
@@ -16,6 +14,7 @@ import (
1614

1715
"bosh-nats-sync/pkg/config"
1816

17+
"code.cloudfoundry.org/tlsconfig"
1918
"golang.org/x/oauth2"
2019
"golang.org/x/oauth2/clientcredentials"
2120
)
@@ -97,24 +96,32 @@ func (a *AuthProvider) uaaTokenHeader(ctx context.Context, uaaURL string) (strin
9796
return formatBearer(tok), nil
9897
}
9998

99+
// buildHTTPClient uses code.cloudfoundry.org/tlsconfig to build the TLS
100+
// configuration for UAA token requests. WithExternalServiceDefaults() pins
101+
// MinVersion/MaxVersion (TLS 1.2-1.3) and a curated cipher-suite list, matching
102+
// CF's standard for talking to services we don't control on the other end.
103+
// director_ca_cert / uaa_ca_cert (via CAFilePath) is used as the trust root
104+
// when the file exists and has non-empty content; otherwise the system trust
105+
// store is used, matching the Ruby AuthProvider behaviour.
100106
func (a *AuthProvider) buildHTTPClient() (*http.Client, error) {
101-
tlsCfg := &tls.Config{MinVersion: tls.VersionTLS12}
102-
103107
caCertPath := a.CAFilePath()
108+
109+
var clientOpts []tlsconfig.ClientOption
104110
if caCertPath != "" {
105111
data, err := os.ReadFile(caCertPath)
106112
if err != nil {
107113
return nil, fmt.Errorf("failed to read CA cert file %q: %w", caCertPath, err)
108114
}
109115
if len(strings.TrimSpace(string(data))) > 0 {
110-
pool := x509.NewCertPool()
111-
if !pool.AppendCertsFromPEM(data) {
112-
return nil, fmt.Errorf("failed to parse CA certificate from %q", caCertPath)
113-
}
114-
tlsCfg.RootCAs = pool
116+
clientOpts = append(clientOpts, tlsconfig.WithAuthorityFromFile(caCertPath))
115117
}
116118
}
117119

120+
tlsCfg, err := tlsconfig.Build(tlsconfig.WithExternalServiceDefaults()).Client(clientOpts...)
121+
if err != nil {
122+
return nil, fmt.Errorf("failed to build TLS config for CA cert %q: %w", caCertPath, err)
123+
}
124+
118125
return &http.Client{
119126
Timeout: httpClientTimeout,
120127
Transport: &http.Transport{TLSClientConfig: tlsCfg},
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package userssync
22

3-
import "crypto/x509"
3+
import (
4+
"crypto/tls"
5+
"net/http"
6+
)
47

58
// IsConnectionError exposes isConnectionError for use in external test packages.
69
// This file is compiled only during test runs.
710
var IsConnectionError = isConnectionError
811

9-
// DirectorCACertPool exposes directorCACertPool so external tests can assert the
10-
// "use system trust store" (nil pool, nil error) vs "fail loudly" (error)
11-
// behavior for a configured director_ca_cert.
12-
func (u *UsersSync) DirectorCACertPool() (*x509.CertPool, error) {
13-
return u.directorCACertPool()
12+
// BuildDirectorTLSConfig exposes the *tls.Config built from director_ca_cert so
13+
// external tests can assert the "use system trust store" (RootCAs nil, no
14+
// error) vs "fail loudly" (error) behavior without reaching into the internals
15+
// of buildHTTPClient.
16+
func (u *UsersSync) BuildDirectorTLSConfig() (*tls.Config, error) {
17+
client, err := u.buildHTTPClient()
18+
if err != nil {
19+
return nil, err
20+
}
21+
return client.Transport.(*http.Transport).TLSClientConfig, nil
1422
}

src/bosh-nats-sync/pkg/userssync/users_sync.go

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
"bytes"
55
"context"
66
"crypto/sha256"
7-
"crypto/tls"
8-
"crypto/x509"
97
"encoding/json"
108
"errors"
119
"fmt"
@@ -24,6 +22,8 @@ import (
2422
"bosh-nats-sync/pkg/authprovider"
2523
"bosh-nats-sync/pkg/config"
2624
"bosh-nats-sync/pkg/natsauthconfig"
25+
26+
"code.cloudfoundry.org/tlsconfig"
2727
)
2828

2929
const (
@@ -394,45 +394,43 @@ func (u *UsersSync) httpClient() (*http.Client, error) {
394394
return u.client, u.clientErr
395395
}
396396

397-
// buildHTTPClient mirrors the Ruby NATSSync::UsersSync HTTP client: TLS peer
398-
// verification is always on, and director_ca_cert is used as the trust root
399-
// when the file exists and has non-empty content; otherwise the system trust
400-
// store is used. A configured-but-unparseable cert is a hard error rather than
401-
// a silent fallback to the system store.
397+
// buildHTTPClient uses code.cloudfoundry.org/tlsconfig to build the TLS
398+
// configuration for director API requests. WithExternalServiceDefaults() pins
399+
// MinVersion/MaxVersion (TLS 1.2-1.3) and a curated cipher-suite list, matching
400+
// CF's standard for talking to services we don't control on the other end.
401+
// director_ca_cert is used as the trust root when the file exists and has
402+
// non-empty content; otherwise the system trust store is used, matching the
403+
// Ruby NATSSync::UsersSync behaviour. A configured-but-unparseable cert is a
404+
// hard error rather than a silent fallback to the system store.
402405
func (u *UsersSync) buildHTTPClient() (*http.Client, error) {
403-
tlsCfg := &tls.Config{MinVersion: tls.VersionTLS12}
404-
pool, err := u.directorCACertPool()
405-
if err != nil {
406-
return nil, err
406+
certPath := u.boshConfig.DirectorCACert
407+
408+
var clientOpts []tlsconfig.ClientOption
409+
if usableCACertContent(certPath) {
410+
clientOpts = append(clientOpts, tlsconfig.WithAuthorityFromFile(certPath))
407411
}
408-
if pool != nil {
409-
tlsCfg.RootCAs = pool
412+
413+
tlsCfg, err := tlsconfig.Build(tlsconfig.WithExternalServiceDefaults()).Client(clientOpts...)
414+
if err != nil {
415+
return nil, fmt.Errorf("director_ca_cert %q: %w", certPath, err)
410416
}
417+
411418
return &http.Client{
412419
Transport: &http.Transport{TLSClientConfig: tlsCfg},
413420
Timeout: httpClientTimeout,
414421
}, nil
415422
}
416423

417-
// directorCACertPool returns the CA pool built from director_ca_cert, or nil to
418-
// signal "use the system trust store". It returns nil (system store) when the
419-
// cert is not configured, missing/unreadable, or empty — matching the Ruby
420-
// usable_director_ca_cert? predicate — but returns an error when a configured
421-
// file contains no parseable certificate.
422-
func (u *UsersSync) directorCACertPool() (*x509.CertPool, error) {
423-
certPath := u.boshConfig.DirectorCACert
424-
if certPath == "" {
425-
return nil, nil
426-
}
427-
data, err := os.ReadFile(certPath)
428-
if err != nil || len(strings.TrimSpace(string(data))) == 0 {
429-
return nil, nil
430-
}
431-
pool := x509.NewCertPool()
432-
if !pool.AppendCertsFromPEM(data) {
433-
return nil, fmt.Errorf("director_ca_cert %q contains no valid certificates", certPath)
424+
// usableCACertContent reports whether path points to a readable, non-empty CA
425+
// certificate file. Matches the Ruby usable_director_ca_cert? predicate: a
426+
// missing, unreadable, or empty file falls back to the system trust store
427+
// rather than being treated as configured.
428+
func usableCACertContent(path string) bool {
429+
if path == "" {
430+
return false
434431
}
435-
return pool, nil
432+
data, err := os.ReadFile(path)
433+
return err == nil && len(strings.TrimSpace(string(data))) > 0
436434
}
437435

438436
type deployment struct {

src/bosh-nats-sync/pkg/userssync/users_sync_test.go

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package userssync_test
33
import (
44
"bytes"
55
"context"
6+
"crypto/tls"
67
"encoding/json"
78
"encoding/pem"
89
"errors"
@@ -866,9 +867,10 @@ var _ = Describe("UsersSync", func() {
866867

867868
// REVIEW S1: a configured-but-unparseable director_ca_cert must be a hard
868869
// error, not a silent fallback to the system trust store. Missing/empty
869-
// certs fall back to the system store (nil pool, nil error), matching Ruby's
870-
// usable_director_ca_cert? predicate.
871-
Describe("directorCACertPool", func() {
870+
// certs fall back to the system store (RootCAs nil, no error), matching
871+
// Ruby's usable_director_ca_cert? predicate. TLS config is built via
872+
// code.cloudfoundry.org/tlsconfig (see PR review comment #1).
873+
Describe("buildHTTPClient TLS config (director_ca_cert)", func() {
872874
var tmpDir string
873875

874876
BeforeEach(func() {
@@ -878,37 +880,44 @@ var _ = Describe("UsersSync", func() {
878880
})
879881
AfterEach(func() { os.RemoveAll(tmpDir) })
880882

881-
It("returns the system store (nil, nil) when not configured", func() {
883+
It("uses the system trust store (RootCAs nil) when not configured", func() {
882884
boshConfig = config.DirectorConfig{DirectorCACert: ""}
883-
pool, err := createSync().DirectorCACertPool()
885+
tlsCfg, err := createSync().BuildDirectorTLSConfig()
884886
Expect(err).NotTo(HaveOccurred())
885-
Expect(pool).To(BeNil())
887+
Expect(tlsCfg.RootCAs).To(BeNil())
886888
})
887889

888-
It("returns the system store (nil, nil) when the file is missing", func() {
890+
It("uses the system trust store (RootCAs nil) when the file is missing", func() {
889891
boshConfig = config.DirectorConfig{DirectorCACert: filepath.Join(tmpDir, "does-not-exist.pem")}
890-
pool, err := createSync().DirectorCACertPool()
892+
tlsCfg, err := createSync().BuildDirectorTLSConfig()
891893
Expect(err).NotTo(HaveOccurred())
892-
Expect(pool).To(BeNil())
894+
Expect(tlsCfg.RootCAs).To(BeNil())
893895
})
894896

895-
It("returns the system store (nil, nil) when the file is whitespace-only", func() {
897+
It("uses the system trust store (RootCAs nil) when the file is whitespace-only", func() {
896898
p := filepath.Join(tmpDir, "empty.pem")
897899
Expect(os.WriteFile(p, []byte(" \n"), 0o600)).To(Succeed())
898900
boshConfig = config.DirectorConfig{DirectorCACert: p}
899-
pool, err := createSync().DirectorCACertPool()
901+
tlsCfg, err := createSync().BuildDirectorTLSConfig()
900902
Expect(err).NotTo(HaveOccurred())
901-
Expect(pool).To(BeNil())
903+
Expect(tlsCfg.RootCAs).To(BeNil())
902904
})
903905

904906
It("fails loudly when the configured cert contains no valid certificate", func() {
905907
p := filepath.Join(tmpDir, "garbage.pem")
906908
Expect(os.WriteFile(p, []byte("not a pem certificate at all"), 0o600)).To(Succeed())
907909
boshConfig = config.DirectorConfig{DirectorCACert: p}
908-
_, err := createSync().DirectorCACertPool()
910+
_, err := createSync().BuildDirectorTLSConfig()
909911
Expect(err).To(HaveOccurred())
910912
Expect(err.Error()).To(ContainSubstring("no valid certificates"))
911913
})
914+
915+
It("pins TLS 1.2 as the minimum version via tlsconfig.WithExternalServiceDefaults", func() {
916+
boshConfig = config.DirectorConfig{DirectorCACert: ""}
917+
tlsCfg, err := createSync().BuildDirectorTLSConfig()
918+
Expect(err).NotTo(HaveOccurred())
919+
Expect(tlsCfg.MinVersion).To(Equal(uint16(tls.VersionTLS12)))
920+
})
912921
})
913922

914923
Describe("ReloadNATSServerConfig", func() {

src/bosh-nats-sync/vendor/code.cloudfoundry.org/tlsconfig/.gitignore

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/bosh-nats-sync/vendor/code.cloudfoundry.org/tlsconfig/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)