mirror of
https://github.com/Forceu/Gokapi.git
synced 2026-01-19 23:49:32 -06:00
213 lines
5.7 KiB
Go
213 lines
5.7 KiB
Go
package encryption
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"github.com/forceu/gokapi/internal/models"
|
|
"github.com/forceu/gokapi/internal/test"
|
|
"io"
|
|
"os"
|
|
"testing"
|
|
|
|
"golang.org/x/crypto/scrypt"
|
|
)
|
|
|
|
// Note: most of these tests are written by AI
|
|
|
|
func TestGetRandomCipher(t *testing.T) {
|
|
cipher1, err := GetRandomCipher()
|
|
test.IsNil(t, err)
|
|
test.IsEqualInt(t, len(cipher1), 32)
|
|
cipher2, err := GetRandomCipher()
|
|
test.IsNil(t, err)
|
|
isEqual := bytes.Compare(cipher1, cipher2)
|
|
test.IsEqualBool(t, isEqual != 0, true)
|
|
}
|
|
|
|
func TestInit(t *testing.T) {
|
|
config := models.Configuration{
|
|
Encryption: models.Encryption{
|
|
Level: NoEncryption,
|
|
Cipher: []byte("01234567890123456789012345678901"),
|
|
},
|
|
}
|
|
Init(config)
|
|
// Testing for no encryption, nothing should change
|
|
|
|
config.Encryption.Level = LocalEncryptionStored
|
|
Init(config)
|
|
test.IsNotNil(t, ramCipher)
|
|
test.IsNotNil(t, encryptedKey)
|
|
|
|
config.Encryption.Level = FullEncryptionStored
|
|
Init(config)
|
|
test.IsNotNil(t, ramCipher)
|
|
test.IsNotNil(t, encryptedKey)
|
|
}
|
|
|
|
func TestPasswordChecksum(t *testing.T) {
|
|
password := "securepassword"
|
|
salt := "somesalt"
|
|
checksum := PasswordChecksum(password, salt)
|
|
expectedChecksum, err := scrypt.Key([]byte(password), []byte(salt), 1048576, 8, 1, blockSize)
|
|
test.IsNil(t, err)
|
|
hasher := sha256.New()
|
|
hasher.Write(expectedChecksum)
|
|
test.IsEqualString(t, hex.EncodeToString(hasher.Sum(nil)), checksum)
|
|
checksum = PasswordChecksum("testpw", "testsalt")
|
|
test.IsEqualString(t, checksum, "30161cdf03347d6d3f99743532b8523e03e79d4d91ddd3a623be414519ee9ca9")
|
|
checksum = PasswordChecksum("testpw", "test")
|
|
test.IsEqualString(t, checksum, "41d1781205837071affbf2268588b3f2e755f0365cfe16aff6136155c1013029")
|
|
checksum = PasswordChecksum("test", "test")
|
|
test.IsEqualString(t, checksum, "a3325e881a99e897aab8ba1de274803cddd4f035409c98e976fec9b8005694e6")
|
|
checksum = PasswordChecksum("test", "testsalt")
|
|
test.IsEqualString(t, checksum, "2dbcdfd0989dd2e1be0eea54f176c102e891fd4cb8182544fa4c9dba45307846")
|
|
}
|
|
|
|
func TestEncryptDecryptBytes(t *testing.T) {
|
|
key := make([]byte, 32)
|
|
_, err := rand.Read(key)
|
|
test.IsNil(t, err)
|
|
|
|
nonce := make([]byte, 12)
|
|
_, err = rand.Read(nonce)
|
|
test.IsNil(t, err)
|
|
|
|
plaintext := []byte("this is some plaintext")
|
|
|
|
ciphertext, err := EncryptDecryptBytes(plaintext, key, nonce, true)
|
|
test.IsNil(t, err)
|
|
|
|
decrypted, err := EncryptDecryptBytes(ciphertext, key, nonce, false)
|
|
test.IsNil(t, err)
|
|
test.IsEqualByteSlice(t, plaintext, decrypted)
|
|
}
|
|
|
|
func TestGenerateNewFileKey(t *testing.T) {
|
|
encInfo := &models.EncryptionInfo{}
|
|
key, err := generateNewFileKey(encInfo)
|
|
test.IsNil(t, err)
|
|
test.IsEqualInt(t, 32, len(key))
|
|
test.IsEqualInt(t, 12, len(encInfo.Nonce))
|
|
test.IsEqualBool(t, encInfo.IsEncrypted, true)
|
|
test.IsEqualInt(t, 48, len(encInfo.DecryptionKey))
|
|
}
|
|
|
|
func TestEncryptDecrypt(t *testing.T) {
|
|
plaintext := []byte("this is some plaintext")
|
|
input := bytes.NewReader(plaintext)
|
|
var encrypted bytes.Buffer
|
|
encInfo := &models.EncryptionInfo{}
|
|
|
|
err := Encrypt(encInfo, input, &encrypted)
|
|
test.IsNil(t, err)
|
|
|
|
var decrypted bytes.Buffer
|
|
err = DecryptReader(*encInfo, &encrypted, &decrypted)
|
|
test.IsNil(t, err)
|
|
test.IsEqualByteSlice(t, plaintext, decrypted.Bytes())
|
|
}
|
|
|
|
func TestGetRandomData(t *testing.T) {
|
|
data, err := getRandomData(32)
|
|
test.IsNil(t, err)
|
|
test.IsEqualInt(t, 32, len(data))
|
|
}
|
|
|
|
func TestCalculateEncryptedFilesize(t *testing.T) {
|
|
size := int64(1024)
|
|
encryptedSize := CalculateEncryptedFilesize(size)
|
|
test.IsEqualBool(t, encryptedSize > size, true)
|
|
}
|
|
|
|
func TestGetStream(t *testing.T) {
|
|
key, err := GetRandomCipher()
|
|
test.IsNil(t, err)
|
|
stream := getStream(key)
|
|
test.IsNotNil(t, stream)
|
|
}
|
|
|
|
func TestStoreMasterKey(t *testing.T) {
|
|
key := make([]byte, 32)
|
|
_, err := rand.Read(key)
|
|
test.IsNil(t, err)
|
|
|
|
storeMasterKey(key)
|
|
test.IsNotNil(t, ramCipher)
|
|
test.IsNotNil(t, encryptedKey)
|
|
}
|
|
|
|
func TestFileCipherEncryptDecrypt(t *testing.T) {
|
|
input := []byte("testdata")
|
|
nonce, err := GetRandomNonce()
|
|
test.IsNil(t, err)
|
|
|
|
encrypted, err := fileCipherEncrypt(input, nonce)
|
|
test.IsNil(t, err)
|
|
|
|
decrypted, err := fileCipherDecrypt(encrypted, nonce)
|
|
test.IsNil(t, err)
|
|
test.IsEqualByteSlice(t, input, decrypted)
|
|
}
|
|
|
|
func TestGetCipherFromFile(t *testing.T) {
|
|
// Initialize the encryption key and nonce
|
|
encInfo := &models.EncryptionInfo{
|
|
DecryptionKey: make([]byte, 32),
|
|
Nonce: make([]byte, 12),
|
|
}
|
|
_, err := rand.Read(encInfo.DecryptionKey)
|
|
test.IsNil(t, err)
|
|
_, err = rand.Read(encInfo.Nonce)
|
|
test.IsNil(t, err)
|
|
|
|
// Set the master key and ram cipher
|
|
key := make([]byte, 32)
|
|
_, err = rand.Read(key)
|
|
test.IsNil(t, err)
|
|
storeMasterKey(key)
|
|
|
|
// Encrypt a sample key to store in encInfo.DecryptionKey
|
|
encKey, err := fileCipherEncrypt(key, encInfo.Nonce)
|
|
test.IsNil(t, err)
|
|
encInfo.DecryptionKey = encKey
|
|
|
|
// Retrieve the cipher from the file info
|
|
retrievedKey, err := GetCipherFromFile(*encInfo)
|
|
test.IsNil(t, err)
|
|
test.IsEqualInt(t, 32, len(retrievedKey))
|
|
test.IsEqualByteSlice(t, key, retrievedKey)
|
|
}
|
|
|
|
func TestIsCorrectKey(t *testing.T) {
|
|
// Create a temporary file for testing
|
|
file, err := os.CreateTemp("", "testfile")
|
|
test.IsNil(t, err)
|
|
defer os.Remove(file.Name())
|
|
|
|
// Write some encrypted data to the file
|
|
encInfo := &models.EncryptionInfo{
|
|
DecryptionKey: make([]byte, 32),
|
|
Nonce: make([]byte, 12),
|
|
}
|
|
_, err = rand.Read(encInfo.DecryptionKey)
|
|
test.IsNil(t, err)
|
|
_, err = rand.Read(encInfo.Nonce)
|
|
test.IsNil(t, err)
|
|
|
|
plaintext := []byte("this is some plaintext")
|
|
input := bytes.NewReader(plaintext)
|
|
err = Encrypt(encInfo, input, file)
|
|
test.IsNil(t, err)
|
|
|
|
// Re-open the file for reading
|
|
_, err = file.Seek(0, io.SeekStart)
|
|
test.IsNil(t, err)
|
|
|
|
// Test if the key is correct
|
|
isCorrect := IsCorrectKey(*encInfo, file)
|
|
test.IsEqualBool(t, isCorrect, true)
|
|
}
|