mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
kms: add support for MinKMS and remove some unused/broken code (#19368)
This commit adds support for MinKMS. Now, there are three KMS implementations in `internal/kms`: Builtin, MinIO KES and MinIO KMS. Adding another KMS integration required some cleanup. In particular: - Various KMS APIs that haven't been and are not used have been removed. A lot of the code was broken anyway. - Metrics are now monitored by the `kms.KMS` itself. For basic metrics this is simpler than collecting metrics for external servers. In particular, each KES server returns its own metrics and no cluster-level view. - The builtin KMS now uses the same en/decryption implemented by MinKMS and KES. It still supports decryption of the previous ciphertext format. It's backwards compatible. - Data encryption keys now include a master key version since MinKMS supports multiple versions (~4 billion in total and 10000 concurrent) per key name. Signed-off-by: Andreas Auernhammer <github@aead.dev>
This commit is contained in:
committed by
GitHub
parent
981497799a
commit
8b660e18f2
@@ -106,7 +106,7 @@ func (ssekms) IsEncrypted(metadata map[string]string) bool {
|
||||
// UnsealObjectKey extracts and decrypts the sealed object key
|
||||
// from the metadata using KMS and returns the decrypted object
|
||||
// key.
|
||||
func (s3 ssekms) UnsealObjectKey(k kms.KMS, metadata map[string]string, bucket, object string) (key ObjectKey, err error) {
|
||||
func (s3 ssekms) UnsealObjectKey(k *kms.KMS, metadata map[string]string, bucket, object string) (key ObjectKey, err error) {
|
||||
if k == nil {
|
||||
return key, Errorf("KMS not configured")
|
||||
}
|
||||
@@ -120,7 +120,11 @@ func (s3 ssekms) UnsealObjectKey(k kms.KMS, metadata map[string]string, bucket,
|
||||
} else if _, ok := ctx[bucket]; !ok {
|
||||
ctx[bucket] = path.Join(bucket, object)
|
||||
}
|
||||
unsealKey, err := k.DecryptKey(keyID, kmsKey, ctx)
|
||||
unsealKey, err := k.Decrypt(context.TODO(), &kms.DecryptRequest{
|
||||
Name: keyID,
|
||||
Ciphertext: kmsKey,
|
||||
AssociatedData: ctx,
|
||||
})
|
||||
if err != nil {
|
||||
return key, err
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (sses3) IsEncrypted(metadata map[string]string) bool {
|
||||
// UnsealObjectKey extracts and decrypts the sealed object key
|
||||
// from the metadata using KMS and returns the decrypted object
|
||||
// key.
|
||||
func (s3 sses3) UnsealObjectKey(k kms.KMS, metadata map[string]string, bucket, object string) (key ObjectKey, err error) {
|
||||
func (s3 sses3) UnsealObjectKey(k *kms.KMS, metadata map[string]string, bucket, object string) (key ObjectKey, err error) {
|
||||
if k == nil {
|
||||
return key, Errorf("KMS not configured")
|
||||
}
|
||||
@@ -79,7 +79,11 @@ func (s3 sses3) UnsealObjectKey(k kms.KMS, metadata map[string]string, bucket, o
|
||||
if err != nil {
|
||||
return key, err
|
||||
}
|
||||
unsealKey, err := k.DecryptKey(keyID, kmsKey, kms.Context{bucket: path.Join(bucket, object)})
|
||||
unsealKey, err := k.Decrypt(context.TODO(), &kms.DecryptRequest{
|
||||
Name: keyID,
|
||||
Ciphertext: kmsKey,
|
||||
AssociatedData: kms.Context{bucket: path.Join(bucket, object)},
|
||||
})
|
||||
if err != nil {
|
||||
return key, err
|
||||
}
|
||||
@@ -92,7 +96,7 @@ func (s3 sses3) UnsealObjectKey(k kms.KMS, metadata map[string]string, bucket, o
|
||||
// keys.
|
||||
//
|
||||
// The metadata, buckets and objects slices must have the same length.
|
||||
func (s3 sses3) UnsealObjectKeys(ctx context.Context, k kms.KMS, metadata []map[string]string, buckets, objects []string) ([]ObjectKey, error) {
|
||||
func (s3 sses3) UnsealObjectKeys(ctx context.Context, k *kms.KMS, metadata []map[string]string, buckets, objects []string) ([]ObjectKey, error) {
|
||||
if k == nil {
|
||||
return nil, Errorf("KMS not configured")
|
||||
}
|
||||
@@ -100,45 +104,8 @@ func (s3 sses3) UnsealObjectKeys(ctx context.Context, k kms.KMS, metadata []map[
|
||||
if len(metadata) != len(buckets) || len(metadata) != len(objects) {
|
||||
return nil, Errorf("invalid metadata/object count: %d != %d != %d", len(metadata), len(buckets), len(objects))
|
||||
}
|
||||
|
||||
keyIDs := make([]string, 0, len(metadata))
|
||||
kmsKeys := make([][]byte, 0, len(metadata))
|
||||
sealedKeys := make([]SealedKey, 0, len(metadata))
|
||||
|
||||
sameKeyID := true
|
||||
keys := make([]ObjectKey, 0, len(metadata))
|
||||
for i := range metadata {
|
||||
keyID, kmsKey, sealedKey, err := s3.ParseMetadata(metadata[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyIDs = append(keyIDs, keyID)
|
||||
kmsKeys = append(kmsKeys, kmsKey)
|
||||
sealedKeys = append(sealedKeys, sealedKey)
|
||||
|
||||
if i > 0 && keyID != keyIDs[i-1] {
|
||||
sameKeyID = false
|
||||
}
|
||||
}
|
||||
if sameKeyID {
|
||||
contexts := make([]kms.Context, 0, len(keyIDs))
|
||||
for i := range buckets {
|
||||
contexts = append(contexts, kms.Context{buckets[i]: path.Join(buckets[i], objects[i])})
|
||||
}
|
||||
unsealKeys, err := k.DecryptAll(ctx, keyIDs[0], kmsKeys, contexts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys := make([]ObjectKey, len(unsealKeys))
|
||||
for i := range keys {
|
||||
if err := keys[i].Unseal(unsealKeys[i], sealedKeys[i], s3.String(), buckets[i], objects[i]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
keys := make([]ObjectKey, 0, len(keyIDs))
|
||||
for i := range keyIDs {
|
||||
key, err := s3.UnsealObjectKey(k, metadata[i], buckets[i], objects[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user