// Copyright 2025 The Gogs Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package database import ( "context" "github.com/pkg/errors" "gogs.io/gogs/internal/gpgutil" ) // VerifyCommitSignature verifies a commit signature against the user's GPG keys. // It returns verification information including whether the signature is valid. func (db *DB) VerifyCommitSignature(ctx context.Context, commitContent string, authorEmail string) (*gpgutil.CommitVerification, error) { // Extract signature from commit signature, payload, hasSig := gpgutil.ExtractSignature(commitContent) if !hasSig { return &gpgutil.CommitVerification{ Verified: false, Reason: "no signature", }, nil } // Find user by email user, err := db.Users().GetByEmail(ctx, authorEmail) if err != nil { return &gpgutil.CommitVerification{ Verified: false, Reason: "user not found", }, nil } // Get all GPG keys for the user keys, err := db.GPGKeys().List(ctx, user.ID) if err != nil { return nil, errors.Wrap(err, "list GPG keys") } if len(keys) == 0 { return &gpgutil.CommitVerification{ Verified: false, Reason: "no GPG keys found", }, nil } // Create keyring from user's GPG keys var armoredKeys []string for _, key := range keys { if key.CanSign && !key.IsExpired() { armoredKeys = append(armoredKeys, key.Content) } } if len(armoredKeys) == 0 { return &gpgutil.CommitVerification{ Verified: false, Reason: "no valid signing keys found", }, nil } keyring, err := gpgutil.CreateKeyring(armoredKeys) if err != nil { return nil, errors.Wrap(err, "create keyring") } // Verify the signature verification, err := gpgutil.VerifyCommitSignature(signature, payload, keyring) if err != nil { return nil, errors.Wrap(err, "verify signature") } return verification, nil }