Browse Source

auth: remove MD5 for secure cookie secret (#4117)

Update vendor accordingly
Unknwon 8 years ago
parent
commit
bd786b8ef0

+ 2 - 3
routers/user/auth.go

@@ -55,7 +55,7 @@ func AutoSignIn(ctx *context.Context) (bool, error) {
 		return false, nil
 	}
 
-	if val, ok := ctx.GetSuperSecureCookie(base.EncodeMD5(u.Rands+u.Passwd), setting.CookieRememberName); !ok || val != u.Name {
+	if val, ok := ctx.GetSuperSecureCookie(u.Rands+u.Passwd, setting.CookieRememberName); !ok || val != u.Name {
 		return false, nil
 	}
 
@@ -124,8 +124,7 @@ func SignInPost(ctx *context.Context, form auth.SignInForm) {
 	if form.Remember {
 		days := 86400 * setting.LogInRememberDays
 		ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubUrl)
-		ctx.SetSuperSecureCookie(base.EncodeMD5(u.Rands+u.Passwd),
-			setting.CookieRememberName, u.Name, days, setting.AppSubUrl)
+		ctx.SetSuperSecureCookie(u.Rands+u.Passwd, setting.CookieRememberName, u.Name, days, setting.AppSubUrl)
 	}
 
 	ctx.Session.Set("uid", u.ID)

+ 31 - 21
vendor/github.com/Unknwon/com/string.go

@@ -19,9 +19,7 @@ import (
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/rand"
-	"encoding/base64"
 	"errors"
-	"io"
 	r "math/rand"
 	"strconv"
 	"strings"
@@ -30,41 +28,53 @@ import (
 	"unicode/utf8"
 )
 
-// AESEncrypt encrypts text and given key with AES.
-func AESEncrypt(key, text []byte) ([]byte, error) {
+// AESGCMEncrypt encrypts plaintext with the given key using AES in GCM mode.
+func AESGCMEncrypt(key, plaintext []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 {
+
+	gcm, err := cipher.NewGCM(block)
+	if err != nil {
 		return nil, err
 	}
-	cfb := cipher.NewCFBEncrypter(block, iv)
-	cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
-	return ciphertext, nil
+
+	nonce := make([]byte, gcm.NonceSize())
+	if _, err := rand.Read(nonce); err != nil {
+		return nil, err
+	}
+
+	ciphertext := gcm.Seal(nil, nonce, plaintext, nil)
+	return append(nonce, ciphertext...), nil
 }
 
-// AESDecrypt decrypts text and given key with AES.
-func AESDecrypt(key, text []byte) ([]byte, error) {
+// AESGCMDecrypt decrypts ciphertext with the given key using AES in GCM mode.
+func AESGCMDecrypt(key, ciphertext []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")
+
+	gcm, err := cipher.NewGCM(block)
+	if err != nil {
+		return nil, err
+	}
+
+	size := gcm.NonceSize()
+	if len(ciphertext)-size <= 0 {
+		return nil, errors.New("Ciphertext is empty")
 	}
-	iv := text[:aes.BlockSize]
-	text = text[aes.BlockSize:]
-	cfb := cipher.NewCFBDecrypter(block, iv)
-	cfb.XORKeyStream(text, text)
-	data, err := base64.StdEncoding.DecodeString(string(text))
+
+	nonce := ciphertext[:size]
+	ciphertext = ciphertext[size:]
+
+	plainText, err := gcm.Open(nil, nonce, ciphertext, nil)
 	if err != nil {
 		return nil, err
 	}
-	return data, nil
+
+	return plainText, nil
 }
 
 // IsLetter returns true if the 'l' is an English letter.

+ 10 - 11
vendor/gopkg.in/macaron.v1/context.go

@@ -15,7 +15,7 @@
 package macaron
 
 import (
-	"crypto/md5"
+	"crypto/sha256"
 	"encoding/hex"
 	"html/template"
 	"io"
@@ -32,8 +32,8 @@ import (
 	"time"
 
 	"github.com/Unknwon/com"
-
 	"github.com/go-macaron/inject"
+	"golang.org/x/crypto/pbkdf2"
 )
 
 // Locale reprents a localization interface.
@@ -419,30 +419,29 @@ func (ctx *Context) GetSecureCookie(key string) (string, bool) {
 
 // SetSuperSecureCookie sets given cookie value to response header with secret string.
 func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) {
-	m := md5.Sum([]byte(secret))
-	secret = hex.EncodeToString(m[:])
-	text, err := com.AESEncrypt([]byte(secret), []byte(value))
+	key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New)
+	text, err := com.AESGCMEncrypt(key, []byte(value))
 	if err != nil {
 		panic("error encrypting cookie: " + err.Error())
 	}
+
 	ctx.SetCookie(name, hex.EncodeToString(text), others...)
 }
 
 // GetSuperSecureCookie returns given cookie value from request header with secret string.
-func (ctx *Context) GetSuperSecureCookie(secret, key string) (string, bool) {
-	val := ctx.GetCookie(key)
+func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) {
+	val := ctx.GetCookie(name)
 	if val == "" {
 		return "", false
 	}
 
-	data, err := hex.DecodeString(val)
+	text, err := hex.DecodeString(val)
 	if err != nil {
 		return "", false
 	}
 
-	m := md5.Sum([]byte(secret))
-	secret = hex.EncodeToString(m[:])
-	text, err := com.AESDecrypt([]byte(secret), data)
+	key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New)
+	text, err = com.AESGCMDecrypt(key, text)
 	return string(text), err == nil
 }
 

+ 2 - 2
vendor/gopkg.in/macaron.v1/macaron.go

@@ -32,7 +32,7 @@ import (
 	"github.com/go-macaron/inject"
 )
 
-const _VERSION = "1.2.0.0128"
+const _VERSION = "1.2.1.0213"
 
 func Version() string {
 	return _VERSION
@@ -144,7 +144,7 @@ func New() *Macaron {
 }
 
 // Classic creates a classic Macaron with some basic default middleware:
-// mocaron.Logger, mocaron.Recovery and mocaron.Static.
+// macaron.Logger, macaron.Recovery and macaron.Static.
 func Classic() *Macaron {
 	m := New()
 	m.Use(Logger())

+ 6 - 6
vendor/vendor.json

@@ -15,10 +15,10 @@
 			"revisionTime": "2016-07-15T03:28:08Z"
 		},
 		{
-			"checksumSHA1": "ly9VLPE9GKo2U7mnbZyjb2LDQ3w=",
+			"checksumSHA1": "7HXb3cry6luicWeJM9Uxwzfo9Rs=",
 			"path": "github.com/Unknwon/com",
-			"revision": "28b053d5a2923b87ce8c5a08f3af779894a72758",
-			"revisionTime": "2015-10-08T13:54:07Z"
+			"revision": "0db4a625e949e956314d7d1adea9bf82384cc10c",
+			"revisionTime": "2017-02-13T07:20:14Z"
 		},
 		{
 			"checksumSHA1": "gSAaJ38R4iqG2CEsZe/ftOs3V9w=",
@@ -543,10 +543,10 @@
 			"revisionTime": "2016-08-08T14:54:09Z"
 		},
 		{
-			"checksumSHA1": "QbG9fWct1WpeoLw+f2ScWxIOuVw=",
+			"checksumSHA1": "XevKi11X5xpgqjYIahVgsx/8pFk=",
 			"path": "gopkg.in/macaron.v1",
-			"revision": "2e636df8e98d0382b1bab92f8d82d08c72a72016",
-			"revisionTime": "2017-01-28T20:05:53Z"
+			"revision": "a325110f8b392bce3e5cdeb8c44bf98078ada3be",
+			"revisionTime": "2017-02-13T09:12:08Z"
 		},
 		{
 			"checksumSHA1": "6QPjE+qflEBHg+JPJd9e4iQuRAk=",