code.gitea.io/gitea@v1.22.3/models/asymkey/gpg_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 "context" 8 "strconv" 9 "time" 10 11 "code.gitea.io/gitea/models/db" 12 user_model "code.gitea.io/gitea/models/user" 13 "code.gitea.io/gitea/modules/base" 14 "code.gitea.io/gitea/modules/log" 15 ) 16 17 // __________________ ________ ____ __. 18 // / _____/\______ \/ _____/ | |/ _|____ ___.__. 19 // / \ ___ | ___/ \ ___ | <_/ __ < | | 20 // \ \_\ \| | \ \_\ \ | | \ ___/\___ | 21 // \______ /|____| \______ / |____|__ \___ > ____| 22 // \/ \/ \/ \/\/ 23 // ____ ____ .__ _____ 24 // \ \ / /___________|__|/ ____\__.__. 25 // \ Y // __ \_ __ \ \ __< | | 26 // \ /\ ___/| | \/ || | \___ | 27 // \___/ \___ >__| |__||__| / ____| 28 // \/ \/ 29 30 // This file provides functions relating verifying gpg keys 31 32 // VerifyGPGKey marks a GPG key as verified 33 func VerifyGPGKey(ctx context.Context, ownerID int64, keyID, token, signature string) (string, error) { 34 ctx, committer, err := db.TxContext(ctx) 35 if err != nil { 36 return "", err 37 } 38 defer committer.Close() 39 40 key := new(GPGKey) 41 42 has, err := db.GetEngine(ctx).Where("owner_id = ? AND key_id = ?", ownerID, keyID).Get(key) 43 if err != nil { 44 return "", err 45 } else if !has { 46 return "", ErrGPGKeyNotExist{} 47 } 48 49 if err := key.LoadSubKeys(ctx); err != nil { 50 return "", err 51 } 52 53 sig, err := extractSignature(signature) 54 if err != nil { 55 return "", ErrGPGInvalidTokenSignature{ 56 ID: key.KeyID, 57 Wrapped: err, 58 } 59 } 60 61 signer, err := hashAndVerifyWithSubKeys(sig, token, key) 62 if err != nil { 63 return "", ErrGPGInvalidTokenSignature{ 64 ID: key.KeyID, 65 Wrapped: err, 66 } 67 } 68 if signer == nil { 69 signer, err = hashAndVerifyWithSubKeys(sig, token+"\n", key) 70 if err != nil { 71 return "", ErrGPGInvalidTokenSignature{ 72 ID: key.KeyID, 73 Wrapped: err, 74 } 75 } 76 } 77 if signer == nil { 78 signer, err = hashAndVerifyWithSubKeys(sig, token+"\n\n", key) 79 if err != nil { 80 return "", ErrGPGInvalidTokenSignature{ 81 ID: key.KeyID, 82 Wrapped: err, 83 } 84 } 85 } 86 87 if signer == nil { 88 log.Error("Unable to validate token signature. Error: %v", err) 89 return "", ErrGPGInvalidTokenSignature{ 90 ID: key.KeyID, 91 } 92 } 93 94 if signer.PrimaryKeyID != key.KeyID && signer.KeyID != key.KeyID { 95 return "", ErrGPGKeyNotExist{} 96 } 97 98 key.Verified = true 99 if _, err := db.GetEngine(ctx).ID(key.ID).SetExpr("verified", true).Update(new(GPGKey)); err != nil { 100 return "", err 101 } 102 103 if err := committer.Commit(); err != nil { 104 return "", err 105 } 106 107 return key.KeyID, nil 108 } 109 110 // VerificationToken returns token for the user that will be valid in minutes (time) 111 func VerificationToken(user *user_model.User, minutes int) string { 112 return base.EncodeSha256( 113 time.Now().Truncate(1*time.Minute).Add(time.Duration(minutes)*time.Minute).Format( 114 time.RFC1123Z) + ":" + 115 user.CreatedUnix.Format(time.RFC1123Z) + ":" + 116 user.Name + ":" + 117 user.Email + ":" + 118 strconv.FormatInt(user.ID, 10)) 119 }