mirror of
https://github.com/minio/minio.git
synced 2025-02-04 10:26:01 -05:00
return AWS S3 compatible error for invalid but equal keys during key rotation (#5783)
This change let the server return the S3 error for a key rotation if the source key is not valid but equal to the destination key. This change also fixes the SSE-C error messages since AWS returns error messages ending with a '.'. Fixes #5625
This commit is contained in:
parent
73f7a98590
commit
da9f0e324e
@ -138,6 +138,7 @@ const (
|
|||||||
ErrMissingSSECustomerKey
|
ErrMissingSSECustomerKey
|
||||||
ErrMissingSSECustomerKeyMD5
|
ErrMissingSSECustomerKeyMD5
|
||||||
ErrSSECustomerKeyMD5Mismatch
|
ErrSSECustomerKeyMD5Mismatch
|
||||||
|
ErrInvalidSSECustomerParameters
|
||||||
|
|
||||||
// Bucket notification related errors.
|
// Bucket notification related errors.
|
||||||
ErrEventNotification
|
ErrEventNotification
|
||||||
@ -629,7 +630,7 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
|||||||
},
|
},
|
||||||
ErrInsecureSSECustomerRequest: {
|
ErrInsecureSSECustomerRequest: {
|
||||||
Code: "InvalidRequest",
|
Code: "InvalidRequest",
|
||||||
Description: errInsecureSSERequest.Error(),
|
Description: "Requests specifying Server Side Encryption with Customer provided keys must be made over a secure connection.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrSSEMultipartEncrypted: {
|
ErrSSEMultipartEncrypted: {
|
||||||
@ -639,7 +640,7 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
|||||||
},
|
},
|
||||||
ErrSSEEncryptedObject: {
|
ErrSSEEncryptedObject: {
|
||||||
Code: "InvalidRequest",
|
Code: "InvalidRequest",
|
||||||
Description: errEncryptedObject.Error(),
|
Description: "The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrInvalidEncryptionParameters: {
|
ErrInvalidEncryptionParameters: {
|
||||||
@ -649,27 +650,32 @@ var errorCodeResponse = map[APIErrorCode]APIError{
|
|||||||
},
|
},
|
||||||
ErrInvalidSSECustomerAlgorithm: {
|
ErrInvalidSSECustomerAlgorithm: {
|
||||||
Code: "InvalidArgument",
|
Code: "InvalidArgument",
|
||||||
Description: errInvalidSSEAlgorithm.Error(),
|
Description: "Requests specifying Server Side Encryption with Customer provided keys must provide a valid encryption algorithm.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrInvalidSSECustomerKey: {
|
ErrInvalidSSECustomerKey: {
|
||||||
Code: "InvalidArgument",
|
Code: "InvalidArgument",
|
||||||
Description: errInvalidSSEKey.Error(),
|
Description: "The secret key was invalid for the specified algorithm.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrMissingSSECustomerKey: {
|
ErrMissingSSECustomerKey: {
|
||||||
Code: "InvalidArgument",
|
Code: "InvalidArgument",
|
||||||
Description: errMissingSSEKey.Error(),
|
Description: "Requests specifying Server Side Encryption with Customer provided keys must provide an appropriate secret key.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrMissingSSECustomerKeyMD5: {
|
ErrMissingSSECustomerKeyMD5: {
|
||||||
Code: "InvalidArgument",
|
Code: "InvalidArgument",
|
||||||
Description: errMissingSSEKeyMD5.Error(),
|
Description: "Requests specifying Server Side Encryption with Customer provided keys must provide the client calculated MD5 of the secret key.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
ErrSSECustomerKeyMD5Mismatch: {
|
ErrSSECustomerKeyMD5Mismatch: {
|
||||||
Code: "InvalidArgument",
|
Code: "InvalidArgument",
|
||||||
Description: errSSEKeyMD5Mismatch.Error(),
|
Description: "The calculated MD5 hash of the key did not match the hash that was provided.",
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
},
|
||||||
|
ErrInvalidSSECustomerParameters: {
|
||||||
|
Code: "InvalidArgument",
|
||||||
|
Description: "The provided encryption parameters did not match the ones used originally.",
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -884,6 +890,8 @@ func toAPIErrorCode(err error) (apiErr APIErrorCode) {
|
|||||||
return ErrObjectTampered
|
return ErrObjectTampered
|
||||||
case errEncryptedObject:
|
case errEncryptedObject:
|
||||||
return ErrSSEEncryptedObject
|
return ErrSSEEncryptedObject
|
||||||
|
case errInvalidSSEParameters:
|
||||||
|
return ErrInvalidSSECustomerParameters
|
||||||
case errSSEKeyMismatch:
|
case errSSEKeyMismatch:
|
||||||
return ErrAccessDenied // no access without correct key
|
return ErrAccessDenied // no access without correct key
|
||||||
}
|
}
|
||||||
|
@ -35,14 +35,15 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// AWS errors for invalid SSE-C requests.
|
// AWS errors for invalid SSE-C requests.
|
||||||
errInsecureSSERequest = errors.New("Requests specifying Server Side Encryption with Customer provided keys must be made over a secure connection")
|
errInsecureSSERequest = errors.New("SSE-C requests require TLS connections")
|
||||||
errEncryptedObject = errors.New("The object was stored using a form of Server Side Encryption. The correct parameters must be provided to retrieve the object")
|
errEncryptedObject = errors.New("The object was stored using a form of SSE")
|
||||||
errInvalidSSEAlgorithm = errors.New("Requests specifying Server Side Encryption with Customer provided keys must provide a valid encryption algorithm")
|
errInvalidSSEAlgorithm = errors.New("The SSE-C algorithm is not valid")
|
||||||
errMissingSSEKey = errors.New("Requests specifying Server Side Encryption with Customer provided keys must provide an appropriate secret key")
|
errMissingSSEKey = errors.New("The SSE-C request is missing the customer key")
|
||||||
errInvalidSSEKey = errors.New("The secret key was invalid for the specified algorithm")
|
errInvalidSSEKey = errors.New("The SSE-C key is invalid")
|
||||||
errMissingSSEKeyMD5 = errors.New("Requests specifying Server Side Encryption with Customer provided keys must provide the client calculated MD5 of the secret key")
|
errMissingSSEKeyMD5 = errors.New("The SSE-C request is missing the customer key MD5")
|
||||||
errSSEKeyMD5Mismatch = errors.New("The calculated MD5 hash of the key did not match the hash that was provided")
|
errSSEKeyMD5Mismatch = errors.New("The key MD5 does not match the SSE-C key")
|
||||||
errSSEKeyMismatch = errors.New("The client provided key does not match the key provided when the object was encrypted") // this msg is not shown to the client
|
errSSEKeyMismatch = errors.New("The SSE-C key is not correct") // access denied
|
||||||
|
errInvalidSSEParameters = errors.New("The SSE-C key for key-rotation is not correct") // special access denied
|
||||||
|
|
||||||
// Additional Minio errors for SSE-C requests.
|
// Additional Minio errors for SSE-C requests.
|
||||||
errObjectTampered = errors.New("The requested object was modified and may be compromised")
|
errObjectTampered = errors.New("The requested object was modified and may be compromised")
|
||||||
@ -247,9 +248,6 @@ func ParseSSECustomerHeader(header http.Header) (key []byte, err error) {
|
|||||||
|
|
||||||
// This function rotates old to new key.
|
// This function rotates old to new key.
|
||||||
func rotateKey(oldKey []byte, newKey []byte, metadata map[string]string) error {
|
func rotateKey(oldKey []byte, newKey []byte, metadata map[string]string) error {
|
||||||
if subtle.ConstantTimeCompare(oldKey, newKey) == 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
delete(metadata, SSECustomerKey) // make sure we do not save the key by accident
|
delete(metadata, SSECustomerKey) // make sure we do not save the key by accident
|
||||||
|
|
||||||
if metadata[ServerSideEncryptionSealAlgorithm] != SSESealAlgorithmDareSha256 { // currently DARE-SHA256 is the only option
|
if metadata[ServerSideEncryptionSealAlgorithm] != SSESealAlgorithmDareSha256 { // currently DARE-SHA256 is the only option
|
||||||
@ -273,10 +271,14 @@ func rotateKey(oldKey []byte, newKey []byte, metadata map[string]string) error {
|
|||||||
n, err := sio.Decrypt(objectEncryptionKey, bytes.NewReader(sealedKey), sio.Config{
|
n, err := sio.Decrypt(objectEncryptionKey, bytes.NewReader(sealedKey), sio.Config{
|
||||||
Key: keyEncryptionKey,
|
Key: keyEncryptionKey,
|
||||||
})
|
})
|
||||||
if n != 32 || err != nil {
|
if n != 32 || err != nil { // Either the provided key does not match or the object was tampered.
|
||||||
// Either the provided key does not match or the object was tampered.
|
if subtle.ConstantTimeCompare(oldKey, newKey) == 1 {
|
||||||
// To provide strict AWS S3 compatibility we return: access denied.
|
return errInvalidSSEParameters // AWS returns special error for equal but invalid keys.
|
||||||
return errSSEKeyMismatch
|
}
|
||||||
|
return errSSEKeyMismatch // To provide strict AWS S3 compatibility we return: access denied.
|
||||||
|
}
|
||||||
|
if subtle.ConstantTimeCompare(oldKey, newKey) == 1 {
|
||||||
|
return nil // we don't need to rotate keys if newKey == oldKey
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce := make([]byte, 32) // generate random values for key derivation
|
nonce := make([]byte, 32) // generate random values for key derivation
|
||||||
|
Loading…
x
Reference in New Issue
Block a user