NOISSUE - Remove AES and use library instead (#226)

Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com>
This commit is contained in:
Dušan Borovčanin
2025-06-26 23:35:40 +02:00
committed by GitHub
parent 0d48e4ecdd
commit bfe6ec09c3
7 changed files with 4 additions and 935 deletions
+2 -4
View File
@@ -24,7 +24,6 @@ require (
github.com/jackc/pgx/v5 v5.7.5
github.com/jmoiron/sqlx v1.4.0
github.com/johnfercher/maroto v1.0.0
github.com/lib/pq v1.10.9
github.com/ory/dockertest/v3 v3.12.0
github.com/pelletier/go-toml v1.9.5
github.com/prometheus/client_golang v1.22.0
@@ -34,7 +33,7 @@ require (
github.com/spf13/viper v1.20.1
github.com/stretchr/testify v1.10.0
github.com/traefik/yaegi v0.16.1
github.com/vadv/gopher-lua-libs v0.6.0
github.com/vadv/gopher-lua-libs v0.7.0
github.com/yuin/gopher-lua v1.1.1
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0
go.opentelemetry.io/otel v1.36.0
@@ -50,6 +49,7 @@ require (
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
github.com/jung-kurt/gofpdf v1.16.2 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245 // indirect
)
@@ -150,5 +150,3 @@ require (
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/vadv/gopher-lua-libs => github.com/dborovcanin/gopher-lua-libs v0.1.0
+2 -2
View File
@@ -90,8 +90,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dborovcanin/gopher-lua-libs v0.1.0 h1:YIyqPTXQiCaVHguVVmzfoe1XOIkudom/CBiaMCQWerc=
github.com/dborovcanin/gopher-lua-libs v0.1.0/go.mod h1:iNYvPoNV6ur7xJj4Uj3hEVebv8Z0/MoeM1igsXQbv8g=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
@@ -497,6 +495,8 @@ github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6
github.com/traefik/yaegi v0.16.1 h1:f1De3DVJqIDKmnasUF6MwmWv1dSEEat0wcpXhD2On3E=
github.com/traefik/yaegi v0.16.1/go.mod h1:4eVhbPb3LnD2VigQjhYbEJ69vDRFdT2HQNrXx8eEwUY=
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vadv/gopher-lua-libs v0.7.0 h1:2svzL0ElKm9HH7fOEfIpM6D7VMOj9gCYrvfqRo4aPJI=
github.com/vadv/gopher-lua-libs v0.7.0/go.mod h1:iNYvPoNV6ur7xJj4Uj3hEVebv8Z0/MoeM1igsXQbv8g=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-64
View File
@@ -1,64 +0,0 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package re
import (
"crypto/aes"
"crypto/cipher"
"fmt"
)
// encrypt implements AES CBC-128 ENCRYPTION which requires 3 data fields
// 1. Key (16 bytes)
// 2. Initialization Vector (IV) (16 bytes)
// 3. Encrypted Data (16 bytes or length multiple a of 16)
// The encrypted data is divided into blocks of 16 bytes (128 bits) which then operated on with the IV and Key.
func encrypt(key []byte, iv []byte, data []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
if len(data)%blockSize != 0 {
return nil, fmt.Errorf("payload length %d is not a multiple of AES block size %d", len(data), blockSize)
}
if len(iv) != blockSize {
return nil, fmt.Errorf("size of the IV %d is not the same as block size %d", len(iv), blockSize)
}
mode := cipher.NewCBCEncrypter(block, iv)
encrypted := make([]byte, len(data))
mode.CryptBlocks(encrypted, data)
return encrypted, nil
}
// decrypt implements AES CBC-128 DECRYPTION which requires 3 data fields
// 1. Key (16 bytes)
// 2. Initialization Vector (IV) (16 bytes)
// 3. Encrypted Data (16 bytes or length multiple a of 16)
// The encrypted data is divided into blocks of 16 bytes (128 bits) which then operated on with the IV and Key.
func decrypt(key []byte, iv []byte, encrypted []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
if len(encrypted)%blockSize != 0 {
return nil, fmt.Errorf("encrypted payload length %d is not a multiple of AES block size %d", len(encrypted), blockSize)
}
if len(iv) != blockSize {
return nil, fmt.Errorf("size of the IV %d is not the same as block size %d", len(iv), blockSize)
}
mode := cipher.NewCBCDecrypter(block, iv)
decrypted := make([]byte, len(encrypted))
mode.CryptBlocks(decrypted, encrypted)
return decrypted, nil
}
-354
View File
@@ -1,354 +0,0 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package re
import (
"bytes"
"crypto/aes"
"crypto/rand"
"encoding/hex"
"errors"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestEncrypt(t *testing.T) {
validKey := make([]byte, aes.BlockSize)
validIV := make([]byte, aes.BlockSize)
validData := make([]byte, aes.BlockSize*2) // 2 blocks
_, err := rand.Read(validKey)
require.Nil(t, err, "Failed to generate valid key")
_, err = rand.Read(validIV)
require.Nil(t, err, "Failed to generate valid IV")
_, err = rand.Read(validData)
require.Nil(t, err, "Failed to generate valid data")
cases := []struct {
name string
key []byte
iv []byte
data []byte
err error
}{
{
name: "valid encryption - single block",
key: validKey,
iv: validIV,
data: make([]byte, 16),
err: nil,
},
{
name: "valid encryption - multiple blocks",
key: validKey,
iv: validIV,
data: validData,
err: nil,
},
{
name: "valid encryption - empty data",
key: validKey,
iv: validIV,
data: make([]byte, 0),
err: nil,
},
{
name: "invalid IV size - too short",
key: validKey,
iv: make([]byte, 8),
data: validData,
err: errors.New("size of the IV 8 is not the same as block size 16"),
},
{
name: "invalid IV size - too long",
key: validKey,
iv: make([]byte, 32),
data: validData,
err: errors.New("size of the IV 32 is not the same as block size 16"),
},
{
name: "invalid IV size - nil",
key: validKey,
iv: nil,
data: validData,
err: errors.New("size of the IV 0 is not the same as block size 16"),
},
{
name: "invalid data size - not multiple of block size",
key: validKey,
iv: validIV,
data: make([]byte, 15),
err: errors.New("payload length 15 is not a multiple of AES block size 16"),
},
{
name: "invalid data size - odd length",
key: validKey,
iv: validIV,
data: make([]byte, 17),
err: errors.New("payload length 17 is not a multiple of AES block size 16"),
},
{
name: "invalid key size - too short",
key: make([]byte, 8),
iv: validIV,
data: validData,
err: aes.KeySizeError(8),
},
{
name: "invalid key size - nil",
key: nil,
iv: validIV,
data: validData,
err: aes.KeySizeError(0),
},
{
name: "AES-192 key",
key: make([]byte, 24),
iv: validIV,
data: validData,
err: nil,
},
{
name: "AES-256 key",
key: make([]byte, 32),
iv: validIV,
data: validData,
err: nil,
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
result, err := encrypt(tt.key, tt.iv, tt.data)
if tt.err != nil {
assert.Error(t, err)
assert.Equal(t, tt.err, err)
assert.Nil(t, result)
} else {
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, len(tt.data), len(result))
// Ensure encrypted data is different from original (unless data is all zeros)
if len(tt.data) > 0 && !bytes.Equal(tt.data, make([]byte, len(tt.data))) {
assert.NotEqual(t, tt.data, result)
}
}
})
}
}
func TestDecrypt(t *testing.T) {
validKey := make([]byte, aes.BlockSize)
validIV := make([]byte, aes.BlockSize)
validData := make([]byte, aes.BlockSize*2) // 2 blocks
_, err := rand.Read(validKey)
require.Nil(t, err, "Failed to generate valid key")
_, err = rand.Read(validIV)
require.Nil(t, err, "Failed to generate valid IV")
_, err = rand.Read(validData)
require.Nil(t, err, "Failed to generate valid data")
validEncrypted, _ := encrypt(validKey, validIV, validData)
cases := []struct {
name string
key []byte
iv []byte
encrypted []byte
err error
}{
{
name: "valid decryption - single block",
key: validKey,
iv: validIV,
encrypted: validEncrypted[:16],
err: nil,
},
{
name: "valid decryption - multiple blocks",
key: validKey,
iv: validIV,
encrypted: validEncrypted,
err: nil,
},
{
name: "valid decryption - empty data",
key: validKey,
iv: validIV,
encrypted: make([]byte, 0),
err: nil,
},
{
name: "invalid IV size - too short",
key: validKey,
iv: make([]byte, 8),
encrypted: validEncrypted,
err: errors.New("size of the IV 8 is not the same as block size 16"),
},
{
name: "invalid IV size - too long",
key: validKey,
iv: make([]byte, 32),
encrypted: validEncrypted,
err: errors.New("size of the IV 32 is not the same as block size 16"),
},
{
name: "invalid IV size - nil",
key: validKey,
iv: nil,
encrypted: validEncrypted,
err: errors.New("size of the IV 0 is not the same as block size 16"),
},
{
name: "invalid encrypted data size - not multiple of block size",
key: validKey,
iv: validIV,
encrypted: make([]byte, 15),
err: errors.New("encrypted payload length 15 is not a multiple of AES block size 16"),
},
{
name: "invalid encrypted data size - odd length",
key: validKey,
iv: validIV,
encrypted: make([]byte, 17),
err: errors.New("encrypted payload length 17 is not a multiple of AES block size 16"),
},
{
name: "invalid key size - too short",
key: make([]byte, 8),
iv: validIV,
encrypted: validEncrypted,
err: aes.KeySizeError(8),
},
{
name: "invalid key size - nil",
key: nil,
iv: validIV,
encrypted: validEncrypted,
err: aes.KeySizeError(0),
},
{
name: "AES-192 key",
key: make([]byte, 24),
iv: validIV,
encrypted: validEncrypted,
err: nil,
},
{
name: "AES-256 key",
key: make([]byte, 32),
iv: validIV,
encrypted: validEncrypted,
err: nil,
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
result, err := decrypt(tt.key, tt.iv, tt.encrypted)
if tt.err != nil {
assert.Error(t, err)
assert.Equal(t, tt.err, err)
} else {
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, len(tt.encrypted), len(result))
}
})
}
}
func TestEncryptDecryptRoundTrip(t *testing.T) {
cases := []struct {
name string
keySize int
dataSize int
}{
{
name: "AES-128 single block",
keySize: 16,
dataSize: 16,
},
{
name: "AES-128 multiple blocks",
keySize: 16,
dataSize: 64,
},
{
name: "AES-192 single block",
keySize: 24,
dataSize: 16,
},
{
name: "AES-192 multiple blocks",
keySize: 24,
dataSize: 48,
},
{
name: "AES-256 single block",
keySize: 32,
dataSize: 16,
},
{
name: "AES-256 multiple blocks",
keySize: 32,
dataSize: 80,
},
{
name: "empty data",
keySize: 16,
dataSize: 0,
},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
key := make([]byte, tt.keySize)
iv := make([]byte, aes.BlockSize)
originalData := make([]byte, tt.dataSize)
_, err := rand.Read(key)
require.Nil(t, err, "Failed to generate valid key")
_, err = rand.Read(iv)
require.Nil(t, err, "Failed to generate valid IV")
if tt.dataSize > 0 {
_, err = rand.Read(originalData)
require.Nil(t, err, "Failed to generate valid data")
}
encrypted, err := encrypt(key, iv, originalData)
assert.NoError(t, err)
assert.NotNil(t, encrypted)
decrypted, err := decrypt(key, iv, encrypted)
assert.NoError(t, err)
assert.NotNil(t, decrypted)
assert.Equal(t, originalData, decrypted)
})
}
}
func TestEncryptDecryptWithSample(t *testing.T) {
iv := "0907780613000704d2d2d2d2d2d2d2d2"
ivBytes, err := hex.DecodeString(iv)
assert.NoError(t, err, "Failed to decode IV")
payload := "Ba56dc989e08a76f855ae12ae8B00ef13fae6ad436eBe8e03e97f17B5751c241"
payloadBytes, err := hex.DecodeString(payload)
assert.NoError(t, err, "Failed to decode payload")
key := "CB6ABFAA8D2247B59127D3B839CF34B4"
keyBytes, err := hex.DecodeString(key)
assert.NoError(t, err, "Failed to decode key")
expected := "2f2f0c0613760100046d27350f380c13555134022f2f2f2f2f2f2f2f2f2f2f2f"
decrypted, err := decrypt(keyBytes, ivBytes, payloadBytes)
assert.NoError(t, err, "Failed to decrypt")
assert.NotNil(t, decrypted, "Decrypted payload is nil")
assert.Equal(t, expected, hex.EncodeToString(decrypted), "Decrypted payload does not match expected")
}
-78
View File
@@ -1,78 +0,0 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package re
import (
"encoding/hex"
"fmt"
lua "github.com/yuin/gopher-lua"
)
const (
MsgKey = "message"
LogicRespKey = "result"
)
func luaEncrypt(l *lua.LState) int {
key, iv, data, err := decodeParams(l)
if err != nil {
l.Push(lua.LNil)
l.Push(lua.LString(fmt.Sprintf("failed to decode params: %v", err)))
return 2
}
enc, err := encrypt(key, iv, data)
if err != nil {
l.Push(lua.LNil)
l.Push(lua.LString(fmt.Sprintf("failed to encrypt: %v", err)))
return 2
}
l.Push(lua.LString(hex.EncodeToString(enc)))
return 1
}
func luaDecrypt(l *lua.LState) int {
key, iv, data, err := decodeParams(l)
if err != nil {
l.Push(lua.LNil)
l.Push(lua.LString(fmt.Sprintf("failed to decode params: %v", err)))
return 2
}
dec, err := decrypt(key, iv, data)
if err != nil {
l.Push(lua.LNil)
l.Push(lua.LString(fmt.Sprintf("failed to decrypt: %v", err)))
return 2
}
l.Push(lua.LString(hex.EncodeToString(dec)))
return 1
}
func decodeParams(l *lua.LState) (key, iv, data []byte, err error) {
keyStr := l.ToString(1)
ivStr := l.ToString(2)
dataStr := l.ToString(3)
key, err = hex.DecodeString(keyStr)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to decode key: %v", err)
}
iv, err = hex.DecodeString(ivStr)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to decode IV: %v", err)
}
data, err = hex.DecodeString(dataStr)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to decode data: %v", err)
}
return key, iv, data, nil
}
-429
View File
@@ -1,429 +0,0 @@
// Copyright (c) Abstract Machines
// SPDX-License-Identifier: Apache-2.0
package re
import (
"encoding/hex"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
lua "github.com/yuin/gopher-lua"
)
func TestDecodeParams(t *testing.T) {
tests := []struct {
name string
keyStr string
ivStr string
dataStr string
expectedKey []byte
expectedIV []byte
expectedData []byte
err bool
errMsg string
}{
{
name: "valid hex strings",
keyStr: "0123456789abcdef0123456789abcdef", // 32 chars = 16 bytes
ivStr: "fedcba9876543210fedcba9876543210", // 32 chars = 16 bytes
dataStr: "deadbeefcafebabe0000111122223333", // 32 chars = 16 bytes
expectedKey: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
expectedIV: []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
expectedData: []byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33},
err: false,
},
{
name: "empty data",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "",
expectedKey: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
expectedIV: []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
expectedData: []byte{},
err: false,
},
{
name: "invalid key hex",
keyStr: "invalid_hex",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "deadbeefcafebabe0000111122223333",
err: true,
errMsg: "failed to decode key",
},
{
name: "invalid IV hex",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "invalid_hex",
dataStr: "deadbeefcafebabe0000111122223333",
err: true,
errMsg: "failed to decode IV",
},
{
name: "invalid data hex",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "invalid_hex",
err: true,
errMsg: "failed to decode data",
},
{
name: "odd length key",
keyStr: "0123456789abcdef0123456789abcde", // 31 chars (odd)
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "deadbeefcafebabe0000111122223333",
err: true,
errMsg: "failed to decode key",
},
{
name: "odd length IV",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba987654321", // 31 chars (odd)
dataStr: "deadbeefcafebabe0000111122223333",
err: true,
errMsg: "failed to decode IV",
},
{
name: "odd length data",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "deadbeefcafebabe000011112222333", // 31 chars (odd)
err: true,
errMsg: "failed to decode data",
},
{
name: "uppercase hex",
keyStr: "0123456789ABCDEF0123456789ABCDEF",
ivStr: "FEDCBA9876543210FEDCBA9876543210",
dataStr: "DEADBEEFCAFEBABE0000111122223333",
expectedKey: []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
expectedIV: []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
expectedData: []byte{0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x11, 0x11, 0x22, 0x22, 0x33, 0x33},
err: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
L := lua.NewState()
defer L.Close()
L.Push(lua.LString(tt.keyStr))
L.Push(lua.LString(tt.ivStr))
L.Push(lua.LString(tt.dataStr))
key, iv, data, err := decodeParams(L)
if tt.err {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.errMsg)
} else {
require.NoError(t, err)
assert.Equal(t, tt.expectedKey, key)
assert.Equal(t, tt.expectedIV, iv)
assert.Equal(t, tt.expectedData, data)
}
})
}
}
func TestLuaEncrypt(t *testing.T) {
validKey := "0123456789abcdef0123456789abcdef" // 16 bytes
validIV := "fedcba9876543210fedcba9876543210" // 16 bytes
validData := "deadbeefcafebabe0000111122223333" // 16 bytes
tests := []struct {
name string
keyStr string
ivStr string
dataStr string
expectReturn int
errMsg string
}{
{
name: "successful encryption",
keyStr: validKey,
ivStr: validIV,
dataStr: validData,
expectReturn: 1,
},
{
name: "successful encryption with empty data",
keyStr: validKey,
ivStr: validIV,
dataStr: "",
expectReturn: 1,
},
{
name: "invalid key hex",
keyStr: "invalid_hex",
ivStr: validIV,
dataStr: validData,
errMsg: "failed to decode params",
expectReturn: 2,
},
{
name: "invalid IV hex",
keyStr: validKey,
ivStr: "invalid_hex",
dataStr: validData,
errMsg: "failed to decode params",
expectReturn: 2,
},
{
name: "invalid data hex",
keyStr: validKey,
ivStr: validIV,
dataStr: "invalid_hex",
errMsg: "failed to decode params",
expectReturn: 2,
},
{
name: "invalid key size",
keyStr: "0123456789abcdef", // 8 bytes, too short
ivStr: validIV,
dataStr: validData,
errMsg: "failed to encrypt",
expectReturn: 2,
},
{
name: "invalid IV size",
keyStr: validKey,
ivStr: "0123456789abcdef", // 8 bytes, too short
dataStr: validData,
errMsg: "failed to encrypt",
expectReturn: 2,
},
{
name: "invalid data size",
keyStr: validKey,
ivStr: validIV,
dataStr: "deadbeefcafebabe000011112222333", // 15 bytes, not multiple of 16
errMsg: "failed to decode params",
expectReturn: 2,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
L := lua.NewState()
defer L.Close()
L.Push(lua.LString(tt.keyStr))
L.Push(lua.LString(tt.ivStr))
L.Push(lua.LString(tt.dataStr))
result := luaEncrypt(L)
assert.Equal(t, tt.expectReturn, result)
if tt.expectReturn == 1 {
encryptedHex := L.ToString(-1)
_, err := hex.DecodeString(encryptedHex)
assert.NoError(t, err, "Pushed value should be valid hex")
} else {
err := L.ToString(-1)
assert.Contains(t, err, tt.errMsg)
}
})
}
}
func TestLuaDecrypt(t *testing.T) {
validKey := "0123456789abcdef0123456789abcdef" // 16 bytes
validIV := "fedcba9876543210fedcba9876543210" // 16 bytes
// Create valid encrypted data by first encrypting some data
keyBytes, _ := hex.DecodeString(validKey)
ivBytes, _ := hex.DecodeString(validIV)
plainData := []byte("1234567890123456") // 16 bytes
encryptedData, _ := encrypt(keyBytes, ivBytes, plainData)
validEncryptedStr := hex.EncodeToString(encryptedData)
tests := []struct {
name string
keyStr string
ivStr string
dataStr string
expectReturn int
errMsg string
}{
{
name: "successful decryption",
keyStr: validKey,
ivStr: validIV,
dataStr: validEncryptedStr,
expectReturn: 1,
},
{
name: "successful decryption with empty data",
keyStr: validKey,
ivStr: validIV,
dataStr: "",
expectReturn: 1,
},
{
name: "invalid key hex",
keyStr: "invalid_hex",
ivStr: validIV,
dataStr: validEncryptedStr,
errMsg: "failed to decode params",
expectReturn: 2,
},
{
name: "invalid IV hex",
keyStr: validKey,
ivStr: "invalid_hex",
dataStr: validEncryptedStr,
errMsg: "failed to decode params",
expectReturn: 2,
},
{
name: "invalid encrypted data hex",
keyStr: validKey,
ivStr: validIV,
dataStr: "invalid_hex",
errMsg: "failed to decode params",
expectReturn: 2,
},
{
name: "invalid key size",
keyStr: "0123456789abcdef", // 8 bytes, too short
ivStr: validIV,
dataStr: validEncryptedStr,
errMsg: "failed to decrypt",
expectReturn: 2,
},
{
name: "invalid IV size",
keyStr: validKey,
ivStr: "0123456789abcdef", // 8 bytes, too short
dataStr: validEncryptedStr,
errMsg: "failed to decrypt",
expectReturn: 2,
},
{
name: "invalid encrypted data size",
keyStr: validKey,
ivStr: validIV,
dataStr: "deadbeefcafebabe000011112222333", // 15 bytes, not multiple of 16
errMsg: "failed to decode params",
expectReturn: 2,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
L := lua.NewState()
defer L.Close()
L.Push(lua.LString(tt.keyStr))
L.Push(lua.LString(tt.ivStr))
L.Push(lua.LString(tt.dataStr))
result := luaDecrypt(L)
assert.Equal(t, tt.expectReturn, result)
if tt.expectReturn == 1 {
decryptedHex := L.ToString(-1)
_, err := hex.DecodeString(decryptedHex)
assert.NoError(t, err, "Pushed value should be valid hex")
} else {
err := L.ToString(-1)
assert.Contains(t, err, tt.errMsg)
}
})
}
}
func TestLuaDecryptWithSample(t *testing.T) {
iv := "0907780613000704d2d2d2d2d2d2d2d2"
payload := "Ba56dc989e08a76f855ae12ae8B00ef13fae6ad436eBe8e03e97f17B5751c241"
key := "CB6ABFAA8D2247B59127D3B839CF34B4"
expected := "2f2f0c0613760100046d27350f380c13555134022f2f2f2f2f2f2f2f2f2f2f2f"
L := lua.NewState()
defer L.Close()
L.Push(lua.LString(key))
L.Push(lua.LString(iv))
L.Push(lua.LString(payload))
result := luaDecrypt(L)
if result != 1 {
t.Errorf("luaDecrypt() expected 1 return value, got %d", result)
return
}
decrypted, err := hex.DecodeString(L.ToString(-1))
require.Nil(t, err, "Failed to decode decrypted payload")
assert.Equal(t, expected, hex.EncodeToString(decrypted), "Decrypted payload does not match expected")
}
func TestLuaEncryptDecryptRoundTrip(t *testing.T) {
tests := []struct {
name string
keyStr string
ivStr string
dataStr string
}{
{
name: "single block round trip",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "deadbeefcafebabe0000111122223333",
},
{
name: "multiple block round trip",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "deadbeefcafebabe0000111122223333cafebabe0123456789abcdef01234567",
},
{
name: "empty data round trip",
keyStr: "0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "",
},
{
name: "AES-256 round trip",
keyStr: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
ivStr: "fedcba9876543210fedcba9876543210",
dataStr: "deadbeefcafebabe0000111122223333",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Test encryption
L1 := lua.NewState()
defer L1.Close()
L1.Push(lua.LString(tt.keyStr))
L1.Push(lua.LString(tt.ivStr))
L1.Push(lua.LString(tt.dataStr))
result := luaEncrypt(L1)
require.Equal(t, 1, result)
// Get encrypted result
encryptedHex := L1.ToString(-1)
// Test decryption
L2 := lua.NewState()
defer L2.Close()
L2.Push(lua.LString(tt.keyStr))
L2.Push(lua.LString(tt.ivStr))
L2.Push(lua.LString(encryptedHex))
result = luaDecrypt(L2)
require.Equal(t, 1, result)
// Verify round trip
decryptedHex := L2.ToString(-1)
assert.Equal(t, strings.ToLower(tt.dataStr), strings.ToLower(decryptedHex))
})
}
}
-4
View File
@@ -40,10 +40,6 @@ func (re *re) processLua(ctx context.Context, details []slog.Attr, r Rule, msg *
// Set the message object as a Lua global variable.
l.SetGlobal("message", message)
// Set binding functions as a Lua global functions.
l.SetGlobal("aes_encrypt", l.NewFunction(luaEncrypt))
l.SetGlobal("aes_decrypt", l.NewFunction(luaDecrypt))
if err := l.DoString(r.Logic.Value); err != nil {
return pkglog.RunInfo{Level: slog.LevelError, Message: fmt.Sprintf("failed to run rule logic: %s", err), Details: details}
}