mirror of
https://github.com/cloudreve/cloudreve.git
synced 2025-12-15 10:04:01 +08:00
106 lines
2.6 KiB
Go
106 lines
2.6 KiB
Go
package encrypt
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
|
)
|
|
|
|
const (
|
|
EnvMasterEncryptKey = "CR_ENCRYPT_MASTER_KEY"
|
|
)
|
|
|
|
// MasterEncryptKeyVault is a vault for the master encrypt key.
|
|
type MasterEncryptKeyVault interface {
|
|
GetMasterKey(ctx context.Context) ([]byte, error)
|
|
}
|
|
|
|
func NewMasterEncryptKeyVault(ctx context.Context, settings setting.Provider) MasterEncryptKeyVault {
|
|
vaultType := settings.MasterEncryptKeyVault(ctx)
|
|
switch vaultType {
|
|
case setting.MasterEncryptKeyVaultTypeEnv:
|
|
return NewEnvMasterEncryptKeyVault()
|
|
case setting.MasterEncryptKeyVaultTypeFile:
|
|
return NewFileMasterEncryptKeyVault(settings.MasterEncryptKeyFile(ctx))
|
|
default:
|
|
return NewSettingMasterEncryptKeyVault(settings)
|
|
}
|
|
}
|
|
|
|
// settingMasterEncryptKeyVault is a vault for the master encrypt key that gets the key from the setting KV.
|
|
type settingMasterEncryptKeyVault struct {
|
|
setting setting.Provider
|
|
}
|
|
|
|
func NewSettingMasterEncryptKeyVault(setting setting.Provider) MasterEncryptKeyVault {
|
|
return &settingMasterEncryptKeyVault{setting: setting}
|
|
}
|
|
|
|
func (v *settingMasterEncryptKeyVault) GetMasterKey(ctx context.Context) ([]byte, error) {
|
|
key := v.setting.MasterEncryptKey(ctx)
|
|
if key == nil {
|
|
return nil, errors.New("master encrypt key is not set")
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
func NewEnvMasterEncryptKeyVault() MasterEncryptKeyVault {
|
|
return &envMasterEncryptKeyVault{}
|
|
}
|
|
|
|
type envMasterEncryptKeyVault struct {
|
|
}
|
|
|
|
var envMasterKeyCache = []byte{}
|
|
|
|
func (v *envMasterEncryptKeyVault) GetMasterKey(ctx context.Context) ([]byte, error) {
|
|
if len(envMasterKeyCache) > 0 {
|
|
return envMasterKeyCache, nil
|
|
}
|
|
|
|
key := os.Getenv(EnvMasterEncryptKey)
|
|
if key == "" {
|
|
return nil, errors.New("master encrypt key is not set")
|
|
}
|
|
|
|
decodedKey, err := base64.StdEncoding.DecodeString(key)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to decode master encrypt key: %w", err)
|
|
}
|
|
|
|
envMasterKeyCache = decodedKey
|
|
return decodedKey, nil
|
|
}
|
|
|
|
func NewFileMasterEncryptKeyVault(path string) MasterEncryptKeyVault {
|
|
return &fileMasterEncryptKeyVault{path: path}
|
|
}
|
|
|
|
var fileMasterKeyCache = []byte{}
|
|
|
|
type fileMasterEncryptKeyVault struct {
|
|
path string
|
|
}
|
|
|
|
func (v *fileMasterEncryptKeyVault) GetMasterKey(ctx context.Context) ([]byte, error) {
|
|
if len(fileMasterKeyCache) > 0 {
|
|
return fileMasterKeyCache, nil
|
|
}
|
|
|
|
key, err := os.ReadFile(v.path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid master encrypt key file")
|
|
}
|
|
|
|
decodedKey, err := base64.StdEncoding.DecodeString(string(key))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid master encrypt key")
|
|
}
|
|
fileMasterKeyCache = decodedKey
|
|
return fileMasterKeyCache, nil
|
|
}
|