81 lines
1.8 KiB
Go
81 lines
1.8 KiB
Go
package boltdb
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/cipher"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/segmentio/encoding/json"
|
|
)
|
|
|
|
var errEncryptedStringTooShort = errors.New("encrypted string too short")
|
|
|
|
// MarshalObject encodes an object to binary format
|
|
func (connection *DbConnection) MarshalObject(object any) ([]byte, error) {
|
|
buf := &bytes.Buffer{}
|
|
|
|
// Special case for the VERSION bucket. Here we're not using json
|
|
if v, ok := object.(string); ok {
|
|
buf.WriteString(v)
|
|
} else {
|
|
enc := json.NewEncoder(buf)
|
|
enc.SetSortMapKeys(false)
|
|
enc.SetAppendNewline(false)
|
|
|
|
if err := enc.Encode(object); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if connection.gcm == nil {
|
|
return buf.Bytes(), nil
|
|
}
|
|
|
|
return encrypt(buf.Bytes(), connection.gcm), nil
|
|
}
|
|
|
|
// UnmarshalObject decodes an object from binary data
|
|
func (connection *DbConnection) UnmarshalObject(data []byte, object any) error {
|
|
var err error
|
|
if connection.gcm != nil {
|
|
data, err = decrypt(data, connection.gcm)
|
|
if err != nil {
|
|
return errors.Wrap(err, "Failed decrypting object")
|
|
}
|
|
}
|
|
|
|
if err := json.Unmarshal(data, object); err != nil {
|
|
// Special case for the VERSION bucket. Here we're not using json
|
|
// So we need to return it as a string
|
|
s, ok := object.(*string)
|
|
if !ok {
|
|
return errors.Wrap(err, "Failed unmarshalling object")
|
|
}
|
|
|
|
*s = string(data)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func encrypt(plaintext []byte, gcm cipher.AEAD) []byte {
|
|
return gcm.Seal(nil, nil, plaintext, nil)
|
|
}
|
|
|
|
func decrypt(encrypted []byte, gcm cipher.AEAD) ([]byte, error) {
|
|
if string(encrypted) == "false" {
|
|
return []byte("false"), nil
|
|
}
|
|
|
|
if len(encrypted) < gcm.Overhead() {
|
|
return encrypted, errEncryptedStringTooShort
|
|
}
|
|
|
|
plaintextByte, err := gcm.Open(nil, nil, encrypted, nil)
|
|
if err != nil {
|
|
return encrypted, errors.Wrap(err, "Error decrypting text")
|
|
}
|
|
|
|
return plaintextByte, nil
|
|
}
|