mirror of
https://github.com/absmach/supermq.git
synced 2026-06-23 06:40:19 +00:00
NOISSUE - Add AES support to RE (#143)
* AES RE support Lua script * AES RE support Lua script * AES support on RE * AES Support on RE * AES code change * Modified AES script * Modified AES script * AES Go script * AES Go script * Update: String use to Byte use * Update: AES Lua binding and Go script * Update: AES Lua binding reviewed changes and Go script * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Reviewed Update: Lint Checking with code * Fix remarks Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> * Add IV size check Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> * Add IV size check Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> * Add IV size check Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> * Fix variable names Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> * Use common decode params Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> --------- Signed-off-by: Dusan Borovcanin <borovcanindusan1@gmail.com> Co-authored-by: Dusan Borovcanin <borovcanindusan1@gmail.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
// Copyright (c) Abstract Machines
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package re
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
|
||||
"github.com/absmach/supermq/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
errInvalidDataSize = errors.New("data is not a multiple of the block size")
|
||||
errInvalidIVSize = errors.New("size of the IV is not the same as block size")
|
||||
)
|
||||
|
||||
// AES CBC-128 DECRYPTION 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) {
|
||||
if len(iv) != aes.BlockSize {
|
||||
return nil, errInvalidIVSize
|
||||
}
|
||||
if len(data)%aes.BlockSize != 0 {
|
||||
return nil, errInvalidDataSize
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
encrypted := make([]byte, len(data))
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(encrypted, data)
|
||||
|
||||
return encrypted, nil
|
||||
}
|
||||
|
||||
func decrypt(key []byte, iv []byte, encrypted []byte) ([]byte, error) {
|
||||
if len(iv) != aes.BlockSize {
|
||||
return nil, errInvalidIVSize
|
||||
}
|
||||
if len(encrypted)%aes.BlockSize != 0 {
|
||||
return nil, errInvalidDataSize
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
decrypted := make([]byte, len(encrypted))
|
||||
mode.CryptBlocks(decrypted, encrypted)
|
||||
return decrypted, err
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/gob"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/absmach/magistrala/alarms"
|
||||
@@ -15,6 +16,61 @@ import (
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
|
||||
func luaEncrypt(l *lua.LState) int {
|
||||
key, iv, data, err := decodeParams(l)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
enc, err := encrypt(key, iv, data)
|
||||
if err != nil {
|
||||
l.RaiseError("Falied to encrypt: %v", err)
|
||||
return 0
|
||||
}
|
||||
l.Push(lua.LString(hex.EncodeToString(enc)))
|
||||
return 1
|
||||
}
|
||||
|
||||
func luaDecrypt(l *lua.LState) int {
|
||||
key, iv, data, err := decodeParams(l)
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
|
||||
dec, err := decrypt(key, iv, data)
|
||||
if err != nil {
|
||||
l.RaiseError("Falied to decrypt: %v", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
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 {
|
||||
l.RaiseError("Failed to decode key: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
iv, err = hex.DecodeString(ivStr)
|
||||
if err != nil {
|
||||
l.RaiseError("Failed to decode IV: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
data, err = hex.DecodeString(dataStr)
|
||||
if err != nil {
|
||||
l.RaiseError("Failed to decode data: %v", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (re *re) sendEmail(l *lua.LState) int {
|
||||
recipientsTable := l.ToTable(1)
|
||||
subject := l.ToString(2)
|
||||
|
||||
+3
-1
@@ -53,9 +53,11 @@ func (re *re) process(ctx context.Context, r Rule, msg *messaging.Message) error
|
||||
// Set the message object as a Lua global variable.
|
||||
l.SetGlobal("message", message)
|
||||
|
||||
// set the email function as a Lua global function.
|
||||
// Set binding functions as a Lua global functions.
|
||||
l.SetGlobal("send_email", l.NewFunction(re.sendEmail))
|
||||
l.SetGlobal("send_alarm", l.NewFunction(re.sendAlarm(ctx, r.ID, msg)))
|
||||
l.SetGlobal("aes_encrypt", l.NewFunction(luaEncrypt))
|
||||
l.SetGlobal("aes_decrypt", l.NewFunction(luaDecrypt))
|
||||
|
||||
if err := l.DoString(r.Logic.Value); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user