Add crypto context errors (#8740)

Currently when connections to vault fail, client
perpetually retries this leads to assumptions that
the server has issues and masks the problem.

Re-purpose *crypto.Error* type to send appropriate
errors back to the client.
master
Harshavardhana 5 years ago committed by kannappanr
parent 796cca4166
commit 933c60bc3a
  1. 2
      Dockerfile
  2. 2
      Dockerfile.dev
  3. 2
      Dockerfile.release
  4. 4
      cmd/api-errors.go
  5. 3
      cmd/crypto/config.go
  6. 55
      cmd/crypto/error.go
  7. 19
      cmd/crypto/kes.go
  8. 3
      cmd/crypto/key.go
  9. 3
      cmd/crypto/legacy.go
  10. 19
      cmd/crypto/metadata.go
  11. 14
      cmd/crypto/metadata_test.go
  12. 7
      cmd/crypto/parse.go
  13. 53
      cmd/crypto/vault.go
  14. 9
      cmd/web-handlers.go
  15. 21
      pkg/iam/policy/error.go
  16. 2
      pkg/iam/policy/policy.go
  17. 19
      pkg/policy/error.go
  18. 2
      pkg/policy/policy.go

@ -12,7 +12,7 @@ RUN \
git clone https://github.com/minio/minio && cd minio && \
go install -v -ldflags "$(go run buildscripts/gen-ldflags.go)"
FROM alpine:3.9
FROM alpine:3.10
ENV MINIO_UPDATE off
ENV MINIO_ACCESS_KEY_FILE=access_key \

@ -1,4 +1,4 @@
FROM alpine:3.9
FROM alpine:3.10
LABEL maintainer="MinIO Inc <dev@min.io>"

@ -8,7 +8,7 @@ RUN \
apk add --no-cache git && \
git clone https://github.com/minio/minio
FROM alpine:3.9
FROM alpine:3.10
LABEL maintainer="MinIO Inc <dev@min.io>"

@ -1727,8 +1727,6 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
apiErr = ErrUnsupportedNotification
case BackendDown:
apiErr = ErrBackendDown
case crypto.Error:
apiErr = ErrObjectTampered
case ObjectNameTooLong:
apiErr = ErrKeyTooLongError
default:
@ -1781,7 +1779,7 @@ func toAPIError(ctx context.Context, err error) APIError {
}
case crypto.Error:
apiErr = APIError{
Code: "XKMSInternalError",
Code: "XMinIOEncryptionError",
Description: e.Error(),
HTTPStatusCode: http.StatusBadRequest,
}

@ -16,7 +16,6 @@ package crypto
import (
"errors"
"fmt"
"net/http"
"reflect"
"strconv"
@ -342,7 +341,7 @@ func LookupVaultConfig(kvs config.KVS) (VaultConfig, error) {
if keyVersion := env.Get(EnvKMSVaultKeyVersion, kvs.Get(KMSVaultKeyVersion)); keyVersion != "" {
vcfg.Key.Version, err = strconv.Atoi(keyVersion)
if err != nil {
return vcfg, fmt.Errorf("Unable to parse VaultKeyVersion value (`%s`)", keyVersion)
return vcfg, Errorf("Unable to parse VaultKeyVersion value (`%s`)", keyVersion)
}
}

@ -14,60 +14,79 @@
package crypto
import "errors"
import (
"fmt"
)
// 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 string
type Error struct {
err error
}
// Errorf - formats according to a format specifier and returns
// the string as a value that satisfies error of type crypto.Error
func Errorf(format string, a ...interface{}) error {
return Error{err: fmt.Errorf(format, a...)}
}
func (e Error) Error() string { return string(e) }
// Unwrap the internal error.
func (e Error) Unwrap() error { return e.err }
// Error 'error' compatible method.
func (e Error) Error() string {
if e.err == nil {
return "crypto: cause <nil>"
}
return e.err.Error()
}
var (
// ErrInvalidEncryptionMethod indicates that the specified SSE encryption method
// is not supported.
ErrInvalidEncryptionMethod = errors.New("The encryption method is not supported")
ErrInvalidEncryptionMethod = Errorf("The encryption method is not supported")
// ErrInvalidCustomerAlgorithm indicates that the specified SSE-C algorithm
// is not supported.
ErrInvalidCustomerAlgorithm = errors.New("The SSE-C algorithm is not supported")
ErrInvalidCustomerAlgorithm = Errorf("The SSE-C algorithm is not supported")
// ErrMissingCustomerKey indicates that the HTTP headers contains no SSE-C client key.
ErrMissingCustomerKey = errors.New("The SSE-C request is missing the customer key")
ErrMissingCustomerKey = Errorf("The SSE-C request is missing the customer key")
// ErrMissingCustomerKeyMD5 indicates that the HTTP headers contains no SSE-C client key
// MD5 checksum.
ErrMissingCustomerKeyMD5 = errors.New("The SSE-C request is missing the customer key MD5")
ErrMissingCustomerKeyMD5 = Errorf("The SSE-C request is missing the customer key MD5")
// ErrInvalidCustomerKey indicates that the SSE-C client key is not valid - e.g. not a
// base64-encoded string or not 256 bits long.
ErrInvalidCustomerKey = errors.New("The SSE-C client key is invalid")
ErrInvalidCustomerKey = Errorf("The SSE-C client key is invalid")
// ErrSecretKeyMismatch indicates that the provided secret key (SSE-C client key / SSE-S3 KMS key)
// does not match the secret key used during encrypting the object.
ErrSecretKeyMismatch = errors.New("The secret key does not match the secret key used during upload")
ErrSecretKeyMismatch = Errorf("The secret key does not match the secret key used during upload")
// ErrCustomerKeyMD5Mismatch indicates that the SSE-C key MD5 does not match the
// computed MD5 sum. This means that the client provided either the wrong key for
// a certain MD5 checksum or the wrong MD5 for a certain key.
ErrCustomerKeyMD5Mismatch = errors.New("The provided SSE-C key MD5 does not match the computed MD5 of the SSE-C key")
ErrCustomerKeyMD5Mismatch = Errorf("The provided SSE-C key MD5 does not match the computed MD5 of the SSE-C key")
// ErrIncompatibleEncryptionMethod indicates that both SSE-C headers and SSE-S3 headers were specified, and are incompatible
// The client needs to remove the SSE-S3 header or the SSE-C headers
ErrIncompatibleEncryptionMethod = errors.New("Server side encryption specified with both SSE-C and SSE-S3 headers")
ErrIncompatibleEncryptionMethod = Errorf("Server side encryption specified with both SSE-C and SSE-S3 headers")
)
const (
errMissingInternalIV Error = "The object metadata is missing the internal encryption IV"
errMissingInternalSealAlgorithm Error = "The object metadata is missing the internal seal algorithm"
var (
errMissingInternalIV = Errorf("The object metadata is missing the internal encryption IV")
errMissingInternalSealAlgorithm = Errorf("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 = Errorf("The internal encryption IV is malformed")
errInvalidInternalSealAlgorithm = Errorf("The internal seal algorithm is invalid and not supported")
errMissingUpdatedKey Error = "The key update returned no error but also no sealed key"
errMissingUpdatedKey = Errorf("The key update returned no error but also no sealed key")
)
var (
// errOutOfEntropy indicates that the a source of randomness (PRNG) wasn't able
// to produce enough random data. This is fatal error and should cause a panic.
errOutOfEntropy = errors.New("Unable to read enough randomness from the system")
errOutOfEntropy = Errorf("Unable to read enough randomness from the system")
)

@ -19,7 +19,6 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
@ -76,13 +75,13 @@ type KesConfig struct {
func (k KesConfig) Verify() (err error) {
switch {
case k.Endpoint == "":
err = errors.New("crypto: missing kes endpoint")
err = Errorf("crypto: missing kes endpoint")
case k.CertFile == "":
err = errors.New("crypto: missing cert file")
err = Errorf("crypto: missing cert file")
case k.KeyFile == "":
err = errors.New("crypto: missing key file")
err = Errorf("crypto: missing key file")
case k.DefaultKeyID == "":
err = errors.New("crypto: missing default key id")
err = Errorf("crypto: missing default key id")
}
return err
}
@ -153,7 +152,7 @@ func (kes *kesService) GenerateKey(keyID string, ctx Context) (key [32]byte, sea
return key, nil, err
}
if len(plainKey) != len(key) {
return key, nil, errors.New("crypto: received invalid plaintext key size from KMS")
return key, nil, Errorf("crypto: received invalid plaintext key size from KMS")
}
copy(key[:], plainKey)
return key, sealedKey, nil
@ -176,7 +175,7 @@ func (kes *kesService) UnsealKey(keyID string, sealedKey []byte, ctx Context) (k
return key, err
}
if len(plainKey) != len(key) {
return key, errors.New("crypto: received invalid plaintext key size from KMS")
return key, Errorf("crypto: received invalid plaintext key size from KMS")
}
copy(key[:], plainKey)
return key, nil
@ -301,7 +300,7 @@ func (c *kesClient) parseErrorResponse(resp *http.Response) error {
if _, err := io.Copy(&errMsg, io.LimitReader(resp.Body, limit)); err != nil {
return err
}
return fmt.Errorf("%s: %s", http.StatusText(resp.StatusCode), errMsg.String())
return Errorf("%s: %s", http.StatusText(resp.StatusCode), errMsg.String())
}
// loadCACertificates returns a new CertPool
@ -334,7 +333,7 @@ func loadCACertificates(path string) (*x509.CertPool, error) {
if os.IsNotExist(err) || os.IsPermission(err) {
return rootCAs, nil
}
return nil, fmt.Errorf("crypto: cannot open '%s': %v", path, err)
return nil, Errorf("crypto: cannot open '%s': %v", path, err)
}
// If path is a file, parse as PEM-encoded certifcate
@ -346,7 +345,7 @@ func loadCACertificates(path string) (*x509.CertPool, error) {
return nil, err
}
if !rootCAs.AppendCertsFromPEM(cert) {
return nil, fmt.Errorf("crypto: '%s' is not a valid PEM-encoded certificate", path)
return nil, Errorf("crypto: '%s' is not a valid PEM-encoded certificate", path)
}
return rootCAs, nil
}

@ -21,7 +21,6 @@ import (
"crypto/rand"
"encoding/binary"
"errors"
"fmt"
"io"
"path"
@ -108,7 +107,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 Errorf("The sealing algorithm '%s' is not supported", sealedKey.Algorithm)
case SealAlgorithm:
mac := hmac.New(sha256.New, extKey[:])
mac.Write(sealedKey.IV[:])

@ -17,7 +17,6 @@
package crypto
import (
"fmt"
"reflect"
"strconv"
@ -167,7 +166,7 @@ func lookupConfigLegacy(kvs config.KVS) (VaultConfig, error) {
if keyVersion := env.Get(EnvLegacyVaultKeyVersion, ""); keyVersion != "" {
vcfg.Key.Version, err = strconv.Atoi(keyVersion)
if err != nil {
return vcfg, fmt.Errorf("Invalid ENV variable: Unable to parse %s value (`%s`)",
return vcfg, Errorf("Invalid ENV variable: Unable to parse %s value (`%s`)",
EnvLegacyVaultKeyVersion, keyVersion)
}
}

@ -18,7 +18,6 @@ import (
"context"
"encoding/base64"
"errors"
"fmt"
"github.com/minio/minio/cmd/logger"
)
@ -126,7 +125,7 @@ func CreateMultipartMetadata(metadata map[string]string) map[string]string {
// is nil.
func (s3) CreateMetadata(metadata map[string]string, keyID string, kmsKey []byte, sealedKey SealedKey) map[string]string {
if sealedKey.Algorithm != SealAlgorithm {
logger.CriticalIf(context.Background(), fmt.Errorf("The seal algorithm '%s' is invalid for SSE-S3", sealedKey.Algorithm))
logger.CriticalIf(context.Background(), Errorf("The seal algorithm '%s' is invalid for SSE-S3", sealedKey.Algorithm))
}
// There are two possibilites:
@ -172,7 +171,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, Errorf("The object metadata is missing the internal sealed key for SSE-S3")
}
// There are two possibilites:
@ -182,10 +181,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, Errorf("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, Errorf("The object metadata is missing the internal sealed KMS data key for SSE-S3")
}
// Check whether all extracted values are well-formed
@ -198,12 +197,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, Errorf("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, Errorf("The internal sealed KMS data key for SSE-S3 is invalid")
}
}
@ -217,7 +216,7 @@ func (s3) ParseMetadata(metadata map[string]string) (keyID string, kmsKey []byte
// It allocates a new metadata map if metadata is nil.
func (ssec) CreateMetadata(metadata map[string]string, sealedKey SealedKey) map[string]string {
if sealedKey.Algorithm != SealAlgorithm {
logger.CriticalIf(context.Background(), fmt.Errorf("The seal algorithm '%s' is invalid for SSE-C", sealedKey.Algorithm))
logger.CriticalIf(context.Background(), Errorf("The seal algorithm '%s' is invalid for SSE-C", sealedKey.Algorithm))
}
if metadata == nil {
@ -244,7 +243,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, Errorf("The object metadata is missing the internal sealed key for SSE-C")
}
// Check whether all extracted values are well-formed
@ -257,7 +256,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, Errorf("The internal sealed key for SSE-C is invalid")
}
sealedKey.Algorithm = algorithm

@ -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: Errorf("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: Errorf("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: Errorf("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: Errorf("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: Errorf("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: Errorf("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: Errorf("The internal sealed key for SSE-C is invalid"),
Metadata: map[string]string{
SSEIV: base64.StdEncoding.EncodeToString(make([]byte, 32)), SSESealAlgorithm: SealAlgorithm, SSECSealedKey: "",
},

@ -16,7 +16,6 @@ package crypto
import (
"encoding/hex"
"fmt"
"strings"
)
@ -25,18 +24,18 @@ import (
func ParseMasterKey(envArg string) (KMS, error) {
values := strings.SplitN(envArg, ":", 2)
if len(values) != 2 {
return nil, fmt.Errorf("Invalid KMS master key: %s does not contain a ':'", envArg)
return nil, Errorf("Invalid KMS master key: %s does not contain a ':'", envArg)
}
var (
keyID = values[0]
hexKey = values[1]
)
if len(hexKey) != 64 { // 2 hex bytes = 1 byte
return nil, fmt.Errorf("Invalid KMS master key: %s not a 32 bytes long HEX value", hexKey)
return nil, Errorf("Invalid KMS master key: %s not a 32 bytes long HEX value", hexKey)
}
var masterKey [32]byte
if _, err := hex.Decode(masterKey[:], []byte(hexKey)); err != nil {
return nil, err
return nil, Errorf("Invalid KMS master key: %v", err)
}
return NewMasterKey(keyID, masterKey), nil
}

@ -17,7 +17,6 @@ package crypto
import (
"bytes"
"encoding/base64"
"errors"
"fmt"
"strings"
"time"
@ -27,7 +26,7 @@ import (
var (
//ErrKMSAuthLogin is raised when there is a failure authenticating to KMS
ErrKMSAuthLogin = errors.New("Vault service did not return auth info")
ErrKMSAuthLogin = Errorf("Vault service did not return auth info")
)
// VaultKey represents vault encryption key-ring.
@ -75,17 +74,17 @@ var _ KMS = (*vaultService)(nil) // compiler check that *vaultService implements
func (v *VaultConfig) Verify() (err error) {
switch {
case v.Endpoint == "":
err = errors.New("crypto: missing hashicorp vault endpoint")
err = Errorf("crypto: missing hashicorp vault endpoint")
case strings.ToLower(v.Auth.Type) != "approle":
err = fmt.Errorf("crypto: invalid hashicorp vault authentication type: %s is not supported", v.Auth.Type)
err = Errorf("crypto: invalid hashicorp vault authentication type: %s is not supported", v.Auth.Type)
case v.Auth.AppRole.ID == "":
err = errors.New("crypto: missing hashicorp vault AppRole ID")
err = Errorf("crypto: missing hashicorp vault AppRole ID")
case v.Auth.AppRole.Secret == "":
err = errors.New("crypto: missing hashicorp vault AppSecret ID")
err = Errorf("crypto: missing hashicorp vault AppSecret ID")
case v.Key.Name == "":
err = errors.New("crypto: missing hashicorp vault key name")
err = Errorf("crypto: missing hashicorp vault key name")
case v.Key.Version < 0:
err = errors.New("crypto: invalid hashicorp vault key version: The key version must not be negative")
err = Errorf("crypto: invalid hashicorp vault key version: The key version must not be negative")
}
return
}
@ -107,7 +106,7 @@ func NewVault(config VaultConfig) (KMS, error) {
}
client, err := vault.NewClient(&vaultCfg)
if err != nil {
return nil, err
return nil, Errorf("crypto: client error %w", err)
}
if config.Namespace != "" {
client.SetNamespace(config.Namespace)
@ -167,6 +166,7 @@ func (v *vaultService) authenticate() (err error) {
var secret *vault.Secret
secret, err = v.client.Logical().Write("auth/approle/login", payload)
if err != nil {
err = Errorf("crypto: client error %w", err)
return
}
if secret == nil {
@ -217,14 +217,23 @@ func (v *vaultService) GenerateKey(keyID string, ctx Context) (key [32]byte, sea
}
s, err := v.client.Logical().Write(fmt.Sprintf("/transit/datakey/plaintext/%s", keyID), payload)
if err != nil {
return key, sealedKey, err
return key, sealedKey, Errorf("crypto: client error %w", err)
}
sealKey, ok := s.Data["ciphertext"].(string)
if !ok {
return key, sealedKey, Errorf("crypto: incorrect 'ciphertext' key type %v", s.Data["ciphertext"])
}
sealKey := s.Data["ciphertext"].(string)
plainKey, err := base64.StdEncoding.DecodeString(s.Data["plaintext"].(string))
plainKeyB64, ok := s.Data["plaintext"].(string)
if !ok {
return key, sealedKey, Errorf("crypto: incorrect 'plaintext' key type %v", s.Data["plaintext"])
}
plainKey, err := base64.StdEncoding.DecodeString(plainKeyB64)
if err != nil {
return key, sealedKey, err
return key, sealedKey, Errorf("crypto: invalid base64 key %w", err)
}
copy(key[:], []byte(plainKey))
copy(key[:], plainKey)
return key, []byte(sealKey), nil
}
@ -243,16 +252,22 @@ func (v *vaultService) UnsealKey(keyID string, sealedKey []byte, ctx Context) (k
"ciphertext": string(sealedKey),
"context": base64.StdEncoding.EncodeToString(contextStream.Bytes()),
}
s, err := v.client.Logical().Write(fmt.Sprintf("/transit/decrypt/%s", keyID), payload)
if err != nil {
return key, err
return key, Errorf("crypto: client error %w", err)
}
base64Key, ok := s.Data["plaintext"].(string)
if !ok {
return key, Errorf("crypto: incorrect 'plaintext' key type %v", s.Data["plaintext"])
}
base64Key := s.Data["plaintext"].(string)
plainKey, err := base64.StdEncoding.DecodeString(base64Key)
if err != nil {
return key, err
return key, Errorf("crypto: invalid base64 key %w", err)
}
copy(key[:], []byte(plainKey))
copy(key[:], plainKey)
return key, nil
}
@ -273,7 +288,7 @@ func (v *vaultService) UpdateKey(keyID string, sealedKey []byte, ctx Context) (r
}
s, err := v.client.Logical().Write(fmt.Sprintf("/transit/rewrap/%s", keyID), payload)
if err != nil {
return nil, err
return nil, Errorf("crypto: client error %w", err)
}
ciphertext, ok := s.Data["ciphertext"]
if !ok {

@ -2026,13 +2026,20 @@ func toJSONError(ctx context.Context, err error, params ...string) (jerr *json2.
// toWebAPIError - convert into error into APIError.
func toWebAPIError(ctx context.Context, err error) APIError {
switch err {
case errNoAuthToken:
return APIError{
Code: "WebTokenMissing",
HTTPStatusCode: http.StatusBadRequest,
Description: err.Error(),
}
case errServerNotInitialized:
return APIError{
Code: "XMinioServerNotInitialized",
HTTPStatusCode: http.StatusServiceUnavailable,
Description: err.Error(),
}
case errAuthentication, auth.ErrInvalidAccessKeyLength, auth.ErrInvalidSecretKeyLength, errInvalidAccessKeyID:
case errAuthentication, auth.ErrInvalidAccessKeyLength,
auth.ErrInvalidSecretKeyLength, errInvalidAccessKeyID:
return APIError{
Code: "AccessDenied",
HTTPStatusCode: http.StatusForbidden,

@ -18,22 +18,25 @@ package iampolicy
import "fmt"
// Error generic iam policy error type
// Error is the generic type for any error happening during policy
// parsing.
type Error struct {
Err string
err error
}
// Errorf - formats according to a format specifier and returns
// the string as a value that satisfies error of type iampolicy.Error
// the string as a value that satisfies error of type policy.Error
func Errorf(format string, a ...interface{}) error {
return Error{Err: fmt.Sprintf(format, a...)}
return Error{err: fmt.Errorf(format, a...)}
}
// New initializes a new Error
func New(err string) error {
return Error{Err: err}
}
// Unwrap the internal error.
func (e Error) Unwrap() error { return e.err }
// Error 'error' compatible method.
func (e Error) Error() string {
return e.Err
if e.err == nil {
return "iam: cause <nil>"
}
return e.err.Error()
}

@ -165,7 +165,7 @@ func ParseConfig(reader io.Reader) (*Policy, error) {
decoder := json.NewDecoder(reader)
decoder.DisallowUnknownFields()
if err := decoder.Decode(&iamp); err != nil {
return nil, err
return nil, Errorf("%w", err)
}
return &iamp, iamp.Validate()

@ -18,22 +18,25 @@ package policy
import "fmt"
// Error generic policy parse error type
// Error is the generic type for any error happening during policy
// parsing.
type Error struct {
Err string
err error
}
// Errorf - formats according to a format specifier and returns
// the string as a value that satisfies error of type policy.Error
func Errorf(format string, a ...interface{}) error {
return Error{Err: fmt.Sprintf(format, a...)}
return Error{err: fmt.Errorf(format, a...)}
}
// New initializes a new Error
func New(err string) error {
return Error{Err: err}
}
// Unwrap the internal error.
func (e Error) Unwrap() error { return e.err }
// Error 'error' compatible method.
func (e Error) Error() string {
return e.Err
if e.err == nil {
return "policy: cause <nil>"
}
return e.err.Error()
}

@ -167,7 +167,7 @@ func ParseConfig(reader io.Reader, bucketName string) (*Policy, error) {
decoder := json.NewDecoder(reader)
decoder.DisallowUnknownFields()
if err := decoder.Decode(&policy); err != nil {
return nil, err
return nil, Errorf("%w", err)
}
err := policy.Validate(bucketName)

Loading…
Cancel
Save