@@ -6,6 +6,7 @@ package asymkey
6
6
import (
7
7
"context"
8
8
"fmt"
9
+ "slices"
9
10
"strings"
10
11
11
12
asymkey_model "code.gitea.io/gitea/models/asymkey"
@@ -359,24 +360,39 @@ func VerifyWithGPGSettings(ctx context.Context, gpgSettings *git.GPGSettings, si
359
360
return nil
360
361
}
361
362
363
+ func verifySSHCommitVerificationByInstanceKey (c * git.Commit , committerUser , signerUser * user_model.User , committerGitEmail , publicKeyContent string ) * asymkey_model.CommitVerification {
364
+ fingerprint , err := asymkey_model .CalcFingerprint (publicKeyContent )
365
+ if err != nil {
366
+ log .Error ("Error calculating the fingerprint public key %q, err: %v" , publicKeyContent , err )
367
+ return nil
368
+ }
369
+ sshPubKey := & asymkey_model.PublicKey {
370
+ Verified : true ,
371
+ Content : publicKeyContent ,
372
+ Fingerprint : fingerprint ,
373
+ HasUsed : true ,
374
+ }
375
+ return verifySSHCommitVerification (c .Signature .Signature , c .Signature .Payload , sshPubKey , committerUser , signerUser , committerGitEmail )
376
+ }
377
+
362
378
// ParseCommitWithSSHSignature check if signature is good against keystore.
363
- func ParseCommitWithSSHSignature (ctx context.Context , c * git.Commit , committer * user_model.User ) * asymkey_model.CommitVerification {
379
+ func ParseCommitWithSSHSignature (ctx context.Context , c * git.Commit , committerUser * user_model.User ) * asymkey_model.CommitVerification {
364
380
// Now try to associate the signature with the committer, if present
365
- if committer .ID != 0 {
381
+ if committerUser .ID != 0 {
366
382
keys , err := db .Find [asymkey_model.PublicKey ](ctx , asymkey_model.FindPublicKeyOptions {
367
- OwnerID : committer .ID ,
383
+ OwnerID : committerUser .ID ,
368
384
NotKeytype : asymkey_model .KeyTypePrincipal ,
369
385
})
370
386
if err != nil { // Skipping failed to get ssh keys of user
371
387
log .Error ("ListPublicKeys: %v" , err )
372
388
return & asymkey_model.CommitVerification {
373
- CommittingUser : committer ,
389
+ CommittingUser : committerUser ,
374
390
Verified : false ,
375
391
Reason : "gpg.error.failed_retrieval_gpg_keys" ,
376
392
}
377
393
}
378
394
379
- committerEmailAddresses , err := cache .GetWithContextCache (ctx , cachegroup .UserEmailAddresses , committer .ID , user_model .GetEmailAddresses )
395
+ committerEmailAddresses , err := cache .GetWithContextCache (ctx , cachegroup .UserEmailAddresses , committerUser .ID , user_model .GetEmailAddresses )
380
396
if err != nil {
381
397
log .Error ("GetEmailAddresses: %v" , err )
382
398
}
@@ -391,64 +407,51 @@ func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *
391
407
392
408
for _ , k := range keys {
393
409
if k .Verified && activated {
394
- commitVerification := verifySSHCommitVerification (c .Signature .Signature , c .Signature .Payload , k , committer , committer , c .Committer .Email )
410
+ commitVerification := verifySSHCommitVerification (c .Signature .Signature , c .Signature .Payload , k , committerUser , committerUser , c .Committer .Email )
395
411
if commitVerification != nil {
396
412
return commitVerification
397
413
}
398
414
}
399
415
}
400
416
}
401
- // Trust more than one key for every User
417
+
418
+ // Try the pre-set trusted keys (for key-rotation purpose)
402
419
for _ , k := range setting .Repository .Signing .TrustedSSHKeys {
403
- if fingerprint , err := asymkey_model .CalcFingerprint (k ); err != nil {
404
- log .Error ("Error calculating the fingerprint public key: %s %v" , k , err )
405
- } else if commitVerification := verifySSHCommitVerification (c .Signature .Signature , c .Signature .Payload , & asymkey_model.PublicKey {
406
- Verified : true ,
407
- Content : k ,
408
- Fingerprint : fingerprint ,
409
- HasUsed : true ,
410
- }, committer , committer , c .Committer .Email ); commitVerification != nil {
420
+ // FIXME: why here uses "commiterUser" as "signerUser" but below don't? why here uses "c.Committer.Email" but below uses "gpgSettings.Email"?
421
+ signerUser := committerUser
422
+ commitVerification := verifySSHCommitVerificationByInstanceKey (c , committerUser , signerUser , c .Committer .Email , k )
423
+ if commitVerification != nil && commitVerification .Verified {
411
424
return commitVerification
412
425
}
413
426
}
414
427
415
- defaultReason := asymkey_model .NoKeyFound
416
-
417
- // Covers ssh verification for the default SSH signing key specified in gitea config
418
- if setting .Repository .Signing .SigningFormat == git .KeyTypeSSH && setting .Repository .Signing .SigningKey != "" && setting .Repository .Signing .SigningKey != "default" && setting .Repository .Signing .SigningKey != "none" {
419
- // OK we should try the default key
428
+ // Try the configured instance-wide SSH public key
429
+ if setting .Repository .Signing .SigningFormat == git .KeyTypeSSH && ! slices .Contains ([]string {"" , "default" , "none" }, setting .Repository .Signing .SigningKey ) {
420
430
gpgSettings := git.GPGSettings {
421
431
Sign : true ,
422
432
KeyID : setting .Repository .Signing .SigningKey ,
423
433
Name : setting .Repository .Signing .SigningName ,
424
434
Email : setting .Repository .Signing .SigningEmail ,
425
435
Format : setting .Repository .Signing .SigningFormat ,
426
436
}
427
- if err := gpgSettings .LoadPublicKeyContent (); err != nil {
428
- log .Error ("Error getting default signing key: %s %v" , gpgSettings .KeyID , err )
429
- } else if fingerprint , err := asymkey_model .CalcFingerprint (gpgSettings .PublicKeyContent ); err != nil {
430
- log .Error ("Error calculating the fingerprint public key: %s %v" , gpgSettings .KeyID , err )
431
- } else if commitVerification := verifySSHCommitVerification (c .Signature .Signature , c .Signature .Payload , & asymkey_model.PublicKey {
432
- Verified : true ,
433
- Content : gpgSettings .PublicKeyContent ,
434
- Fingerprint : fingerprint ,
435
- HasUsed : true ,
436
- }, committer , & user_model.User {
437
+ signerUser := & user_model.User {
437
438
Name : gpgSettings .Name ,
438
439
Email : gpgSettings .Email ,
439
- }, gpgSettings .Email ); commitVerification != nil {
440
- if commitVerification .Reason == asymkey_model .BadSignature {
441
- defaultReason = asymkey_model .BadSignature
442
- } else {
440
+ }
441
+ if err := gpgSettings .LoadPublicKeyContent (); err != nil {
442
+ log .Error ("Error getting instance-wide SSH signing key %q, err: %v" , gpgSettings .KeyID , err )
443
+ } else {
444
+ commitVerification := verifySSHCommitVerificationByInstanceKey (c , committerUser , signerUser , gpgSettings .Email , gpgSettings .PublicKeyContent )
445
+ if commitVerification != nil && commitVerification .Verified {
443
446
return commitVerification
444
447
}
445
448
}
446
449
}
447
450
448
451
return & asymkey_model.CommitVerification {
449
- CommittingUser : committer ,
452
+ CommittingUser : committerUser ,
450
453
Verified : false ,
451
- Reason : defaultReason ,
454
+ Reason : asymkey_model . NoKeyFound ,
452
455
}
453
456
}
454
457
0 commit comments