Skip to content

Commit

Permalink
Fixing AliCloud KMS seal encryption/decryption (#5756)
Browse files Browse the repository at this point in the history
* fixing seal encryption/decryption

* Address feedback.

Co-Authored-By: chrishoffman <[email protected]>
  • Loading branch information
chrishoffman authored Nov 12, 2018
1 parent 1ec2aba commit 98ea0a3
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
18 changes: 13 additions & 5 deletions vault/seal/alicloudkms/alicloudkms.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package alicloudkms

import (
"context"
"encoding/base64"
"errors"
"fmt"
"os"
Expand Down Expand Up @@ -64,13 +65,12 @@ func (k *AliCloudKMSSeal) SetConfig(config map[string]string) (map[string]string

region := ""
if k.client == nil {

// Check and set region.
region = os.Getenv("ALICLOUD_REGION")
if region == "" {
ok := false
if region, ok = config["region"]; !ok {
region = "us-east-1"
region = "cn-beijing"
}
}

Expand Down Expand Up @@ -129,6 +129,9 @@ func (k *AliCloudKMSSeal) SetConfig(config map[string]string) (map[string]string
if keyInfo == nil || keyInfo.KeyMetadata.KeyId == "" {
return nil, errors.New("no key information returned")
}

// Store the current key id. If using a key alias, this will point to the actual
// unique key that that was used for this encrypt operation.
k.currentKeyID.Store(keyInfo.KeyMetadata.KeyId)

// Map that holds non-sensitive configuration info
Expand Down Expand Up @@ -178,7 +181,7 @@ func (k *AliCloudKMSSeal) Encrypt(_ context.Context, plaintext []byte) (*physica

input := kms.CreateEncryptRequest()
input.KeyId = k.keyID
input.Plaintext = string(env.Key)
input.Plaintext = base64.StdEncoding.EncodeToString(env.Key)
input.Domain = k.domain

output, err := k.client.Encrypt(input)
Expand Down Expand Up @@ -208,7 +211,7 @@ func (k *AliCloudKMSSeal) Decrypt(_ context.Context, in *physical.EncryptedBlobI
return nil, fmt.Errorf("given input for decryption is nil")
}

// KeyID is not passed to this call because AWS handles this
// KeyID is not passed to this call because AliCloud handles this
// internally based on the metadata stored with the encrypted data
input := kms.CreateDecryptRequest()
input.CiphertextBlob = string(in.KeyInfo.WrappedKey)
Expand All @@ -219,8 +222,13 @@ func (k *AliCloudKMSSeal) Decrypt(_ context.Context, in *physical.EncryptedBlobI
return nil, errwrap.Wrapf("error decrypting data encryption key: {{err}}", err)
}

keyBytes, err := base64.StdEncoding.DecodeString(output.Plaintext)
if err != nil {
return nil, err
}

envInfo := &seal.EnvelopeInfo{
Key: []byte(output.Plaintext),
Key: keyBytes,
IV: in.IV,
Ciphertext: in.Ciphertext,
}
Expand Down
48 changes: 48 additions & 0 deletions vault/seal/alicloudkms/alicloudkms_acc_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package alicloudkms

import (
"context"
"os"
"reflect"
"testing"

log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/helper/logging"
)

// This test executes real calls. The calls themselves should be free,
// but the KMS key used is generally not free. Alibaba doesn't publish
// the price but it can be assumed to be around $1/month because that's
// what AWS charges for the same.
//
// To run this test, the following env variables need to be set:
// - VAULT_ALICLOUDKMS_SEAL_KEY_ID
// - ALICLOUD_REGION
// - ALICLOUD_ACCESS_KEY
// - ALICLOUD_SECRET_KEY
func TestAccAliCloudKMSSeal_Lifecycle(t *testing.T) {
if os.Getenv("VAULT_ACC") == "" {
t.SkipNow()
}

s := NewSeal(logging.NewVaultLogger(log.Trace))
_, err := s.SetConfig(nil)
if err != nil {
t.Fatalf("err : %s", err)
}

input := []byte("foo")
swi, err := s.Encrypt(context.Background(), input)
if err != nil {
t.Fatalf("err: %s", err.Error())
}

pt, err := s.Decrypt(context.Background(), swi)
if err != nil {
t.Fatalf("err: %s", err.Error())
}

if !reflect.DeepEqual(input, pt) {
t.Fatalf("expected %s, got %s", input, pt)
}
}

0 comments on commit 98ea0a3

Please sign in to comment.