code.gitea.io/gitea@v1.22.3/models/asymkey/ssh_key_verify.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package asymkey 5 6 import ( 7 "bytes" 8 "context" 9 10 "code.gitea.io/gitea/models/db" 11 "code.gitea.io/gitea/modules/log" 12 13 "github.com/42wim/sshsig" 14 ) 15 16 // VerifySSHKey marks a SSH key as verified 17 func VerifySSHKey(ctx context.Context, ownerID int64, fingerprint, token, signature string) (string, error) { 18 ctx, committer, err := db.TxContext(ctx) 19 if err != nil { 20 return "", err 21 } 22 defer committer.Close() 23 24 key := new(PublicKey) 25 26 has, err := db.GetEngine(ctx).Where("owner_id = ? AND fingerprint = ?", ownerID, fingerprint).Get(key) 27 if err != nil { 28 return "", err 29 } else if !has { 30 return "", ErrKeyNotExist{} 31 } 32 33 err = sshsig.Verify(bytes.NewBuffer([]byte(token)), []byte(signature), []byte(key.Content), "gitea") 34 if err != nil { 35 // edge case for Windows based shells that will add CR LF if piped to ssh-keygen command 36 // see https://github.com/PowerShell/PowerShell/issues/5974 37 if sshsig.Verify(bytes.NewBuffer([]byte(token+"\r\n")), []byte(signature), []byte(key.Content), "gitea") != nil { 38 log.Error("Unable to validate token signature. Error: %v", err) 39 return "", ErrSSHInvalidTokenSignature{ 40 Fingerprint: key.Fingerprint, 41 } 42 } 43 } 44 45 key.Verified = true 46 if _, err := db.GetEngine(ctx).ID(key.ID).Cols("verified").Update(key); err != nil { 47 return "", err 48 } 49 50 if err := committer.Commit(); err != nil { 51 return "", err 52 } 53 54 return key.Fingerprint, nil 55 }