- Add .golangci.yml with minimal linters (govet, ineffassign) - Run gofmt -s and goimports on all files to fix formatting - Disable fieldalignment and copylocks checks in govet
78 lines
2.2 KiB
Go
78 lines
2.2 KiB
Go
package cmd
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"dbbackup/internal/crypto"
|
|
)
|
|
|
|
// loadEncryptionKey loads encryption key from file or environment variable
|
|
func loadEncryptionKey(keyFile, keyEnvVar string) ([]byte, error) {
|
|
// Priority 1: Key file
|
|
if keyFile != "" {
|
|
keyData, err := os.ReadFile(keyFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read encryption key file: %w", err)
|
|
}
|
|
|
|
// Try to decode as base64 first
|
|
if decoded, err := base64.StdEncoding.DecodeString(strings.TrimSpace(string(keyData))); err == nil && len(decoded) == crypto.KeySize {
|
|
return decoded, nil
|
|
}
|
|
|
|
// Use raw bytes if exactly 32 bytes
|
|
if len(keyData) == crypto.KeySize {
|
|
return keyData, nil
|
|
}
|
|
|
|
// Otherwise treat as passphrase and derive key
|
|
salt, err := crypto.GenerateSalt()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate salt: %w", err)
|
|
}
|
|
key := crypto.DeriveKey([]byte(strings.TrimSpace(string(keyData))), salt)
|
|
return key, nil
|
|
}
|
|
|
|
// Priority 2: Environment variable
|
|
if keyEnvVar != "" {
|
|
keyData := os.Getenv(keyEnvVar)
|
|
if keyData == "" {
|
|
return nil, fmt.Errorf("encryption enabled but %s environment variable not set", keyEnvVar)
|
|
}
|
|
|
|
// Try to decode as base64 first
|
|
if decoded, err := base64.StdEncoding.DecodeString(strings.TrimSpace(keyData)); err == nil && len(decoded) == crypto.KeySize {
|
|
return decoded, nil
|
|
}
|
|
|
|
// Otherwise treat as passphrase and derive key
|
|
salt, err := crypto.GenerateSalt()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to generate salt: %w", err)
|
|
}
|
|
key := crypto.DeriveKey([]byte(strings.TrimSpace(keyData)), salt)
|
|
return key, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("encryption enabled but no key source specified (use --encryption-key-file or set %s)", keyEnvVar)
|
|
}
|
|
|
|
// isEncryptionEnabled checks if encryption is requested
|
|
func isEncryptionEnabled() bool {
|
|
return encryptBackupFlag
|
|
}
|
|
|
|
// generateEncryptionKey generates a new random encryption key
|
|
func generateEncryptionKey() ([]byte, error) {
|
|
salt, err := crypto.GenerateSalt()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// For key generation, use salt as both password and salt (random)
|
|
return crypto.DeriveKey(salt, salt), nil
|
|
}
|