mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
crypto: add SSE-KMS HTTP header detection (#6228)
This commit adds support for detecting SSE-KMS headers. The server should be able to detect SSE-KMS headers to at least fail such S3 requests with not implemented.
This commit is contained in:
parent
efac90461a
commit
525c04fd07
@ -19,11 +19,22 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SSEHeader is the general AWS SSE HTTP header key.
|
// SSEHeader is the general AWS SSE HTTP header key.
|
||||||
const SSEHeader = "X-Amz-Server-Side-Encryption"
|
const SSEHeader = "X-Amz-Server-Side-Encryption"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SSEKmsID is the HTTP header key referencing the SSE-KMS
|
||||||
|
// key ID.
|
||||||
|
SSEKmsID = SSEHeader + "-Aws-Kms-Key-Id"
|
||||||
|
|
||||||
|
// SSEKmsContext is the HTTP header key referencing the
|
||||||
|
// SSE-KMS encryption context.
|
||||||
|
SSEKmsContext = SSEHeader + "-Context"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// SSECAlgorithm is the HTTP header key referencing
|
// SSECAlgorithm is the HTTP header key referencing
|
||||||
// the SSE-C algorithm.
|
// the SSE-C algorithm.
|
||||||
@ -52,10 +63,16 @@ const (
|
|||||||
SSECopyKeyMD5 = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5"
|
SSECopyKeyMD5 = "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SSEAlgorithmAES256 is the only supported value for the SSE-S3 or SSE-C algorithm header.
|
const (
|
||||||
// For SSE-S3 see: https://docs.aws.amazon.com/AmazonS3/latest/dev/SSEUsingRESTAPI.html
|
// SSEAlgorithmAES256 is the only supported value for the SSE-S3 or SSE-C algorithm header.
|
||||||
// For SSE-C see: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
|
// For SSE-S3 see: https://docs.aws.amazon.com/AmazonS3/latest/dev/SSEUsingRESTAPI.html
|
||||||
const SSEAlgorithmAES256 = "AES256"
|
// For SSE-C see: https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html
|
||||||
|
SSEAlgorithmAES256 = "AES256"
|
||||||
|
|
||||||
|
// SSEAlgorithmKMS is the value of 'X-Amz-Server-Side-Encryption' for SSE-KMS.
|
||||||
|
// See: https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html
|
||||||
|
SSEAlgorithmKMS = "aws:kms"
|
||||||
|
)
|
||||||
|
|
||||||
// S3 represents AWS SSE-S3. It provides functionality to handle
|
// S3 represents AWS SSE-S3. It provides functionality to handle
|
||||||
// SSE-S3 requests.
|
// SSE-S3 requests.
|
||||||
@ -67,7 +84,7 @@ type s3 struct{}
|
|||||||
// the S3 client requests SSE-S3.
|
// the S3 client requests SSE-S3.
|
||||||
func (s3) IsRequested(h http.Header) bool {
|
func (s3) IsRequested(h http.Header) bool {
|
||||||
_, ok := h[SSEHeader]
|
_, ok := h[SSEHeader]
|
||||||
return ok
|
return ok && strings.ToLower(h.Get(SSEHeader)) != SSEAlgorithmKMS // Return only true if the SSE header is specified and does not contain the SSE-KMS value
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHTTP parses the SSE-S3 related HTTP headers and checks
|
// ParseHTTP parses the SSE-S3 related HTTP headers and checks
|
||||||
@ -79,6 +96,27 @@ func (s3) ParseHTTP(h http.Header) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// S3KMS represents AWS SSE-KMS. It provides functionality to
|
||||||
|
// handle SSE-KMS requests.
|
||||||
|
var S3KMS = s3KMS{}
|
||||||
|
|
||||||
|
type s3KMS struct{}
|
||||||
|
|
||||||
|
// IsRequested returns true if the HTTP headers indicates that
|
||||||
|
// the S3 client requests SSE-KMS.
|
||||||
|
func (s3KMS) IsRequested(h http.Header) bool {
|
||||||
|
if _, ok := h[SSEKmsID]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := h[SSEKmsContext]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := h[SSEHeader]; ok {
|
||||||
|
return strings.ToUpper(h.Get(SSEHeader)) != SSEAlgorithmAES256 // Return only true if the SSE header is specified and does not contain the SSE-S3 value
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// SSEC represents AWS SSE-C. It provides functionality to handle
|
// SSEC represents AWS SSE-C. It provides functionality to handle
|
||||||
// SSE-C requests.
|
// SSE-C requests.
|
||||||
|
@ -19,14 +19,49 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var kmsIsRequestedTests = []struct {
|
||||||
|
Header http.Header
|
||||||
|
Expected bool
|
||||||
|
}{
|
||||||
|
{Header: http.Header{}, Expected: false}, // 0
|
||||||
|
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"aws:kms"}}, Expected: true}, // 1
|
||||||
|
{Header: http.Header{"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{"0839-9047947-844842874-481"}}, Expected: true}, // 2
|
||||||
|
{Header: http.Header{"X-Amz-Server-Side-Encryption-Context": []string{"7PpPLAK26ONlVUGOWlusfg=="}}, Expected: true}, // 3
|
||||||
|
{
|
||||||
|
Header: http.Header{
|
||||||
|
"X-Amz-Server-Side-Encryption": []string{""},
|
||||||
|
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{""},
|
||||||
|
"X-Amz-Server-Side-Encryption-Context": []string{""},
|
||||||
|
},
|
||||||
|
Expected: true,
|
||||||
|
}, // 4
|
||||||
|
{
|
||||||
|
Header: http.Header{
|
||||||
|
"X-Amz-Server-Side-Encryption": []string{"AES256"},
|
||||||
|
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": []string{""},
|
||||||
|
},
|
||||||
|
Expected: true,
|
||||||
|
}, // 5
|
||||||
|
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES256"}}, Expected: false}, // 6
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKMSIsRequested(t *testing.T) {
|
||||||
|
for i, test := range kmsIsRequestedTests {
|
||||||
|
if got := S3KMS.IsRequested(test.Header); got != test.Expected {
|
||||||
|
t.Errorf("Test %d: Wanted %v but got %v", i, test.Expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var s3IsRequestedTests = []struct {
|
var s3IsRequestedTests = []struct {
|
||||||
Header http.Header
|
Header http.Header
|
||||||
Expected bool
|
Expected bool
|
||||||
}{
|
}{
|
||||||
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES256"}}, Expected: true}, // 0
|
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES256"}}, Expected: true}, // 0
|
||||||
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES-256"}}, Expected: true}, // 1
|
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{"AES-256"}}, Expected: true}, // 1
|
||||||
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{""}}, Expected: true}, // 2
|
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{""}}, Expected: true}, // 2
|
||||||
{Header: http.Header{"X-Amz-Server-Side-Encryptio": []string{"AES256"}}, Expected: false}, // 3
|
{Header: http.Header{"X-Amz-Server-Side-Encryptio": []string{"AES256"}}, Expected: false}, // 3
|
||||||
|
{Header: http.Header{"X-Amz-Server-Side-Encryption": []string{SSEAlgorithmKMS}}, Expected: false}, // 4
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestS3IsRequested(t *testing.T) {
|
func TestS3IsRequested(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user