mirror of
https://github.com/drakkan/sftpgo.git
synced 2025-12-07 06:40:54 +03:00
kms: remember if a secret was saved without a master key
So we will be able to decrypt secret stored without a master key if a such key is provided later
This commit is contained in:
@@ -30,6 +30,7 @@ func (s *baseGCloudSecret) Encrypt() error {
|
||||
|
||||
payload := s.Payload
|
||||
key := ""
|
||||
mode := 0
|
||||
if s.masterKey != "" {
|
||||
localSecret := newLocalSecret(s.baseSecret, s.masterKey)
|
||||
err := localSecret.Encrypt()
|
||||
@@ -38,6 +39,7 @@ func (s *baseGCloudSecret) Encrypt() error {
|
||||
}
|
||||
payload = localSecret.GetPayload()
|
||||
key = localSecret.GetKey()
|
||||
mode = localSecret.GetMode()
|
||||
}
|
||||
|
||||
ctx, cancelFn := context.WithDeadline(context.Background(), time.Now().Add(defaultTimeout))
|
||||
@@ -55,6 +57,7 @@ func (s *baseGCloudSecret) Encrypt() error {
|
||||
}
|
||||
s.Payload = base64.StdEncoding.EncodeToString(ciphertext)
|
||||
s.Key = key
|
||||
s.Mode = mode
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -83,6 +86,7 @@ func (s *baseGCloudSecret) Decrypt() error {
|
||||
Payload: string(plaintext),
|
||||
Key: s.Key,
|
||||
AdditionalData: s.AdditionalData,
|
||||
Mode: s.Mode,
|
||||
}
|
||||
localSecret := newLocalSecret(baseSecret, s.masterKey)
|
||||
err = localSecret.Decrypt()
|
||||
@@ -95,5 +99,6 @@ func (s *baseGCloudSecret) Decrypt() error {
|
||||
s.Payload = payload
|
||||
s.Key = ""
|
||||
s.AdditionalData = ""
|
||||
s.Mode = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ type baseSecret struct {
|
||||
Payload string `json:"payload,omitempty"`
|
||||
Key string `json:"key,omitempty"`
|
||||
AdditionalData string `json:"additional_data,omitempty"`
|
||||
// 1 means encrypted using a master key
|
||||
Mode int `json:"mode,omitempty"`
|
||||
}
|
||||
|
||||
func (s *baseSecret) GetStatus() SecretStatus {
|
||||
@@ -20,6 +22,10 @@ func (s *baseSecret) GetKey() string {
|
||||
return s.Key
|
||||
}
|
||||
|
||||
func (s *baseSecret) GetMode() int {
|
||||
return s.Mode
|
||||
}
|
||||
|
||||
func (s *baseSecret) GetAdditionalData() string {
|
||||
return s.AdditionalData
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ type SecretProvider interface {
|
||||
GetPayload() string
|
||||
GetKey() string
|
||||
GetAdditionalData() string
|
||||
GetMode() int
|
||||
SetKey(string)
|
||||
SetAdditionalData(string)
|
||||
SetStatus(SecretStatus)
|
||||
@@ -145,6 +146,7 @@ func (s *Secret) MarshalJSON() ([]byte, error) {
|
||||
Payload: s.provider.GetPayload(),
|
||||
Key: s.provider.GetKey(),
|
||||
AdditionalData: s.provider.GetAdditionalData(),
|
||||
Mode: s.provider.GetMode(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -186,6 +188,7 @@ func (s *Secret) Clone() *Secret {
|
||||
Payload: s.provider.GetPayload(),
|
||||
Key: s.provider.GetKey(),
|
||||
AdditionalData: s.provider.GetAdditionalData(),
|
||||
Mode: s.provider.GetMode(),
|
||||
}
|
||||
switch s.provider.Name() {
|
||||
case builtinProviderName:
|
||||
@@ -249,6 +252,11 @@ func (s *Secret) GetKey() string {
|
||||
return s.provider.GetKey()
|
||||
}
|
||||
|
||||
// GetMode returns the secret mode
|
||||
func (s *Secret) GetMode() int {
|
||||
return s.provider.GetMode()
|
||||
}
|
||||
|
||||
// SetAdditionalData sets the given additional data
|
||||
func (s *Secret) SetAdditionalData(value string) {
|
||||
s.provider.SetAdditionalData(value)
|
||||
|
||||
17
kms/local.go
17
kms/local.go
@@ -46,7 +46,7 @@ func (s *localSecret) Encrypt() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := s.deriveKey(secretKey[:])
|
||||
key, err := s.deriveKey(secretKey[:], false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -60,6 +60,7 @@ func (s *localSecret) Encrypt() error {
|
||||
s.Key = hex.EncodeToString(secretKey[:])
|
||||
s.Payload = base64.StdEncoding.EncodeToString(ciphertext)
|
||||
s.Status = SecretStatusSecretBox
|
||||
s.Mode = s.getEncryptionMode()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ func (s *localSecret) Decrypt() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := s.deriveKey(secretKey[:])
|
||||
key, err := s.deriveKey(secretKey[:], true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -90,12 +91,13 @@ func (s *localSecret) Decrypt() error {
|
||||
s.Payload = string(plaintext)
|
||||
s.Key = ""
|
||||
s.AdditionalData = ""
|
||||
s.Mode = 0
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *localSecret) deriveKey(key []byte) ([32]byte, error) {
|
||||
func (s *localSecret) deriveKey(key []byte, isForDecryption bool) ([32]byte, error) {
|
||||
var masterKey []byte
|
||||
if s.masterKey == "" {
|
||||
if s.masterKey == "" || (isForDecryption && s.Mode == 0) {
|
||||
var combined []byte
|
||||
combined = append(combined, key...)
|
||||
if s.AdditionalData != "" {
|
||||
@@ -118,3 +120,10 @@ func (s *localSecret) deriveKey(key []byte) ([32]byte, error) {
|
||||
}
|
||||
return derivedKey, nil
|
||||
}
|
||||
|
||||
func (s *localSecret) getEncryptionMode() int {
|
||||
if s.masterKey == "" {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user