diff --git a/config_test.go b/config_test.go index 0ba1e1e..2c0e38a 100644 --- a/config_test.go +++ b/config_test.go @@ -2,9 +2,11 @@ package main import ( "fmt" + "os" "path/filepath" "testing" + "github.com/NBISweden/S3-Upload-Proxy/helper" log "github.com/sirupsen/logrus" "github.com/spf13/viper" @@ -16,7 +18,12 @@ type TestSuite struct { suite.Suite } +var certPath string + func (suite *TestSuite) SetupTest() { + certPath, _ = os.MkdirTemp("", "gocerts") + helper.MakeCerts(certPath) + viper.Set("broker.host", "testhost") viper.Set("broker.port", 123) viper.Set("broker.user", "testuser") @@ -33,6 +40,7 @@ func (suite *TestSuite) SetupTest() { func (suite *TestSuite) TearDownTest() { viper.Reset() + defer os.RemoveAll(certPath) } func TestConfigTestSuite(t *testing.T) { @@ -123,7 +131,7 @@ func (suite *TestSuite) TestConfigBroker() { func (suite *TestSuite) TestTLSConfigBroker() { viper.Set("broker.serverName", "broker") viper.Set("broker.ssl", true) - viper.Set("broker.cacert", "/certs/ca.crt") + viper.Set("broker.cacert", certPath+"/ca.crt") config, err := NewConfig() assert.NotNil(suite.T(), config) assert.NoError(suite.T(), err) @@ -132,8 +140,8 @@ func (suite *TestSuite) TestTLSConfigBroker() { assert.NoError(suite.T(), err) viper.Set("broker.verifyPeer", true) - viper.Set("broker.clientCert", "/certs/client.crt") - viper.Set("broker.clientKey", "/certs/client.key") + viper.Set("broker.clientCert", certPath+"/tls.crt") + viper.Set("broker.clientKey", certPath+"/tls.key") config, err = NewConfig() assert.NotNil(suite.T(), config) assert.NoError(suite.T(), err) @@ -141,19 +149,18 @@ func (suite *TestSuite) TestTLSConfigBroker() { assert.NotNil(suite.T(), tlsBroker) assert.NoError(suite.T(), err) - viper.Set("broker.clientCert", "/certs/client.pem") - viper.Set("broker.clientKey", "/certs/client-key.pem") + viper.Set("broker.clientCert", certPath+"tls.crt") + viper.Set("broker.clientKey", certPath+"/tls.key") config, err = NewConfig() assert.NotNil(suite.T(), config) assert.NoError(suite.T(), err) tlsBroker, err = TLSConfigBroker(config) assert.Nil(suite.T(), tlsBroker) assert.Error(suite.T(), err) - } func (suite *TestSuite) TestTLSConfigProxy() { - viper.Set("aws.cacert", "/certs/ca.crt") + viper.Set("aws.cacert", certPath+"/ca.crt") config, err := NewConfig() assert.NotNil(suite.T(), config) assert.NoError(suite.T(), err) diff --git a/helper/helper.go b/helper/helper.go index 843d63b..47c2e16 100644 --- a/helper/helper.go +++ b/helper/helper.go @@ -6,7 +6,11 @@ import ( "crypto/rand" "crypto/rsa" "crypto/x509" + "crypto/x509/pkix" "encoding/pem" + "log" + "math/big" + "net" "os" "path/filepath" "time" @@ -270,3 +274,107 @@ func CreateECkeys(prPath, pubPath string) error { return nil } + +func MakeCerts(outDir string) { + + // set up our CA certificate + caTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(2000), + Subject: pkix.Name{ + Organization: []string{"NEIC"}, + CommonName: "Root CA", + }, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(0, 0, 1), + KeyUsage: x509.KeyUsageCertSign, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + IsCA: true, + } + + // create our private and public key + caPrivKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + log.Fatalln(err) + } + + // create the CA certificate + caBytes, err := x509.CreateCertificate(rand.Reader, caTemplate, caTemplate, &caPrivKey.PublicKey, caPrivKey) + if err != nil { + log.Fatalln(err) + } + + err = TLScertToFile(outDir+"/ca.crt", caBytes) + if err != nil { + log.Fatalln(err) + } + + tlsKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + log.Fatalln(err) + } + + err = TLSkeyToFile(outDir+"/tls.key", tlsKey) + if err != nil { + log.Fatalln(err) + } + + // set up our server certificate + certTemplate := &x509.Certificate{ + SerialNumber: big.NewInt(2121), + Subject: pkix.Name{ + Organization: []string{"NEIC"}, + CommonName: "test_cert", + }, + IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback}, + DNSNames: []string{"localhost,mq,proxy,s3"}, + NotBefore: time.Now(), + NotAfter: time.Now().AddDate(0, 0, 1), + KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + IsCA: false, + } + + // create the TLS certificate + certBytes, err := x509.CreateCertificate(rand.Reader, certTemplate, caTemplate, &tlsKey.PublicKey, caPrivKey) + if err != nil { + log.Fatalln(err) + } + + err = TLScertToFile(outDir+"/tls.crt", certBytes) + if err != nil { + log.Fatalln(err) + } + log.Printf("certificartes written to: %s", outDir) +} + +func TLSkeyToFile(filename string, key *ecdsa.PrivateKey) error { + keyFile, err := os.Create(filename) + if err != nil { + return err + } + defer keyFile.Close() + + pk, err := x509.MarshalECPrivateKey(key) + if err != nil { + return err + } + if err := pem.Encode(keyFile, &pem.Block{Type: "EC PRIVATE KEY", Bytes: pk}); err != nil { + return err + } + + return nil +} + +func TLScertToFile(filename string, derBytes []byte) error { + certFile, err := os.Create(filename) + if err != nil { + return err + } + defer certFile.Close() + if err := pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { + return err + } + + return nil +} diff --git a/proxy_test.go b/proxy_test.go index 5f44605..5187121 100644 --- a/proxy_test.go +++ b/proxy_test.go @@ -95,7 +95,6 @@ func TestServeHTTP_disallowed(t *testing.T) { secretKey: "someSecret", bucket: "buckbuck", region: "us-east-1", - cacert: "/certs/ca.crt", } messenger := NewMockMessenger() proxy := NewProxy(s3conf, &AlwaysDeny{}, messenger, new(tls.Config)) @@ -172,7 +171,6 @@ func TestServeHTTP_S3Unresponsive(t *testing.T) { secretKey: "someSecret", bucket: "buckbuck", region: "us-east-1", - cacert: "/certs/ca.crt", } messenger := NewMockMessenger() proxy := NewProxy(s3conf, &AlwaysAllow{}, messenger, new(tls.Config)) @@ -201,7 +199,6 @@ func TestServeHTTP_allowed(t *testing.T) { secretKey: "someSecret", bucket: "buckbuck", region: "us-east-1", - cacert: "/certs/ca.crt", } messenger := NewMockMessenger() proxy := NewProxy(s3conf, NewAlwaysAllow(), messenger, new(tls.Config)) @@ -308,7 +305,6 @@ func TestMessageFormatting(t *testing.T) { secretKey: "someSecret", bucket: "buckbuck", region: "us-east-1", - cacert: "/certs/ca.crt", } messenger := NewMockMessenger() proxy := NewProxy(s3conf, &AlwaysDeny{}, messenger, new(tls.Config))