mirror of
https://github.com/minio/minio.git
synced 2025-11-07 21:02: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
@@ -22,6 +22,7 @@ import (
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/minio/kes"
|
||||
@@ -69,15 +70,30 @@ func NewWithConfig(config Config) (KMS, error) {
|
||||
ClientSessionCache: tls.NewLRUClientSessionCache(tlsClientSessionCacheSize),
|
||||
})
|
||||
client.Endpoints = endpoints
|
||||
|
||||
var bulkAvailable bool
|
||||
_, policy, err := client.DescribeSelf(context.Background())
|
||||
if err == nil {
|
||||
const BulkAPI = "/v1/key/bulk/decrypt/"
|
||||
for _, allow := range policy.Allow {
|
||||
if strings.HasPrefix(allow, BulkAPI) {
|
||||
bulkAvailable = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return &kesClient{
|
||||
client: client,
|
||||
defaultKeyID: config.DefaultKeyID,
|
||||
client: client,
|
||||
defaultKeyID: config.DefaultKeyID,
|
||||
bulkAvailable: bulkAvailable,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type kesClient struct {
|
||||
defaultKeyID string
|
||||
client *kes.Client
|
||||
|
||||
bulkAvailable bool
|
||||
}
|
||||
|
||||
var _ KMS = (*kesClient)(nil) // compiler check
|
||||
@@ -145,3 +161,38 @@ func (c *kesClient) DecryptKey(keyID string, ciphertext []byte, ctx Context) ([]
|
||||
}
|
||||
return c.client.Decrypt(context.Background(), keyID, ciphertext, ctxBytes)
|
||||
}
|
||||
|
||||
func (c *kesClient) DecryptAll(keyID string, ciphertexts [][]byte, contexts []Context) ([][]byte, error) {
|
||||
if c.bulkAvailable {
|
||||
CCPs := make([]kes.CCP, 0, len(ciphertexts))
|
||||
for i := range ciphertexts {
|
||||
bCtx, err := contexts[i].MarshalText()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
CCPs = append(CCPs, kes.CCP{
|
||||
Ciphertext: ciphertexts[i],
|
||||
Context: bCtx,
|
||||
})
|
||||
}
|
||||
PCPs, err := c.client.DecryptAll(context.Background(), keyID, CCPs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plaintexts := make([][]byte, 0, len(PCPs))
|
||||
for _, p := range PCPs {
|
||||
plaintexts = append(plaintexts, p.Plaintext)
|
||||
}
|
||||
return plaintexts, nil
|
||||
}
|
||||
|
||||
plaintexts := make([][]byte, 0, len(ciphertexts))
|
||||
for i := range ciphertexts {
|
||||
plaintext, err := c.DecryptKey(keyID, ciphertexts[i], contexts[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plaintexts = append(plaintexts, plaintext)
|
||||
}
|
||||
return plaintexts, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user