1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-28 05:08:37 +00:00

Improve instance wide ssh commit signing (#34341)

* Signed SSH commits can look in the UI like on GitHub, just like gpg keys today in Gitea
* SSH format can be added in gitea config
* SSH Signing worked before with DEFAULT_TRUST_MODEL=committer

`TRUSTED_SSH_KEYS` can be a list of additional ssh public key contents
to trust for every user of this instance

Closes #34329
Related #31392

---------

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
ChristopherHX
2025-06-11 12:32:55 +02:00
committed by GitHub
parent fbc3796f9e
commit c9505a26b9
22 changed files with 469 additions and 124 deletions

View File

@@ -4,7 +4,10 @@
package integration
import (
"crypto/ed25519"
"crypto/rand"
"encoding/base64"
"encoding/pem"
"fmt"
"net/url"
"os"
@@ -23,6 +26,7 @@ import (
"github.com/ProtonMail/go-crypto/openpgp/armor"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
)
func TestGPGGit(t *testing.T) {
@@ -42,6 +46,37 @@ func TestGPGGit(t *testing.T) {
defer test.MockVariableValue(&setting.Repository.Signing.InitialCommit, []string{"never"})()
defer test.MockVariableValue(&setting.Repository.Signing.CRUDActions, []string{"never"})()
testGitSigning(t)
}
func TestSSHGit(t *testing.T) {
tmpDir := t.TempDir() // use a temp dir to store the SSH keys
err := os.Chmod(tmpDir, 0o700)
assert.NoError(t, err)
pub, priv, err := ed25519.GenerateKey(rand.Reader)
require.NoError(t, err, "ed25519.GenerateKey")
sshPubKey, err := ssh.NewPublicKey(pub)
require.NoError(t, err, "ssh.NewPublicKey")
err = os.WriteFile(tmpDir+"/id_ed25519.pub", ssh.MarshalAuthorizedKey(sshPubKey), 0o600)
require.NoError(t, err, "os.WriteFile id_ed25519.pub")
block, err := ssh.MarshalPrivateKey(priv, "")
require.NoError(t, err, "ssh.MarshalPrivateKey")
err = os.WriteFile(tmpDir+"/id_ed25519", pem.EncodeToMemory(block), 0o600)
require.NoError(t, err, "os.WriteFile id_ed25519")
defer test.MockVariableValue(&setting.Repository.Signing.SigningKey, tmpDir+"/id_ed25519.pub")()
defer test.MockVariableValue(&setting.Repository.Signing.SigningName, "gitea")()
defer test.MockVariableValue(&setting.Repository.Signing.SigningEmail, "gitea@fake.local")()
defer test.MockVariableValue(&setting.Repository.Signing.SigningFormat, "ssh")()
defer test.MockVariableValue(&setting.Repository.Signing.InitialCommit, []string{"never"})()
defer test.MockVariableValue(&setting.Repository.Signing.CRUDActions, []string{"never"})()
testGitSigning(t)
}
func testGitSigning(t *testing.T) {
username := "user2"
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: username})
baseAPITestContext := NewAPITestContext(t, username, "repo1")