Files
syscrypt/internal/utils/salt.go

142 lines
3.8 KiB
Go
Raw Permalink Normal View History

package utils
import (
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"strings"
"sources.truenas.cloud/code/syscrypt"
"sources.truenas.cloud/code/syscrypt/internal/configuration"
"sources.truenas.cloud/code/syscrypt/internal/vars"
)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func HashEntry(value, x25519Str string) string {
key := strings.TrimPrefix(x25519Str, vars.PrivateKeyPrefixLabel)
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(value))
return hex.EncodeToString(h.Sum(nil))
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func AddSaltEntry(ref, serial, salt, x25519Key string) error {
var vault syscrypt.Vault
//vaultPath := config.KeyFolder + "/" + config.MasterKeySalt
vaultPath := configuration.KeyFolder + "/" + configuration.MasterKeySalt
if data, err := os.ReadFile(vaultPath); err == nil {
json.Unmarshal(data, &vault)
}
for _, e := range vault.Entries {
if e.Ref == ref {
return fmt.Errorf("reference %s already exists", ref)
}
}
encSalt := salt
newEntry := syscrypt.SaltEntry{
Ref: ref,
Salt: encSalt,
}
vault.Entries = append(vault.Entries, newEntry)
updated, _ := json.MarshalIndent(vault, "", " ")
return os.WriteFile(vaultPath, updated, 0644)
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func VerifySaltEntry(ref, x25519Key string) (salt string, exists bool, err error) {
//var vault syscrypt.Vault
//vaultPath := config.KeyFolder + "/" + config.MasterKeySalt
/*
data, err := os.ReadFile(vaultPath)
if err != nil {
return "", false, err
}
json.Unmarshal(data, &vault)
for _, e := range vault.Entries {
if e.Ref == ref {
//
//decSerial, errS := DecryptString(e.Serial, x25519Key)
decSalt, errSalt := DecryptString(e.Salt, x25519Key)
if errSalt != nil {
return "", false, fmt.Errorf("failed to decrypt entry")
}
return decSalt, true, nil
//
//
}
}
*/
//return "", false, fmt.Errorf("reference %s not found", ref)
return "", false, nil
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func EncryptString(plaintext, x25519Key string) (string, error) {
keyBytes := sha256.Sum256([]byte(x25519Key))
block, _ := aes.NewCipher(keyBytes[:])
gcm, _ := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
rand.Read(nonce)
return base64.StdEncoding.EncodeToString(gcm.Seal(nonce, nonce, []byte(plaintext), nil)), nil
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func DecryptString(cipherText string, x25519Key string) (string, error) {
data, err := base64.StdEncoding.DecodeString(cipherText)
if err != nil {
return "", err
}
keyBytes := sha256.Sum256([]byte(x25519Key))
block, _ := aes.NewCipher(keyBytes[:])
gcm, _ := cipher.NewGCM(block)
nonceSize := gcm.NonceSize()
nonce, ciphertextBytes := data[:nonceSize], data[nonceSize:]
plain, err := gcm.Open(nil, nonce, ciphertextBytes, nil)
return string(plain), err
//keyBytes := sha256.Sum256([]byte(x25519Key))
//block, _ := aes.NewCipher(keyBytes[:])
//gcm, _ := cipher.NewGCM(block)
//nonceSize := gcm.NonceSize()
//nonce, cipher := cipherText[:nonceSize], cipherText[nonceSize:]
//plain, err := gcm.Open(nil, nonce, cipher, nil)
//return string(plain), err
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////