From 24b94dd2f15d33cf48ccd1cb3d7b90f30bdf1518 Mon Sep 17 00:00:00 2001 From: "A.Unger" Date: Tue, 8 Jun 2021 12:50:15 +0200 Subject: [PATCH] add unit tests --- ocis-pkg/crypto/gencert.go | 49 ++++++---- ocis-pkg/crypto/gencert_test.go | 160 ++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 20 deletions(-) create mode 100644 ocis-pkg/crypto/gencert_test.go diff --git a/ocis-pkg/crypto/gencert.go b/ocis-pkg/crypto/gencert.go index 0021fab6b5..42f646b5e9 100644 --- a/ocis-pkg/crypto/gencert.go +++ b/ocis-pkg/crypto/gencert.go @@ -39,38 +39,45 @@ func GenCert(certName string, keyName string, l log.Logger) error { return nil } - persistCertificate(certName, l, pk) - persistKey(keyName, l, pk) + if err := persistCertificate(certName, l, pk); err != nil { + l.Fatal().Err(err).Msg("failed to store certificate") + } + + if err := persistKey(keyName, l, pk); err != nil { + l.Fatal().Err(err).Msg("failed to store key") + } return nil } // persistCertificate generates a certificate using pk as private key and proceeds to store it into a file named certName. -func persistCertificate(certName string, l log.Logger, pk interface{}) { +func persistCertificate(certName string, l log.Logger, pk interface{}) error { if err := ensureExistsDir(certName); err != nil { - l.Fatal().Err(err).Msg("creating certificate destination: " + certName) + return fmt.Errorf("creating certificate destination: " + certName) } certificate, err := generateCertificate(pk) if err != nil { - l.Fatal().Err(err).Msg("creating certificate: " + filepath.Dir(certName)) + return fmt.Errorf("creating certificate: " + filepath.Dir(certName)) } certOut, err := os.Create(certName) if err != nil { - l.Fatal().Err(err).Msgf("failed to open `%v` for writing", certName) + return fmt.Errorf("failed to open `%v` for writing", certName) } err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certificate}) if err != nil { - l.Fatal().Err(err).Msg("failed to encode certificate") + return fmt.Errorf("failed to encode certificate") } err = certOut.Close() if err != nil { - l.Fatal().Err(err).Msg("failed to write cert") + return fmt.Errorf("failed to write cert") } l.Info().Msg(fmt.Sprintf("written certificate to %v", certName)) + + return nil } // genCert generates a self signed certificate using a random rsa key. @@ -87,29 +94,31 @@ func generateCertificate(pk interface{}) ([]byte, error) { } // persistKey persists the private key used to generate the certificate at the configured location. -func persistKey(keyName string, l log.Logger, pk interface{}) { - if err := ensureExistsDir(keyName); err != nil { - l.Fatal().Err(err).Msg("creating certificate destination: " + keyName) +func persistKey(destination string, l log.Logger, pk interface{}) error { + if err := ensureExistsDir(destination); err != nil { + return fmt.Errorf("creating key destination: " + destination) } - keyOut, err := os.OpenFile(keyName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + keyOut, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - l.Fatal().Err(err).Msgf("failed to open %v for writing", keyName) + return fmt.Errorf("failed to open %v for writing", destination) } err = pem.Encode(keyOut, pemBlockForKey(pk, l)) if err != nil { - l.Fatal().Err(err).Msg("failed to encode key") + return fmt.Errorf("failed to encode key") } err = keyOut.Close() if err != nil { - l.Fatal().Err(err).Msg("failed to write key") + return fmt.Errorf("failed to write key") } - l.Info().Msg(fmt.Sprintf("written key to %v", keyName)) + l.Info().Msg(fmt.Sprintf("written key to %v", destination)) + + return nil } -func publicKey(priv interface{}) interface{} { - switch k := priv.(type) { +func publicKey(pk interface{}) interface{} { + switch k := pk.(type) { case *rsa.PrivateKey: return &k.PublicKey case *ecdsa.PrivateKey: @@ -119,8 +128,8 @@ func publicKey(priv interface{}) interface{} { } } -func pemBlockForKey(priv interface{}, l log.Logger) *pem.Block { - switch k := priv.(type) { +func pemBlockForKey(pk interface{}, l log.Logger) *pem.Block { + switch k := pk.(type) { case *rsa.PrivateKey: return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)} case *ecdsa.PrivateKey: diff --git a/ocis-pkg/crypto/gencert_test.go b/ocis-pkg/crypto/gencert_test.go new file mode 100644 index 0000000000..efc480dcd0 --- /dev/null +++ b/ocis-pkg/crypto/gencert_test.go @@ -0,0 +1,160 @@ +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "crypto/rsa" + "os" + "path/filepath" + "testing" + + "github.com/owncloud/ocis/ocis-pkg/log" +) + +func Test_ensureExistsDir(t *testing.T) { + var tmpDir = t.TempDir() + + type args struct { + uri string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "creates a dir if it does not exist", + args: args{ + uri: filepath.Join(tmpDir, "example"), + }, + wantErr: false, + }, + { + name: "noop if the target directory exists", + args: args{ + uri: filepath.Join(tmpDir, "example"), + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := ensureExistsDir(tt.args.uri); (err != nil) != tt.wantErr { + t.Errorf("ensureExistsDir() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_persistKey(t *testing.T) { + p256 := elliptic.P256() + var ( + tmpDir = t.TempDir() + keyPath = filepath.Join(tmpDir, "ocis", "testKey") + rsaPk, _ = rsa.GenerateKey(rand.Reader, 2048) + ecdsaPk, _ = ecdsa.GenerateKey(p256, rand.Reader) + ) + + type args struct { + keyName string + l log.Logger + pk interface{} + } + tests := []struct { + name string + args args + }{ + { + name: "writes a private key (rsa) to the specified location", + args: args{ + keyName: keyPath, + l: log.NewLogger(), + pk: rsaPk, + }, + }, + { + name: "writes a private key (ecdsa) to the specified location", + args: args{ + keyName: keyPath, + l: log.NewLogger(), + pk: ecdsaPk, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + persistKey(tt.args.keyName, tt.args.l, tt.args.pk) + }) + + // side effect: tt.args.keyName is created + if _, err := os.Stat(tt.args.keyName); err != nil { + t.Errorf("persistKey() error = %v", err) + } + } +} + +func Test_persistCertificate(t *testing.T) { + p256 := elliptic.P256() + var ( + tmpDir = t.TempDir() + certPath = filepath.Join(tmpDir, "ocis", "testCert") + rsaPk, _ = rsa.GenerateKey(rand.Reader, 2048) + ecdsaPk, _ = ecdsa.GenerateKey(p256, rand.Reader) + ) + + type args struct { + certName string + l log.Logger + pk interface{} + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "store a certificate with an rsa private key", + args: args{ + certName: certPath, + l: log.NewLogger(), + pk: rsaPk, + }, + wantErr: false, + }, + { + name: "store a certificate with an ecdsa private key", + args: args{ + certName: certPath, + l: log.NewLogger(), + pk: ecdsaPk, + }, + wantErr: false, + }, + { + name: "should fail", + args: args{ + certName: certPath, + l: log.NewLogger(), + pk: 42, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { + if err := persistCertificate(tt.args.certName, tt.args.l, tt.args.pk); err != nil { + if !tt.wantErr { + t.Error(err) + } + } + }) + + // side effect: tt.args.keyName is created + if _, err := os.Stat(tt.args.certName); err != nil { + t.Errorf("persistCertificate() error = %v", err) + } + }) + } +}