mirror of
https://github.com/minio/minio.git
synced 2025-11-20 01:50:24 -05:00
fix: allow parsing keys in both new and old format (#12144)
Bonus fix fallback to decrypt previously encrypted content as well using older master key ciphertext format. Signed-off-by: Harshavardhana <harsha@minio.io>
This commit is contained in:
@@ -28,7 +28,9 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/minio/sio"
|
||||
"github.com/secure-io/sio-go/sioutil"
|
||||
"golang.org/x/crypto/chacha20"
|
||||
"golang.org/x/crypto/chacha20poly1305"
|
||||
@@ -55,7 +57,7 @@ func Parse(s string) (KMS, error) {
|
||||
}
|
||||
|
||||
// New returns a single-key KMS that derives new DEKs from the
|
||||
// given key. The given key must always be 32 bytes.
|
||||
// given key.
|
||||
func New(keyID string, key []byte) (KMS, error) {
|
||||
if len(key) != 32 {
|
||||
return nil, errors.New("kms: invalid key length " + strconv.Itoa(len(key)))
|
||||
@@ -168,11 +170,39 @@ func (kms secretKey) GenerateKey(keyID string, context Context) (DEK, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (kms secretKey) legacyDecryptKey(keyID string, sealedKey []byte, ctx Context) ([]byte, error) {
|
||||
var derivedKey = kms.deriveKey(keyID, ctx)
|
||||
|
||||
var key [32]byte
|
||||
out, err := sio.DecryptBuffer(key[:0], sealedKey, sio.Config{Key: derivedKey[:]})
|
||||
if err != nil || len(out) != 32 {
|
||||
return nil, err // TODO(aead): upgrade sio to use sio.Error
|
||||
}
|
||||
return key[:], nil
|
||||
}
|
||||
|
||||
func (kms secretKey) deriveKey(keyID string, context Context) (key [32]byte) {
|
||||
if context == nil {
|
||||
context = Context{}
|
||||
}
|
||||
ctxBytes, _ := context.MarshalText()
|
||||
|
||||
mac := hmac.New(sha256.New, kms.key[:])
|
||||
mac.Write([]byte(keyID))
|
||||
mac.Write(ctxBytes)
|
||||
mac.Sum(key[:0])
|
||||
return key
|
||||
}
|
||||
|
||||
func (kms secretKey) DecryptKey(keyID string, ciphertext []byte, context Context) ([]byte, error) {
|
||||
if keyID != kms.keyID {
|
||||
return nil, fmt.Errorf("kms: key %q does not exist", keyID)
|
||||
}
|
||||
|
||||
if !utf8.Valid(ciphertext) {
|
||||
return kms.legacyDecryptKey(keyID, ciphertext, context)
|
||||
}
|
||||
|
||||
var encryptedKey encryptedKey
|
||||
if err := json.Unmarshal(ciphertext, &encryptedKey); err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user