Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions transport/httpcommon/httpcommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@
return err
}

_, err := tlscommon.LoadTLSConfig(tmp.TLS)
// TODO: use local logger here
_, err := tlscommon.LoadTLSConfig(tmp.TLS, logp.NewLogger(""))
if err != nil {
return err
}
Expand Down Expand Up @@ -213,6 +214,11 @@
}
}

logger := logp.NewLogger("")
if log := extra.logger; log != nil {
logger = log
}

for _, opt := range opts {
if dialOpt, ok := opt.(dialerOption); ok {
dialer = dialOpt.baseDialer()
Expand All @@ -223,7 +229,7 @@
dialer = transport.NetDialer(settings.Timeout)
}

tls, err := tlscommon.LoadTLSConfig(settings.TLS)
tls, err := tlscommon.LoadTLSConfig(settings.TLS, logger)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -264,7 +270,7 @@
dialer, tlsDialer transport.Dialer,
opts ...TransportOption,
) *http.Transport {
t := http.DefaultTransport.(*http.Transport).Clone()

Check failure on line 273 in transport/httpcommon/httpcommon.go

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest)

Error return value is not checked (errcheck)
t.DialContext = dialer.DialContext
t.DialTLSContext = tlsDialer.DialContext
t.TLSClientConfig = tls.ToConfig()
Expand Down
5 changes: 3 additions & 2 deletions transport/tlscommon/ca_pinning_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

"github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/iobuf"
"github.com/elastic/elastic-agent-libs/logp/logptest"
"github.com/elastic/elastic-agent-libs/transport/tlscommontest"
)

Expand All @@ -51,7 +52,7 @@ func TestCAPinning(t *testing.T) {
err := cfg.Unpack(config)
require.NoError(t, err)

tlsCfg, err := LoadTLSConfig(config)
tlsCfg, err := LoadTLSConfig(config, logptest.NewTestingLogger(t, ""))
require.NoError(t, err)

tls := tlsCfg.BuildModuleClientConfig(host)
Expand All @@ -67,7 +68,7 @@ func TestCAPinning(t *testing.T) {
err := cfg.Unpack(config)
require.NoError(t, err)

tlsCfg, err := LoadTLSConfig(config)
tlsCfg, err := LoadTLSConfig(config, logptest.NewTestingLogger(t, ""))
require.NoError(t, err)

tls := tlsCfg.BuildModuleClientConfig(host)
Expand Down
5 changes: 4 additions & 1 deletion transport/tlscommon/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ package tlscommon
import (
"crypto/tls"
"errors"

"github.com/elastic/elastic-agent-libs/logp"
)

// Config defines the user configurable options in the yaml file.
Expand All @@ -40,7 +42,7 @@ type Config struct {
// defined. If Certificate and CertificateKey are configured, client authentication
// will be configured. If no CAs are configured, the host CA will be used by go
// built-in TLS support.
func LoadTLSConfig(config *Config) (*TLSConfig, error) {
func LoadTLSConfig(config *Config, logger *logp.Logger) (*TLSConfig, error) {
if !config.IsEnabled() {
return nil, nil
}
Expand Down Expand Up @@ -86,6 +88,7 @@ func LoadTLSConfig(config *Config) (*TLSConfig, error) {
Renegotiation: tls.RenegotiationSupport(config.Renegotiation),
CASha256: config.CASha256,
CATrustedFingerprint: config.CATrustedFingerprint,
logger: logger,
}, nil
}

Expand Down
4 changes: 3 additions & 1 deletion transport/tlscommon/server_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"

"github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/logp"
)

// ServerConfig defines the user configurable tls options for any TCP based service.
Expand All @@ -40,7 +41,7 @@ type ServerConfig struct {

// LoadTLSServerConfig tranforms a ServerConfig into a `tls.Config` to be used directly with golang
// network types.
func LoadTLSServerConfig(config *ServerConfig) (*TLSConfig, error) {
func LoadTLSServerConfig(config *ServerConfig, logger *logp.Logger) (*TLSConfig, error) {
if !config.IsEnabled() {
return nil, nil
}
Expand Down Expand Up @@ -95,6 +96,7 @@ func LoadTLSServerConfig(config *ServerConfig) (*TLSConfig, error) {
CurvePreferences: curves,
ClientAuth: tls.ClientAuthType(clientAuth),
CASha256: config.CASha256,
logger: logger,
}, nil
}

Expand Down
20 changes: 11 additions & 9 deletions transport/tlscommon/tls_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ type TLSConfig struct {
// time returns the current time as the number of seconds since the epoch.
// If time is nil, TLS uses time.Now.
time func() time.Time

logger *logp.Logger
}

var (
Expand All @@ -104,7 +106,7 @@ func (c *TLSConfig) ToConfig() *tls.Config {

insecure := c.Verification != VerifyStrict
if c.Verification == VerifyNone {
logp.NewLogger("tls").Warn("SSL/TLS verifications disabled.")
c.logger.Named("tls").Warn("SSL/TLS verifications disabled.")
}

return &tls.Config{
Expand All @@ -119,7 +121,7 @@ func (c *TLSConfig) ToConfig() *tls.Config {
Renegotiation: c.Renegotiation,
ClientAuth: c.ClientAuth,
Time: c.time,
VerifyConnection: makeVerifyConnection(c),
VerifyConnection: makeVerifyConnection(c, c.logger),
}
}

Expand All @@ -133,7 +135,7 @@ func (c *TLSConfig) BuildModuleClientConfig(host string) *tls.Config {
VerifyConnection: makeVerifyConnection(&TLSConfig{
Verification: VerifyFull,
ServerName: host,
}),
}, logp.NewLogger("tls")),
}
}

Expand Down Expand Up @@ -175,8 +177,8 @@ func (c *TLSConfig) BuildServerConfig(host string) *tls.Config {
return config
}

func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate) error {
logger := logp.NewLogger("tls")
func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate, logger *logp.Logger) error {
logger = logger.Named("tls")
logger.Info("'ca_trusted_fingerprint' set, looking for matching fingerprints")
fingerprint, err := hex.DecodeString(cfg.CATrustedFingerprint)
if err != nil {
Expand Down Expand Up @@ -223,7 +225,7 @@ func trustRootCA(cfg *TLSConfig, peerCerts []*x509.Certificate) error {
return nil
}

func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error {
func makeVerifyConnection(cfg *TLSConfig, logger *logp.Logger) func(tls.ConnectionState) error {
serverName := cfg.ServerName

switch cfg.Verification {
Expand All @@ -233,7 +235,7 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error {
// tls.Config.InsecureSkipVerify is set to true
return func(cs tls.ConnectionState) error {
if cfg.CATrustedFingerprint != "" {
if err := trustRootCA(cfg, cs.PeerCertificates); err != nil {
if err := trustRootCA(cfg, cs.PeerCertificates, logger); err != nil {
return err
}
}
Expand All @@ -259,7 +261,7 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error {
// tls.Config.InsecureSkipVerify is set to true
return func(cs tls.ConnectionState) error {
if cfg.CATrustedFingerprint != "" {
if err := trustRootCA(cfg, cs.PeerCertificates); err != nil {
if err := trustRootCA(cfg, cs.PeerCertificates, logger); err != nil {
return err
}
}
Expand All @@ -284,7 +286,7 @@ func makeVerifyConnection(cfg *TLSConfig) func(tls.ConnectionState) error {
if len(cfg.CASha256) > 0 {
return func(cs tls.ConnectionState) error {
if cfg.CATrustedFingerprint != "" {
if err := trustRootCA(cfg, cs.PeerCertificates); err != nil {
if err := trustRootCA(cfg, cs.PeerCertificates, logger); err != nil {
return err
}
}
Expand Down
18 changes: 13 additions & 5 deletions transport/tlscommon/tls_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"go.uber.org/zap/zaptest/observer"

"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/logp/logptest"
"github.com/elastic/elastic-agent-libs/transport/tlscommontest"
)

Expand Down Expand Up @@ -262,9 +266,12 @@ func TestTrustRootCA(t *testing.T) {
}

// Capture the logs
_ = logp.DevelopmentSetup(logp.ToObserverOutput())
observedCore, observedLogs := observer.New(zapcore.DebugLevel)
logger := logptest.NewTestingLogger(t, "test", zap.WrapCore(func(core zapcore.Core) zapcore.Core {
return observedCore
}))

err := trustRootCA(&cfg, tc.peerCerts)
err := trustRootCA(&cfg, tc.peerCerts, logger)
if tc.expectingError && err == nil {
t.Fatal("expecting an error when calling trustRootCA")
}
Expand All @@ -274,7 +281,7 @@ func TestTrustRootCA(t *testing.T) {
}

if len(tc.expectingWarnings) > 0 {
warnings := logp.ObserverLogs().FilterLevelExact(logp.WarnLevel.ZapLevel()).TakeAll()
warnings := observedLogs.FilterLevelExact(logp.WarnLevel.ZapLevel()).TakeAll()
if len(warnings) == 0 {
t.Fatal("expecting a warning message")
}
Expand Down Expand Up @@ -385,7 +392,7 @@ func TestMakeVerifyConnectionUsesCATrustedFingerprint(t *testing.T) {
CASha256: test.CASHA256,
}

verifier := makeVerifyConnection(cfg)
verifier := makeVerifyConnection(cfg, logptest.NewTestingLogger(t, ""))
if test.expectedCallback {
require.NotNil(t, verifier, "makeVerifyConnection returned a nil verifier")
} else {
Expand Down Expand Up @@ -469,7 +476,7 @@ func TestMakeVerifyServerConnectionForIPs(t *testing.T) {
Verification: test.verificationMode,
ServerName: test.serverName,
}
verifier := makeVerifyConnection(cfg)
verifier := makeVerifyConnection(cfg, logptest.NewTestingLogger(t, ""))

err = verifier(tls.ConnectionState{
PeerCertificates: []*x509.Certificate{peerCerts.Leaf},
Expand Down Expand Up @@ -644,6 +651,7 @@ func TestVerificationMode(t *testing.T) {
Verification: test.verificationMode,
RootCAs: certPool,
ServerName: test.hostname,
logger: logptest.NewTestingLogger(t, ""),
}

if test.ignoreCerts {
Expand Down
5 changes: 3 additions & 2 deletions transport/tlscommon/tls_fips_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"path/filepath"
"testing"

"github.com/elastic/elastic-agent-libs/logp/logptest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -53,7 +54,7 @@ func TestFIPSCertificateAndKeys(t *testing.T) {
cfg.Certificate.Key = string(rawKey)
cfg.Certificate.Passphrase = password

_, err = LoadTLSConfig(cfg)
_, err = LoadTLSConfig(cfg, logptest.NewTestingLogger(t, ""))
require.Error(t, err)
assert.ErrorIs(t, err, errors.ErrUnsupported, err)
})
Expand All @@ -68,7 +69,7 @@ func TestFIPSCertificateAndKeys(t *testing.T) {
cfg.Certificate.Key = key
cfg.Certificate.Passphrase = password

_, err = LoadTLSConfig(cfg)
_, err = LoadTLSConfig(cfg, logptest.NewTestingLogger(t, ""))
assert.ErrorIs(t, err, errors.ErrUnsupported)
})
}
16 changes: 9 additions & 7 deletions transport/tlscommon/tls_nofips_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"path/filepath"
"testing"

"github.com/elastic/elastic-agent-libs/logp/logptest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -52,7 +53,7 @@ func TestNoFIPSCertificateAndKeys(t *testing.T) {
cfg.Certificate.Key = string(rawKey)
cfg.Certificate.Passphrase = password

tlsC, err := LoadTLSConfig(cfg)
tlsC, err := LoadTLSConfig(cfg, logptest.NewTestingLogger(t, ""))
require.NoError(t, err)
assert.NotNil(t, tlsC)
})
Expand All @@ -67,20 +68,21 @@ func TestNoFIPSCertificateAndKeys(t *testing.T) {
cfg.Certificate.Key = key
cfg.Certificate.Passphrase = password

tlsC, err := LoadTLSConfig(cfg)
tlsC, err := LoadTLSConfig(cfg, logptest.NewTestingLogger(t, ""))
require.NoError(t, err)
assert.NotNil(t, tlsC)
})
}

func TestEncryptedKeyPassphrase(t *testing.T) {
const passphrase = "Abcd1234!" // passphrase for testdata/ca.encrypted.key
logger := logptest.NewTestingLogger(t, "")
t.Run("no passphrase", func(t *testing.T) {
_, err := LoadTLSConfig(mustLoad(t, `
enabled: true
certificate: testdata/ca.crt
key: testdata/ca.encrypted.key
`))
`), logger)
assert.ErrorContains(t, err, "no PEM blocks") // ReadPEMFile will generate an internal "no passphrase available" error that is logged and the no PEM blocks error is returned instead
})

Expand All @@ -90,7 +92,7 @@ func TestEncryptedKeyPassphrase(t *testing.T) {
certificate: testdata/ca.crt
key: testdata/ca.encrypted.key
key_passphrase: "abcd1234!"
`))
`), logger)
assert.ErrorContains(t, err, "no PEM blocks") // ReadPEMFile will fail decrypting with x509.IncorrectPasswordError that will be logged and a no PEM blocks error is returned instead
})

Expand All @@ -100,7 +102,7 @@ func TestEncryptedKeyPassphrase(t *testing.T) {
certificate: testdata/ca.crt
key: testdata/ca.encrypted.key
key_passphrase: Abcd1234!
`))
`), logger)
require.NoError(t, err)
assert.Equal(t, 1, len(cfg.Certificates), "expected 1 certificate to be loaded")
})
Expand All @@ -112,7 +114,7 @@ func TestEncryptedKeyPassphrase(t *testing.T) {
certificate: testdata/ca.crt
key: testdata/ca.encrypted.key
key_passphrase_path: %s
`, fileName)))
`, fileName)), logger)
require.NoError(t, err)
assert.Equal(t, 1, len(cfg.Certificates), "expected 1 certificate to be loaded")
})
Expand All @@ -124,7 +126,7 @@ func TestEncryptedKeyPassphrase(t *testing.T) {
certificate: testdata/ca.crt
key: testdata/ca.encrypted.key
key_passphrase_path: %s
`, fileName)))
`, fileName)), logger)
assert.ErrorContains(t, err, "no PEM blocks") // ReadPEMFile will generate an internal "no passphrase available" error that is logged and the no PEM blocks error is returned instead
})
}
Loading
Loading