fix: resolve all nlreturn linter errors
Add blank lines before return statements in all files to satisfy the nlreturn linter. This improves code readability by providing visual separation before return statements. Changes made across 24 files: - internal/cli/*.go - internal/secret/*.go - internal/vault/*.go - pkg/agehd/agehd.go - pkg/bip85/bip85.go All 143 nlreturn issues have been resolved.
This commit is contained in:
parent
811ddee3b7
commit
080a3dc253
@ -17,7 +17,12 @@
|
|||||||
"Bash(gofumpt:*)",
|
"Bash(gofumpt:*)",
|
||||||
"Bash(git stash:*)",
|
"Bash(git stash:*)",
|
||||||
"Bash(git commit:*)",
|
"Bash(git commit:*)",
|
||||||
"Bash(git push:*)"
|
"Bash(git push:*)",
|
||||||
|
"Bash(golangci-lint:*)",
|
||||||
|
"Bash(git checkout:*)",
|
||||||
|
"Bash(ls:*)",
|
||||||
|
"WebFetch(domain:golangci-lint.run)",
|
||||||
|
"Bash(go:*)"
|
||||||
],
|
],
|
||||||
"deny": []
|
"deny": []
|
||||||
}
|
}
|
||||||
|
@ -81,10 +81,6 @@ issues:
|
|||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
max-same-issues: 0
|
max-same-issues: 0
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
# Exclude all linters from running on test files
|
|
||||||
- path: _test\.go
|
|
||||||
|
|
||||||
# Allow long lines in generated code or test data
|
|
||||||
- path: ".*_gen\\.go"
|
- path: ".*_gen\\.go"
|
||||||
linters:
|
linters:
|
||||||
- lll
|
- lll
|
||||||
|
@ -37,6 +37,7 @@ func NewCLIInstance() *Instance {
|
|||||||
// NewCLIInstanceWithFs creates a new CLI instance with the given filesystem (for testing)
|
// NewCLIInstanceWithFs creates a new CLI instance with the given filesystem (for testing)
|
||||||
func NewCLIInstanceWithFs(fs afero.Fs) *Instance {
|
func NewCLIInstanceWithFs(fs afero.Fs) *Instance {
|
||||||
stateDir := secret.DetermineStateDir("")
|
stateDir := secret.DetermineStateDir("")
|
||||||
|
|
||||||
return &Instance{
|
return &Instance{
|
||||||
fs: fs,
|
fs: fs,
|
||||||
stateDir: stateDir,
|
stateDir: stateDir,
|
||||||
|
@ -236,6 +236,7 @@ func (cli *Instance) Decrypt(secretName, inputFile, outputFile string) error {
|
|||||||
// isValidAgeSecretKey checks if a string is a valid age secret key by attempting to parse it
|
// isValidAgeSecretKey checks if a string is a valid age secret key by attempting to parse it
|
||||||
func isValidAgeSecretKey(key string) bool {
|
func isValidAgeSecretKey(key string) bool {
|
||||||
_, err := age.ParseX25519Identity(key)
|
_, err := age.ParseX25519Identity(key)
|
||||||
|
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ func newGenerateMnemonicCmd() *cobra.Command {
|
|||||||
`or 'secret import'.`,
|
`or 'secret import'.`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.GenerateMnemonic(cmd)
|
return cli.GenerateMnemonic(cmd)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -147,12 +148,14 @@ func (cli *Instance) GenerateSecret(
|
|||||||
// generateRandomBase58 generates a random base58 string of the specified length
|
// generateRandomBase58 generates a random base58 string of the specified length
|
||||||
func generateRandomBase58(length int) (string, error) {
|
func generateRandomBase58(length int) (string, error) {
|
||||||
const base58Chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
const base58Chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||||
|
|
||||||
return generateRandomString(length, base58Chars)
|
return generateRandomString(length, base58Chars)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateRandomAlnum generates a random alphanumeric string of the specified length
|
// generateRandomAlnum generates a random alphanumeric string of the specified length
|
||||||
func generateRandomAlnum(length int) (string, error) {
|
func generateRandomAlnum(length int) (string, error) {
|
||||||
const alnumChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
const alnumChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
return generateRandomString(length, alnumChars)
|
return generateRandomString(length, alnumChars)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ func NewInitCmd() *cobra.Command {
|
|||||||
// RunInit is the exported function that handles the init command
|
// RunInit is the exported function that handles the init command
|
||||||
func RunInit(cmd *cobra.Command, args []string) error {
|
func RunInit(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.Init(cmd)
|
return cli.Init(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
|
|
||||||
if err := cli.fs.MkdirAll(stateDir, secret.DirPerms); err != nil {
|
if err := cli.fs.MkdirAll(stateDir, secret.DirPerms); err != nil {
|
||||||
secret.Debug("Failed to create state directory", "error", err)
|
secret.Debug("Failed to create state directory", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to create state directory: %w", err)
|
return fmt.Errorf("failed to create state directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,12 +64,14 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
mnemonicStr, err = readLineFromStdin("Enter your BIP39 mnemonic phrase: ")
|
mnemonicStr, err = readLineFromStdin("Enter your BIP39 mnemonic phrase: ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read mnemonic from stdin", "error", err)
|
secret.Debug("Failed to read mnemonic from stdin", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to read mnemonic: %w", err)
|
return fmt.Errorf("failed to read mnemonic: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if mnemonicStr == "" {
|
if mnemonicStr == "" {
|
||||||
secret.Debug("Empty mnemonic provided")
|
secret.Debug("Empty mnemonic provided")
|
||||||
|
|
||||||
return fmt.Errorf("mnemonic cannot be empty")
|
return fmt.Errorf("mnemonic cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +79,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
secret.DebugWith("Validating BIP39 mnemonic", slog.Int("word_count", len(strings.Fields(mnemonicStr))))
|
secret.DebugWith("Validating BIP39 mnemonic", slog.Int("word_count", len(strings.Fields(mnemonicStr))))
|
||||||
if !bip39.IsMnemonicValid(mnemonicStr) {
|
if !bip39.IsMnemonicValid(mnemonicStr) {
|
||||||
secret.Debug("Invalid BIP39 mnemonic provided")
|
secret.Debug("Invalid BIP39 mnemonic provided")
|
||||||
|
|
||||||
return fmt.Errorf("invalid BIP39 mnemonic phrase\nRun 'secret generate mnemonic' to create a valid mnemonic")
|
return fmt.Errorf("invalid BIP39 mnemonic phrase\nRun 'secret generate mnemonic' to create a valid mnemonic")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +99,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
vlt, err := vault.CreateVault(cli.fs, cli.stateDir, "default")
|
vlt, err := vault.CreateVault(cli.fs, cli.stateDir, "default")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to create default vault", "error", err)
|
secret.Debug("Failed to create default vault", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to create default vault: %w", err)
|
return fmt.Errorf("failed to create default vault: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +108,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
metadata, err := vault.LoadVaultMetadata(cli.fs, vaultDir)
|
metadata, err := vault.LoadVaultMetadata(cli.fs, vaultDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to load vault metadata", "error", err)
|
secret.Debug("Failed to load vault metadata", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to load vault metadata: %w", err)
|
return fmt.Errorf("failed to load vault metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +116,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
ltIdentity, err := agehd.DeriveIdentity(mnemonicStr, metadata.DerivationIndex)
|
ltIdentity, err := agehd.DeriveIdentity(mnemonicStr, metadata.DerivationIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to derive long-term key", "error", err)
|
secret.Debug("Failed to derive long-term key", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
return fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
||||||
}
|
}
|
||||||
ltPubKey := ltIdentity.Recipient().String()
|
ltPubKey := ltIdentity.Recipient().String()
|
||||||
@ -127,6 +135,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
passphraseStr, err = readSecurePassphrase("Enter passphrase for unlocker: ")
|
passphraseStr, err = readSecurePassphrase("Enter passphrase for unlocker: ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read unlock passphrase", "error", err)
|
secret.Debug("Failed to read unlock passphrase", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to read passphrase: %w", err)
|
return fmt.Errorf("failed to read passphrase: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,6 +145,7 @@ func (cli *Instance) Init(cmd *cobra.Command) error {
|
|||||||
passphraseUnlocker, err := vlt.CreatePassphraseUnlocker(passphraseStr)
|
passphraseUnlocker, err := vlt.CreatePassphraseUnlocker(passphraseStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to create unlocker", "error", err)
|
secret.Debug("Failed to create unlocker", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to create unlocker: %w", err)
|
return fmt.Errorf("failed to create unlocker: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@ func (cli *Instance) AddSecret(secretName string, force bool) error {
|
|||||||
secret.Debug("Calling vault.AddSecret", "secret_name", secretName, "value_length", len(value), "force", force)
|
secret.Debug("Calling vault.AddSecret", "secret_name", secretName, "value_length", len(value), "force", force)
|
||||||
if err := vlt.AddSecret(secretName, value, force); err != nil {
|
if err := vlt.AddSecret(secretName, value, force); err != nil {
|
||||||
secret.Debug("vault.AddSecret failed", "error", err)
|
secret.Debug("vault.AddSecret failed", "error", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +157,7 @@ func (cli *Instance) GetSecretWithVersion(cmd *cobra.Command, secretName string,
|
|||||||
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get current vault", "error", err)
|
secret.Debug("Failed to get current vault", "error", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +170,7 @@ func (cli *Instance) GetSecretWithVersion(cmd *cobra.Command, secretName string,
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get secret", "error", err)
|
secret.Debug("Failed to get secret", "error", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ func newUnlockersAddCmd() *cobra.Command {
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.UnlockersAdd(args[0], cmd)
|
return cli.UnlockersAdd(args[0], cmd)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -75,6 +76,7 @@ func newUnlockersRmCmd() *cobra.Command {
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.UnlockersRemove(args[0])
|
return cli.UnlockersRemove(args[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -99,6 +101,7 @@ func newUnlockerSelectSubCmd() *cobra.Command {
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.UnlockerSelect(args[0])
|
return cli.UnlockerSelect(args[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ func newVaultCreateCmd() *cobra.Command {
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.CreateVault(cmd, args[0])
|
return cli.CreateVault(cmd, args[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -67,6 +68,7 @@ func newVaultSelectCmd() *cobra.Command {
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return cli.SelectVault(cmd, args[0])
|
return cli.SelectVault(cmd, args[0])
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -209,6 +211,7 @@ func (cli *Instance) VaultImport(cmd *cobra.Command, vaultName string) error {
|
|||||||
derivationIndex, err := vault.GetNextDerivationIndex(cli.fs, cli.stateDir, mnemonic)
|
derivationIndex, err := vault.GetNextDerivationIndex(cli.fs, cli.stateDir, mnemonic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get next derivation index", "error", err)
|
secret.Debug("Failed to get next derivation index", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to get next derivation index: %w", err)
|
return fmt.Errorf("failed to get next derivation index: %w", err)
|
||||||
}
|
}
|
||||||
secret.Debug("Using derivation index", "index", derivationIndex)
|
secret.Debug("Using derivation index", "index", derivationIndex)
|
||||||
@ -256,6 +259,7 @@ func (cli *Instance) VaultImport(cmd *cobra.Command, vaultName string) error {
|
|||||||
|
|
||||||
if err := vault.SaveVaultMetadata(cli.fs, vaultDir, existingMetadata); err != nil {
|
if err := vault.SaveVaultMetadata(cli.fs, vaultDir, existingMetadata); err != nil {
|
||||||
secret.Debug("Failed to save vault metadata", "error", err)
|
secret.Debug("Failed to save vault metadata", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to save vault metadata: %w", err)
|
return fmt.Errorf("failed to save vault metadata: %w", err)
|
||||||
}
|
}
|
||||||
secret.Debug("Saved vault metadata with derivation index and public key hash")
|
secret.Debug("Saved vault metadata with derivation index and public key hash")
|
||||||
@ -276,6 +280,7 @@ func (cli *Instance) VaultImport(cmd *cobra.Command, vaultName string) error {
|
|||||||
passphraseUnlocker, err := vlt.CreatePassphraseUnlocker(passphraseStr)
|
passphraseUnlocker, err := vlt.CreatePassphraseUnlocker(passphraseStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to create unlocker", "error", err)
|
secret.Debug("Failed to create unlocker", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to create unlocker: %w", err)
|
return fmt.Errorf("failed to create unlocker: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ const (
|
|||||||
// newVersionCmd returns the version management command
|
// newVersionCmd returns the version management command
|
||||||
func newVersionCmd() *cobra.Command {
|
func newVersionCmd() *cobra.Command {
|
||||||
cli := NewCLIInstance()
|
cli := NewCLIInstance()
|
||||||
|
|
||||||
return VersionCommands(cli)
|
return VersionCommands(cli)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,12 +65,14 @@ func (cli *Instance) ListVersions(cmd *cobra.Command, secretName string) error {
|
|||||||
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
vlt, err := vault.GetCurrentVault(cli.fs, cli.stateDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get current vault", "error", err)
|
secret.Debug("Failed to get current vault", "error", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
vaultDir, err := vlt.GetDirectory()
|
vaultDir, err := vlt.GetDirectory()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get vault directory", "error", err)
|
secret.Debug("Failed to get vault directory", "error", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,10 +84,12 @@ func (cli *Instance) ListVersions(cmd *cobra.Command, secretName string) error {
|
|||||||
exists, err := afero.DirExists(cli.fs, secretDir)
|
exists, err := afero.DirExists(cli.fs, secretDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to check if secret exists", "error", err)
|
secret.Debug("Failed to check if secret exists", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to check if secret exists: %w", err)
|
return fmt.Errorf("failed to check if secret exists: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
secret.Debug("Secret not found", "secret_name", secretName)
|
secret.Debug("Secret not found", "secret_name", secretName)
|
||||||
|
|
||||||
return fmt.Errorf("secret '%s' not found", secretName)
|
return fmt.Errorf("secret '%s' not found", secretName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +97,13 @@ func (cli *Instance) ListVersions(cmd *cobra.Command, secretName string) error {
|
|||||||
versions, err := secret.ListVersions(cli.fs, secretDir)
|
versions, err := secret.ListVersions(cli.fs, secretDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to list versions", "error", err)
|
secret.Debug("Failed to list versions", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to list versions: %w", err)
|
return fmt.Errorf("failed to list versions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(versions) == 0 {
|
if len(versions) == 0 {
|
||||||
cmd.Println("No versions found")
|
cmd.Println("No versions found")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ func EncryptToRecipient(data []byte, recipient age.Recipient) ([]byte, error) {
|
|||||||
w, err := age.Encrypt(&buf, recipient)
|
w, err := age.Encrypt(&buf, recipient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to create encryptor", "error", err)
|
Debug("Failed to create encryptor", "error", err)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to create encryptor: %w", err)
|
return nil, fmt.Errorf("failed to create encryptor: %w", err)
|
||||||
}
|
}
|
||||||
Debug("Created age encryptor successfully")
|
Debug("Created age encryptor successfully")
|
||||||
@ -27,6 +28,7 @@ func EncryptToRecipient(data []byte, recipient age.Recipient) ([]byte, error) {
|
|||||||
Debug("Writing data to encryptor")
|
Debug("Writing data to encryptor")
|
||||||
if _, err := w.Write(data); err != nil {
|
if _, err := w.Write(data); err != nil {
|
||||||
Debug("Failed to write data to encryptor", "error", err)
|
Debug("Failed to write data to encryptor", "error", err)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to write data: %w", err)
|
return nil, fmt.Errorf("failed to write data: %w", err)
|
||||||
}
|
}
|
||||||
Debug("Wrote data to encryptor successfully")
|
Debug("Wrote data to encryptor successfully")
|
||||||
@ -34,6 +36,7 @@ func EncryptToRecipient(data []byte, recipient age.Recipient) ([]byte, error) {
|
|||||||
Debug("Closing encryptor")
|
Debug("Closing encryptor")
|
||||||
if err := w.Close(); err != nil {
|
if err := w.Close(); err != nil {
|
||||||
Debug("Failed to close encryptor", "error", err)
|
Debug("Failed to close encryptor", "error", err)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to close encryptor: %w", err)
|
return nil, fmt.Errorf("failed to close encryptor: %w", err)
|
||||||
}
|
}
|
||||||
Debug("Closed encryptor successfully")
|
Debug("Closed encryptor successfully")
|
||||||
|
@ -29,6 +29,7 @@ func InitDebugLogging() {
|
|||||||
if !debugEnabled {
|
if !debugEnabled {
|
||||||
// Create a no-op logger that discards all output
|
// Create a no-op logger that discards all output
|
||||||
debugLogger = slog.New(slog.NewTextHandler(io.Discard, nil))
|
debugLogger = slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ func DetermineStateDir(customConfigDir string) string {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// Fallback to a reasonable default if we can't determine user config dir
|
// Fallback to a reasonable default if we can't determine user config dir
|
||||||
homeDir, _ := os.UserHomeDir()
|
homeDir, _ := os.UserHomeDir()
|
||||||
|
|
||||||
return filepath.Join(homeDir, ".config", AppID)
|
return filepath.Join(homeDir, ".config", AppID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,7 @@ func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
keychainItemName, err := k.GetKeychainItemName()
|
keychainItemName, err := k.GetKeychainItemName()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to get keychain item name", "error", err, "unlocker_id", k.GetID())
|
Debug("Failed to get keychain item name", "error", err, "unlocker_id", k.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get keychain item name: %w", err)
|
return nil, fmt.Errorf("failed to get keychain item name: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +65,7 @@ func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
keychainDataBytes, err := retrieveFromKeychain(keychainItemName)
|
keychainDataBytes, err := retrieveFromKeychain(keychainItemName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to retrieve data from keychain", "error", err, "keychain_item", keychainItemName)
|
Debug("Failed to retrieve data from keychain", "error", err, "keychain_item", keychainItemName)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to retrieve data from keychain: %w", err)
|
return nil, fmt.Errorf("failed to retrieve data from keychain: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +78,7 @@ func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
var keychainData KeychainData
|
var keychainData KeychainData
|
||||||
if err := json.Unmarshal(keychainDataBytes, &keychainData); err != nil {
|
if err := json.Unmarshal(keychainDataBytes, &keychainData); err != nil {
|
||||||
Debug("Failed to parse keychain data", "error", err, "unlocker_id", k.GetID())
|
Debug("Failed to parse keychain data", "error", err, "unlocker_id", k.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse keychain data: %w", err)
|
return nil, fmt.Errorf("failed to parse keychain data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +91,7 @@ func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
encryptedAgePrivKeyData, err := afero.ReadFile(k.fs, agePrivKeyPath)
|
encryptedAgePrivKeyData, err := afero.ReadFile(k.fs, agePrivKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read encrypted age private key", "error", err, "path", agePrivKeyPath)
|
Debug("Failed to read encrypted age private key", "error", err, "path", agePrivKeyPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read encrypted age private key: %w", err)
|
return nil, fmt.Errorf("failed to read encrypted age private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,6 +105,7 @@ func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
agePrivKeyData, err := DecryptWithPassphrase(encryptedAgePrivKeyData, keychainData.AgePrivKeyPassphrase)
|
agePrivKeyData, err := DecryptWithPassphrase(encryptedAgePrivKeyData, keychainData.AgePrivKeyPassphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt age private key with keychain passphrase", "error", err, "unlocker_id", k.GetID())
|
Debug("Failed to decrypt age private key with keychain passphrase", "error", err, "unlocker_id", k.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt age private key with keychain passphrase: %w", err)
|
return nil, fmt.Errorf("failed to decrypt age private key with keychain passphrase: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +119,7 @@ func (k *KeychainUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
ageIdentity, err := age.ParseX25519Identity(string(agePrivKeyData))
|
ageIdentity, err := age.ParseX25519Identity(string(agePrivKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse age private key", "error", err, "unlocker_id", k.GetID())
|
Debug("Failed to parse age private key", "error", err, "unlocker_id", k.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse age private key: %w", err)
|
return nil, fmt.Errorf("failed to parse age private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +165,7 @@ func (k *KeychainUnlocker) Remove() error {
|
|||||||
keychainItemName, err := k.GetKeychainItemName()
|
keychainItemName, err := k.GetKeychainItemName()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to get keychain item name during removal", "error", err, "unlocker_id", k.GetID())
|
Debug("Failed to get keychain item name during removal", "error", err, "unlocker_id", k.GetID())
|
||||||
|
|
||||||
return fmt.Errorf("failed to get keychain item name: %w", err)
|
return fmt.Errorf("failed to get keychain item name: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +173,7 @@ func (k *KeychainUnlocker) Remove() error {
|
|||||||
Debug("Removing keychain item", "keychain_item", keychainItemName)
|
Debug("Removing keychain item", "keychain_item", keychainItemName)
|
||||||
if err := deleteFromKeychain(keychainItemName); err != nil {
|
if err := deleteFromKeychain(keychainItemName); err != nil {
|
||||||
Debug("Failed to remove keychain item", "error", err, "keychain_item", keychainItemName)
|
Debug("Failed to remove keychain item", "error", err, "keychain_item", keychainItemName)
|
||||||
|
|
||||||
return fmt.Errorf("failed to remove keychain item: %w", err)
|
return fmt.Errorf("failed to remove keychain item: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +181,7 @@ func (k *KeychainUnlocker) Remove() error {
|
|||||||
Debug("Removing keychain unlocker directory", "directory", k.Directory)
|
Debug("Removing keychain unlocker directory", "directory", k.Directory)
|
||||||
if err := k.fs.RemoveAll(k.Directory); err != nil {
|
if err := k.fs.RemoveAll(k.Directory); err != nil {
|
||||||
Debug("Failed to remove keychain unlocker directory", "error", err, "directory", k.Directory)
|
Debug("Failed to remove keychain unlocker directory", "error", err, "directory", k.Directory)
|
||||||
|
|
||||||
return fmt.Errorf("failed to remove keychain unlocker directory: %w", err)
|
return fmt.Errorf("failed to remove keychain unlocker directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +239,7 @@ func getLongTermPrivateKey(fs afero.Fs, vault VaultInterface) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte(ltIdentity.String()), nil
|
return []byte(ltIdentity.String()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ func (p *PassphraseUnlocker) getPassphrase() (string, error) {
|
|||||||
// First check if we already have the passphrase
|
// First check if we already have the passphrase
|
||||||
if p.Passphrase != "" {
|
if p.Passphrase != "" {
|
||||||
Debug("Using in-memory passphrase", "unlocker_id", p.GetID())
|
Debug("Using in-memory passphrase", "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return p.Passphrase, nil
|
return p.Passphrase, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ func (p *PassphraseUnlocker) getPassphrase() (string, error) {
|
|||||||
passphraseStr := os.Getenv(EnvUnlockPassphrase)
|
passphraseStr := os.Getenv(EnvUnlockPassphrase)
|
||||||
if passphraseStr != "" {
|
if passphraseStr != "" {
|
||||||
Debug("Using passphrase from environment", "unlocker_id", p.GetID())
|
Debug("Using passphrase from environment", "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return passphraseStr, nil
|
return passphraseStr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,8 +41,10 @@ func (p *PassphraseUnlocker) getPassphrase() (string, error) {
|
|||||||
passphraseStr, err := ReadPassphrase("Enter unlock passphrase: ")
|
passphraseStr, err := ReadPassphrase("Enter unlock passphrase: ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read passphrase", "error", err, "unlocker_id", p.GetID())
|
Debug("Failed to read passphrase", "error", err, "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return "", fmt.Errorf("failed to read passphrase: %w", err)
|
return "", fmt.Errorf("failed to read passphrase: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return passphraseStr, nil
|
return passphraseStr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +67,7 @@ func (p *PassphraseUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
encryptedPrivKeyData, err := afero.ReadFile(p.fs, unlockerPrivPath)
|
encryptedPrivKeyData, err := afero.ReadFile(p.fs, unlockerPrivPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read passphrase unlocker private key", "error", err, "path", unlockerPrivPath)
|
Debug("Failed to read passphrase unlocker private key", "error", err, "path", unlockerPrivPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read unlocker private key: %w", err)
|
return nil, fmt.Errorf("failed to read unlocker private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +82,7 @@ func (p *PassphraseUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
privKeyData, err := DecryptWithPassphrase(encryptedPrivKeyData, passphraseStr)
|
privKeyData, err := DecryptWithPassphrase(encryptedPrivKeyData, passphraseStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt unlocker private key", "error", err, "unlocker_id", p.GetID())
|
Debug("Failed to decrypt unlocker private key", "error", err, "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt unlocker private key: %w", err)
|
return nil, fmt.Errorf("failed to decrypt unlocker private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +96,7 @@ func (p *PassphraseUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
identity, err := age.ParseX25519Identity(string(privKeyData))
|
identity, err := age.ParseX25519Identity(string(privKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse unlocker private key", "error", err, "unlocker_id", p.GetID())
|
Debug("Failed to parse unlocker private key", "error", err, "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse unlocker private key: %w", err)
|
return nil, fmt.Errorf("failed to parse unlocker private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +127,7 @@ func (p *PassphraseUnlocker) GetDirectory() string {
|
|||||||
func (p *PassphraseUnlocker) GetID() string {
|
func (p *PassphraseUnlocker) GetID() string {
|
||||||
// Generate ID using creation timestamp: YYYY-MM-DD.HH.mm-passphrase
|
// Generate ID using creation timestamp: YYYY-MM-DD.HH.mm-passphrase
|
||||||
createdAt := p.Metadata.CreatedAt
|
createdAt := p.Metadata.CreatedAt
|
||||||
|
|
||||||
return fmt.Sprintf("%s-passphrase", createdAt.Format("2006-01-02.15.04"))
|
return fmt.Sprintf("%s-passphrase", createdAt.Format("2006-01-02.15.04"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ func (p *PGPUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
encryptedAgePrivKeyData, err := afero.ReadFile(p.fs, agePrivKeyPath)
|
encryptedAgePrivKeyData, err := afero.ReadFile(p.fs, agePrivKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read PGP-encrypted age private key", "error", err, "path", agePrivKeyPath)
|
Debug("Failed to read PGP-encrypted age private key", "error", err, "path", agePrivKeyPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read encrypted age private key: %w", err)
|
return nil, fmt.Errorf("failed to read encrypted age private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +81,7 @@ func (p *PGPUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
agePrivKeyData, err := GPGDecryptFunc(encryptedAgePrivKeyData)
|
agePrivKeyData, err := GPGDecryptFunc(encryptedAgePrivKeyData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt age private key with GPG", "error", err, "unlocker_id", p.GetID())
|
Debug("Failed to decrypt age private key with GPG", "error", err, "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt age private key with GPG: %w", err)
|
return nil, fmt.Errorf("failed to decrypt age private key with GPG: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +95,7 @@ func (p *PGPUnlocker) GetIdentity() (*age.X25519Identity, error) {
|
|||||||
ageIdentity, err := age.ParseX25519Identity(string(agePrivKeyData))
|
ageIdentity, err := age.ParseX25519Identity(string(agePrivKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse age private key", "error", err, "unlocker_id", p.GetID())
|
Debug("Failed to parse age private key", "error", err, "unlocker_id", p.GetID())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse age private key: %w", err)
|
return nil, fmt.Errorf("failed to parse age private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@ func (s *Secret) Save(value []byte, force bool) error {
|
|||||||
err := s.vault.AddSecret(s.Name, value, force)
|
err := s.vault.AddSecret(s.Name, value, force)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to save secret", "error", err, "secret_name", s.Name)
|
Debug("Failed to save secret", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,10 +94,12 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
exists, err := s.Exists()
|
exists, err := s.Exists()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to check if secret exists during GetValue", "error", err, "secret_name", s.Name)
|
Debug("Failed to check if secret exists during GetValue", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to check if secret exists: %w", err)
|
return nil, fmt.Errorf("failed to check if secret exists: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
Debug("Secret not found during GetValue", "secret_name", s.Name, "vault_name", s.vault.GetName())
|
Debug("Secret not found during GetValue", "secret_name", s.Name, "vault_name", s.vault.GetName())
|
||||||
|
|
||||||
return nil, fmt.Errorf("secret %s not found", s.Name)
|
return nil, fmt.Errorf("secret %s not found", s.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +109,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
currentVersion, err := GetCurrentVersion(s.vault.GetFilesystem(), s.Directory)
|
currentVersion, err := GetCurrentVersion(s.vault.GetFilesystem(), s.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to get current version", "error", err, "secret_name", s.Name)
|
Debug("Failed to get current version", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get current version: %w", err)
|
return nil, fmt.Errorf("failed to get current version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +124,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
vaultDir, err := s.vault.GetDirectory()
|
vaultDir, err := s.vault.GetDirectory()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to get vault directory", "error", err, "secret_name", s.Name)
|
Debug("Failed to get vault directory", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get vault directory: %w", err)
|
return nil, fmt.Errorf("failed to get vault directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,12 +133,14 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
metadataBytes, err := afero.ReadFile(s.vault.GetFilesystem(), metadataPath)
|
metadataBytes, err := afero.ReadFile(s.vault.GetFilesystem(), metadataPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read vault metadata", "error", err, "path", metadataPath)
|
Debug("Failed to read vault metadata", "error", err, "path", metadataPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read vault metadata: %w", err)
|
return nil, fmt.Errorf("failed to read vault metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadata VaultMetadata
|
var metadata VaultMetadata
|
||||||
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
|
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
|
||||||
Debug("Failed to parse vault metadata", "error", err, "secret_name", s.Name)
|
Debug("Failed to parse vault metadata", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse vault metadata: %w", err)
|
return nil, fmt.Errorf("failed to parse vault metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +154,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
ltIdentity, err := agehd.DeriveIdentity(envMnemonic, metadata.DerivationIndex)
|
ltIdentity, err := agehd.DeriveIdentity(envMnemonic, metadata.DerivationIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to derive long-term key from mnemonic for secret", "error", err, "secret_name", s.Name)
|
Debug("Failed to derive long-term key from mnemonic for secret", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +169,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
// Use the provided unlocker to get the vault's long-term private key
|
// Use the provided unlocker to get the vault's long-term private key
|
||||||
if unlocker == nil {
|
if unlocker == nil {
|
||||||
Debug("No unlocker provided for secret decryption", "secret_name", s.Name)
|
Debug("No unlocker provided for secret decryption", "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("unlocker required to decrypt secret")
|
return nil, fmt.Errorf("unlocker required to decrypt secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,6 +183,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
unlockIdentity, err := unlocker.GetIdentity()
|
unlockIdentity, err := unlocker.GetIdentity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to get unlocker identity", "error", err, "secret_name", s.Name, "unlocker_type", unlocker.GetType())
|
Debug("Failed to get unlocker identity", "error", err, "secret_name", s.Name, "unlocker_type", unlocker.GetType())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get unlocker identity: %w", err)
|
return nil, fmt.Errorf("failed to get unlocker identity: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +194,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
encryptedLtPrivKey, err := afero.ReadFile(s.vault.GetFilesystem(), encryptedLtPrivKeyPath)
|
encryptedLtPrivKey, err := afero.ReadFile(s.vault.GetFilesystem(), encryptedLtPrivKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read encrypted long-term private key", "error", err, "path", encryptedLtPrivKeyPath)
|
Debug("Failed to read encrypted long-term private key", "error", err, "path", encryptedLtPrivKeyPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read encrypted long-term private key: %w", err)
|
return nil, fmt.Errorf("failed to read encrypted long-term private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,6 +203,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
ltPrivKeyData, err := DecryptWithIdentity(encryptedLtPrivKey, unlockIdentity)
|
ltPrivKeyData, err := DecryptWithIdentity(encryptedLtPrivKey, unlockIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt long-term private key", "error", err, "secret_name", s.Name)
|
Debug("Failed to decrypt long-term private key", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt long-term private key: %w", err)
|
return nil, fmt.Errorf("failed to decrypt long-term private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +212,7 @@ func (s *Secret) GetValue(unlocker Unlocker) ([]byte, error) {
|
|||||||
ltIdentity, err := age.ParseX25519Identity(string(ltPrivKeyData))
|
ltIdentity, err := age.ParseX25519Identity(string(ltPrivKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse long-term private key", "error", err, "secret_name", s.Name)
|
Debug("Failed to parse long-term private key", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse long-term private key: %w", err)
|
return nil, fmt.Errorf("failed to parse long-term private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,12 +241,14 @@ func (s *Secret) LoadMetadata() error {
|
|||||||
// GetMetadata returns the secret metadata (deprecated)
|
// GetMetadata returns the secret metadata (deprecated)
|
||||||
func (s *Secret) GetMetadata() Metadata {
|
func (s *Secret) GetMetadata() Metadata {
|
||||||
Debug("GetMetadata called but is deprecated in versioned model", "secret_name", s.Name)
|
Debug("GetMetadata called but is deprecated in versioned model", "secret_name", s.Name)
|
||||||
|
|
||||||
return s.Metadata
|
return s.Metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEncryptedData is deprecated - data is now stored in versions
|
// GetEncryptedData is deprecated - data is now stored in versions
|
||||||
func (s *Secret) GetEncryptedData() ([]byte, error) {
|
func (s *Secret) GetEncryptedData() ([]byte, error) {
|
||||||
Debug("GetEncryptedData called but is deprecated in versioned model", "secret_name", s.Name)
|
Debug("GetEncryptedData called but is deprecated in versioned model", "secret_name", s.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("GetEncryptedData is deprecated - use version-specific methods")
|
return nil, fmt.Errorf("GetEncryptedData is deprecated - use version-specific methods")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,11 +263,13 @@ func (s *Secret) Exists() (bool, error) {
|
|||||||
exists, err := afero.DirExists(s.vault.GetFilesystem(), s.Directory)
|
exists, err := afero.DirExists(s.vault.GetFilesystem(), s.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to check secret directory existence", "error", err, "secret_dir", s.Directory)
|
Debug("Failed to check secret directory existence", "error", err, "secret_dir", s.Directory)
|
||||||
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !exists {
|
if !exists {
|
||||||
Debug("Secret directory does not exist", "secret_dir", s.Directory)
|
Debug("Secret directory does not exist", "secret_dir", s.Directory)
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +277,7 @@ func (s *Secret) Exists() (bool, error) {
|
|||||||
_, err = GetCurrentVersion(s.vault.GetFilesystem(), s.Directory)
|
_, err = GetCurrentVersion(s.vault.GetFilesystem(), s.Directory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("No current version found", "error", err, "secret_name", s.Name)
|
Debug("No current version found", "error", err, "secret_name", s.Name)
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
// Create version directory
|
// Create version directory
|
||||||
if err := fs.MkdirAll(sv.Directory, DirPerms); err != nil {
|
if err := fs.MkdirAll(sv.Directory, DirPerms); err != nil {
|
||||||
Debug("Failed to create version directory", "error", err, "dir", sv.Directory)
|
Debug("Failed to create version directory", "error", err, "dir", sv.Directory)
|
||||||
|
|
||||||
return fmt.Errorf("failed to create version directory: %w", err)
|
return fmt.Errorf("failed to create version directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,6 +141,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
versionIdentity, err := age.GenerateX25519Identity()
|
versionIdentity, err := age.GenerateX25519Identity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to generate version keypair", "error", err, "version", sv.Version)
|
Debug("Failed to generate version keypair", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to generate version keypair: %w", err)
|
return fmt.Errorf("failed to generate version keypair: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +158,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
Debug("Writing version public key", "path", pubKeyPath)
|
Debug("Writing version public key", "path", pubKeyPath)
|
||||||
if err := afero.WriteFile(fs, pubKeyPath, []byte(versionPublicKey), FilePerms); err != nil {
|
if err := afero.WriteFile(fs, pubKeyPath, []byte(versionPublicKey), FilePerms); err != nil {
|
||||||
Debug("Failed to write version public key", "error", err, "path", pubKeyPath)
|
Debug("Failed to write version public key", "error", err, "path", pubKeyPath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to write version public key: %w", err)
|
return fmt.Errorf("failed to write version public key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,6 +167,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
encryptedValue, err := EncryptToRecipient(value, versionIdentity.Recipient())
|
encryptedValue, err := EncryptToRecipient(value, versionIdentity.Recipient())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to encrypt version value", "error", err, "version", sv.Version)
|
Debug("Failed to encrypt version value", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to encrypt version value: %w", err)
|
return fmt.Errorf("failed to encrypt version value: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,6 +176,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
Debug("Writing encrypted version value", "path", valuePath)
|
Debug("Writing encrypted version value", "path", valuePath)
|
||||||
if err := afero.WriteFile(fs, valuePath, encryptedValue, FilePerms); err != nil {
|
if err := afero.WriteFile(fs, valuePath, encryptedValue, FilePerms); err != nil {
|
||||||
Debug("Failed to write encrypted version value", "error", err, "path", valuePath)
|
Debug("Failed to write encrypted version value", "error", err, "path", valuePath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to write encrypted version value: %w", err)
|
return fmt.Errorf("failed to write encrypted version value: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +188,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
ltPubKeyData, err := afero.ReadFile(fs, ltPubKeyPath)
|
ltPubKeyData, err := afero.ReadFile(fs, ltPubKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read long-term public key", "error", err, "path", ltPubKeyPath)
|
Debug("Failed to read long-term public key", "error", err, "path", ltPubKeyPath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to read long-term public key: %w", err)
|
return fmt.Errorf("failed to read long-term public key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,6 +196,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
ltRecipient, err := age.ParseX25519Recipient(string(ltPubKeyData))
|
ltRecipient, err := age.ParseX25519Recipient(string(ltPubKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse long-term public key", "error", err)
|
Debug("Failed to parse long-term public key", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to parse long-term public key: %w", err)
|
return fmt.Errorf("failed to parse long-term public key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +205,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
encryptedPrivKey, err := EncryptToRecipient([]byte(versionPrivateKey), ltRecipient)
|
encryptedPrivKey, err := EncryptToRecipient([]byte(versionPrivateKey), ltRecipient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to encrypt version private key", "error", err, "version", sv.Version)
|
Debug("Failed to encrypt version private key", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to encrypt version private key: %w", err)
|
return fmt.Errorf("failed to encrypt version private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +214,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
Debug("Writing encrypted version private key", "path", privKeyPath)
|
Debug("Writing encrypted version private key", "path", privKeyPath)
|
||||||
if err := afero.WriteFile(fs, privKeyPath, encryptedPrivKey, FilePerms); err != nil {
|
if err := afero.WriteFile(fs, privKeyPath, encryptedPrivKey, FilePerms); err != nil {
|
||||||
Debug("Failed to write encrypted version private key", "error", err, "path", privKeyPath)
|
Debug("Failed to write encrypted version private key", "error", err, "path", privKeyPath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to write encrypted version private key: %w", err)
|
return fmt.Errorf("failed to write encrypted version private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +223,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
metadataBytes, err := json.MarshalIndent(sv.Metadata, "", " ")
|
metadataBytes, err := json.MarshalIndent(sv.Metadata, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to marshal version metadata", "error", err)
|
Debug("Failed to marshal version metadata", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to marshal version metadata: %w", err)
|
return fmt.Errorf("failed to marshal version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +231,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
encryptedMetadata, err := EncryptToRecipient(metadataBytes, versionIdentity.Recipient())
|
encryptedMetadata, err := EncryptToRecipient(metadataBytes, versionIdentity.Recipient())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to encrypt version metadata", "error", err, "version", sv.Version)
|
Debug("Failed to encrypt version metadata", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to encrypt version metadata: %w", err)
|
return fmt.Errorf("failed to encrypt version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +239,7 @@ func (sv *Version) Save(value []byte) error {
|
|||||||
Debug("Writing encrypted version metadata", "path", metadataPath)
|
Debug("Writing encrypted version metadata", "path", metadataPath)
|
||||||
if err := afero.WriteFile(fs, metadataPath, encryptedMetadata, FilePerms); err != nil {
|
if err := afero.WriteFile(fs, metadataPath, encryptedMetadata, FilePerms); err != nil {
|
||||||
Debug("Failed to write encrypted version metadata", "error", err, "path", metadataPath)
|
Debug("Failed to write encrypted version metadata", "error", err, "path", metadataPath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to write encrypted version metadata: %w", err)
|
return fmt.Errorf("failed to write encrypted version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,6 +262,7 @@ func (sv *Version) LoadMetadata(ltIdentity *age.X25519Identity) error {
|
|||||||
encryptedPrivKey, err := afero.ReadFile(fs, encryptedPrivKeyPath)
|
encryptedPrivKey, err := afero.ReadFile(fs, encryptedPrivKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read encrypted version private key", "error", err, "path", encryptedPrivKeyPath)
|
Debug("Failed to read encrypted version private key", "error", err, "path", encryptedPrivKeyPath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to read encrypted version private key: %w", err)
|
return fmt.Errorf("failed to read encrypted version private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,6 +270,7 @@ func (sv *Version) LoadMetadata(ltIdentity *age.X25519Identity) error {
|
|||||||
versionPrivKeyData, err := DecryptWithIdentity(encryptedPrivKey, ltIdentity)
|
versionPrivKeyData, err := DecryptWithIdentity(encryptedPrivKey, ltIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt version private key", "error", err, "version", sv.Version)
|
Debug("Failed to decrypt version private key", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to decrypt version private key: %w", err)
|
return fmt.Errorf("failed to decrypt version private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +278,7 @@ func (sv *Version) LoadMetadata(ltIdentity *age.X25519Identity) error {
|
|||||||
versionIdentity, err := age.ParseX25519Identity(string(versionPrivKeyData))
|
versionIdentity, err := age.ParseX25519Identity(string(versionPrivKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse version private key", "error", err, "version", sv.Version)
|
Debug("Failed to parse version private key", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to parse version private key: %w", err)
|
return fmt.Errorf("failed to parse version private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +287,7 @@ func (sv *Version) LoadMetadata(ltIdentity *age.X25519Identity) error {
|
|||||||
encryptedMetadata, err := afero.ReadFile(fs, encryptedMetadataPath)
|
encryptedMetadata, err := afero.ReadFile(fs, encryptedMetadataPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read encrypted version metadata", "error", err, "path", encryptedMetadataPath)
|
Debug("Failed to read encrypted version metadata", "error", err, "path", encryptedMetadataPath)
|
||||||
|
|
||||||
return fmt.Errorf("failed to read encrypted version metadata: %w", err)
|
return fmt.Errorf("failed to read encrypted version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +295,7 @@ func (sv *Version) LoadMetadata(ltIdentity *age.X25519Identity) error {
|
|||||||
metadataBytes, err := DecryptWithIdentity(encryptedMetadata, versionIdentity)
|
metadataBytes, err := DecryptWithIdentity(encryptedMetadata, versionIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt version metadata", "error", err, "version", sv.Version)
|
Debug("Failed to decrypt version metadata", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to decrypt version metadata: %w", err)
|
return fmt.Errorf("failed to decrypt version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +303,7 @@ func (sv *Version) LoadMetadata(ltIdentity *age.X25519Identity) error {
|
|||||||
var metadata VersionMetadata
|
var metadata VersionMetadata
|
||||||
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
|
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
|
||||||
Debug("Failed to unmarshal version metadata", "error", err, "version", sv.Version)
|
Debug("Failed to unmarshal version metadata", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return fmt.Errorf("failed to unmarshal version metadata: %w", err)
|
return fmt.Errorf("failed to unmarshal version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +335,7 @@ func (sv *Version) GetValue(ltIdentity *age.X25519Identity) ([]byte, error) {
|
|||||||
encryptedPrivKey, err := afero.ReadFile(fs, encryptedPrivKeyPath)
|
encryptedPrivKey, err := afero.ReadFile(fs, encryptedPrivKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read encrypted version private key", "error", err, "path", encryptedPrivKeyPath)
|
Debug("Failed to read encrypted version private key", "error", err, "path", encryptedPrivKeyPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read encrypted version private key: %w", err)
|
return nil, fmt.Errorf("failed to read encrypted version private key: %w", err)
|
||||||
}
|
}
|
||||||
Debug("Successfully read encrypted version private key", "path", encryptedPrivKeyPath, "size", len(encryptedPrivKey))
|
Debug("Successfully read encrypted version private key", "path", encryptedPrivKeyPath, "size", len(encryptedPrivKey))
|
||||||
@ -326,6 +345,7 @@ func (sv *Version) GetValue(ltIdentity *age.X25519Identity) ([]byte, error) {
|
|||||||
versionPrivKeyData, err := DecryptWithIdentity(encryptedPrivKey, ltIdentity)
|
versionPrivKeyData, err := DecryptWithIdentity(encryptedPrivKey, ltIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt version private key", "error", err, "version", sv.Version)
|
Debug("Failed to decrypt version private key", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt version private key: %w", err)
|
return nil, fmt.Errorf("failed to decrypt version private key: %w", err)
|
||||||
}
|
}
|
||||||
Debug("Successfully decrypted version private key", "version", sv.Version, "size", len(versionPrivKeyData))
|
Debug("Successfully decrypted version private key", "version", sv.Version, "size", len(versionPrivKeyData))
|
||||||
@ -334,6 +354,7 @@ func (sv *Version) GetValue(ltIdentity *age.X25519Identity) ([]byte, error) {
|
|||||||
versionIdentity, err := age.ParseX25519Identity(string(versionPrivKeyData))
|
versionIdentity, err := age.ParseX25519Identity(string(versionPrivKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to parse version private key", "error", err, "version", sv.Version)
|
Debug("Failed to parse version private key", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse version private key: %w", err)
|
return nil, fmt.Errorf("failed to parse version private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,6 +364,7 @@ func (sv *Version) GetValue(ltIdentity *age.X25519Identity) ([]byte, error) {
|
|||||||
encryptedValue, err := afero.ReadFile(fs, encryptedValuePath)
|
encryptedValue, err := afero.ReadFile(fs, encryptedValuePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to read encrypted version value", "error", err, "path", encryptedValuePath)
|
Debug("Failed to read encrypted version value", "error", err, "path", encryptedValuePath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read encrypted version value: %w", err)
|
return nil, fmt.Errorf("failed to read encrypted version value: %w", err)
|
||||||
}
|
}
|
||||||
Debug("Successfully read encrypted value", "path", encryptedValuePath, "size", len(encryptedValue))
|
Debug("Successfully read encrypted value", "path", encryptedValuePath, "size", len(encryptedValue))
|
||||||
@ -352,6 +374,7 @@ func (sv *Version) GetValue(ltIdentity *age.X25519Identity) ([]byte, error) {
|
|||||||
value, err := DecryptWithIdentity(encryptedValue, versionIdentity)
|
value, err := DecryptWithIdentity(encryptedValue, versionIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Debug("Failed to decrypt version value", "error", err, "version", sv.Version)
|
Debug("Failed to decrypt version value", "error", err, "version", sv.Version)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt version value: %w", err)
|
return nil, fmt.Errorf("failed to decrypt version value: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ func resolveRelativeSymlink(symlinkPath, target string) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// Try to restore original directory before returning error
|
// Try to restore original directory before returning error
|
||||||
_ = os.Chdir(originalDir)
|
_ = os.Chdir(originalDir)
|
||||||
|
|
||||||
return "", fmt.Errorf("failed to get absolute path: %w", err)
|
return "", fmt.Errorf("failed to get absolute path: %w", err)
|
||||||
}
|
}
|
||||||
secret.Debug("Got absolute path", "absolute_path", absolutePath)
|
secret.Debug("Got absolute path", "absolute_path", absolutePath)
|
||||||
@ -79,6 +80,7 @@ func ResolveVaultSymlink(fs afero.Fs, symlinkPath string) (string, error) {
|
|||||||
target, err := tryResolveOsSymlink(symlinkPath)
|
target, err := tryResolveOsSymlink(symlinkPath)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
secret.Debug("resolveVaultSymlink completed successfully", "result", target)
|
secret.Debug("resolveVaultSymlink completed successfully", "result", target)
|
||||||
|
|
||||||
return target, nil
|
return target, nil
|
||||||
}
|
}
|
||||||
// Fall through to fallback if symlink resolution failed
|
// Fall through to fallback if symlink resolution failed
|
||||||
@ -92,6 +94,7 @@ func ResolveVaultSymlink(fs afero.Fs, symlinkPath string) (string, error) {
|
|||||||
fileData, err := afero.ReadFile(fs, symlinkPath)
|
fileData, err := afero.ReadFile(fs, symlinkPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read target path file", "error", err)
|
secret.Debug("Failed to read target path file", "error", err)
|
||||||
|
|
||||||
return "", fmt.Errorf("failed to read vault symlink: %w", err)
|
return "", fmt.Errorf("failed to read vault symlink: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +139,7 @@ func GetCurrentVault(fs afero.Fs, stateDir string) (*Vault, error) {
|
|||||||
_, err := fs.Stat(currentVaultPath)
|
_, err := fs.Stat(currentVaultPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to stat current vault symlink", "error", err, "path", currentVaultPath)
|
secret.Debug("Failed to stat current vault symlink", "error", err, "path", currentVaultPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read current vault symlink: %w", err)
|
return nil, fmt.Errorf("failed to read current vault symlink: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,6 +249,7 @@ func CreateVault(fs afero.Fs, stateDir string, name string) (*Vault, error) {
|
|||||||
// Validate vault name
|
// Validate vault name
|
||||||
if !isValidVaultName(name) {
|
if !isValidVaultName(name) {
|
||||||
secret.Debug("Invalid vault name provided", "vault_name", name)
|
secret.Debug("Invalid vault name provided", "vault_name", name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("invalid vault name '%s': must match pattern [a-z0-9.\\-_]+", name)
|
return nil, fmt.Errorf("invalid vault name '%s': must match pattern [a-z0-9.\\-_]+", name)
|
||||||
}
|
}
|
||||||
secret.Debug("Vault name validation passed", "vault_name", name)
|
secret.Debug("Vault name validation passed", "vault_name", name)
|
||||||
@ -306,6 +311,7 @@ func SelectVault(fs afero.Fs, stateDir string, name string) error {
|
|||||||
// Validate vault name
|
// Validate vault name
|
||||||
if !isValidVaultName(name) {
|
if !isValidVaultName(name) {
|
||||||
secret.Debug("Invalid vault name provided", "vault_name", name)
|
secret.Debug("Invalid vault name provided", "vault_name", name)
|
||||||
|
|
||||||
return fmt.Errorf("invalid vault name '%s': must match pattern [a-z0-9.\\-_]+", name)
|
return fmt.Errorf("invalid vault name '%s': must match pattern [a-z0-9.\\-_]+", name)
|
||||||
}
|
}
|
||||||
secret.Debug("Vault name validation passed", "vault_name", name)
|
secret.Debug("Vault name validation passed", "vault_name", name)
|
||||||
@ -337,6 +343,7 @@ func SelectVault(fs afero.Fs, stateDir string, name string) error {
|
|||||||
secret.Debug("Creating vault symlink", "target", targetPath, "link", currentVaultPath)
|
secret.Debug("Creating vault symlink", "target", targetPath, "link", currentVaultPath)
|
||||||
if err := os.Symlink(targetPath, currentVaultPath); err == nil {
|
if err := os.Symlink(targetPath, currentVaultPath); err == nil {
|
||||||
secret.Debug("Successfully selected vault", "vault_name", name)
|
secret.Debug("Successfully selected vault", "vault_name", name)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// If symlink creation fails, fall back to regular file
|
// If symlink creation fails, fall back to regular file
|
||||||
|
@ -21,6 +21,7 @@ func (v *Vault) ListSecrets() ([]string, error) {
|
|||||||
vaultDir, err := v.GetDirectory()
|
vaultDir, err := v.GetDirectory()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get vault directory for secret listing", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to get vault directory for secret listing", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,10 +31,12 @@ func (v *Vault) ListSecrets() ([]string, error) {
|
|||||||
exists, err := afero.DirExists(v.fs, secretsDir)
|
exists, err := afero.DirExists(v.fs, secretsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to check secrets directory", "error", err, "secrets_dir", secretsDir)
|
secret.Debug("Failed to check secrets directory", "error", err, "secrets_dir", secretsDir)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to check if secrets directory exists: %w", err)
|
return nil, fmt.Errorf("failed to check if secrets directory exists: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
secret.Debug("Secrets directory does not exist", "secrets_dir", secretsDir, "vault_name", v.Name)
|
secret.Debug("Secrets directory does not exist", "secrets_dir", secretsDir, "vault_name", v.Name)
|
||||||
|
|
||||||
return []string{}, nil
|
return []string{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +44,7 @@ func (v *Vault) ListSecrets() ([]string, error) {
|
|||||||
files, err := afero.ReadDir(v.fs, secretsDir)
|
files, err := afero.ReadDir(v.fs, secretsDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read secrets directory", "error", err, "secrets_dir", secretsDir)
|
secret.Debug("Failed to read secrets directory", "error", err, "secrets_dir", secretsDir)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read secrets directory: %w", err)
|
return nil, fmt.Errorf("failed to read secrets directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +109,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
// Validate secret name
|
// Validate secret name
|
||||||
if !isValidSecretName(name) {
|
if !isValidSecretName(name) {
|
||||||
secret.Debug("Invalid secret name provided", "secret_name", name)
|
secret.Debug("Invalid secret name provided", "secret_name", name)
|
||||||
|
|
||||||
return fmt.Errorf("invalid secret name '%s': must match pattern [a-z0-9.\\-_/]+", name)
|
return fmt.Errorf("invalid secret name '%s': must match pattern [a-z0-9.\\-_/]+", name)
|
||||||
}
|
}
|
||||||
secret.Debug("Secret name validation passed", "secret_name", name)
|
secret.Debug("Secret name validation passed", "secret_name", name)
|
||||||
@ -113,6 +118,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
vaultDir, err := v.GetDirectory()
|
vaultDir, err := v.GetDirectory()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get vault directory for secret addition", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to get vault directory for secret addition", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
secret.Debug("Got vault directory", "vault_dir", vaultDir)
|
secret.Debug("Got vault directory", "vault_dir", vaultDir)
|
||||||
@ -131,6 +137,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
exists, err := afero.DirExists(v.fs, secretDir)
|
exists, err := afero.DirExists(v.fs, secretDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to check if secret exists", "error", err, "secret_dir", secretDir)
|
secret.Debug("Failed to check if secret exists", "error", err, "secret_dir", secretDir)
|
||||||
|
|
||||||
return fmt.Errorf("failed to check if secret exists: %w", err)
|
return fmt.Errorf("failed to check if secret exists: %w", err)
|
||||||
}
|
}
|
||||||
secret.Debug("Secret existence check complete", "exists", exists)
|
secret.Debug("Secret existence check complete", "exists", exists)
|
||||||
@ -142,6 +149,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
if exists {
|
if exists {
|
||||||
if !force {
|
if !force {
|
||||||
secret.Debug("Secret already exists and force not specified", "secret_name", name, "secret_dir", secretDir)
|
secret.Debug("Secret already exists and force not specified", "secret_name", name, "secret_dir", secretDir)
|
||||||
|
|
||||||
return fmt.Errorf("secret %s already exists (use --force to overwrite)", name)
|
return fmt.Errorf("secret %s already exists (use --force to overwrite)", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +164,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
secret.Debug("Creating secret directory", "secret_dir", secretDir)
|
secret.Debug("Creating secret directory", "secret_dir", secretDir)
|
||||||
if err := v.fs.MkdirAll(secretDir, secret.DirPerms); err != nil {
|
if err := v.fs.MkdirAll(secretDir, secret.DirPerms); err != nil {
|
||||||
secret.Debug("Failed to create secret directory", "error", err, "secret_dir", secretDir)
|
secret.Debug("Failed to create secret directory", "error", err, "secret_dir", secretDir)
|
||||||
|
|
||||||
return fmt.Errorf("failed to create secret directory: %w", err)
|
return fmt.Errorf("failed to create secret directory: %w", err)
|
||||||
}
|
}
|
||||||
secret.Debug("Created secret directory successfully")
|
secret.Debug("Created secret directory successfully")
|
||||||
@ -165,6 +174,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
versionName, err := secret.GenerateVersionName(v.fs, secretDir)
|
versionName, err := secret.GenerateVersionName(v.fs, secretDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to generate version name", "error", err, "secret_name", name)
|
secret.Debug("Failed to generate version name", "error", err, "secret_name", name)
|
||||||
|
|
||||||
return fmt.Errorf("failed to generate version name: %w", err)
|
return fmt.Errorf("failed to generate version name: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,6 +198,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
// Save the new version
|
// Save the new version
|
||||||
if err := newVersion.Save(value); err != nil {
|
if err := newVersion.Save(value); err != nil {
|
||||||
secret.Debug("Failed to save new version", "error", err, "version", versionName)
|
secret.Debug("Failed to save new version", "error", err, "version", versionName)
|
||||||
|
|
||||||
return fmt.Errorf("failed to save version: %w", err)
|
return fmt.Errorf("failed to save version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,12 +208,14 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
ltIdentity, err := v.GetOrDeriveLongTermKey()
|
ltIdentity, err := v.GetOrDeriveLongTermKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get long-term key for metadata update", "error", err)
|
secret.Debug("Failed to get long-term key for metadata update", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to get long-term key: %w", err)
|
return fmt.Errorf("failed to get long-term key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load previous version metadata
|
// Load previous version metadata
|
||||||
if err := previousVersion.LoadMetadata(ltIdentity); err != nil {
|
if err := previousVersion.LoadMetadata(ltIdentity); err != nil {
|
||||||
secret.Debug("Failed to load previous version metadata", "error", err)
|
secret.Debug("Failed to load previous version metadata", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to load previous version metadata: %w", err)
|
return fmt.Errorf("failed to load previous version metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +225,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
// Re-save the metadata (we need to implement an update method)
|
// Re-save the metadata (we need to implement an update method)
|
||||||
if err := updateVersionMetadata(v.fs, previousVersion, ltIdentity); err != nil {
|
if err := updateVersionMetadata(v.fs, previousVersion, ltIdentity); err != nil {
|
||||||
secret.Debug("Failed to update previous version metadata", "error", err)
|
secret.Debug("Failed to update previous version metadata", "error", err)
|
||||||
|
|
||||||
return fmt.Errorf("failed to update previous version metadata: %w", err)
|
return fmt.Errorf("failed to update previous version metadata: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,6 +233,7 @@ func (v *Vault) AddSecret(name string, value []byte, force bool) error {
|
|||||||
// Set current symlink to new version
|
// Set current symlink to new version
|
||||||
if err := secret.SetCurrentVersion(v.fs, secretDir, versionName); err != nil {
|
if err := secret.SetCurrentVersion(v.fs, secretDir, versionName); err != nil {
|
||||||
secret.Debug("Failed to set current version", "error", err, "version", versionName)
|
secret.Debug("Failed to set current version", "error", err, "version", versionName)
|
||||||
|
|
||||||
return fmt.Errorf("failed to set current version: %w", err)
|
return fmt.Errorf("failed to set current version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,6 +308,7 @@ func (v *Vault) GetSecretVersion(name string, version string) ([]byte, error) {
|
|||||||
vaultDir, err := v.GetDirectory()
|
vaultDir, err := v.GetDirectory()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get vault directory", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to get vault directory", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,10 +320,12 @@ func (v *Vault) GetSecretVersion(name string, version string) ([]byte, error) {
|
|||||||
exists, err := afero.DirExists(v.fs, secretDir)
|
exists, err := afero.DirExists(v.fs, secretDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to check if secret exists", "error", err, "secret_name", name)
|
secret.Debug("Failed to check if secret exists", "error", err, "secret_name", name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to check if secret exists: %w", err)
|
return nil, fmt.Errorf("failed to check if secret exists: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
secret.Debug("Secret not found in vault", "secret_name", name, "vault_name", v.Name)
|
secret.Debug("Secret not found in vault", "secret_name", name, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("secret %s not found", name)
|
return nil, fmt.Errorf("secret %s not found", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,6 +335,7 @@ func (v *Vault) GetSecretVersion(name string, version string) ([]byte, error) {
|
|||||||
currentVersion, err := secret.GetCurrentVersion(v.fs, secretDir)
|
currentVersion, err := secret.GetCurrentVersion(v.fs, secretDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get current version", "error", err, "secret_name", name)
|
secret.Debug("Failed to get current version", "error", err, "secret_name", name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get current version: %w", err)
|
return nil, fmt.Errorf("failed to get current version: %w", err)
|
||||||
}
|
}
|
||||||
version = currentVersion
|
version = currentVersion
|
||||||
@ -331,10 +350,12 @@ func (v *Vault) GetSecretVersion(name string, version string) ([]byte, error) {
|
|||||||
exists, err = afero.DirExists(v.fs, versionPath)
|
exists, err = afero.DirExists(v.fs, versionPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to check if version exists", "error", err, "version", version)
|
secret.Debug("Failed to check if version exists", "error", err, "version", version)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to check if version exists: %w", err)
|
return nil, fmt.Errorf("failed to check if version exists: %w", err)
|
||||||
}
|
}
|
||||||
if !exists {
|
if !exists {
|
||||||
secret.Debug("Version not found", "version", version, "secret_name", name)
|
secret.Debug("Version not found", "version", version, "secret_name", name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("version %s not found for secret %s", version, name)
|
return nil, fmt.Errorf("version %s not found for secret %s", version, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,6 +365,7 @@ func (v *Vault) GetSecretVersion(name string, version string) ([]byte, error) {
|
|||||||
longTermIdentity, err := v.UnlockVault()
|
longTermIdentity, err := v.UnlockVault()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to unlock vault", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to unlock vault", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to unlock vault: %w", err)
|
return nil, fmt.Errorf("failed to unlock vault: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,6 +381,7 @@ func (v *Vault) GetSecretVersion(name string, version string) ([]byte, error) {
|
|||||||
decryptedValue, err := secretVersion.GetValue(longTermIdentity)
|
decryptedValue, err := secretVersion.GetValue(longTermIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to decrypt version value", "error", err, "version", version, "secret_name", name)
|
secret.Debug("Failed to decrypt version value", "error", err, "version", version, "secret_name", name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt version: %w", err)
|
return nil, fmt.Errorf("failed to decrypt version: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,6 +409,7 @@ func (v *Vault) UnlockVault() (*age.X25519Identity, error) {
|
|||||||
// If vault is already unlocked, return the cached key
|
// If vault is already unlocked, return the cached key
|
||||||
if !v.Locked() {
|
if !v.Locked() {
|
||||||
secret.Debug("Vault already unlocked, returning cached long-term key", "vault_name", v.Name)
|
secret.Debug("Vault already unlocked, returning cached long-term key", "vault_name", v.Name)
|
||||||
|
|
||||||
return v.longTermKey, nil
|
return v.longTermKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +417,7 @@ func (v *Vault) UnlockVault() (*age.X25519Identity, error) {
|
|||||||
longTermIdentity, err := v.GetOrDeriveLongTermKey()
|
longTermIdentity, err := v.GetOrDeriveLongTermKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get or derive long-term key", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to get or derive long-term key", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get long-term key: %w", err)
|
return nil, fmt.Errorf("failed to get long-term key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ func (v *Vault) GetCurrentUnlocker() (secret.Unlocker, error) {
|
|||||||
vaultDir, err := v.GetDirectory()
|
vaultDir, err := v.GetDirectory()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get vault directory for unlocker", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to get vault directory for unlocker", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ func (v *Vault) GetCurrentUnlocker() (secret.Unlocker, error) {
|
|||||||
_, err = v.fs.Stat(currentUnlockerPath)
|
_, err = v.fs.Stat(currentUnlockerPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to stat current unlocker symlink", "error", err, "path", currentUnlockerPath)
|
secret.Debug("Failed to stat current unlocker symlink", "error", err, "path", currentUnlockerPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read current unlocker: %w", err)
|
return nil, fmt.Errorf("failed to read current unlocker: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,12 +52,14 @@ func (v *Vault) GetCurrentUnlocker() (secret.Unlocker, error) {
|
|||||||
metadataBytes, err := afero.ReadFile(v.fs, metadataPath)
|
metadataBytes, err := afero.ReadFile(v.fs, metadataPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read unlocker metadata", "error", err, "path", metadataPath)
|
secret.Debug("Failed to read unlocker metadata", "error", err, "path", metadataPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read unlocker metadata: %w", err)
|
return nil, fmt.Errorf("failed to read unlocker metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var metadata UnlockerMetadata
|
var metadata UnlockerMetadata
|
||||||
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
|
if err := json.Unmarshal(metadataBytes, &metadata); err != nil {
|
||||||
secret.Debug("Failed to parse unlocker metadata", "error", err, "path", metadataPath)
|
secret.Debug("Failed to parse unlocker metadata", "error", err, "path", metadataPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse unlocker metadata: %w", err)
|
return nil, fmt.Errorf("failed to parse unlocker metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +84,7 @@ func (v *Vault) GetCurrentUnlocker() (secret.Unlocker, error) {
|
|||||||
unlocker = secret.NewKeychainUnlocker(v.fs, unlockerDir, metadata)
|
unlocker = secret.NewKeychainUnlocker(v.fs, unlockerDir, metadata)
|
||||||
default:
|
default:
|
||||||
secret.Debug("Unsupported unlocker type", "type", metadata.Type)
|
secret.Debug("Unsupported unlocker type", "type", metadata.Type)
|
||||||
|
|
||||||
return nil, fmt.Errorf("unsupported unlocker type: %s", metadata.Type)
|
return nil, fmt.Errorf("unsupported unlocker type: %s", metadata.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +124,10 @@ func (v *Vault) readUnlockerPathFromFile(path string) (string, error) {
|
|||||||
unlockerDirBytes, err := afero.ReadFile(v.fs, path)
|
unlockerDirBytes, err := afero.ReadFile(v.fs, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read unlocker path file", "error", err, "path", path)
|
secret.Debug("Failed to read unlocker path file", "error", err, "path", path)
|
||||||
|
|
||||||
return "", fmt.Errorf("failed to read current unlocker: %w", err)
|
return "", fmt.Errorf("failed to read current unlocker: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.TrimSpace(string(unlockerDirBytes)), nil
|
return strings.TrimSpace(string(unlockerDirBytes)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +76,14 @@ func (v *Vault) GetOrDeriveLongTermKey() (*age.X25519Identity, error) {
|
|||||||
metadata, err := LoadVaultMetadata(v.fs, vaultDir)
|
metadata, err := LoadVaultMetadata(v.fs, vaultDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to load vault metadata", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to load vault metadata", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to load vault metadata: %w", err)
|
return nil, fmt.Errorf("failed to load vault metadata: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ltIdentity, err := agehd.DeriveIdentity(envMnemonic, metadata.DerivationIndex)
|
ltIdentity, err := agehd.DeriveIdentity(envMnemonic, metadata.DerivationIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to derive long-term key from mnemonic", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to derive long-term key from mnemonic", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
return nil, fmt.Errorf("failed to derive long-term key from mnemonic: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +119,7 @@ func (v *Vault) GetOrDeriveLongTermKey() (*age.X25519Identity, error) {
|
|||||||
unlocker, err := v.GetCurrentUnlocker()
|
unlocker, err := v.GetCurrentUnlocker()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get current unlocker", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to get current unlocker", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get current unlocker: %w", err)
|
return nil, fmt.Errorf("failed to get current unlocker: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +133,7 @@ func (v *Vault) GetOrDeriveLongTermKey() (*age.X25519Identity, error) {
|
|||||||
unlockerIdentity, err := unlocker.GetIdentity()
|
unlockerIdentity, err := unlocker.GetIdentity()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to get unlocker identity", "error", err, "unlocker_type", unlocker.GetType())
|
secret.Debug("Failed to get unlocker identity", "error", err, "unlocker_type", unlocker.GetType())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to get unlocker identity: %w", err)
|
return nil, fmt.Errorf("failed to get unlocker identity: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +145,7 @@ func (v *Vault) GetOrDeriveLongTermKey() (*age.X25519Identity, error) {
|
|||||||
encryptedLtPrivKey, err := afero.ReadFile(v.fs, encryptedLtPrivKeyPath)
|
encryptedLtPrivKey, err := afero.ReadFile(v.fs, encryptedLtPrivKeyPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to read encrypted long-term private key", "error", err, "path", encryptedLtPrivKeyPath)
|
secret.Debug("Failed to read encrypted long-term private key", "error", err, "path", encryptedLtPrivKeyPath)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to read encrypted long-term private key: %w", err)
|
return nil, fmt.Errorf("failed to read encrypted long-term private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +160,7 @@ func (v *Vault) GetOrDeriveLongTermKey() (*age.X25519Identity, error) {
|
|||||||
ltPrivKeyData, err := secret.DecryptWithIdentity(encryptedLtPrivKey, unlockerIdentity)
|
ltPrivKeyData, err := secret.DecryptWithIdentity(encryptedLtPrivKey, unlockerIdentity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to decrypt long-term private key", "error", err, "unlocker_type", unlocker.GetType())
|
secret.Debug("Failed to decrypt long-term private key", "error", err, "unlocker_type", unlocker.GetType())
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to decrypt long-term private key: %w", err)
|
return nil, fmt.Errorf("failed to decrypt long-term private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +175,7 @@ func (v *Vault) GetOrDeriveLongTermKey() (*age.X25519Identity, error) {
|
|||||||
ltIdentity, err := age.ParseX25519Identity(string(ltPrivKeyData))
|
ltIdentity, err := age.ParseX25519Identity(string(ltPrivKeyData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
secret.Debug("Failed to parse long-term private key", "error", err, "vault_name", v.Name)
|
secret.Debug("Failed to parse long-term private key", "error", err, "vault_name", v.Name)
|
||||||
|
|
||||||
return nil, fmt.Errorf("failed to parse long-term private key: %w", err)
|
return nil, fmt.Errorf("failed to parse long-term private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,11 +21,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
purpose = uint32(83696968) // fixed by BIP-85 ("bip")
|
purpose = uint32(83696968) // fixed by BIP-85 ("bip")
|
||||||
vendorID = uint32(592366788) // berlin.sneak
|
vendorID = uint32(592366788) // berlin.sneak
|
||||||
appID = uint32(733482323) // secret
|
appID = uint32(733482323) // secret
|
||||||
hrp = "age-secret-key-" // Bech32 HRP used by age
|
hrp = "age-secret-key-" // Bech32 HRP used by age
|
||||||
x25519KeySize = 32 // 256-bit key size for X25519
|
x25519KeySize = 32 // 256-bit key size for X25519
|
||||||
)
|
)
|
||||||
|
|
||||||
// clamp applies RFC-7748 clamping to a 32-byte scalar.
|
// clamp applies RFC-7748 clamping to a 32-byte scalar.
|
||||||
|
@ -28,13 +28,13 @@ const (
|
|||||||
BIP85_KEY_HMAC_KEY = "bip-entropy-from-k" //nolint:revive // ALL_CAPS used for BIP85 constants
|
BIP85_KEY_HMAC_KEY = "bip-entropy-from-k" //nolint:revive // ALL_CAPS used for BIP85 constants
|
||||||
|
|
||||||
// Application numbers
|
// Application numbers
|
||||||
AppBIP39 = 39 // BIP39 mnemonics
|
AppBIP39 = 39 // BIP39 mnemonics
|
||||||
AppHDWIF = 2 // WIF for Bitcoin Core
|
AppHDWIF = 2 // WIF for Bitcoin Core
|
||||||
AppXPRV = 32 // Extended private key
|
AppXPRV = 32 // Extended private key
|
||||||
APP_HEX = 128169 //nolint:revive // ALL_CAPS used for BIP85 constants
|
APP_HEX = 128169 //nolint:revive // ALL_CAPS used for BIP85 constants
|
||||||
APP_PWD64 = 707764 // Base64 passwords //nolint:revive // ALL_CAPS used for BIP85 constants
|
APP_PWD64 = 707764 // Base64 passwords //nolint:revive // ALL_CAPS used for BIP85 constants
|
||||||
AppPWD85 = 707785 // Base85 passwords
|
AppPWD85 = 707785 // Base85 passwords
|
||||||
APP_RSA = 828365 //nolint:revive // ALL_CAPS used for BIP85 constants
|
APP_RSA = 828365 //nolint:revive // ALL_CAPS used for BIP85 constants
|
||||||
)
|
)
|
||||||
|
|
||||||
// Version bytes for extended keys
|
// Version bytes for extended keys
|
||||||
|
Loading…
Reference in New Issue
Block a user