114 lines
2.4 KiB
Go
114 lines
2.4 KiB
Go
package transcrypt
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
|
|
"github.com/minio/sio"
|
|
"golang.org/x/crypto/hkdf"
|
|
)
|
|
|
|
func createCryptoConfig(key string, cipher []byte, salt []byte) (sio.Config, error) {
|
|
if key == "" {
|
|
return sio.Config{}, errors.New("key is empty")
|
|
}
|
|
|
|
if cipher == nil {
|
|
return sio.Config{}, errors.New("cipher is empty")
|
|
}
|
|
|
|
var err error
|
|
// If salt is nil, create a new salt that can be used for encryption
|
|
if salt == nil {
|
|
if salt, err = createSalt(); err != nil {
|
|
return sio.Config{}, fmt.Errorf("could not create salt: %w", err)
|
|
}
|
|
}
|
|
|
|
// Create encryption key
|
|
kdf := hkdf.New(sha256.New, []byte(key), salt[:12], nil)
|
|
var encKey [32]byte
|
|
if _, err = io.ReadFull(kdf, encKey[:]); err != nil {
|
|
return sio.Config{}, fmt.Errorf("failed to derive encryption encKey: %w", err)
|
|
}
|
|
|
|
return sio.Config{
|
|
CipherSuites: cipher,
|
|
Key: encKey[:],
|
|
Nonce: (*[12]byte)(salt[:]),
|
|
}, nil
|
|
}
|
|
|
|
// createSalt creates a random salt for use with the encrypt/decrypt functionality
|
|
func createSalt() ([]byte, error) {
|
|
var nonce [12]byte
|
|
if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
|
|
return nil, fmt.Errorf("failed to read random data for nonce: %w", err)
|
|
}
|
|
|
|
return nonce[:], nil
|
|
}
|
|
|
|
func getKindForString(s string) reflect.Kind {
|
|
switch s {
|
|
case "bool":
|
|
return reflect.Bool
|
|
case "int":
|
|
return reflect.Int
|
|
case "int8":
|
|
return reflect.Int8
|
|
case "int16":
|
|
return reflect.Int16
|
|
case "int32":
|
|
return reflect.Int32
|
|
case "int64":
|
|
return reflect.Int64
|
|
case "uint":
|
|
return reflect.Uint
|
|
case "uint8":
|
|
return reflect.Uint8
|
|
case "uint16":
|
|
return reflect.Uint16
|
|
case "uint32":
|
|
return reflect.Uint32
|
|
case "uint64":
|
|
return reflect.Uint64
|
|
case "uintptr":
|
|
return reflect.Uintptr
|
|
case "float32":
|
|
return reflect.Float32
|
|
case "float64":
|
|
return reflect.Float64
|
|
case "complex64":
|
|
return reflect.Complex64
|
|
case "complex128":
|
|
return reflect.Complex128
|
|
case "array":
|
|
return reflect.Array
|
|
case "chan":
|
|
return reflect.Chan
|
|
case "func":
|
|
return reflect.Func
|
|
case "interface":
|
|
return reflect.Interface
|
|
case "map":
|
|
return reflect.Map
|
|
case "pointer":
|
|
return reflect.Pointer
|
|
case "slice":
|
|
return reflect.Slice
|
|
case "string":
|
|
return reflect.String
|
|
case "struct":
|
|
return reflect.Struct
|
|
case "unsafepointer":
|
|
return reflect.UnsafePointer
|
|
default:
|
|
return reflect.Invalid
|
|
}
|
|
}
|