Files
qfixpt/quickfix/tls_test.go
2026-03-12 12:14:13 -03:00

334 lines
11 KiB
Go

// Copyright (c) quickfixengine.org All rights reserved.
//
// This file may be distributed under the terms of the quickfixengine.org
// license as defined by quickfixengine.org and appearing in the file
// LICENSE included in the packaging of this file.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE.
//
// See http://www.quickfixengine.org/LICENSE for licensing information.
//
// Contact ask@quickfixengine.org if any conditions of this licensing
// are not clear to you.
package quickfix
import (
"crypto/tls"
"os"
"testing"
"github.com/stretchr/testify/suite"
"quantex.com/qfixpt/quickfix/config"
)
type TLSTestSuite struct {
suite.Suite
settings *Settings
PrivateKeyFile, CertificateFile, CAFile string
PrivateKeyBytes, CertificateBytes, CABytes []byte
}
func TestTLSTestSuite(t *testing.T) {
suite.Run(t, new(TLSTestSuite))
}
func (s *TLSTestSuite) SetupTest() {
s.settings = NewSettings()
s.PrivateKeyFile = "_test_data/localhost.key"
s.CertificateFile = "_test_data/localhost.crt"
s.CAFile = "_test_data/ca.crt"
privateKeyBytes, err := os.ReadFile(s.PrivateKeyFile)
s.Require().NoError(err)
s.PrivateKeyBytes = privateKeyBytes
certificateBytes, err := os.ReadFile(s.CertificateFile)
s.Require().NoError(err)
s.CertificateBytes = certificateBytes
caBytes, err := os.ReadFile(s.CAFile)
s.Require().NoError(err)
s.CABytes = caBytes
}
func (s *TLSTestSuite) TestLoadTLSNoSettings() {
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(tlsConfig)
s.Nil(err)
}
func (s *TLSTestSuite) TestLoadTLSMissingKeyOrCert() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
_, err := loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "Conditionally Required Setting: SocketCertificateFile")
s.SetupTest()
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
_, err = loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "Conditionally Required Setting: SocketPrivateKeyFile")
}
func (s *TLSTestSuite) TestLoadTLSInvalidKeyOrCert() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, "blah")
s.settings.GlobalSettings().Set(config.SocketCertificateFile, "foo")
_, err := loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "failed to load key pair: open foo: no such file or directory")
}
func (s *TLSTestSuite) TestLoadTLSNoCA() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Len(tlsConfig.Certificates, 1)
s.Nil(tlsConfig.RootCAs)
s.Nil(tlsConfig.ClientCAs)
s.Equal(tls.RequireAndVerifyClientCert, tlsConfig.ClientAuth)
}
func (s *TLSTestSuite) TestLoadTLSWithBadCA() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
s.settings.GlobalSettings().Set(config.SocketCAFile, "bar")
_, err := loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "failed to read CA bundle: open bar: no such file or directory")
}
func (s *TLSTestSuite) TestLoadTLSWithCA() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
s.settings.GlobalSettings().Set(config.SocketCAFile, s.CAFile)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Len(tlsConfig.Certificates, 1)
s.NotNil(tlsConfig.RootCAs)
s.NotNil(tlsConfig.ClientCAs)
s.Equal(tls.RequireAndVerifyClientCert, tlsConfig.ClientAuth)
}
func (s *TLSTestSuite) TestLoadTLSWithOnlyCA() {
s.settings.GlobalSettings().Set(config.SocketUseSSL, "Y")
s.settings.GlobalSettings().Set(config.SocketCAFile, s.CAFile)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.NotNil(tlsConfig.RootCAs)
s.NotNil(tlsConfig.ClientCAs)
}
func (s *TLSTestSuite) TestLoadTLSWithoutSSLWithOnlyCA() {
s.settings.GlobalSettings().Set(config.SocketCAFile, s.CAFile)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.Nil(tlsConfig)
}
func (s *TLSTestSuite) TestLoadTLSAllowSkipClientCerts() {
s.settings.GlobalSettings().Set(config.SocketUseSSL, "Y")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal(tls.NoClientCert, tlsConfig.ClientAuth)
}
func (s *TLSTestSuite) TestServerNameUseSSL() {
s.settings.GlobalSettings().Set(config.SocketUseSSL, "Y")
s.settings.GlobalSettings().Set(config.SocketServerName, "DummyServerNameUseSSL")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal("DummyServerNameUseSSL", tlsConfig.ServerName)
}
func (s *TLSTestSuite) TestServerNameWithCerts() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
s.settings.GlobalSettings().Set(config.SocketServerName, "DummyServerNameWithCerts")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal("DummyServerNameWithCerts", tlsConfig.ServerName)
}
func (s *TLSTestSuite) TestInsecureSkipVerify() {
s.settings.GlobalSettings().Set(config.SocketInsecureSkipVerify, "Y")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.Nil(tlsConfig)
}
func (s *TLSTestSuite) TestInsecureSkipVerifyWithUseSSL() {
s.settings.GlobalSettings().Set(config.SocketUseSSL, "Y")
s.settings.GlobalSettings().Set(config.SocketInsecureSkipVerify, "Y")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.True(tlsConfig.InsecureSkipVerify)
}
func (s *TLSTestSuite) TestInsecureSkipVerifyAndCerts() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
s.settings.GlobalSettings().Set(config.SocketInsecureSkipVerify, "Y")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.True(tlsConfig.InsecureSkipVerify)
s.Len(tlsConfig.Certificates, 1)
}
func (s *TLSTestSuite) TestMinimumTLSVersion() {
s.settings.GlobalSettings().Set(config.SocketPrivateKeyFile, s.PrivateKeyFile)
s.settings.GlobalSettings().Set(config.SocketCertificateFile, s.CertificateFile)
// SSL30
s.settings.GlobalSettings().Set(config.SocketMinimumTLSVersion, "SSL30")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
//nolint:staticcheck
s.Equal(tlsConfig.MinVersion, uint16(tls.VersionSSL30))
// TLS10
s.settings.GlobalSettings().Set(config.SocketMinimumTLSVersion, "TLS10")
tlsConfig, err = loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal(tlsConfig.MinVersion, uint16(tls.VersionTLS10))
// TLS11
s.settings.GlobalSettings().Set(config.SocketMinimumTLSVersion, "TLS11")
tlsConfig, err = loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal(tlsConfig.MinVersion, uint16(tls.VersionTLS11))
// TLS12
s.settings.GlobalSettings().Set(config.SocketMinimumTLSVersion, "TLS12")
tlsConfig, err = loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal(tlsConfig.MinVersion, uint16(tls.VersionTLS12))
}
func (s *TLSTestSuite) TestLoadTLSBytesMissingKeyOrCert() {
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, s.PrivateKeyBytes)
_, err := loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "Conditionally Required Setting: SocketCertificateBytes")
s.SetupTest()
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, s.CertificateBytes)
_, err = loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "Conditionally Required Setting: SocketPrivateKeyBytes")
}
func (s *TLSTestSuite) TestLoadTLSBytesInvalidKeyOrCert() {
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, s.PrivateKeyBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, []byte("not a cert"))
_, err := loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "failed to parse key pair: tls: failed to find any PEM data in certificate input")
s.SetupTest()
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, s.CertificateBytes)
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, []byte("not a key"))
_, err = loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "failed to parse key pair: tls: failed to find any PEM data in key input")
}
func (s *TLSTestSuite) TestLoadTLSBytesNoCA() {
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, s.PrivateKeyBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, s.CertificateBytes)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.NoError(err)
s.NotNil(tlsConfig)
s.Len(tlsConfig.Certificates, 1)
s.Nil(tlsConfig.RootCAs)
s.Nil(tlsConfig.ClientCAs)
s.Equal(tls.RequireAndVerifyClientCert, tlsConfig.ClientAuth)
}
func (s *TLSTestSuite) TestLoadTLSBytesWithBadCA() {
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, s.PrivateKeyBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, s.CertificateBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCABytes, []byte("bar"))
_, err := loadTLSConfig(s.settings.GlobalSettings())
s.NotNil(err)
s.EqualError(err, "failed to parse CA bundle from raw bytes")
}
func (s *TLSTestSuite) TestLoadTLSBytesWithCA() {
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, s.PrivateKeyBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, s.CertificateBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCABytes, s.CABytes)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Len(tlsConfig.Certificates, 1)
s.NotNil(tlsConfig.RootCAs)
s.NotNil(tlsConfig.ClientCAs)
s.Equal(tls.RequireAndVerifyClientCert, tlsConfig.ClientAuth)
}
func (s *TLSTestSuite) TestLoadTLSBytesWithOnlyCA() {
s.settings.GlobalSettings().Set(config.SocketUseSSL, "Y")
s.settings.GlobalSettings().SetRaw(config.SocketCABytes, s.CABytes)
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.NotNil(tlsConfig.RootCAs)
s.NotNil(tlsConfig.ClientCAs)
}
func (s *TLSTestSuite) TestServerNameWithCertsFromBytes() {
s.settings.GlobalSettings().SetRaw(config.SocketPrivateKeyBytes, s.PrivateKeyBytes)
s.settings.GlobalSettings().SetRaw(config.SocketCertificateBytes, s.CertificateBytes)
s.settings.GlobalSettings().Set(config.SocketServerName, "DummyServerNameWithCerts")
tlsConfig, err := loadTLSConfig(s.settings.GlobalSettings())
s.Nil(err)
s.NotNil(tlsConfig)
s.Equal("DummyServerNameWithCerts", tlsConfig.ServerName)
}