]> source.dussan.org Git - gitea.git/commitdiff
Handle duplicate keys on GPG key ring (#17242)
authorzeripath <art27@cantab.net>
Thu, 7 Oct 2021 20:10:14 +0000 (21:10 +0100)
committerGitHub <noreply@github.com>
Thu, 7 Oct 2021 20:10:14 +0000 (23:10 +0300)
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 <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
models/gpg_key_add.go

index 635872c920f5b0bf887f4e84307a5f7d843bdac4..711fc86dee5f280b4b4c43e2d3a5c2382dc579d2 100644 (file)
@@ -101,6 +101,46 @@ func AddGPGKey(ownerID int64, content, token, signature string) ([]*GPGKey, erro
                verified = true
        }
 
+       if len(ekeys) > 1 {
+               id2key := map[string]*openpgp.Entity{}
+               newEKeys := 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 {
+                                       if subkey.PublicKey == nil {
+                                               continue
+                                       }
+                                       found := false
+
+                                       for _, originalSubkey := range original.Subkeys {
+                                               if originalSubkey.PublicKey == nil {
+                                                       continue
+                                               }
+                                               if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId {
+                                                       found = true
+                                                       break
+                                               }
+                                       }
+                                       if !found {
+                                               original.Subkeys = append(original.Subkeys, subkey)
+                                       }
+                               }
+                               for name, identity := range ekey.Identities {
+                                       if _, has := original.Identities[name]; has {
+                                               continue
+                                       }
+                                       original.Identities[name] = identity
+                               }
+                               continue
+                       }
+                       id2key[id] = ekey
+                       newEKeys = append(newEKeys, ekey)
+               }
+               ekeys = newEKeys
+       }
+
        for _, ekey := range ekeys {
                // Key ID cannot be duplicated.
                has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()).