1
0
mirror of https://github.com/getsops/sops.git synced 2026-02-05 12:45:21 +01:00

This fixes a bug with age encryption when specifying multiple age recipients

I encountered an issue when I tried so specify multiple age recipients
in the .sops.yaml config file of my repository.

I tried running `sops --age 'agePubKey1,agePubKey2' -e -i values.secret.yaml`
which produced an appropriate file with two entries in the `/sops/age/-`
part of the encrypted yaml file.

However, I then continued to set multiple recipients in my .sops.yaml
file to simplify handling:

```yaml
creation_rules:
  - encrypted_regex: '^(data|stringData|spec)$'
    age: 'agePubKey1,agePubKey2'
```

However, this resulted in encryption only being done for the first
specified agePubKey, not the second or third one.

After digging a bit trough the code, I think this should fix it.

I verified the fix locally on my machine and got it working. Also adding
some unit tests and extending the repository examples so they can be
decrypted using the age keys provided in `age/keys.txt`

Signed-off-by: Cedric Kienzler <github@cedric-kienzler.de>
This commit is contained in:
Cedric Kienzler
2022-03-20 22:49:11 +01:00
parent 86f500de61
commit 7ebee3dc7b
4 changed files with 38 additions and 14 deletions

View File

@@ -1,3 +1,6 @@
# created: 2020-07-18T03:16:47-07:00
# public key: age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw
AGE-SECRET-KEY-1NJT5YCS2LWU4V4QAJQ6R4JNU7LXPDX602DZ9NUFANVU5GDTGUWCQ5T59M6
# created: 2021-12-12T01:39:30+01:00
# public key: age1tmaae3ld5vpevmsh5yacsauzx8jetg300mpvc4ugp5zr5l6ssq9sla97ep
AGE-SECRET-KEY-1T0Z66WSXS6RMNCPSL7P2E8N4Q7SUD8VMG9ND27S08JL7Y2XAU9EQECHDS7

View File

@@ -31,26 +31,43 @@ func TestMasterKeyFromRecipientWithLeadingAndTrailingSpaces(t *testing.T) {
assert.Equal(key.Recipient, "age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw")
}
func TestMasterKeysFromRecipientsWithMultiple(t *testing.T) {
assert := assert.New(t)
keys, err := MasterKeysFromRecipients("age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw,age1tmaae3ld5vpevmsh5yacsauzx8jetg300mpvc4ugp5zr5l6ssq9sla97ep")
assert.NoError(err)
assert.Equal(len(keys), 2)
assert.Equal(keys[0].Recipient, "age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw")
assert.Equal(keys[1].Recipient, "age1tmaae3ld5vpevmsh5yacsauzx8jetg300mpvc4ugp5zr5l6ssq9sla97ep")
}
func TestAge(t *testing.T) {
assert := assert.New(t)
key, err := MasterKeyFromRecipient("age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw")
keys, err := MasterKeysFromRecipients("age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw,age1tmaae3ld5vpevmsh5yacsauzx8jetg300mpvc4ugp5zr5l6ssq9sla97ep")
assert.NoError(err)
assert.Equal("age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw", key.ToString())
assert.Equal(len(keys), 2)
assert.Equal(keys[0].Recipient, "age1yt3tfqlfrwdwx0z0ynwplcr6qxcxfaqycuprpmy89nr83ltx74tqdpszlw")
assert.Equal(keys[1].Recipient, "age1tmaae3ld5vpevmsh5yacsauzx8jetg300mpvc4ugp5zr5l6ssq9sla97ep")
dataKey := []byte("abcdefghijklmnopqrstuvwxyz123456")
err = key.Encrypt(dataKey)
assert.NoError(err)
for _, key := range keys {
err = key.Encrypt(dataKey)
assert.NoError(err)
_, filename, _, _ := runtime.Caller(0)
err = os.Setenv(SopsAgeKeyFileEnv, path.Join(path.Dir(filename), "keys.txt"))
assert.NoError(err)
_, filename, _, _ := runtime.Caller(0)
err = os.Setenv("SOPS_AGE_KEY_FILE", path.Join(path.Dir(filename), "keys.txt"))
assert.NoError(err)
decryptedKey, err := key.Decrypt()
assert.NoError(err)
assert.Equal(dataKey, decryptedKey)
}
decryptedKey, err := key.Decrypt()
assert.NoError(err)
assert.Equal(dataKey, decryptedKey)
}
func TestAgeDotEnv(t *testing.T) {

View File

@@ -442,12 +442,14 @@ func main() {
group = append(group, k)
}
for _, recipient := range ageRecipients {
k, err := age.MasterKeyFromRecipient(recipient)
keys, err := age.MasterKeysFromRecipients(recipient)
if err != nil {
log.WithError(err).Error("Failed to add key")
continue
}
group = append(group, k)
for _, key := range keys {
group = append(group, key)
}
}
return groups.Add(groups.AddOpts{
InputPath: c.String("file"),

View File

@@ -153,11 +153,13 @@ func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[
for _, group := range cRule.KeyGroups {
var keyGroup sops.KeyGroup
for _, k := range group.Age {
key, err := age.MasterKeyFromRecipient(k)
keys, err := age.MasterKeysFromRecipients(k)
if err != nil {
return nil, err
}
keyGroup = append(keyGroup, key)
for _, key := range keys {
keyGroup = append(keyGroup, key)
}
}
for _, k := range group.PGP {
keyGroup = append(keyGroup, pgp.NewMasterKeyFromFingerprint(k))