mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
add support for SSE-S3 bulk ETag decryption (#14627)
This commit adds support for bulk ETag decryption for SSE-S3 encrypted objects. If KES supports a bulk decryption API, then MinIO will check whether its policy grants access to this API. If so, MinIO will use a bulk API call instead of sending encrypted ETags serially to KES. Note that MinIO will not use the KES bulk API if its client certificate is an admin identity. MinIO will process object listings in batches. A batch has a configurable size that can be set via `MINIO_KMS_KES_BULK_API_BATCH_SIZE=N`. It defaults to `500`. This env. variable is experimental and may be renamed / removed in the future. Signed-off-by: Andreas Auernhammer <hi@aead.dev>
This commit is contained in:
committed by
GitHub
parent
3970204009
commit
4d2fc530d0
@@ -84,6 +84,63 @@ func (s3 sses3) UnsealObjectKey(KMS kms.KMS, metadata map[string]string, bucket,
|
||||
return key, err
|
||||
}
|
||||
|
||||
// UnsealObjectsKeys extracts and decrypts all sealed object keys
|
||||
// from the metadata using the KMS and returns the decrypted object
|
||||
// keys.
|
||||
//
|
||||
// The metadata, buckets and objects slices must have the same length.
|
||||
func (s3 sses3) UnsealObjectKeys(KMS kms.KMS, metadata []map[string]string, buckets, objects []string) ([]ObjectKey, error) {
|
||||
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
|
||||
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 := KMS.DecryptAll(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(KMS, metadata[i], buckets[i], objects[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// CreateMetadata encodes the sealed object key into the metadata and returns
|
||||
// the modified metadata. If the keyID and the kmsKey is not empty it encodes
|
||||
// both into the metadata as well. It allocates a new metadata map if metadata
|
||||
|
||||
Reference in New Issue
Block a user