mirror of
https://github.com/minio/minio.git
synced 2025-11-13 07:11:44 -05:00
add SSE-KMS support and use SSE-KMS for auto encryption (#12237)
This commit adds basic SSE-KMS support. Now, a client can specify the SSE-KMS headers (algorithm, optional key-id, optional context) such that the object gets encrypted using the SSE-KMS method. Further, auto-encryption now defaults to SSE-KMS. This commit does not try to do any refactoring and instead tries to implement SSE-KMS as a minimal change to the code base. However, refactoring the entire crypto-related code is planned - but needs a separate effort. Signed-off-by: Andreas Auernhammer <aead@mail.de>
This commit is contained in:
committed by
GitHub
parent
989e394a32
commit
af0c65be93
@@ -18,6 +18,7 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"net/http"
|
||||
"sort"
|
||||
"testing"
|
||||
@@ -96,27 +97,27 @@ var kmsParseHTTPTests = []struct {
|
||||
{Header: http.Header{
|
||||
"X-Amz-Server-Side-Encryption": []string{"aws:kms"},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{"{}"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{base64.StdEncoding.EncodeToString([]byte("{}"))},
|
||||
}, ShouldFail: false}, // 3
|
||||
{Header: http.Header{
|
||||
"X-Amz-Server-Side-Encryption": []string{"aws:kms"},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\"}"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{base64.StdEncoding.EncodeToString([]byte(`{"bucket": "some-bucket"}`))},
|
||||
}, ShouldFail: false}, // 4
|
||||
{Header: http.Header{
|
||||
"X-Amz-Server-Side-Encryption": []string{"aws:kms"},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\"}"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{base64.StdEncoding.EncodeToString([]byte(`{"bucket": "some-bucket"}`))},
|
||||
}, ShouldFail: false}, // 5
|
||||
{Header: http.Header{
|
||||
"X-Amz-Server-Side-Encryption": []string{"AES256"},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\"}"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{base64.StdEncoding.EncodeToString([]byte(`{"bucket": "some-bucket"}`))},
|
||||
}, ShouldFail: true}, // 6
|
||||
{Header: http.Header{
|
||||
"X-Amz-Server-Side-Encryption": []string{"aws:kms"},
|
||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"s3-007-293847485-724784"},
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{"{\"bucket\": \"some-bucket\""}, // invalid JSON
|
||||
"X-Amz-Server-Side-Encryption-Context": []string{base64.StdEncoding.EncodeToString([]byte(`{"bucket": "some-bucket"`))}, // invalid JSON
|
||||
}, ShouldFail: true}, // 7
|
||||
|
||||
}
|
||||
|
||||
@@ -69,8 +69,13 @@ func (ssekms) ParseHTTP(h http.Header) (string, Context, error) {
|
||||
|
||||
var ctx Context
|
||||
if context, ok := h[xhttp.AmzServerSideEncryptionKmsContext]; ok {
|
||||
b, err := base64.StdEncoding.DecodeString(context[0])
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
if err := json.Unmarshal([]byte(context[0]), &ctx); err != nil {
|
||||
if err := json.Unmarshal(b, &ctx); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
@@ -109,7 +114,7 @@ func (s3 ssekms) UnsealObjectKey(kms KMS, metadata map[string]string, bucket, ob
|
||||
// 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
|
||||
// is nil.
|
||||
func (ssekms) CreateMetadata(metadata map[string]string, keyID string, kmsKey []byte, sealedKey SealedKey) map[string]string {
|
||||
func (ssekms) CreateMetadata(metadata map[string]string, keyID string, kmsKey []byte, sealedKey SealedKey, ctx Context) map[string]string {
|
||||
if sealedKey.Algorithm != SealAlgorithm {
|
||||
logger.CriticalIf(context.Background(), Errorf("The seal algorithm '%s' is invalid for SSE-S3", sealedKey.Algorithm))
|
||||
}
|
||||
@@ -132,6 +137,10 @@ func (ssekms) CreateMetadata(metadata map[string]string, keyID string, kmsKey []
|
||||
metadata[MetaAlgorithm] = sealedKey.Algorithm
|
||||
metadata[MetaIV] = base64.StdEncoding.EncodeToString(sealedKey.IV[:])
|
||||
metadata[MetaSealedKeyKMS] = base64.StdEncoding.EncodeToString(sealedKey.Key[:])
|
||||
if len(ctx) > 0 {
|
||||
b, _ := ctx.MarshalText()
|
||||
metadata[MetaContext] = base64.StdEncoding.EncodeToString(b)
|
||||
}
|
||||
if len(kmsKey) > 0 && keyID != "" { // We use a KMS -> Store key ID and sealed KMS data key.
|
||||
metadata[MetaKeyID] = keyID
|
||||
metadata[MetaDataEncryptionKey] = base64.StdEncoding.EncodeToString(kmsKey)
|
||||
|
||||
Reference in New Issue
Block a user