From 4deffe44a247432da0e05a174d25e8fef24af0ff Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Wed, 6 Oct 2021 20:57:13 +0100 Subject: [PATCH 1/3] Handle duplicate keys on GPG key ring It is possible that a keyring can contain duplicate keys on a keyring due to jpegs or other layers. This currently leads to a confusing error for the user - where we report a duplicate key insertion. This PR simply coalesces keys into one key if there are duplicates. Signed-off-by: Andrew Thornton --- models/gpg_key_add.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/models/gpg_key_add.go b/models/gpg_key_add.go index 635872c920f5b..650783c4ea12e 100644 --- a/models/gpg_key_add.go +++ b/models/gpg_key_add.go @@ -101,6 +101,39 @@ func AddGPGKey(ownerID int64, content, token, signature string) ([]*GPGKey, erro verified = true } + if len(ekeys) > 1 { + id2key := map[string]*openpgp.Entity{} + newKeys := make([]*openpgp.Entity, 0, len(ekeys)) + for _, ekey := range ekeys { + id := ekey.PrimaryKey.KeyIdString() + if original, has := id2key[id]; has { + // Coalesce this with the other one + for _, subkey := range ekey.Subkeys { + for _, originalSubkey := range original.Subkeys { + if subkey.PublicKey == nil || originalSubkey.PublicKey == nil { + continue + } + if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId { + continue + } + original.Subkeys = append(original.Subkeys, subkey) + break + } + } + for name, identity := range ekey.Identities { + if _, has := original.Identities[name]; has { + continue + } + original.Identities[name] = identity + } + continue + } + id2key[id] = ekey + newKeys = append(newKeys, ekey) + } + ekeys = newKeys + } + for _, ekey := range ekeys { // Key ID cannot be duplicated. has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()). From f4cf47f96cf3f68e21f002419357743e413ee193 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 7 Oct 2021 08:31:37 +0100 Subject: [PATCH 2/3] handle duplicate subkeys properly Signed-off-by: Andrew Thornton --- models/gpg_key_add.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/models/gpg_key_add.go b/models/gpg_key_add.go index 650783c4ea12e..4b09e7964853e 100644 --- a/models/gpg_key_add.go +++ b/models/gpg_key_add.go @@ -109,15 +109,22 @@ func AddGPGKey(ownerID int64, content, token, signature string) ([]*GPGKey, erro if original, has := id2key[id]; has { // Coalesce this with the other one for _, subkey := range ekey.Subkeys { + if subkey.PublicKey == nil { + continue + } + found := false + for _, originalSubkey := range original.Subkeys { - if subkey.PublicKey == nil || originalSubkey.PublicKey == nil { + if originalSubkey.PublicKey == nil { continue } if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId { - continue + found = true + break } + } + if !found { original.Subkeys = append(original.Subkeys, subkey) - break } } for name, identity := range ekey.Identities { From e4c3a9b89da1f1d5291962f624bede4a49732258 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 7 Oct 2021 18:18:07 +0100 Subject: [PATCH 3/3] rename to newEKeys Signed-off-by: Andrew Thornton --- models/gpg_key_add.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/models/gpg_key_add.go b/models/gpg_key_add.go index 4b09e7964853e..711fc86dee5f2 100644 --- a/models/gpg_key_add.go +++ b/models/gpg_key_add.go @@ -103,7 +103,7 @@ func AddGPGKey(ownerID int64, content, token, signature string) ([]*GPGKey, erro if len(ekeys) > 1 { id2key := map[string]*openpgp.Entity{} - newKeys := make([]*openpgp.Entity, 0, len(ekeys)) + newEKeys := make([]*openpgp.Entity, 0, len(ekeys)) for _, ekey := range ekeys { id := ekey.PrimaryKey.KeyIdString() if original, has := id2key[id]; has { @@ -136,9 +136,9 @@ func AddGPGKey(ownerID int64, content, token, signature string) ([]*GPGKey, erro continue } id2key[id] = ekey - newKeys = append(newKeys, ekey) + newEKeys = append(newEKeys, ekey) } - ekeys = newKeys + ekeys = newEKeys } for _, ekey := range ekeys {