kms: add context.Context to KMS API calls (#15327)

This commit adds a `context.Context` to the
the KMS `{Stat, CreateKey, GenerateKey}` API
calls.

The context will be used to terminate external calls
as soon as the client requests gets canceled.

A follow-up PR will add a `context.Context` to
the remaining `DecryptKey` API call.

Signed-off-by: Andreas Auernhammer <hi@aead.dev>
This commit is contained in:
Andreas Auernhammer 2022-07-19 03:54:27 +02:00 committed by GitHub
parent 957e3ed729
commit 242d06274a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 64 additions and 65 deletions

View File

@ -953,7 +953,7 @@ func (a adminAPIHandlers) ImportBucketMetadataHandler(w http.ResponseWriter, r *
kmsKey := encConfig.KeyID() kmsKey := encConfig.KeyID()
if kmsKey != "" { if kmsKey != "" {
kmsContext := kms.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation kmsContext := kms.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation
_, err := GlobalKMS.GenerateKey(kmsKey, kmsContext) _, err := GlobalKMS.GenerateKey(ctx, kmsKey, kmsContext)
if err != nil { if err != nil {
if errors.Is(err, kes.ErrKeyNotFound) { if errors.Is(err, kes.ErrKeyNotFound) {
writeErrorResponse(ctx, w, importError(ctx, errKMSKeyNotFound, file.Name, bucket), r.URL) writeErrorResponse(ctx, w, importError(ctx, errKMSKeyNotFound, file.Name, bucket), r.URL)

View File

@ -1615,7 +1615,7 @@ func (a adminAPIHandlers) KMSCreateKeyHandler(w http.ResponseWriter, r *http.Req
return return
} }
if err := GlobalKMS.CreateKey(r.Form.Get("key-id")); err != nil { if err := GlobalKMS.CreateKey(ctx, r.Form.Get("key-id")); err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return return
} }
@ -1637,7 +1637,7 @@ func (a adminAPIHandlers) KMSStatusHandler(w http.ResponseWriter, r *http.Reques
return return
} }
stat, err := GlobalKMS.Stat() stat, err := GlobalKMS.Stat(ctx)
if err != nil { if err != nil {
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL)
return return
@ -1676,7 +1676,7 @@ func (a adminAPIHandlers) KMSKeyStatusHandler(w http.ResponseWriter, r *http.Req
return return
} }
stat, err := GlobalKMS.Stat() stat, err := GlobalKMS.Stat(ctx)
if err != nil { if err != nil {
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL) writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInternalError), err.Error(), r.URL)
return return
@ -1692,7 +1692,7 @@ func (a adminAPIHandlers) KMSKeyStatusHandler(w http.ResponseWriter, r *http.Req
kmsContext := kms.Context{"MinIO admin API": "KMSKeyStatusHandler"} // Context for a test key operation kmsContext := kms.Context{"MinIO admin API": "KMSKeyStatusHandler"} // Context for a test key operation
// 1. Generate a new key using the KMS. // 1. Generate a new key using the KMS.
key, err := GlobalKMS.GenerateKey(keyID, kmsContext) key, err := GlobalKMS.GenerateKey(ctx, keyID, kmsContext)
if err != nil { if err != nil {
response.EncryptionErr = err.Error() response.EncryptionErr = err.Error()
resp, err := json.Marshal(response) resp, err := json.Marshal(response)
@ -2542,7 +2542,7 @@ func fetchKMSStatus() madmin.KMS {
return kmsStat return kmsStat
} }
stat, err := GlobalKMS.Stat() stat, err := GlobalKMS.Stat(context.Background())
if err != nil { if err != nil {
kmsStat.Status = string(madmin.ItemOffline) kmsStat.Status = string(madmin.ItemOffline)
return kmsStat return kmsStat
@ -2555,7 +2555,7 @@ func fetchKMSStatus() madmin.KMS {
kmsContext := kms.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation kmsContext := kms.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation
// 1. Generate a new key using the KMS. // 1. Generate a new key using the KMS.
key, err := GlobalKMS.GenerateKey("", kmsContext) key, err := GlobalKMS.GenerateKey(context.Background(), "", kmsContext)
if err != nil { if err != nil {
kmsStat.Encrypt = fmt.Sprintf("Encryption failed: %v", err) kmsStat.Encrypt = fmt.Sprintf("Encryption failed: %v", err)
} else { } else {

View File

@ -90,7 +90,7 @@ func (api objectAPIHandlers) PutBucketEncryptionHandler(w http.ResponseWriter, r
kmsKey := encConfig.KeyID() kmsKey := encConfig.KeyID()
if kmsKey != "" { if kmsKey != "" {
kmsContext := kms.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation kmsContext := kms.Context{"MinIO admin API": "ServerInfoHandler"} // Context for a test key operation
_, err := GlobalKMS.GenerateKey(kmsKey, kmsContext) _, err := GlobalKMS.GenerateKey(ctx, kmsKey, kmsContext)
if err != nil { if err != nil {
if errors.Is(err, kes.ErrKeyNotFound) { if errors.Is(err, kes.ErrKeyNotFound) {
writeErrorResponse(ctx, w, toAPIError(ctx, errKMSKeyNotFound), r.URL) writeErrorResponse(ctx, w, toAPIError(ctx, errKMSKeyNotFound), r.URL)

View File

@ -1067,7 +1067,7 @@ func (api objectAPIHandlers) PostPolicyBucketHandler(w http.ResponseWriter, r *h
return return
} }
} }
reader, objectEncryptionKey, err = newEncryptReader(hashReader, kind, keyID, key, bucket, object, metadata, kmsCtx) reader, objectEncryptionKey, err = newEncryptReader(ctx, hashReader, kind, keyID, key, bucket, object, metadata, kmsCtx)
if err != nil { if err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL) writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
return return

View File

@ -136,7 +136,7 @@ func (sys *BucketMetadataSys) Update(ctx context.Context, bucket string, configF
meta.ReplicationConfigXML = configData meta.ReplicationConfigXML = configData
meta.ReplicationConfigUpdatedAt = updatedAt meta.ReplicationConfigUpdatedAt = updatedAt
case bucketTargetsFile: case bucketTargetsFile:
meta.BucketTargetsConfigJSON, meta.BucketTargetsConfigMetaJSON, err = encryptBucketMetadata(meta.Name, configData, kms.Context{ meta.BucketTargetsConfigJSON, meta.BucketTargetsConfigMetaJSON, err = encryptBucketMetadata(ctx, meta.Name, configData, kms.Context{
bucket: meta.Name, bucket: meta.Name,
bucketTargetsFile: bucketTargetsFile, bucketTargetsFile: bucketTargetsFile,
}) })

View File

@ -438,7 +438,7 @@ func (b *BucketMetadata) migrateTargetConfig(ctx context.Context, objectAPI Obje
return nil return nil
} }
encBytes, metaBytes, err := encryptBucketMetadata(b.Name, b.BucketTargetsConfigJSON, kms.Context{b.Name: b.Name, bucketTargetsFile: bucketTargetsFile}) encBytes, metaBytes, err := encryptBucketMetadata(ctx, b.Name, b.BucketTargetsConfigJSON, kms.Context{b.Name: b.Name, bucketTargetsFile: bucketTargetsFile})
if err != nil { if err != nil {
return err return err
} }
@ -449,14 +449,14 @@ func (b *BucketMetadata) migrateTargetConfig(ctx context.Context, objectAPI Obje
} }
// encrypt bucket metadata if kms is configured. // encrypt bucket metadata if kms is configured.
func encryptBucketMetadata(bucket string, input []byte, kmsContext kms.Context) (output, metabytes []byte, err error) { func encryptBucketMetadata(ctx context.Context, bucket string, input []byte, kmsContext kms.Context) (output, metabytes []byte, err error) {
if GlobalKMS == nil { if GlobalKMS == nil {
output = input output = input
return return
} }
metadata := make(map[string]string) metadata := make(map[string]string)
key, err := GlobalKMS.GenerateKey("", kmsContext) key, err := GlobalKMS.GenerateKey(ctx, "", kmsContext)
if err != nil { if err != nil {
return return
} }

View File

@ -868,7 +868,7 @@ func handleKMSConfig() {
// This implicitly checks that we can communicate to KES. We don't treat // This implicitly checks that we can communicate to KES. We don't treat
// a policy error as failure condition since MinIO may not have the permission // a policy error as failure condition since MinIO may not have the permission
// to create keys - just to generate/decrypt data encryption keys. // to create keys - just to generate/decrypt data encryption keys.
if err = KMS.CreateKey(defaultKeyID); err != nil && !errors.Is(err, kes.ErrKeyExists) && !errors.Is(err, kes.ErrNotAllowed) { if err = KMS.CreateKey(context.Background(), defaultKeyID); err != nil && !errors.Is(err, kes.ErrKeyExists) && !errors.Is(err, kes.ErrNotAllowed) {
logger.Fatal(err, "Unable to initialize a connection to KES as specified by the shell environment") logger.Fatal(err, "Unable to initialize a connection to KES as specified by the shell environment")
} }
GlobalKMS = KMS GlobalKMS = KMS

View File

@ -70,7 +70,7 @@ func migrateIAMConfigsEtcdToEncrypted(ctx context.Context, client *etcd.Client)
} }
if encrypted && GlobalKMS != nil { if encrypted && GlobalKMS != nil {
stat, err := GlobalKMS.Stat() stat, err := GlobalKMS.Stat(ctx)
if err != nil { if err != nil {
return err return err
} }
@ -139,7 +139,7 @@ func migrateConfigPrefixToEncrypted(objAPI ObjectLayer, encrypted bool) error {
return nil return nil
} }
if encrypted && GlobalKMS != nil { if encrypted && GlobalKMS != nil {
stat, err := GlobalKMS.Stat() stat, err := GlobalKMS.Stat(context.Background())
if err != nil { if err != nil {
return err return err
} }

View File

@ -797,8 +797,8 @@ func (c *diskCache) bitrotWriteToCache(cachePath, fileName string, reader io.Rea
return bytesWritten, base64.StdEncoding.EncodeToString(md5sumCurr), nil return bytesWritten, base64.StdEncoding.EncodeToString(md5sumCurr), nil
} }
func newCacheEncryptReader(content io.Reader, bucket, object string, metadata map[string]string) (r io.Reader, err error) { func newCacheEncryptReader(ctx context.Context, content io.Reader, bucket, object string, metadata map[string]string) (r io.Reader, err error) {
objectEncryptionKey, err := newCacheEncryptMetadata(bucket, object, metadata) objectEncryptionKey, err := newCacheEncryptMetadata(ctx, bucket, object, metadata)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -810,12 +810,12 @@ func newCacheEncryptReader(content io.Reader, bucket, object string, metadata ma
return reader, nil return reader, nil
} }
func newCacheEncryptMetadata(bucket, object string, metadata map[string]string) ([]byte, error) { func newCacheEncryptMetadata(ctx context.Context, bucket, object string, metadata map[string]string) ([]byte, error) {
var sealedKey crypto.SealedKey var sealedKey crypto.SealedKey
if globalCacheKMS == nil { if globalCacheKMS == nil {
return nil, errKMSNotConfigured return nil, errKMSNotConfigured
} }
key, err := globalCacheKMS.GenerateKey("", kms.Context{bucket: pathJoin(bucket, object)}) key, err := globalCacheKMS.GenerateKey(ctx, "", kms.Context{bucket: pathJoin(bucket, object)})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -891,7 +891,7 @@ func (c *diskCache) put(ctx context.Context, bucket, object string, data io.Read
reader := data reader := data
actualSize := uint64(size) actualSize := uint64(size)
if globalCacheKMS != nil { if globalCacheKMS != nil {
reader, err = newCacheEncryptReader(data, bucket, object, metadata) reader, err = newCacheEncryptReader(ctx, data, bucket, object, metadata)
if err != nil { if err != nil {
removeAll(cachePath) removeAll(cachePath)
return oi, err return oi, err
@ -948,7 +948,7 @@ func (c *diskCache) putRange(ctx context.Context, bucket, object string, data io
// objSize is the actual size of object (with encryption overhead if any) // objSize is the actual size of object (with encryption overhead if any)
objSize := uint64(size) objSize := uint64(size)
if globalCacheKMS != nil { if globalCacheKMS != nil {
reader, err = newCacheEncryptReader(data, bucket, object, metadata) reader, err = newCacheEncryptReader(ctx, data, bucket, object, metadata)
if err != nil { if err != nil {
return err return err
} }
@ -1301,7 +1301,7 @@ func (c *diskCache) NewMultipartUpload(ctx context.Context, bucket, object, uID
m.Stat.ModTime = UTCNow() m.Stat.ModTime = UTCNow()
if globalCacheKMS != nil { if globalCacheKMS != nil {
m.Meta[ReservedMetadataPrefix+"Encrypted-Multipart"] = "" m.Meta[ReservedMetadataPrefix+"Encrypted-Multipart"] = ""
if _, err := newCacheEncryptMetadata(bucket, object, m.Meta); err != nil { if _, err := newCacheEncryptMetadata(ctx, bucket, object, m.Meta); err != nil {
return uploadID, err return uploadID, err
} }
} }

View File

@ -255,7 +255,7 @@ 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, newKeyID string, newKey []byte, bucket, object string, metadata map[string]string, ctx kms.Context) error { func rotateKey(ctx context.Context, oldKey []byte, newKeyID string, newKey []byte, bucket, object string, metadata map[string]string, cryptoCtx kms.Context) error {
kind, _ := crypto.IsEncrypted(metadata) kind, _ := crypto.IsEncrypted(metadata)
switch kind { switch kind {
case crypto.S3: case crypto.S3:
@ -275,7 +275,7 @@ func rotateKey(oldKey []byte, newKeyID string, newKey []byte, bucket, object str
return err return err
} }
newKey, err := GlobalKMS.GenerateKey("", kms.Context{bucket: path.Join(bucket, object)}) newKey, err := GlobalKMS.GenerateKey(ctx, "", kms.Context{bucket: path.Join(bucket, object)})
if err != nil { if err != nil {
return err return err
} }
@ -291,8 +291,8 @@ func rotateKey(oldKey []byte, newKeyID string, newKey []byte, bucket, object str
return err return err
} }
if len(ctx) == 0 { if len(cryptoCtx) == 0 {
_, _, _, ctx, err = crypto.S3KMS.ParseMetadata(metadata) _, _, _, cryptoCtx, err = crypto.S3KMS.ParseMetadata(metadata)
if err != nil { if err != nil {
return err return err
} }
@ -305,19 +305,19 @@ func rotateKey(oldKey []byte, newKeyID string, newKey []byte, bucket, object str
// of the client provided context and add the bucket // of the client provided context and add the bucket
// key, if not present. // key, if not present.
kmsCtx := kms.Context{} kmsCtx := kms.Context{}
for k, v := range ctx { for k, v := range cryptoCtx {
kmsCtx[k] = v kmsCtx[k] = v
} }
if _, ok := kmsCtx[bucket]; !ok { if _, ok := kmsCtx[bucket]; !ok {
kmsCtx[bucket] = path.Join(bucket, object) kmsCtx[bucket] = path.Join(bucket, object)
} }
newKey, err := GlobalKMS.GenerateKey(newKeyID, kmsCtx) newKey, err := GlobalKMS.GenerateKey(ctx, newKeyID, kmsCtx)
if err != nil { if err != nil {
return err return err
} }
sealedKey := objectKey.Seal(newKey.Plaintext, crypto.GenerateIV(rand.Reader), crypto.S3KMS.String(), bucket, object) sealedKey := objectKey.Seal(newKey.Plaintext, crypto.GenerateIV(rand.Reader), crypto.S3KMS.String(), bucket, object)
crypto.S3KMS.CreateMetadata(metadata, newKey.KeyID, newKey.Ciphertext, sealedKey, ctx) crypto.S3KMS.CreateMetadata(metadata, newKey.KeyID, newKey.Ciphertext, sealedKey, cryptoCtx)
return nil return nil
case crypto.SSEC: case crypto.SSEC:
sealedKey, err := crypto.SSEC.ParseMetadata(metadata) sealedKey, err := crypto.SSEC.ParseMetadata(metadata)
@ -344,14 +344,14 @@ func rotateKey(oldKey []byte, newKeyID string, newKey []byte, bucket, object str
} }
} }
func newEncryptMetadata(kind crypto.Type, keyID string, key []byte, bucket, object string, metadata map[string]string, ctx kms.Context) (crypto.ObjectKey, error) { func newEncryptMetadata(ctx context.Context, kind crypto.Type, keyID string, key []byte, bucket, object string, metadata map[string]string, cryptoCtx kms.Context) (crypto.ObjectKey, error) {
var sealedKey crypto.SealedKey var sealedKey crypto.SealedKey
switch kind { switch kind {
case crypto.S3: case crypto.S3:
if GlobalKMS == nil { if GlobalKMS == nil {
return crypto.ObjectKey{}, errKMSNotConfigured return crypto.ObjectKey{}, errKMSNotConfigured
} }
key, err := GlobalKMS.GenerateKey("", kms.Context{bucket: path.Join(bucket, object)}) key, err := GlobalKMS.GenerateKey(ctx, "", kms.Context{bucket: path.Join(bucket, object)})
if err != nil { if err != nil {
return crypto.ObjectKey{}, err return crypto.ObjectKey{}, err
} }
@ -372,13 +372,13 @@ func newEncryptMetadata(kind crypto.Type, keyID string, key []byte, bucket, obje
// of the client provided context and add the bucket // of the client provided context and add the bucket
// key, if not present. // key, if not present.
kmsCtx := kms.Context{} kmsCtx := kms.Context{}
for k, v := range ctx { for k, v := range cryptoCtx {
kmsCtx[k] = v kmsCtx[k] = v
} }
if _, ok := kmsCtx[bucket]; !ok { if _, ok := kmsCtx[bucket]; !ok {
kmsCtx[bucket] = path.Join(bucket, object) kmsCtx[bucket] = path.Join(bucket, object)
} }
key, err := GlobalKMS.GenerateKey(keyID, kmsCtx) key, err := GlobalKMS.GenerateKey(ctx, keyID, kmsCtx)
if err != nil { if err != nil {
if errors.Is(err, kes.ErrKeyNotFound) { if errors.Is(err, kes.ErrKeyNotFound) {
return crypto.ObjectKey{}, errKMSKeyNotFound return crypto.ObjectKey{}, errKMSKeyNotFound
@ -388,7 +388,7 @@ func newEncryptMetadata(kind crypto.Type, keyID string, key []byte, bucket, obje
objectKey := crypto.GenerateKey(key.Plaintext, rand.Reader) objectKey := crypto.GenerateKey(key.Plaintext, rand.Reader)
sealedKey = objectKey.Seal(key.Plaintext, crypto.GenerateIV(rand.Reader), crypto.S3KMS.String(), bucket, object) sealedKey = objectKey.Seal(key.Plaintext, crypto.GenerateIV(rand.Reader), crypto.S3KMS.String(), bucket, object)
crypto.S3KMS.CreateMetadata(metadata, key.KeyID, key.Ciphertext, sealedKey, ctx) crypto.S3KMS.CreateMetadata(metadata, key.KeyID, key.Ciphertext, sealedKey, cryptoCtx)
return objectKey, nil return objectKey, nil
case crypto.SSEC: case crypto.SSEC:
objectKey := crypto.GenerateKey(key, rand.Reader) objectKey := crypto.GenerateKey(key, rand.Reader)
@ -400,8 +400,8 @@ func newEncryptMetadata(kind crypto.Type, keyID string, key []byte, bucket, obje
} }
} }
func newEncryptReader(content io.Reader, kind crypto.Type, keyID string, key []byte, bucket, object string, metadata map[string]string, ctx kms.Context) (io.Reader, crypto.ObjectKey, error) { func newEncryptReader(ctx context.Context, content io.Reader, kind crypto.Type, keyID string, key []byte, bucket, object string, metadata map[string]string, cryptoCtx kms.Context) (io.Reader, crypto.ObjectKey, error) {
objectEncryptionKey, err := newEncryptMetadata(kind, keyID, key, bucket, object, metadata, ctx) objectEncryptionKey, err := newEncryptMetadata(ctx, kind, keyID, key, bucket, object, metadata, cryptoCtx)
if err != nil { if err != nil {
return nil, crypto.ObjectKey{}, err return nil, crypto.ObjectKey{}, err
} }
@ -418,9 +418,9 @@ func newEncryptReader(content io.Reader, kind crypto.Type, keyID string, key []b
// SSE-S3 // SSE-S3
func setEncryptionMetadata(r *http.Request, bucket, object string, metadata map[string]string) (err error) { func setEncryptionMetadata(r *http.Request, bucket, object string, metadata map[string]string) (err error) {
var ( var (
key []byte key []byte
keyID string keyID string
ctx kms.Context kmsCtx kms.Context
) )
kind, _ := crypto.IsRequested(r.Header) kind, _ := crypto.IsRequested(r.Header)
switch kind { switch kind {
@ -430,12 +430,12 @@ func setEncryptionMetadata(r *http.Request, bucket, object string, metadata map[
return err return err
} }
case crypto.S3KMS: case crypto.S3KMS:
keyID, ctx, err = crypto.S3KMS.ParseHTTP(r.Header) keyID, kmsCtx, err = crypto.S3KMS.ParseHTTP(r.Header)
if err != nil { if err != nil {
return err return err
} }
} }
_, err = newEncryptMetadata(kind, keyID, key, bucket, object, metadata, ctx) _, err = newEncryptMetadata(r.Context(), kind, keyID, key, bucket, object, metadata, kmsCtx)
return return
} }
@ -468,7 +468,7 @@ func EncryptRequest(content io.Reader, r *http.Request, bucket, object string, m
return nil, crypto.ObjectKey{}, err return nil, crypto.ObjectKey{}, err
} }
} }
return newEncryptReader(content, kind, keyID, key, bucket, object, metadata, ctx) return newEncryptReader(r.Context(), content, kind, keyID, key, bucket, object, metadata, ctx)
} }
func decryptObjectInfo(key []byte, bucket, object string, metadata map[string]string) ([]byte, error) { func decryptObjectInfo(key []byte, bucket, object string, metadata map[string]string) ([]byte, error) {

View File

@ -359,7 +359,7 @@ func migrateCacheData(ctx context.Context, c *diskCache, bucket, object, oldfile
actualSize := uint64(st.Size()) actualSize := uint64(st.Size())
if globalCacheKMS != nil { if globalCacheKMS != nil {
reader, err = newCacheEncryptReader(readCloser, bucket, object, metadata) reader, err = newCacheEncryptReader(ctx, readCloser, bucket, object, metadata)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1249,7 +1249,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
} }
} }
if err = rotateKey(oldKey, newKeyID, newKey, srcBucket, srcObject, encMetadata, kmsCtx); err != nil { if err = rotateKey(ctx, oldKey, newKeyID, newKey, srcBucket, srcObject, encMetadata, kmsCtx); err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL) writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
return return
} }
@ -1287,7 +1287,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re
if isTargetEncrypted { if isTargetEncrypted {
var encReader io.Reader var encReader io.Reader
kind, _ := crypto.IsRequested(r.Header) kind, _ := crypto.IsRequested(r.Header)
encReader, objEncKey, err = newEncryptReader(srcInfo.Reader, kind, newKeyID, newKey, dstBucket, dstObject, encMetadata, kmsCtx) encReader, objEncKey, err = newEncryptReader(ctx, srcInfo.Reader, kind, newKeyID, newKey, dstBucket, dstObject, encMetadata, kmsCtx)
if err != nil { if err != nil {
writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL) writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL)
return return

View File

@ -287,7 +287,7 @@ func (config *TierConfigMgr) configReader() (*PutObjReader, *ObjectOptions, erro
// Encrypt json encoded tier configurations // Encrypt json encoded tier configurations
metadata := make(map[string]string) metadata := make(map[string]string)
encBr, oek, err := newEncryptReader(hr, crypto.S3, "", nil, minioMetaBucket, tierConfigPath, metadata, kms.Context{}) encBr, oek, err := newEncryptReader(context.Background(), hr, crypto.S3, "", nil, minioMetaBucket, tierConfigPath, metadata, kms.Context{})
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

View File

@ -19,6 +19,7 @@ package config
import ( import (
"bytes" "bytes"
"context"
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
"errors" "errors"
@ -61,13 +62,13 @@ func DecryptBytes(KMS kms.KMS, ciphertext []byte, context kms.Context) ([]byte,
// //
// The same context must be provided when decrypting the // The same context must be provided when decrypting the
// ciphertext. // ciphertext.
func Encrypt(KMS kms.KMS, plaintext io.Reader, context kms.Context) (io.Reader, error) { func Encrypt(KMS kms.KMS, plaintext io.Reader, ctx kms.Context) (io.Reader, error) {
algorithm := sio.AES_256_GCM algorithm := sio.AES_256_GCM
if !fips.Enabled && !sioutil.NativeAES() { if !fips.Enabled && !sioutil.NativeAES() {
algorithm = sio.ChaCha20Poly1305 algorithm = sio.ChaCha20Poly1305
} }
key, err := KMS.GenerateKey("", context) key, err := KMS.GenerateKey(context.Background(), "", ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -23,7 +23,6 @@ import (
"crypto/x509" "crypto/x509"
"errors" "errors"
"strings" "strings"
"time"
"github.com/minio/kes" "github.com/minio/kes"
) )
@ -100,9 +99,7 @@ var _ KMS = (*kesClient)(nil) // compiler check
// Stat returns the current KES status containing a // Stat returns the current KES status containing a
// list of KES endpoints and the default key ID. // list of KES endpoints and the default key ID.
func (c *kesClient) Stat() (Status, error) { func (c *kesClient) Stat(ctx context.Context) (Status, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if _, err := c.client.Version(ctx); err != nil { if _, err := c.client.Version(ctx); err != nil {
return Status{}, err return Status{}, err
} }
@ -124,8 +121,8 @@ func (c *kesClient) Metrics(ctx context.Context) (kes.Metric, error) {
// //
// If the a key with the same keyID already exists then // If the a key with the same keyID already exists then
// CreateKey returns kes.ErrKeyExists. // CreateKey returns kes.ErrKeyExists.
func (c *kesClient) CreateKey(keyID string) error { func (c *kesClient) CreateKey(ctx context.Context, keyID string) error {
return c.client.CreateKey(context.Background(), keyID) return c.client.CreateKey(ctx, keyID)
} }
// GenerateKey generates a new data encryption key using // GenerateKey generates a new data encryption key using
@ -136,15 +133,15 @@ func (c *kesClient) CreateKey(keyID string) error {
// The context is associated and tied to the generated DEK. // The context is associated and tied to the generated DEK.
// The same context must be provided when the generated // The same context must be provided when the generated
// key should be decrypted. // key should be decrypted.
func (c *kesClient) GenerateKey(keyID string, ctx Context) (DEK, error) { func (c *kesClient) GenerateKey(ctx context.Context, keyID string, cryptoCtx Context) (DEK, error) {
if keyID == "" { if keyID == "" {
keyID = c.defaultKeyID keyID = c.defaultKeyID
} }
ctxBytes, err := ctx.MarshalText() ctxBytes, err := cryptoCtx.MarshalText()
if err != nil { if err != nil {
return DEK{}, err return DEK{}, err
} }
dek, err := c.client.GenerateKey(context.Background(), keyID, ctxBytes) dek, err := c.client.GenerateKey(ctx, keyID, ctxBytes)
if err != nil { if err != nil {
return DEK{}, err return DEK{}, err
} }

View File

@ -30,13 +30,13 @@ import (
// different KMS implementations. // different KMS implementations.
type KMS interface { type KMS interface {
// Stat returns the current KMS status. // Stat returns the current KMS status.
Stat() (Status, error) Stat(cxt context.Context) (Status, error)
// Metrics returns a KMS metric snapshot. // Metrics returns a KMS metric snapshot.
Metrics(ctx context.Context) (kes.Metric, error) Metrics(ctx context.Context) (kes.Metric, error)
// CreateKey creates a new key at the KMS with the given key ID. // CreateKey creates a new key at the KMS with the given key ID.
CreateKey(keyID string) error CreateKey(ctx context.Context, keyID string) error
// GenerateKey generates a new data encryption key using the // GenerateKey generates a new data encryption key using the
// key referenced by the key ID. // key referenced by the key ID.
@ -50,7 +50,7 @@ type KMS interface {
// should be decrypted. Therefore, it is the callers // should be decrypted. Therefore, it is the callers
// responsibility to remember the corresponding context for // responsibility to remember the corresponding context for
// a particular DEK. The context may be nil. // a particular DEK. The context may be nil.
GenerateKey(keyID string, context Context) (DEK, error) GenerateKey(ctx context.Context, keyID string, context Context) (DEK, error)
// DecryptKey decrypts the ciphertext with the key referenced // DecryptKey decrypts the ciphertext with the key referenced
// by the key ID. The context must match the context value // by the key ID. The context must match the context value

View File

@ -83,7 +83,7 @@ const ( // algorithms used to derive and encrypt DEKs
algorithmChaCha20Poly1305 = "ChaCha20Poly1305" algorithmChaCha20Poly1305 = "ChaCha20Poly1305"
) )
func (kms secretKey) Stat() (Status, error) { func (kms secretKey) Stat(context.Context) (Status, error) {
return Status{ return Status{
Name: "SecretKey", Name: "SecretKey",
DefaultKey: kms.keyID, DefaultKey: kms.keyID,
@ -94,11 +94,11 @@ func (secretKey) Metrics(ctx context.Context) (kes.Metric, error) {
return kes.Metric{}, errors.New("kms: metrics are not supported") return kes.Metric{}, errors.New("kms: metrics are not supported")
} }
func (secretKey) CreateKey(string) error { func (secretKey) CreateKey(context.Context, string) error {
return errors.New("kms: creating keys is not supported") return errors.New("kms: creating keys is not supported")
} }
func (kms secretKey) GenerateKey(keyID string, context Context) (DEK, error) { func (kms secretKey) GenerateKey(_ context.Context, keyID string, context Context) (DEK, error) {
if keyID == "" { if keyID == "" {
keyID = kms.keyID keyID = kms.keyID
} }

View File

@ -19,6 +19,7 @@ package kms
import ( import (
"bytes" "bytes"
"context"
"encoding/base64" "encoding/base64"
"testing" "testing"
) )
@ -29,7 +30,7 @@ func TestSingleKeyRoundtrip(t *testing.T) {
t.Fatalf("Failed to initialize KMS: %v", err) t.Fatalf("Failed to initialize KMS: %v", err)
} }
key, err := KMS.GenerateKey("my-key", Context{}) key, err := KMS.GenerateKey(context.Background(), "my-key", Context{})
if err != nil { if err != nil {
t.Fatalf("Failed to generate key: %v", err) t.Fatalf("Failed to generate key: %v", err)
} }