Files
syscrypt/internal/actions/keygen/keygen.go

505 lines
14 KiB
Go
Raw Normal View History

package keygen
import (
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"os"
"strconv"
"time"
"sources.truenas.cloud/code/syscrypt/internal/utils"
"sources.truenas.cloud/code/syscrypt/internal/vars"
)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func FirstRun() {
defaultFolder := configuration.ConfigKeyFolder
//fmt.Printf("default folder: %s\n", defaultFolder)
//fmt.Printf("[DEBUG KEYGEN] Value: %s | Addr: %p\n", config.KeyFolder, &config.KeyFolder)
//defaultFolder := config.KeyFolder
//defaultKey := config.KeyFolder + "/" + config.MasterKey
//defaultKeyExists := utils.FileExists(defaultKey)
//defaultFolderExists := utils.FolderExists(defaultFolder)
//fmt.Printf("CONFIG KEY FOLDER: %s\n", config.KeyFolder)
_ = defaultFolder
os.Exit(1)
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func Validate() {
keygenAllowedFlags := map[string]struct{}{
"-C": {},
"-i": {},
"-c": {},
"-PQ": {},
"-k": {},
"-f": {},
}
utils.ValidateAllowedFlags(keygenAllowedFlags)
keygenRequiredFlags := []vars.FlagRequirement{
{Flag: "-f", IsRequired: true},
}
// friendly name -f
// keypath -K
// output -o
utils.ValidateRequiredFlags(keygenRequiredFlags, "keygen")
// friendlyname
isFriendlySet, friendlyHasValue := utils.IsFlagPassed("f")
friendlyValue, _ := utils.GetFlagValue("f")
isFriendlyValid := utils.IsAlphaNumeric(friendlyValue)
if isFriendlySet && !friendlyHasValue {
msg := fmt.Sprintf("%s: -f FRIENDLYNAME: requires a value.\n"+
"Do not enter spaces or special characters. e.g. 'masterkey'", vars.CommandFlag)
utils.HandleFailure(msg)
os.Exit(1)
}
if isFriendlySet && friendlyHasValue && !isFriendlyValid {
msg := fmt.Sprintf("%s: -f FRIENDLYNAME: invalid friendly name.\n"+
"The friendly name requires an alphanumeric value. e.g. 'masterkey'\n"+
"Do not enter paths, spaces, special characters or file extensions.", vars.CommandFlag)
utils.HandleFailure(msg)
os.Exit(1)
}
// check default keys
// keypath
isKeyPathSet, keyPathHasValue := utils.IsFlagPassed("k")
keyPathValue, _ := utils.GetFlagValue("k")
keyPathIsValid := utils.IsValidPath(keyPathValue)
keyPathExists := utils.FolderExists(keyPathValue)
if isKeyPathSet && !keyPathHasValue {
msg := fmt.Sprintf("%s: -k KEYPATH: requires a value.", vars.CommandFlag)
utils.HandleFailure(msg)
os.Exit(1)
}
if isKeyPathSet && !keyPathIsValid {
msg := fmt.Sprintf("%s: -k KEYPATH: requires a valid folder path.", vars.CommandFlag)
utils.HandleFailure(msg)
os.Exit(1)
}
if isKeyPathSet && keyPathIsValid && !keyPathExists {
msg := fmt.Sprintf("%s: -k KEYPATH: folder path '%s' does not exist.", vars.CommandFlag, keyPathValue)
utils.HandleFailure(msg)
os.Exit(1)
}
var keyFolder string
var defaultSet bool
if isKeyPathSet {
defaultSet = false
keyFolder = keyPathValue
} else {
defaultSet = true
keyFolder = config.KeyFolder
}
if defaultSet {
keyPathIsValid = utils.IsValidPath(keyFolder)
}
if defaultSet && !keyPathIsValid {
msg := fmt.Sprintf("%s: DEFAULT KEYPATH '%s' was not found.", vars.CommandFlag, config.KeyFolder)
utils.HandleFailure(msg)
os.Exit(1)
}
// comment
isCommentSet, commentHasValue := utils.IsFlagPassed("C")
if isCommentSet && !commentHasValue {
msg := fmt.Sprintf("%s: -C COMMENT: flag is set but no value was provided.", vars.CommandFlag)
utils.HandleFailure(msg)
os.Exit(1)
}
fmt.Printf("key folder: %s\n", keyFolder)
_ = isKeyPathSet
_ = keyPathHasValue
_ = keyPathIsValid
_ = keyPathExists
_ = keyFolder
// comment
// output
KeyGen()
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func generateRandomSerial() string {
token := make([]byte, 15)
rand.Read(token)
return hex.EncodeToString(token)
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func getCurrentDate() string {
return time.Now().Format("2006-01-02 15:04:05")
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func saveKeyFile(filename string, permission string, data interface{}) {
fmt.Printf("%v\n", data)
os.Exit(1)
if permission == "" {
fmt.Printf("error: permission code required.\n")
return
}
fileData, err := json.MarshalIndent(data, "", " ")
if err != nil {
fmt.Printf("error encoding json: %v\n", err)
return
}
err = os.WriteFile(filename, fileData, 0600)
if err != nil {
fmt.Printf("Error writing %s: %v\n", filename, err)
return
}
permUint, _ := strconv.ParseUint(permission, 8, 32)
err = os.Chmod(filename, os.FileMode(permUint))
if err != nil {
fmt.Printf("Error adjusting permissions on %s: %v\n", filename, err)
return
}
fmt.Printf("Success: '%s' saved successfully.\n", filename)
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
func KeyGen() {
outputFolder, _ := utils.GetFlagValue("o")
isPQSet, _ := utils.IsFlagPassed("PQ")
commentValue, _ := utils.GetFlagValue("C")
if outputFolder == "" {
outputFolder = config.KeyFolder
}
_ = isPQSet
_ = commentValue
//fmt.Printf("%s", config.KeyFolder)
//outputValue, _ := utils.GetFlagValue("o")
//isPQSet, _ := utils.IsFlagPassed("PQ")
//commentValue, _ := utils.GetFlagValue("C")
//pubWrap := syscrypt.PublicKeyWrapper{}
//privWrap := syscrypt.PrivateKeyWrapper{}
//apiWrap := syscrypt.ApiKeyWrapper{}
///
//var privX, pubX [32]byte
//io.ReadFull(rand.Reader, privX[:])
//curve25519.ScalarBaseMult(&pubX, &privX)
//serial := generateRandomSerial()
//date := getCurrentDate()
//password := (generatepassword)
//pubWrap.PublicKey.Key = vars.DefaultPrefixLabel + hex.EncodeToString(pubX[:])
//pubWrap.PublicKey.Serial = serial
//pubWrap.PublicKey.Date = date
//pubWrap.PublicKey.Comment = commentValue
//privWrap.PrivateKey.Key = vars.PrivateKeyPrefixLabel + hex.EncodeToString(privX[:])
//privWrap.PrivateKey.Serial = serial
//privWrap.PrivateKey.Date = date
//privWrap.PrivateKey.Comment = commentValue
//apiWrap.ApiKey.Key = ""
//apiWrap.ApiKey.Serial = serial
//apiWrap.ApiKey.Date = date
//apiWrap.ApiKey.Comment = commentValue
/*
type ApiKeyWrapper struct {
ApiKey struct {
Key string `json:"key"`
Serial string `json:"serial"`
Date string `json:"date"`
Comment string `json:"comment"`
} `json:"APIKey"`
}
*/
//if isPQSet {
// scheme := kyber768.Scheme()
// pkK, skK, err := scheme.GenerateKeyPair()
// if err != nil {
// fmt.Printf("error: keygen failed: %v\n", err)
// return
// }
// pkBytes, _ := pkK.MarshalBinary()
// skBytes, _ := skK.MarshalBinary()
// pubWrap.PublicKey.MLKEMKey = vars.PQPublicKeyPrefixLabel + hex.EncodeToString(pkBytes)
// privWrap.PrivateKey.MLKEMKey = vars.PQPrivateKeyPrefixLabel + hex.EncodeToString(skBytes)
//}
//pubJSON, err := json.MarshalIndent(pubWrap, "", " ")
//if err != nil {
// fmt.Printf("Marshal Error: %v\n", err)
// return
//}
//privJSON, err := json.MarshalIndent(privWrap, "", " ")
//if err != nil {
// fmt.Printf("Marshal Error: %v\n", err)
// return
//}
//MasterFolder := config.KeyFolder
// Public Key File
//pubFullPath := outputValue
//pubDir := filepath.Dir(pubFullPath)
//pubBase := filepath.Base(pubFullPath)
//pubExt := filepath.Ext(pubBase)
//pubFileName := strings.TrimSuffix(pubBase, pubExt)
//pubFilePath := MasterFolder + "/" + pubFileName + ".pub" + pubExt
// API Key File
//apiFullPath := outputValue
//apiDir := filepath.Dir(apiFullPath)
//apiBase := filepath.Base(apiFullPath)
//apiExt := filepath.Ext(apiBase)
//apiFileName := strings.TrimSuffix(apiBase, apiExt)
//apiFilePath := MasterFolder + "/" + apiFileName + ".api" + apiExt
// Master Password
/*
passFullPath := outputValue
passDir := filepath.Dir(passFullPath)
passBase := filepath.Base(passFullPath)
passExt := filepath.Ext(passBase)
passFileName := strings.TrimSuffix(passBase, passExt)
passFilePath := MasterFolder + "/" + passFileName + ".secret" + passExt
fmt.Printf("fullpath: %s\n", passFullPath)
fmt.Printf("dir: %s\n", passDir)
fmt.Printf("base: %s\n", passBase)
fmt.Printf("ext: %s\n", passExt)
fmt.Printf("filename: %s\n", passFileName)
fmt.Printf("path: %s\n", passFilePath)
*/
// Save to disk
//err = os.WriteFile(pubFilePath, pubJSON, 0644)
//if err != nil {
// fmt.Printf("File Error: %v\n", err)
// os.Exit(1)
//}
//err = os.WriteFile(outputValue, privJSON, 0600)
//if err != nil {
// fmt.Printf("File Error: %v\n", err)
// os.Exit(1)
//}
//saveKeyFile(outputValue, "600", privJSON)
//saveKeyFile(filename string, permission string, data interface{})
////pubFullPath := outputValue
////pubDir := filepath.Dir(pubFullPath)
////pubBase := filepath.Base(pubFullPath)
////pubExt := filepath.Ext(pubBase)
////pubClean := strings.TrimSuffix(pubBase, pubExt)
////pubFileOut := pubClean + ".pub" + pubExt
////pubFileOut = pubDir + "/" + pubFileOut
//_ = outputValue
//_ = commentValue
//_ = pubJSON
//_ = privJSON
//_ = pubDir
//_ = pubFilePath
//_ = apiDir
//_ = apiFilePath
//_ = apiWrap
//_ = passDir
//_ = passFilePath
//fmt.Printf("%v\n", pkK)
//fmt.Printf("%v\n", skK)
////outputValue, _ := utils.GetFlagValue("o")
////isPQSet, _ := utils.IsFlagPassed("PQ")
////commentValue, _ := utils.GetFlagValue("C")
////privX := make([]byte, 32)
////rand.Read(privX)
////pubX, _ := curve25519.X25519(privX, curve25519.Basepoint)
////pubWrap := syscrypt.PublicKeyWrapper{}
////privWrap := syscrypt.PrivateKeyWrapper{}
////apiWrap := syscrypt.ApiKeyWrapper{}
////_ = apiWrap
///
////serial := generateRandomSerial()
////date := getCurrentDate()
////if isPQSet {
//// pubK, privK, _ := kyber768.GenerateKeyPair(rand.Reader)
//// pBytes, _ := pubK.MarshalBinary()
//// sBytes, _ := privK.MarshalBinary()
//// pubWrap.PublicKey.MLKEMKey = vars.PQPublicKeyPrefixLabel + hex.EncodeToString(pBytes)
//// privWrap.PrivateKey.MLKEMKey = vars.PQPrivateKeyPrefixLabel + hex.EncodeToString(sBytes)
////}
////pubWrap.PublicKey.Key = vars.DefaultPrefixLabel + hex.EncodeToString(pubX)
////pubWrap.PublicKey.Serial = serial
////pubWrap.PublicKey.Date = date
////pubWrap.PublicKey.Comment = commentValue
////privWrap.PrivateKey.Key = vars.PrivateKeyPrefixLabel + hex.EncodeToString(privX)
////privWrap.PrivateKey.Serial = serial
////privWrap.PrivateKey.Date = date
////privWrap.PrivateKey.Comment = commentValue
//apiWrap.ApiKey.Key = GenerateAPIKey(xxx, )
//apiWrap.ApiKey.Serial = serial
//apiWrap.ApiKey.Date = date
//apiWrap.ApiKey.Comment = commentValue
//type ApiKeyWrapper struct {
// ApiKey struct {
// Key string `json:"key"`
// Serial string `json:"serial"`
// Date string `json:"date"`
// Comment string `json:"comment"`
// } `json:"APIKey"`
//}
////fmt.Printf("public key: %s\n", pubWrap.PublicKey.Key)
////fmt.Printf("private key: %s\n", privWrap.PrivateKey.Key)
////fmt.Printf("pq: %s\n", pubWrap.PublicKey.MLKEMKey)
//preview, _ := json.MarshalIndent(privWrap, "", " ")
//fmt.Println(string(preview))
////pubFullPath := outputValue
////pubDir := filepath.Dir(pubFullPath)
////pubBase := filepath.Base(pubFullPath)
////pubExt := filepath.Ext(pubBase)
////pubClean := strings.TrimSuffix(pubBase, pubExt)
////pubFileOut := pubClean + ".pub" + pubExt
////pubFileOut = pubDir + "/" + pubFileOut
////apiFullPath := outputValue
////apiDir := filepath.Dir(apiFullPath)
////apiBase := filepath.Base(apiFullPath)
////apiExt := filepath.Ext(apiBase)
////apiClean := strings.TrimSuffix(apiBase, apiExt)
////apiFileOut := apiClean + ".api" + apiExt
////apiFileOut = apiDir + "/" + apiFileOut
// Generate Master Password if one doesnt already exist
//mpExists := utils.ReadJson("config.masterpass", config.ConfigPath)
////_ = pubDir
////_ = apiDir
////_ = apiFileOut
////fmt.Printf("public out: %s\n", pubDir+"/"+pubFileOut)
////fmt.Printf("api out: %s\n", apiDir+"/"+apiFileOut)
////saveKeyFile(pubFileOut, "0600", pubWrap)
////saveKeyFile(outputValue, "0644", privWrap)
//saveKeyFile(xxxx, 0600, xxxxxx)
//func saveKeyFile(filename string, permission string, data interface{}) {
//type PublicKeyWrapper struct {
// PublicKey struct {
// Key string `json:"key"`
// MLKEMKey string `json:"mlkem_key,omitempty"`
// Serial string `json:"serial"`
// Date string `json:"date"`
// Comment string `json:"comment"`
// } `json:"PublicKey"`
//}
//privRaw := make([]byte, 32)
//serial := utils.GenerateSerial(27)
//io.ReadFull(rand.Reader, privRaw)
//pubRaw, _ := curve25519.X25519(privRaw, curve25519.Basepoint)
//dateStr := time.Now().Format("2006-01-02 15:04:05")
//privStruct := syscrypt.PrivateKeyWrapper{}
//privStruct.PrivateKey.Key = vars.PrivateKeyPrefixLabel + hex.EncodeToString(privRaw)
//privStruct.PrivateKey.Serial = serial
//privStruct.PrivateKey.Date = dateStr
//privStruct.PrivateKey.Comment = vars.Comment
//pubStruct := syscrypt.PublicKeyWrapper{}
//pubStruct.PublicKey.Key = vars.DefaultPrefixLabel + hex.EncodeToString(pubRaw)
//pubStruct.PublicKey.Serial = serial
//pubStruct.PublicKey.Date = dateStr
//pubStruct.PublicKey.Comment = vars.Comment
//pBytes, _ := json.MarshalIndent(privStruct, "", " ")
//pubBytes, _ := json.MarshalIndent(pubStruct, "", " ")
//fmt.Printf("%s\n", pBytes)
//fmt.Printf("%s\n", pubBytes)
//fmt.Printf("%s\n", pubStruct.PublicKey.Serial)
//utils.GenerateKeys(pubStruct.PublicKey.Key, privStruct.PrivateKey.Key, serial)
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////