237 lines
7.3 KiB
Go
237 lines
7.3 KiB
Go
package go_encryption
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/hex"
|
|
"math/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
type testStruct struct {
|
|
BoolVal bool `json:"boolVal"`
|
|
IntVal int `json:"intVal"`
|
|
FloatVal float64 `json:"floatVal"`
|
|
StringVal string `json:"stringVal"`
|
|
}
|
|
|
|
const (
|
|
defaultTestStructJSON = "{\"boolVal\":true,\"intVal\":1,\"floatVal\":0.42,\"stringVal\":\"testing\"}"
|
|
defaultTestStructEncrypted = "SaRociSolutions\x80e#.\x8e\xc5M:\x90\xbe\x98\xd2\xdasA䊭\\cp%\xc4w\xea\x8bSِ\x80\xbe\xdc|o\x13\xb1JݛC\x0fG\xca\xdbc\x85I6\xbdd\x03O[a@%\x91'K\xd0r\x9e\xf1[\x8cx\xdfG\x8cc^|\x82\x95Jf[\xdaC\xd9I"
|
|
contextTestStructEncrypted = "__-=SaRoci=-__\xe45\xefVFJ\xa2\x1b\xb3\x93\t\x10lar՜\x992\xaf}\x83V\xa9\xff\xfe,U\x19%\xe7\xfbvۚ\xb2\xfe\xaeH@=Q\xabX\x17\u007f\xb0\xf4\xc9\f3\x02\x84\x80\x8b\xac\x86\x97C\f\xe8)\xf7f\x1e\u05cdy\xd0|p\x936\xe5\xe3\xb9u\xf3\x01̋"
|
|
)
|
|
|
|
var (
|
|
defaultTestStruct = testStruct{
|
|
BoolVal: true,
|
|
IntVal: 1,
|
|
FloatVal: 0.42,
|
|
StringVal: "testing",
|
|
}
|
|
)
|
|
|
|
func getImplementation() *aes128encryption {
|
|
return NewAES128EncryptionProvider().(*aes128encryption)
|
|
}
|
|
|
|
func Test_GetCrypter(t *testing.T) {
|
|
t.Parallel()
|
|
e := getImplementation()
|
|
var err error
|
|
if _, err = e.getCrypter(); err != nil {
|
|
t.Error("unexpected error in default crypter-generation")
|
|
}
|
|
|
|
e.encryptionKey = e.encryptionKey[:len(e.encryptionKey)-1]
|
|
if _, err = e.getCrypter(); err == nil {
|
|
t.Error("expected error in crypter-generation for bad length hex-encoded key did not occur")
|
|
}
|
|
|
|
e.encryptionKey = e.encryptionKey[:len(e.encryptionKey)-1]
|
|
if _, err = e.getCrypter(); err == nil {
|
|
t.Error("expected error in crypter-generation for bad key size did not occur")
|
|
}
|
|
}
|
|
|
|
func Test_SetEncryptionKey(t *testing.T) {
|
|
t.Parallel()
|
|
e := getImplementation()
|
|
binaryKey := append([]byte{}, e.encryptionKey...)
|
|
e.SetEncryptionKey(binaryKey)
|
|
if !strings.EqualFold(defaultEncryptionKey, hex.EncodeToString(e.encryptionKey)) {
|
|
t.Error("Test_SetEncryptionKey: test case 1: encryption key should not have changed")
|
|
}
|
|
|
|
binaryKey[4] = 42
|
|
binaryKey[5] = 42
|
|
binaryKey[6] = 42
|
|
e.SetEncryptionKey(binaryKey)
|
|
if strings.EqualFold(defaultEncryptionKey, hex.EncodeToString(e.encryptionKey)) {
|
|
t.Error("Test_SetEncryptionKey: test case 2: encryption key was not changed")
|
|
}
|
|
|
|
binaryKey = append(binaryKey, binaryKey...)
|
|
e.SetEncryptionKey(binaryKey)
|
|
if strings.EqualFold(defaultEncryptionKey, hex.EncodeToString(e.encryptionKey)) {
|
|
t.Error("Test_SetEncryptionKey: test case 3: encryption key was not changed")
|
|
}
|
|
|
|
binaryKey = binaryKey[:3]
|
|
e.SetEncryptionKey(binaryKey)
|
|
if strings.EqualFold(defaultEncryptionKey, hex.EncodeToString(e.encryptionKey)) {
|
|
t.Error("Test_SetEncryptionKey: test case 4: encryption key was not changed")
|
|
}
|
|
|
|
e.SetEncryptionKey(nil)
|
|
if !strings.EqualFold(defaultEncryptionKey, hex.EncodeToString(e.encryptionKey)) {
|
|
t.Error("Test_SetEncryptionKey: test case 5: encryption key was not reset to default")
|
|
}
|
|
}
|
|
|
|
func randomByteArray() []byte {
|
|
len := rand.Intn(32)
|
|
result := make([]byte, 0)
|
|
for i := 0; i < len; i++ {
|
|
result = append(result, byte(rand.Intn(256)))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func Fuzz_SetContext(f *testing.F) {
|
|
testCases := [][]byte{
|
|
nil,
|
|
{},
|
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
|
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
|
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
|
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17},
|
|
}
|
|
for i := 0; i < 5; i++ {
|
|
testCases = append(testCases, randomByteArray())
|
|
}
|
|
for _, tc := range testCases {
|
|
f.Add(tc)
|
|
}
|
|
f.Fuzz(func(t *testing.T, a []byte) {
|
|
t.Parallel()
|
|
e := NewAES128EncryptionProvider()
|
|
result := e.SetContext(a)
|
|
if 12 > len(a) || len(a) > 16 {
|
|
if result == nil {
|
|
t.Errorf("got no error for %v", a)
|
|
}
|
|
} else if result != nil {
|
|
t.Errorf("got an error for %v", a)
|
|
}
|
|
|
|
if e.SetContext(defaultContext) != nil {
|
|
t.Error("unable to reset context")
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_Encrypt(t *testing.T) {
|
|
t.Parallel()
|
|
e := getImplementation()
|
|
binary := []byte(defaultTestStructJSON)
|
|
blank := make([]byte, len(binary))
|
|
if encrypted, err := e.Encrypt(binary); err != nil {
|
|
t.Error("unexpected error in default encryption")
|
|
} else if !bytes.Equal(encrypted, []byte(defaultTestStructEncrypted)) {
|
|
t.Error("unexpected data for encrypted content")
|
|
} else if !bytes.Equal(binary, blank) {
|
|
t.Error("binary has not been blanked out")
|
|
}
|
|
}
|
|
|
|
func Test_Decrypt(t *testing.T) {
|
|
t.Parallel()
|
|
e := getImplementation()
|
|
if decrypted, err := e.Decrypt([]byte(defaultTestStructEncrypted)); err != nil {
|
|
t.Error("unexpected error in default decryption")
|
|
} else if !bytes.Equal(decrypted, []byte(defaultTestStructJSON)) {
|
|
t.Error("unexpected data for decrypted content")
|
|
}
|
|
|
|
if _, err := e.Decrypt([]byte(contextTestStructEncrypted)); err == nil {
|
|
t.Error("expected context error did not occur")
|
|
}
|
|
|
|
if _, err := e.Decrypt([]byte(contextTestStructEncrypted)[:11]); err == nil {
|
|
t.Error("expected length error did not occur")
|
|
}
|
|
}
|
|
|
|
func Test_EncryptData(t *testing.T) {
|
|
t.Parallel()
|
|
e := NewAES128EncryptionProvider()
|
|
if encrypted, err := e.EncryptData(defaultTestStruct); err != nil {
|
|
t.Error("unexpected error in default data encryption")
|
|
} else if !bytes.Equal(encrypted, []byte(defaultTestStructEncrypted)) {
|
|
t.Error("unexpected data for encrypted content")
|
|
}
|
|
}
|
|
|
|
func Test_DecryptData(t *testing.T) {
|
|
t.Parallel()
|
|
e := NewAES128EncryptionProvider()
|
|
target := &testStruct{}
|
|
if err := e.DecryptData([]byte(defaultTestStructEncrypted), target); err != nil {
|
|
t.Error("unexpected error in default data decryption")
|
|
} else if target.BoolVal != defaultTestStruct.BoolVal ||
|
|
target.FloatVal != defaultTestStruct.FloatVal ||
|
|
target.IntVal != defaultTestStruct.IntVal ||
|
|
target.StringVal != defaultTestStruct.StringVal {
|
|
t.Error("retrieved struct does not match the expectations")
|
|
}
|
|
}
|
|
|
|
func getTestFilePath(encrypt bool) string {
|
|
fileName := "encryption_test_encrypted.data"
|
|
if !encrypt {
|
|
fileName = "encryption_test_decryptable.data"
|
|
}
|
|
return filepath.Join(os.Getenv("temp"), fileName)
|
|
}
|
|
|
|
func Test_EncryptToFile(t *testing.T) {
|
|
t.Parallel()
|
|
e := NewAES128EncryptionProvider()
|
|
targetPath := getTestFilePath(true)
|
|
if err := e.EncryptToFile(defaultTestStruct, targetPath); err != nil {
|
|
t.Error("unexpected error in default encryption")
|
|
} else if encrypted, errRead := os.ReadFile(targetPath); errRead == nil {
|
|
os.Remove(targetPath)
|
|
if !bytes.Equal(encrypted, []byte(defaultTestStructEncrypted)) {
|
|
t.Error("unexpected data for encrypted content")
|
|
}
|
|
} else {
|
|
t.Errorf("expected file could not be read: %s", errRead)
|
|
if !os.IsNotExist(errRead) {
|
|
os.Remove(targetPath)
|
|
}
|
|
}
|
|
}
|
|
|
|
func Test_DecryptFile(t *testing.T) {
|
|
t.Parallel()
|
|
sourcePath := getTestFilePath(false)
|
|
if os.WriteFile(sourcePath, []byte(defaultTestStructEncrypted), os.ModePerm) == nil {
|
|
target := &testStruct{}
|
|
e := NewAES128EncryptionProvider()
|
|
if err := e.DecryptFile(sourcePath, target); err != nil {
|
|
t.Error("unexpected error in default decryption")
|
|
} else if target.BoolVal != defaultTestStruct.BoolVal ||
|
|
target.FloatVal != defaultTestStruct.FloatVal ||
|
|
target.IntVal != defaultTestStruct.IntVal ||
|
|
target.StringVal != defaultTestStruct.StringVal {
|
|
t.Error("retrieved struct does not match the expectations")
|
|
}
|
|
os.Remove(sourcePath)
|
|
} else {
|
|
t.Error("could not prepare test file for decryption")
|
|
}
|
|
}
|