зеркало из https://github.com/getsops/sops.git
Родитель
17132124e8
Коммит
3fa7cc43f1
|
@ -150,6 +150,10 @@ func main() {
|
|||
Name: "config",
|
||||
Usage: "path to sops' config file. If set, sops will not search for the config file recursively.",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "encryption-context",
|
||||
Usage: "comma separated list of KMS encryption context key:value pairs",
|
||||
},
|
||||
}
|
||||
app.Action = func(c *cli.Context) error {
|
||||
if c.NArg() < 1 {
|
||||
|
@ -304,9 +308,9 @@ func decrypt(c *cli.Context, file string, fileBytes []byte, output io.Writer) er
|
|||
func getKeysources(c *cli.Context, file string) ([]sops.KeySource, error) {
|
||||
var kmsKeys []sops.MasterKey
|
||||
var pgpKeys []sops.MasterKey
|
||||
|
||||
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
|
||||
if c.String("kms") != "" {
|
||||
for _, k := range kms.MasterKeysFromArnString(c.String("kms")) {
|
||||
for _, k := range kms.MasterKeysFromArnString(c.String("kms"), kmsEncryptionContext) {
|
||||
kmsKeys = append(kmsKeys, k)
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +333,7 @@ func getKeysources(c *cli.Context, file string) ([]sops.KeySource, error) {
|
|||
for _, k := range pgp.MasterKeysFromFingerprintString(pgpString) {
|
||||
pgpKeys = append(pgpKeys, k)
|
||||
}
|
||||
for _, k := range kms.MasterKeysFromArnString(kmsString) {
|
||||
for _, k := range kms.MasterKeysFromArnString(kmsString, kmsEncryptionContext) {
|
||||
kmsKeys = append(kmsKeys, k)
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +391,8 @@ func rotate(c *cli.Context, file string, fileBytes []byte, output io.Writer) err
|
|||
if err != nil {
|
||||
return cli.NewExitError(fmt.Sprintf("Error encrypting tree: %s", err), exitErrorEncryptingTree)
|
||||
}
|
||||
tree.Metadata.AddKMSMasterKeys(c.String("add-kms"))
|
||||
kmsEncryptionContext := kms.ParseKMSContext(c.String("encryption-context"))
|
||||
tree.Metadata.AddKMSMasterKeys(c.String("add-kms"), kmsEncryptionContext)
|
||||
tree.Metadata.AddPGPMasterKeys(c.String("add-pgp"))
|
||||
tree.Metadata.RemoveKMSMasterKeys(c.String("rm-kms"))
|
||||
tree.Metadata.RemovePGPMasterKeys(c.String("rm-pgp"))
|
||||
|
|
|
@ -274,6 +274,7 @@ func (store Store) kmsEntries(in []interface{}) (sops.KeySource, error) {
|
|||
if err != nil {
|
||||
return keysource, fmt.Errorf("Could not parse creation date: %s", err)
|
||||
}
|
||||
key.EncryptionContext = kms.ParseKMSContext(entry["context"].(string))
|
||||
key.CreationDate = creationDate
|
||||
keysource.Keys = append(keysource.Keys, key)
|
||||
}
|
||||
|
|
|
@ -20,10 +20,11 @@ var kmsSvc kmsiface.KMSAPI
|
|||
|
||||
// MasterKey is a AWS KMS key used to encrypt and decrypt sops' data key.
|
||||
type MasterKey struct {
|
||||
Arn string
|
||||
Role string
|
||||
EncryptedKey string
|
||||
CreationDate time.Time
|
||||
Arn string
|
||||
Role string
|
||||
EncryptedKey string
|
||||
CreationDate time.Time
|
||||
EncryptionContext map[string]*string
|
||||
}
|
||||
|
||||
// Encrypt takes a sops data key, encrypts it with KMS and stores the result in the EncryptedKey field
|
||||
|
@ -36,7 +37,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
|
|||
}
|
||||
kmsSvc = kms.New(sess)
|
||||
}
|
||||
out, err := kmsSvc.Encrypt(&kms.EncryptInput{Plaintext: dataKey, KeyId: &key.Arn})
|
||||
out, err := kmsSvc.Encrypt(&kms.EncryptInput{Plaintext: dataKey, KeyId: &key.Arn, EncryptionContext: key.EncryptionContext})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -44,7 +45,7 @@ func (key *MasterKey) Encrypt(dataKey []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// EncryptIfNeeded encrypts the provided sops' data ket and encrypts it if it hasn't been encrypted yet
|
||||
// EncryptIfNeeded encrypts the provided sops' data key and encrypts it if it hasn't been encrypted yet
|
||||
func (key *MasterKey) EncryptIfNeeded(dataKey []byte) error {
|
||||
if key.EncryptedKey == "" {
|
||||
return key.Encrypt(dataKey)
|
||||
|
@ -65,7 +66,7 @@ func (key *MasterKey) Decrypt() ([]byte, error) {
|
|||
}
|
||||
kmsSvc = kms.New(sess)
|
||||
}
|
||||
decrypted, err := kmsSvc.Decrypt(&kms.DecryptInput{CiphertextBlob: k})
|
||||
decrypted, err := kmsSvc.Decrypt(&kms.DecryptInput{CiphertextBlob: k, EncryptionContext: key.EncryptionContext})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error decrypting key: %v", err)
|
||||
}
|
||||
|
@ -83,7 +84,7 @@ func (key *MasterKey) ToString() string {
|
|||
}
|
||||
|
||||
// NewMasterKeyFromArn takes an ARN string and returns a new MasterKey for that ARN
|
||||
func NewMasterKeyFromArn(arn string) *MasterKey {
|
||||
func NewMasterKeyFromArn(arn string, context map[string]*string) *MasterKey {
|
||||
k := &MasterKey{}
|
||||
arn = strings.Replace(arn, " ", "", -1)
|
||||
roleIndex := strings.Index(arn, "+arn:aws:iam::")
|
||||
|
@ -93,18 +94,19 @@ func NewMasterKeyFromArn(arn string) *MasterKey {
|
|||
} else {
|
||||
k.Arn = arn
|
||||
}
|
||||
k.EncryptionContext = context
|
||||
k.CreationDate = time.Now().UTC()
|
||||
return k
|
||||
}
|
||||
|
||||
// MasterKeysFromArnString takes a comma separated list of AWS KMS ARNs and returns a slice of new MasterKeys for those ARNs
|
||||
func MasterKeysFromArnString(arn string) []*MasterKey {
|
||||
func MasterKeysFromArnString(arn string, context map[string]*string) []*MasterKey {
|
||||
var keys []*MasterKey
|
||||
if arn == "" {
|
||||
return keys
|
||||
}
|
||||
for _, s := range strings.Split(arn, ",") {
|
||||
keys = append(keys, NewMasterKeyFromArn(s))
|
||||
keys = append(keys, NewMasterKeyFromArn(s, context))
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
@ -156,5 +158,22 @@ func (key MasterKey) ToMap() map[string]string {
|
|||
}
|
||||
out["created_at"] = key.CreationDate.UTC().Format(time.RFC3339)
|
||||
out["enc"] = key.EncryptedKey
|
||||
if key.EncryptionContext != nil {
|
||||
var outContexts []string
|
||||
for k, v := range key.EncryptionContext {
|
||||
outContexts = append(outContexts, k+":"+*v)
|
||||
}
|
||||
out["context"] = strings.Join(outContexts, ",")
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ParseKMSContext takes a comma-separated list of KMS context key:value pairs and returns a map
|
||||
func ParseKMSContext(in string) map[string]*string {
|
||||
out := make(map[string]*string)
|
||||
for _, kv := range strings.Split(in, ",") {
|
||||
kv := strings.Split(kv, ":")
|
||||
out[kv[0]] = &kv[1]
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ func TestKMS(t *testing.T) {
|
|||
|
||||
func TestKMSKeySourceFromString(t *testing.T) {
|
||||
s := "arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e+arn:aws:iam::927034868273:role/sops-dev, arn:aws:kms:ap-southeast-1:656532927350:key/9006a8aa-0fa6-4c14-930e-a2dfb916de1d"
|
||||
ks := MasterKeysFromArnString(s)
|
||||
ks := MasterKeysFromArnString(s, nil)
|
||||
k1 := ks[0]
|
||||
k2 := ks[1]
|
||||
expectedArn1 := "arn:aws:kms:us-east-1:656532927350:key/920aff2e-c5f1-4040-943a-047fa387b27e"
|
||||
|
|
6
sops.go
6
sops.go
|
@ -308,11 +308,11 @@ func (m *Metadata) AddPGPMasterKeys(pgpFps string) {
|
|||
}
|
||||
|
||||
// AddKMSMasterKeys parses the input comma separated string of AWS KMS ARNs, generates a KMS MasterKey for each ARN, and then adds the keys to the KMS KeySource
|
||||
func (m *Metadata) AddKMSMasterKeys(kmsArns string) {
|
||||
func (m *Metadata) AddKMSMasterKeys(kmsArns string, context map[string]*string) {
|
||||
for i, ks := range m.KeySources {
|
||||
if ks.Name == "kms" {
|
||||
var keys []MasterKey
|
||||
for _, k := range kms.MasterKeysFromArnString(kmsArns) {
|
||||
for _, k := range kms.MasterKeysFromArnString(kmsArns, context) {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
ks.Keys = append(ks.Keys, keys...)
|
||||
|
@ -333,7 +333,7 @@ func (m *Metadata) RemovePGPMasterKeys(pgpFps string) {
|
|||
// RemoveKMSMasterKeys takes a comma separated string of AWS KMS ARNs and removes the keys corresponding to those ARNs from the metadata's KeySources
|
||||
func (m *Metadata) RemoveKMSMasterKeys(arns string) {
|
||||
var keys []MasterKey
|
||||
for _, k := range kms.MasterKeysFromArnString(arns) {
|
||||
for _, k := range kms.MasterKeysFromArnString(arns, nil) {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
m.RemoveMasterKeys(keys)
|
||||
|
|
|
@ -200,6 +200,7 @@ func (store *Store) kmsEntries(in []interface{}) (sops.KeySource, error) {
|
|||
return keysource, fmt.Errorf("Could not parse creation date: %s", err)
|
||||
}
|
||||
key.CreationDate = creationDate
|
||||
key.EncryptionContext = kms.ParseKMSContext(entry["context"].(string))
|
||||
keysource.Keys = append(keysource.Keys, key)
|
||||
}
|
||||
return keysource, nil
|
||||
|
|
Загрузка…
Ссылка в новой задаче