1
0
Fork 0
forked from forgejo/forgejo

Switch plaintext scratch tokens to use hash instead (#4331)

This commit is contained in:
techknowlogick 2018-07-27 08:54:50 -04:00 committed by GitHub
parent ac968c3c6f
commit adf3f004b6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 118 additions and 12 deletions

View file

@ -9,12 +9,15 @@ import (
"crypto/cipher"
"crypto/md5"
"crypto/rand"
"crypto/sha256"
"crypto/subtle"
"encoding/base64"
"errors"
"fmt"
"io"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/pbkdf2"
"code.gitea.io/gitea/modules/generate"
"code.gitea.io/gitea/modules/setting"
@ -26,20 +29,27 @@ type TwoFactor struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE"`
Secret string
ScratchToken string
ScratchSalt string
ScratchHash string
LastUsedPasscode string `xorm:"VARCHAR(10)"`
CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
}
// GenerateScratchToken recreates the scratch token the user is using.
func (t *TwoFactor) GenerateScratchToken() error {
func (t *TwoFactor) GenerateScratchToken() (string, error) {
token, err := generate.GetRandomString(8)
if err != nil {
return err
return "", err
}
t.ScratchToken = token
return nil
t.ScratchSalt, _ = generate.GetRandomString(10)
t.ScratchHash = hashToken(token, t.ScratchSalt)
return token, nil
}
func hashToken(token, salt string) string {
tempHash := pbkdf2.Key([]byte(token), []byte(salt), 10000, 50, sha256.New)
return fmt.Sprintf("%x", tempHash)
}
// VerifyScratchToken verifies if the specified scratch token is valid.
@ -47,7 +57,8 @@ func (t *TwoFactor) VerifyScratchToken(token string) bool {
if len(token) == 0 {
return false
}
return subtle.ConstantTimeCompare([]byte(token), []byte(t.ScratchToken)) == 1
tempHash := hashToken(token, t.ScratchSalt)
return subtle.ConstantTimeCompare([]byte(t.ScratchHash), []byte(tempHash)) == 1
}
func (t *TwoFactor) getEncryptionKey() []byte {
@ -118,7 +129,7 @@ func aesDecrypt(key, text []byte) ([]byte, error) {
// NewTwoFactor creates a new two-factor authentication token.
func NewTwoFactor(t *TwoFactor) error {
err := t.GenerateScratchToken()
_, err := t.GenerateScratchToken()
if err != nil {
return err
}