Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const cfgSecretShares = "secret-shares"
const cfgSecretThreshold = "secret-threshold"

const cfgMode = "mode"
const cfgModeValueAlicloudKMSOSS = "alicloud-kms-ssm"
const cfgModeValueAWSKMSSSM = "aws-kms-ssm"
const cfgModeValueGoogleCloudKMSGCS = "google-cloud-kms-gcs"
const cfgModeValueLocal = "local"
Expand All @@ -31,6 +32,13 @@ const cfgGoogleCloudStoragePrefix = "google-cloud-storage-prefix"
const cfgAWSKMSKeyID = "aws-kms-key-id"
const cfgAWSSSMKeyPrefix = "aws-ssm-key-prefix"

const cfgAlicloudKMSRegion = "alicloud-kms-region"
const cfgAlicloudKMSKeyID = "alicloud-kms-id"

const cfgAlicloudStorageEndpoint = "alicloud-storage-endpoint"
const cfgAlicloudStorageBucket = "alicloud-storage-bucket"
const cfgAlicloudStoragePrefix = "alicloud-storage-prefix"

const cfgLocalKeyDir = "local-key-dir"

// RootCmd represents the base command when called without any subcommands
Expand Down Expand Up @@ -78,7 +86,7 @@ func init() {
configStringVar(
cfgMode,
cfgModeValueGoogleCloudKMSGCS,
fmt.Sprintf("Select the mode to use '%s' => Google Cloud Storage with encryption using Google KMS; '%s' => AWS SSM parameter store using AWS KMS encryption; %s => Use local keys in path", cfgModeValueGoogleCloudKMSGCS, cfgModeValueAWSKMSSSM, cfgModeValueLocal),
fmt.Sprintf("Select the mode to use '%s' => Google Cloud Storage with encryption using Google KMS; '%s' => AWS SSM parameter store using AWS KMS encryption; '%s' => Alicloud KMS parameter store using Alicloud KMS encryption; %s => Use local keys in path", cfgModeValueGoogleCloudKMSGCS, cfgModeValueAWSKMSSSM, cfgModeValueAlicloudKMSOSS, cfgModeValueLocal),
)

// Secret config
Expand All @@ -101,5 +109,14 @@ func init() {
// AWS SSM Parameter Storage flags
configStringVar("aws-ssm-key-prefix", "", "The Key Prefix for SSM Parameter store")

// Alicloud KMS flags
configStringVar(cfgAlicloudKMSRegion, "", "The Region string of the Alicloud KMS to encrypt values")
configStringVar(cfgAlicloudKMSKeyID, "", "The Key ID string of the Alicloud KMS key to encrypt values")

// Alicloud Storage flags
configStringVar(cfgAlicloudStorageEndpoint, "", "The endpoint of the Alicloud Bucket")
configStringVar(cfgAlicloudStorageBucket, "", "The Region string of the Alicloud KMS to encrypt values")
configStringVar(cfgAlicloudStoragePrefix, "", "The prefix to use for values store in Alicloud Storage")

configStringVar("local-key-dir", "", "Directory of key shares in path")
}
33 changes: 31 additions & 2 deletions cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ package cmd

import (
"fmt"

"github.com/jetstack/vault-unsealer/pkg/kv/alicloud_kms"
"github.com/jetstack/vault-unsealer/pkg/kv/alicloud_oss"
"github.com/spf13/viper"
"os"

"github.com/jetstack/vault-unsealer/pkg/kv"
"github.com/jetstack/vault-unsealer/pkg/kv/aws_kms"
"github.com/jetstack/vault-unsealer/pkg/kv/aws_ssm"
"github.com/jetstack/vault-unsealer/pkg/kv/cloudkms"
"github.com/jetstack/vault-unsealer/pkg/kv/gcs"
"github.com/jetstack/vault-unsealer/pkg/kv/local"

"github.com/jetstack/vault-unsealer/pkg/vault"
)

Expand Down Expand Up @@ -70,6 +71,34 @@ func kvStoreForConfig(cfg *viper.Viper) (kv.Service, error) {

return kms, nil

case cfgModeValueAlicloudKMSOSS:
envAlicloudAccessKey := os.Getenv("ALICLOUD_ACCESS_KEY")
envAlicloudSecretKey := os.Getenv("ALICLOUD_SECRET_KEY")

o, err := alicloud_oss.New(
cfg.GetString(cfgAlicloudStorageEndpoint),
cfg.GetString(cfgAlicloudStorageBucket),
cfg.GetString(cfgAlicloudStoragePrefix),
envAlicloudSecretKey,
envAlicloudSecretKey)

if err != nil {
return nil, fmt.Errorf("error creating Alicloud storage kv store: %s", err.Error())
}


kms, err := alicloud_kms.New(o,
cfg.GetString(cfgAlicloudKMSKeyID),
cfg.GetString(cfgAlicloudKMSRegion),
envAlicloudAccessKey,
envAlicloudSecretKey)

if err != nil {
return nil, fmt.Errorf("error creating Alicloud KMS ID kv store: %s", err.Error())
}

return kms, nil

case cfgModeValueLocal:
return local.New(cfg.GetString(cfgLocalKeyDir))

Expand Down
84 changes: 84 additions & 0 deletions pkg/kv/alicloud_kms/alicloud_kms.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package alicloud_kms

import (
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/services/kms"

"github.com/jetstack/vault-unsealer/pkg/kv"
)

type alicloudKms struct {
kmsClient *kms.Client
store kv.Service
keyId string
}

var _ kv.Service = &alicloudKms{}

func New(store kv.Service, keyId, regionId, alicloudAccessKey, alicloudSecretKey string) (kv.Service, error) {
client, err := kms.NewClientWithAccessKey(regionId, alicloudAccessKey, alicloudSecretKey)

if err != nil {
return nil, fmt.Errorf("error creating alicloud kms client: %s", err.Error())
}

return &alicloudKms{
store: store,
kmsClient: client,
keyId: keyId,
}, nil
}

func (a *alicloudKms) encrypt(s []byte) ([]byte, error) {
requestStruct := kms.CreateEncryptRequest()
requestStruct.KeyId = a.keyId
requestStruct.RpcRequest.SetScheme("HTTPS")
requestStruct.Plaintext = string(s[:])

genresp, err := a.kmsClient.Encrypt(requestStruct)

if err != nil {
return nil, fmt.Errorf("error encrypting data: %s", err.Error())
}

return []byte(genresp.CiphertextBlob), nil
}

func (a *alicloudKms) decrypt(s []byte) ([]byte, error) {
derequestStruct := kms.CreateDecryptRequest()
derequestStruct.CiphertextBlob = string(s[:])
derequestStruct.RpcRequest.SetScheme("HTTPS")

degenresp, err := a.kmsClient.Decrypt(derequestStruct)

if err != nil {
return nil, fmt.Errorf("error decrypting data: %s", err.Error())
}

return []byte(degenresp.Plaintext), nil
}

func (a *alicloudKms) Get(key string) ([]byte, error) {
cipherText, err := a.store.Get(key)

if err != nil {
return nil, err
}

return a.decrypt(cipherText)
}

func (a *alicloudKms) Set(key string, val []byte) error {
cipherText, err := a.encrypt(val)

if err != nil {
return err
}

return a.store.Set(key, cipherText)
}

func (a *alicloudKms) Test(key string) error {
// TODO: Implement a test if a Set is likely to work, Alicloud doesn't seemt to provide a dry-run on the parameter store
return nil
}
88 changes: 88 additions & 0 deletions pkg/kv/alicloud_oss/alicloud_oss.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package alicloud_oss

import (
"bytes"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"io"

"github.com/jetstack/vault-unsealer/pkg/kv"
)

type ossStorage struct {
cl *oss.Client
endpoint string
bucket string
prefix string
}

func New(endpoint, bucket, prefix, alicloudAccessKey, alicloudSecretKey string) (kv.Service, error) {
cl, err := oss.New(endpoint, alicloudAccessKey, alicloudSecretKey)

lsRes, _ := cl.ListBuckets()
for _, bucket := range lsRes.Buckets {
fmt.Println("Buckets:", bucket.Name)

}


if err != nil {
return nil, fmt.Errorf("error creating oss client: %s", err.Error())
}

return &ossStorage{cl, endpoint, bucket, prefix}, nil
}

func (o *ossStorage) Set(key string, val []byte) error {
n := objectNameWithPrefix(o.prefix, key)
bucket, err := o.cl.Bucket(o.bucket)
if err != nil {
return fmt.Errorf("error writing key '%s' to oss bucket '%s'", n, o.bucket)
}

err = bucket.PutObject(n, bytes.NewReader(val))
if err != nil {
return fmt.Errorf("error writing key '%s' to oss bucket '%s'", n, o.bucket)
}

return nil
}

func (o *ossStorage) Get(key string) ([]byte, error) {
n := objectNameWithPrefix(o.prefix, key)
b := new(bytes.Buffer)

bucket, err := o.cl.Bucket(o.bucket)
if err != nil {
return nil, fmt.Errorf("error writing key '%s' to oss bucket '%s'", n, o.bucket)
}

lsRes, _ := o.cl.ListBuckets()
for _, bucket := range lsRes.Buckets {
fmt.Println("Buckets:", bucket.Name)

}


body, err := bucket.GetObject(n)
if err != nil {
if err != nil {
return nil, kv.NewNotFoundError("error getting object for key '%s': %s", n, err.Error())
}
//return nil, fmt.Errorf("error writing key '%s' to oss bucket '%s'", n, o.bucket)
}

io.Copy(b, body)
body.Close()

return b.Bytes(), nil
}

func objectNameWithPrefix(prefix, key string) string {
return fmt.Sprintf("%s%s", prefix, key)
}

func (o *ossStorage) Test(key string) error {
// TODO: Implement me properly
return nil
}