From ffded5a930f7704f23b5d2e1f9ce2fc30512373d Mon Sep 17 00:00:00 2001 From: Andreas Auernhammer Date: Sun, 22 Sep 2019 10:12:51 +0200 Subject: [PATCH] make the crypto error type a native go type (#8267) This commit makes the `crypto.Error` type a native go (string) type. That allows us to define error values as constants instead of variables. For reference see: - https://twitter.com/_aead_/status/1118170258215514115?s=20 - https://dave.cheney.net/2016/04/07/constant-errors --- cmd/api-errors.go | 6 ++++++ cmd/crypto/error.go | 16 ++++++++-------- cmd/crypto/key.go | 2 +- cmd/crypto/metadata.go | 14 +++++++------- cmd/crypto/metadata_test.go | 14 +++++++------- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/cmd/api-errors.go b/cmd/api-errors.go index cd0deaa96..257bf7f97 100644 --- a/cmd/api-errors.go +++ b/cmd/api-errors.go @@ -1723,6 +1723,12 @@ func toAPIError(ctx context.Context, err error) APIError { // their internal error types. This code is only // useful with gateway implementations. switch e := err.(type) { + case crypto.Error: + apiErr = APIError{ + Code: "XKMSInternalError", + Description: e.Error(), + HTTPStatusCode: http.StatusBadRequest, + } case minio.ErrorResponse: apiErr = APIError{ Code: e.Code, diff --git a/cmd/crypto/error.go b/cmd/crypto/error.go index d3a3a2c6a..dcbe6d579 100644 --- a/cmd/crypto/error.go +++ b/cmd/crypto/error.go @@ -19,9 +19,9 @@ import "errors" // Error is the generic type for any error happening during decrypting // an object. It indicates that the object itself or its metadata was // modified accidentally or maliciously. -type Error struct{ msg string } +type Error string -func (e Error) Error() string { return e.msg } +func (e Error) Error() string { return string(e) } var ( // ErrInvalidEncryptionMethod indicates that the specified SSE encryption method @@ -56,14 +56,14 @@ var ( ErrIncompatibleEncryptionMethod = errors.New("Server side encryption specified with both SSE-C and SSE-S3 headers") ) -var ( - errMissingInternalIV = Error{"The object metadata is missing the internal encryption IV"} - errMissingInternalSealAlgorithm = Error{"The object metadata is missing the internal seal algorithm"} +const ( + errMissingInternalIV Error = "The object metadata is missing the internal encryption IV" + errMissingInternalSealAlgorithm Error = "The object metadata is missing the internal seal algorithm" - errInvalidInternalIV = Error{"The internal encryption IV is malformed"} - errInvalidInternalSealAlgorithm = Error{"The internal seal algorithm is invalid and not supported"} + errInvalidInternalIV Error = "The internal encryption IV is malformed" + errInvalidInternalSealAlgorithm Error = "The internal seal algorithm is invalid and not supported" - errMissingUpdatedKey = Error{"The key update returned no error but also no sealed key"} + errMissingUpdatedKey Error = "The key update returned no error but also no sealed key" ) var ( diff --git a/cmd/crypto/key.go b/cmd/crypto/key.go index b955a9a88..84a01d5b4 100644 --- a/cmd/crypto/key.go +++ b/cmd/crypto/key.go @@ -108,7 +108,7 @@ func (key *ObjectKey) Unseal(extKey [32]byte, sealedKey SealedKey, domain, bucke ) switch sealedKey.Algorithm { default: - return Error{fmt.Sprintf("The sealing algorithm '%s' is not supported", sealedKey.Algorithm)} + return Error(fmt.Sprintf("The sealing algorithm '%s' is not supported", sealedKey.Algorithm)) case SealAlgorithm: mac := hmac.New(sha256.New, extKey[:]) mac.Write(sealedKey.IV[:]) diff --git a/cmd/crypto/metadata.go b/cmd/crypto/metadata.go index 9da9b6774..5942019df 100644 --- a/cmd/crypto/metadata.go +++ b/cmd/crypto/metadata.go @@ -172,7 +172,7 @@ func (s3) ParseMetadata(metadata map[string]string) (keyID string, kmsKey []byte } b64SealedKey, ok := metadata[S3SealedKey] if !ok { - return keyID, kmsKey, sealedKey, Error{"The object metadata is missing the internal sealed key for SSE-S3"} + return keyID, kmsKey, sealedKey, Error("The object metadata is missing the internal sealed key for SSE-S3") } // There are two possibilites: @@ -182,10 +182,10 @@ func (s3) ParseMetadata(metadata map[string]string) (keyID string, kmsKey []byte keyID, idPresent := metadata[S3KMSKeyID] b64KMSSealedKey, kmsKeyPresent := metadata[S3KMSSealedKey] if !idPresent && kmsKeyPresent { - return keyID, kmsKey, sealedKey, Error{"The object metadata is missing the internal KMS key-ID for SSE-S3"} + return keyID, kmsKey, sealedKey, Error("The object metadata is missing the internal KMS key-ID for SSE-S3") } if idPresent && !kmsKeyPresent { - return keyID, kmsKey, sealedKey, Error{"The object metadata is missing the internal sealed KMS data key for SSE-S3"} + return keyID, kmsKey, sealedKey, Error("The object metadata is missing the internal sealed KMS data key for SSE-S3") } // Check whether all extracted values are well-formed @@ -198,12 +198,12 @@ func (s3) ParseMetadata(metadata map[string]string) (keyID string, kmsKey []byte } encryptedKey, err := base64.StdEncoding.DecodeString(b64SealedKey) if err != nil || len(encryptedKey) != 64 { - return keyID, kmsKey, sealedKey, Error{"The internal sealed key for SSE-S3 is invalid"} + return keyID, kmsKey, sealedKey, Error("The internal sealed key for SSE-S3 is invalid") } if idPresent && kmsKeyPresent { // We are using a KMS -> parse the sealed KMS data key. kmsKey, err = base64.StdEncoding.DecodeString(b64KMSSealedKey) if err != nil { - return keyID, kmsKey, sealedKey, Error{"The internal sealed KMS data key for SSE-S3 is invalid"} + return keyID, kmsKey, sealedKey, Error("The internal sealed KMS data key for SSE-S3 is invalid") } } @@ -244,7 +244,7 @@ func (ssec) ParseMetadata(metadata map[string]string) (sealedKey SealedKey, err } b64SealedKey, ok := metadata[SSECSealedKey] if !ok { - return sealedKey, Error{"The object metadata is missing the internal sealed key for SSE-C"} + return sealedKey, Error("The object metadata is missing the internal sealed key for SSE-C") } // Check whether all extracted values are well-formed @@ -257,7 +257,7 @@ func (ssec) ParseMetadata(metadata map[string]string) (sealedKey SealedKey, err } encryptedKey, err := base64.StdEncoding.DecodeString(b64SealedKey) if err != nil || len(encryptedKey) != 64 { - return sealedKey, Error{"The internal sealed key for SSE-C is invalid"} + return sealedKey, Error("The internal sealed key for SSE-C is invalid") } sealedKey.Algorithm = algorithm diff --git a/cmd/crypto/metadata_test.go b/cmd/crypto/metadata_test.go index 7141f17c6..4c3731baa 100644 --- a/cmd/crypto/metadata_test.go +++ b/cmd/crypto/metadata_test.go @@ -125,15 +125,15 @@ var s3ParseMetadataTests = []struct { DataKey: []byte{}, KeyID: "", SealedKey: SealedKey{}, }, // 1 { - ExpectedErr: Error{"The object metadata is missing the internal sealed key for SSE-S3"}, + ExpectedErr: Error("The object metadata is missing the internal sealed key for SSE-S3"), Metadata: map[string]string{SSEIV: "", SSESealAlgorithm: ""}, DataKey: []byte{}, KeyID: "", SealedKey: SealedKey{}, }, // 2 { - ExpectedErr: Error{"The object metadata is missing the internal KMS key-ID for SSE-S3"}, + ExpectedErr: Error("The object metadata is missing the internal KMS key-ID for SSE-S3"), Metadata: map[string]string{SSEIV: "", SSESealAlgorithm: "", S3SealedKey: "", S3KMSSealedKey: "IAAF0b=="}, DataKey: []byte{}, KeyID: "", SealedKey: SealedKey{}, }, // 3 { - ExpectedErr: Error{"The object metadata is missing the internal sealed KMS data key for SSE-S3"}, + ExpectedErr: Error("The object metadata is missing the internal sealed KMS data key for SSE-S3"), Metadata: map[string]string{SSEIV: "", SSESealAlgorithm: "", S3SealedKey: "", S3KMSKeyID: ""}, DataKey: []byte{}, KeyID: "", SealedKey: SealedKey{}, }, // 4 @@ -150,7 +150,7 @@ var s3ParseMetadataTests = []struct { DataKey: []byte{}, KeyID: "", SealedKey: SealedKey{}, }, // 6 { - ExpectedErr: Error{"The internal sealed key for SSE-S3 is invalid"}, + ExpectedErr: Error("The internal sealed key for SSE-S3 is invalid"), Metadata: map[string]string{ SSEIV: base64.StdEncoding.EncodeToString(make([]byte, 32)), SSESealAlgorithm: SealAlgorithm, S3SealedKey: "", S3KMSKeyID: "", S3KMSSealedKey: "", @@ -158,7 +158,7 @@ var s3ParseMetadataTests = []struct { DataKey: []byte{}, KeyID: "", SealedKey: SealedKey{}, }, // 7 { - ExpectedErr: Error{"The internal sealed KMS data key for SSE-S3 is invalid"}, + ExpectedErr: Error("The internal sealed KMS data key for SSE-S3 is invalid"), Metadata: map[string]string{ SSEIV: base64.StdEncoding.EncodeToString(make([]byte, 32)), SSESealAlgorithm: SealAlgorithm, S3SealedKey: base64.StdEncoding.EncodeToString(make([]byte, 64)), S3KMSKeyID: "key-1", @@ -218,7 +218,7 @@ var ssecParseMetadataTests = []struct { {ExpectedErr: errMissingInternalIV, Metadata: map[string]string{}, SealedKey: SealedKey{}}, // 0 {ExpectedErr: errMissingInternalSealAlgorithm, Metadata: map[string]string{SSEIV: ""}, SealedKey: SealedKey{}}, // 1 { - ExpectedErr: Error{"The object metadata is missing the internal sealed key for SSE-C"}, + ExpectedErr: Error("The object metadata is missing the internal sealed key for SSE-C"), Metadata: map[string]string{SSEIV: "", SSESealAlgorithm: ""}, SealedKey: SealedKey{}, }, // 2 { @@ -233,7 +233,7 @@ var ssecParseMetadataTests = []struct { SealedKey: SealedKey{}, }, // 4 { - ExpectedErr: Error{"The internal sealed key for SSE-C is invalid"}, + ExpectedErr: Error("The internal sealed key for SSE-C is invalid"), Metadata: map[string]string{ SSEIV: base64.StdEncoding.EncodeToString(make([]byte, 32)), SSESealAlgorithm: SealAlgorithm, SSECSealedKey: "", },