Pad GPG Key ID with preceding zeroes (#20878) (#20885)

Backport #20878

The go crypto library does not pad keyIDs to 16 characters with preceding zeroes. This
is a somewhat confusing thing for most users who expect these to have preceding zeroes.

This PR prefixes any sub 16 length KeyID with preceding zeroes and removes preceding
zeroes from KeyIDs inputted on the API.

Fix #20876

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2022-08-22 19:35:18 +01:00 committed by GitHub
parent 033178f2fc
commit bf41958c16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 8 deletions

View file

@ -63,6 +63,15 @@ func (key *GPGKey) AfterLoad(session *xorm.Session) {
} }
} }
// PaddedKeyID show KeyID padded to 16 characters
func (key *GPGKey) PaddedKeyID() string {
if len(key.KeyID) > 15 {
return key.KeyID
}
zeros := "0000000000000000"
return zeros[0:16-len(key.KeyID)] + key.KeyID
}
// ListGPGKeys returns a list of public keys belongs to given user. // ListGPGKeys returns a list of public keys belongs to given user.
func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) { func ListGPGKeys(ctx context.Context, uid int64, listOptions db.ListOptions) ([]*GPGKey, error) {
sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid) sess := db.GetEngine(ctx).Table(&GPGKey{}).Where("owner_id=? AND primary_key_id=''", uid)

View file

@ -7,6 +7,7 @@ package user
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"strings"
asymkey_model "code.gitea.io/gitea/models/asymkey" asymkey_model "code.gitea.io/gitea/models/asymkey"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -177,6 +178,12 @@ func VerifyUserGPGKey(ctx *context.APIContext) {
token := asymkey_model.VerificationToken(ctx.Doer, 1) token := asymkey_model.VerificationToken(ctx.Doer, 1)
lastToken := asymkey_model.VerificationToken(ctx.Doer, 0) lastToken := asymkey_model.VerificationToken(ctx.Doer, 0)
form.KeyID = strings.TrimLeft(form.KeyID, "0")
if form.KeyID == "" {
ctx.NotFound()
return
}
_, err := asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, token, form.Signature) _, err := asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, token, form.Signature)
if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) { if err != nil && asymkey_model.IsErrGPGInvalidTokenSignature(err) {
_, err = asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, lastToken, form.Signature) _, err = asymkey_model.VerifyGPGKey(ctx.Doer.ID, form.KeyID, lastToken, form.Signature)

View file

@ -222,7 +222,7 @@
{{.Verification.SigningSSHKey.Fingerprint}} {{.Verification.SigningSSHKey.Fingerprint}}
{{else}} {{else}}
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
{{.Verification.SigningKey.KeyID}} {{.Verification.SigningKey.PaddedKeyID}}
{{end}} {{end}}
{{else}} {{else}}
{{svg "octicon-shield-lock" 16 "mr-3"}} {{svg "octicon-shield-lock" 16 "mr-3"}}
@ -231,7 +231,7 @@
{{.Verification.SigningSSHKey.Fingerprint}} {{.Verification.SigningSSHKey.Fingerprint}}
{{else}} {{else}}
<span class="ui text mr-3 tooltip" data-content="{{.i18n.Tr "gpg.default_key"}}">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <span class="ui text mr-3 tooltip" data-content="{{.i18n.Tr "gpg.default_key"}}">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
{{.Verification.SigningKey.KeyID}} {{.Verification.SigningKey.PaddedKeyID}}
{{end}} {{end}}
{{end}} {{end}}
{{else if .Verification.Warning}} {{else if .Verification.Warning}}
@ -241,14 +241,14 @@
{{.Verification.SigningSSHKey.Fingerprint}} {{.Verification.SigningSSHKey.Fingerprint}}
{{else}} {{else}}
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
{{.Verification.SigningKey.KeyID}} {{.Verification.SigningKey.PaddedKeyID}}
{{end}} {{end}}
{{else}} {{else}}
{{if .Verification.SigningKey}} {{if .Verification.SigningKey}}
{{if ne .Verification.SigningKey.KeyID ""}} {{if ne .Verification.SigningKey.KeyID ""}}
{{svg "octicon-shield" 16 "mr-3"}} {{svg "octicon-shield" 16 "mr-3"}}
<span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <span class="ui text mr-3">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span>
{{.Verification.SigningKey.KeyID}} {{.Verification.SigningKey.PaddedKeyID}}
{{end}} {{end}}
{{end}} {{end}}
{{if .Verification.SigningSSHKey}} {{if .Verification.SigningSSHKey}}

View file

@ -22,7 +22,7 @@
<input readonly="" value="{{.TokenToSign}}"> <input readonly="" value="{{.TokenToSign}}">
<div class="help"> <div class="help">
<p>{{.i18n.Tr "settings.gpg_token_help"}}</p> <p>{{.i18n.Tr "settings.gpg_token_help"}}</p>
<p><code>{{$.i18n.Tr "settings.gpg_token_code" .TokenToSign .KeyID}}</code></p> <p><code>{{$.i18n.Tr "settings.gpg_token_code" .TokenToSign .PaddedKeyID}}</code></p>
</div> </div>
</div> </div>
<div class="field"> <div class="field">
@ -64,8 +64,8 @@
<span class="tooltip" data-content="{{$.i18n.Tr "settings.gpg_key_matched_identities_long"}}">{{svg "octicon-mail"}} {{$.i18n.Tr "settings.gpg_key_matched_identities"}} {{range .Emails}}<strong>{{.Email}} </strong>{{end}}</span> <span class="tooltip" data-content="{{$.i18n.Tr "settings.gpg_key_matched_identities_long"}}">{{svg "octicon-mail"}} {{$.i18n.Tr "settings.gpg_key_matched_identities"}} {{range .Emails}}<strong>{{.Email}} </strong>{{end}}</span>
{{end}} {{end}}
<div class="print meta"> <div class="print meta">
<b>{{$.i18n.Tr "settings.key_id"}}:</b> {{.KeyID}} <b>{{$.i18n.Tr "settings.key_id"}}:</b> {{.PaddedKeyID}}
<b>{{$.i18n.Tr "settings.subkeys"}}:</b> {{range .SubsKey}} {{.KeyID}} {{end}} <b>{{$.i18n.Tr "settings.subkeys"}}:</b> {{range .SubsKey}} {{.PaddedKeyID}} {{end}}
</div> </div>
<div class="activity meta"> <div class="activity meta">
<i>{{$.i18n.Tr "settings.add_on"}} <span>{{.AddedUnix.FormatShort}}</span></i> <i>{{$.i18n.Tr "settings.add_on"}} <span>{{.AddedUnix.FormatShort}}</span></i>
@ -87,7 +87,7 @@
<input readonly="" value="{{$.TokenToSign}}"> <input readonly="" value="{{$.TokenToSign}}">
<div class="help"> <div class="help">
<p>{{$.i18n.Tr "settings.gpg_token_help"}}</p> <p>{{$.i18n.Tr "settings.gpg_token_help"}}</p>
<p><code>{{$.i18n.Tr "settings.gpg_token_code" $.TokenToSign .KeyID}}</code></p> <p><code>{{$.i18n.Tr "settings.gpg_token_code" $.TokenToSign .PaddedKeyID}}</code></p>
</div> </div>
<br> <br>
</div> </div>