2021-07-13 16:28:07 +03:00
// Copyright 2021 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2021-07-13 16:28:07 +03:00
2021-12-10 11:14:24 +03:00
package asymkey
2021-07-13 16:28:07 +03:00
import (
"strconv"
"time"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2021-07-13 16:28:07 +03:00
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
)
// __________________ ________ ____ __.
// / _____/\______ \/ _____/ | |/ _|____ ___.__.
// / \ ___ | ___/ \ ___ | <_/ __ < | |
// \ \_\ \| | \ \_\ \ | | \ ___/\___ |
// \______ /|____| \______ / |____|__ \___ > ____|
// \/ \/ \/ \/\/
// ____ ____ .__ _____
// \ \ / /___________|__|/ ____\__.__.
// \ Y // __ \_ __ \ \ __< | |
// \ /\ ___/| | \/ || | \___ |
// \___/ \___ >__| |__||__| / ____|
// \/ \/
// This file provides functions relating verifying gpg keys
// VerifyGPGKey marks a GPG key as verified
func VerifyGPGKey ( ownerID int64 , keyID , token , signature string ) ( string , error ) {
2022-11-12 23:18:50 +03:00
ctx , committer , err := db . TxContext ( db . DefaultContext )
2021-09-19 14:49:59 +03:00
if err != nil {
2021-07-13 16:28:07 +03:00
return "" , err
}
2021-09-19 14:49:59 +03:00
defer committer . Close ( )
2021-07-13 16:28:07 +03:00
key := new ( GPGKey )
2021-09-23 18:45:36 +03:00
has , err := db . GetEngine ( ctx ) . Where ( "owner_id = ? AND key_id = ?" , ownerID , keyID ) . Get ( key )
2021-07-13 16:28:07 +03:00
if err != nil {
return "" , err
} else if ! has {
return "" , ErrGPGKeyNotExist { }
}
sig , err := extractSignature ( signature )
if err != nil {
return "" , ErrGPGInvalidTokenSignature {
ID : key . KeyID ,
Wrapped : err ,
}
}
signer , err := hashAndVerifyWithSubKeys ( sig , token , key )
if err != nil {
return "" , ErrGPGInvalidTokenSignature {
ID : key . KeyID ,
Wrapped : err ,
}
}
if signer == nil {
signer , err = hashAndVerifyWithSubKeys ( sig , token + "\n" , key )
if err != nil {
return "" , ErrGPGInvalidTokenSignature {
ID : key . KeyID ,
Wrapped : err ,
}
}
}
if signer == nil {
signer , err = hashAndVerifyWithSubKeys ( sig , token + "\n\n" , key )
if err != nil {
return "" , ErrGPGInvalidTokenSignature {
ID : key . KeyID ,
Wrapped : err ,
}
}
}
if signer == nil {
log . Error ( "Unable to validate token signature. Error: %v" , err )
return "" , ErrGPGInvalidTokenSignature {
ID : key . KeyID ,
}
}
if signer . PrimaryKeyID != key . KeyID && signer . KeyID != key . KeyID {
return "" , ErrGPGKeyNotExist { }
}
key . Verified = true
2021-09-23 18:45:36 +03:00
if _ , err := db . GetEngine ( ctx ) . ID ( key . ID ) . SetExpr ( "verified" , true ) . Update ( new ( GPGKey ) ) ; err != nil {
2021-07-13 16:28:07 +03:00
return "" , err
}
2021-09-19 14:49:59 +03:00
if err := committer . Commit ( ) ; err != nil {
2021-07-13 16:28:07 +03:00
return "" , err
}
return key . KeyID , nil
}
// VerificationToken returns token for the user that will be valid in minutes (time)
2021-11-24 12:49:20 +03:00
func VerificationToken ( user * user_model . User , minutes int ) string {
2021-07-13 16:28:07 +03:00
return base . EncodeSha256 (
time . Now ( ) . Truncate ( 1 * time . Minute ) . Add ( time . Duration ( minutes ) * time . Minute ) . Format ( time . RFC1123Z ) + ":" +
user . CreatedUnix . FormatLong ( ) + ":" +
user . Name + ":" +
user . Email + ":" +
strconv . FormatInt ( user . ID , 10 ) )
}