diff options
author | techknowlogick <techknowlogick@users.noreply.github.com> | 2018-07-27 08:54:50 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-27 08:54:50 -0400 |
commit | adf3f004b65135e9375ae60dfd0d9ecba340342e (patch) | |
tree | 7878b7c6cd11a6f0911f36d71b358e73ea5bfbce /models/twofactor.go | |
parent | ac968c3c6fab89043e11d44b656f2feea01b5931 (diff) | |
download | gitea-adf3f004b65135e9375ae60dfd0d9ecba340342e.tar.gz gitea-adf3f004b65135e9375ae60dfd0d9ecba340342e.zip |
Switch plaintext scratch tokens to use hash instead (#4331)
Diffstat (limited to 'models/twofactor.go')
-rw-r--r-- | models/twofactor.go | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/models/twofactor.go b/models/twofactor.go index 5f3c6efc21..be37c50b46 100644 --- a/models/twofactor.go +++ b/models/twofactor.go @@ -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 } |