From d9c18cbba01b259615ac5da851164c8e20240a23 Mon Sep 17 00:00:00 2001
From: zeripath
Date: Tue, 7 Jul 2020 01:13:18 +0100
Subject: Ensure Subkeys are verified (#12155) (#12168)

Backport #12155

When attempting to verify subkeys the email address verification step
requires checking the emails however, these emails are not stored on
subkeys but instead on the primary key.

This PR will obtain the primaryKey and check against these emails too.

Fix #12128

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>

Co-authored-by: techknowlogick <techknowlogick@gitea.io>---
 models/gpg_key.go | 42 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)

diff --git a/models/gpg_key.go b/models/gpg_key.go
index 49e510839..309d914bb 100644
--- a/models/gpg_key.go
+++ b/models/gpg_key.go
@@ -509,6 +509,18 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
 		return nil
 	}
 	for _, key := range keys {
+		var primaryKeys []*GPGKey
+		if key.PrimaryKeyID != "" {
+			primaryKeys, err = GetGPGKeysByKeyID(key.PrimaryKeyID)
+			if err != nil {
+				log.Error("GetGPGKeysByKeyID: %v", err)
+				return &CommitVerification{
+					CommittingUser: committer,
+					Verified:       false,
+					Reason:         "gpg.error.failed_retrieval_gpg_keys",
+				}
+			}
+		}
 		activated := false
 		if len(email) != 0 {
 			for _, e := range key.Emails {
@@ -518,6 +530,20 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
 					break
 				}
 			}
+			if !activated {
+				for _, pkey := range primaryKeys {
+					for _, e := range pkey.Emails {
+						if e.IsActivated && strings.EqualFold(e.Email, email) {
+							activated = true
+							email = e.Email
+							break
+						}
+					}
+					if activated {
+						break
+					}
+				}
+			}
 		} else {
 			for _, e := range key.Emails {
 				if e.IsActivated {
@@ -526,7 +552,22 @@ func hashAndVerifyForKeyID(sig *packet.Signature, payload string, committer *Use
 					break
 				}
 			}
+			if !activated {
+				for _, pkey := range primaryKeys {
+					for _, e := range pkey.Emails {
+						if e.IsActivated {
+							activated = true
+							email = e.Email
+							break
+						}
+					}
+					if activated {
+						break
+					}
+				}
+			}
 		}
+
 		if !activated {
 			continue
 		}
@@ -614,7 +655,6 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
 	if keyID == "" && sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) > 0 {
 		keyID = fmt.Sprintf("%X", sig.IssuerFingerprint[12:20])
 	}
-
 	defaultReason := NoKeyFound
 
 	// First check if the sig has a keyID and if so just look at that
-- 
cgit v1.2.3