convert.go:

- Add documentation
- Add tests
This commit is contained in:
Jan Tytgat
2025-01-13 14:54:09 +01:00
parent cdd1953978
commit 92feadbb70
2 changed files with 332 additions and 18 deletions

View File

@ -12,35 +12,58 @@ import (
"github.com/minio/sio"
)
// Defines the default layout of a string representing encrypted data.
// The string is divided in sections delimited by a colon.
// 1. Cipher suite
// 2. Salt
// 3. Data
// 4. Original data type
var regexEncryptedString = regexp.MustCompile(`\d{2}:[\w\d]{24}:[\w\d]*:[\w\d]*`)
// convertBytesToValue converts a byte-array to a reflect.Value.
// It takes a byte-slice and a reflect.Kind and returns an error if the conversion fails.
func convertBytesToValue(d []byte, k reflect.Kind) (reflect.Value, error) {
switch k {
case reflect.Int:
v := reflect.New(reflect.TypeOf(0))
v.Elem().SetInt(int64(binary.BigEndian.Uint64(d)))
return reflect.ValueOf(v.Elem().Interface()), nil
case reflect.Uint64:
v := reflect.New(reflect.TypeOf(uint64(0)))
v.Elem().SetUint(binary.BigEndian.Uint64(d))
return reflect.ValueOf(v.Elem().Interface()), nil
case reflect.String:
return reflect.ValueOf(string(d)), nil
default:
return reflect.Value{}, fmt.Errorf("unknown type %v", k)
}
}
// convertValueToHexString converts a value to a hex-encoded string.
// It returns an empty string and an error if the value is a kind reflect.Int and cannot be converted.
func convertValueToHexString(v reflect.Value) (string, error) {
var err error
switch v.Kind() {
case reflect.Int:
buf := make([]byte, 0)
bufWriter := bytes.NewBuffer(buf)
err = binary.Write(bufWriter, binary.BigEndian, v.Int())
if err != nil {
bufWriter := bytes.NewBuffer(make([]byte, 0))
if err = binary.Write(bufWriter, binary.BigEndian, v.Int()); err != nil {
return "", err
}
return hex.EncodeToString(bufWriter.Bytes()), nil
default:
case reflect.String:
return hex.EncodeToString([]byte(v.String())), nil
}
}
func convertBytesToValue(d []byte, k reflect.Kind) (reflect.Value, error) {
switch k {
case reflect.Int:
decodedInt := binary.BigEndian.Uint64(d)
return reflect.ValueOf(int(decodedInt)), nil
default:
return reflect.ValueOf(string(d)), nil
return "", fmt.Errorf("unknown type %v", v.Kind())
}
}
// decodeHexString decodes data into the pieces that make up the encrypted data.
// It takes an encrypted key and data string and returns the actual encrypted data as a byte-slice, reflect.Kind and the encryption config.
// It returns an error if the data string is empty or invalid, or any of the steps to get the encrypted data fails.
func decodeHexString(key string, data string) ([]byte, reflect.Kind, sio.Config, error) {
if key == "" {
return nil, reflect.Invalid, sio.Config{}, fmt.Errorf("key is empty")
}
if data == "" {
return nil, reflect.Invalid, sio.Config{}, fmt.Errorf("value is empty")
}
@ -58,9 +81,9 @@ func decodeHexString(key string, data string) ([]byte, reflect.Kind, sio.Config,
return nil, reflect.Invalid, sio.Config{}, fmt.Errorf("cannot decode cipersuite: %w", err)
}
var nonce []byte
if nonce, err = hex.DecodeString(split[1]); err != nil {
return nil, reflect.Invalid, sio.Config{}, fmt.Errorf("cannot decode nonce: %w", err)
var salt []byte
if salt, err = hex.DecodeString(split[1]); err != nil {
return nil, reflect.Invalid, sio.Config{}, fmt.Errorf("cannot decode salt: %w", err)
}
var encryptedBytes []byte
@ -79,7 +102,7 @@ func decodeHexString(key string, data string) ([]byte, reflect.Kind, sio.Config,
}
var cryptoConfig sio.Config
if cryptoConfig, err = createCryptoConfig(key, cipherSuiteBytes, nonce); err != nil {
if cryptoConfig, err = createCryptoConfig(key, cipherSuiteBytes, salt); err != nil {
return nil, reflect.Invalid, sio.Config{}, fmt.Errorf("cannot create crypto config: %w", err)
}