go back to using CFB for AES decryption/encryption for 2FA (#3274)
This commit is contained in:
		
							parent
							
								
									d2736e268b
								
							
						
					
					
						commit
						edce41ae65
					
				
					 1 changed files with 44 additions and 3 deletions
				
			
		|  | @ -5,11 +5,15 @@ | |||
| package models | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/aes" | ||||
| 	"crypto/cipher" | ||||
| 	"crypto/md5" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/subtle" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/Unknwon/com" | ||||
| 	"github.com/pquerna/otp/totp" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/base" | ||||
|  | @ -52,7 +56,7 @@ func (t *TwoFactor) getEncryptionKey() []byte { | |||
| 
 | ||||
| // SetSecret sets the 2FA secret.
 | ||||
| func (t *TwoFactor) SetSecret(secret string) error { | ||||
| 	secretBytes, err := com.AESGCMEncrypt(t.getEncryptionKey(), []byte(secret)) | ||||
| 	secretBytes, err := aesEncrypt(t.getEncryptionKey(), []byte(secret)) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | @ -66,7 +70,7 @@ func (t *TwoFactor) ValidateTOTP(passcode string) (bool, error) { | |||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| 	secret, err := com.AESGCMDecrypt(t.getEncryptionKey(), decodedStoredSecret) | ||||
| 	secret, err := aesDecrypt(t.getEncryptionKey(), decodedStoredSecret) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
|  | @ -74,6 +78,43 @@ func (t *TwoFactor) ValidateTOTP(passcode string) (bool, error) { | |||
| 	return totp.Validate(passcode, secretStr), nil | ||||
| } | ||||
| 
 | ||||
| // aesEncrypt encrypts text and given key with AES.
 | ||||
| func aesEncrypt(key, text []byte) ([]byte, error) { | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	b := base64.StdEncoding.EncodeToString(text) | ||||
| 	ciphertext := make([]byte, aes.BlockSize+len(b)) | ||||
| 	iv := ciphertext[:aes.BlockSize] | ||||
| 	if _, err := io.ReadFull(rand.Reader, iv); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	cfb := cipher.NewCFBEncrypter(block, iv) | ||||
| 	cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) | ||||
| 	return ciphertext, nil | ||||
| } | ||||
| 
 | ||||
| // aesDecrypt decrypts text and given key with AES.
 | ||||
| func aesDecrypt(key, text []byte) ([]byte, error) { | ||||
| 	block, err := aes.NewCipher(key) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if len(text) < aes.BlockSize { | ||||
| 		return nil, errors.New("ciphertext too short") | ||||
| 	} | ||||
| 	iv := text[:aes.BlockSize] | ||||
| 	text = text[aes.BlockSize:] | ||||
| 	cfb := cipher.NewCFBDecrypter(block, iv) | ||||
| 	cfb.XORKeyStream(text, text) | ||||
| 	data, err := base64.StdEncoding.DecodeString(string(text)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return data, nil | ||||
| } | ||||
| 
 | ||||
| // NewTwoFactor creates a new two-factor authentication token.
 | ||||
| func NewTwoFactor(t *TwoFactor) error { | ||||
| 	err := t.GenerateScratchToken() | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue