summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorsilverwind <me@silverwind.io>2021-05-10 08:45:17 +0200
committerGitHub <noreply@github.com>2021-05-10 07:45:17 +0100
commit1e6fa57acbe3c05cb996b789e8c2d381c953826f (patch)
treec4f1ce55b3423f97952b630462cef5b2035961ec /modules
parent270aab429ef025df9a0b9bf9e3982729ae8df449 (diff)
downloadgitea-1e6fa57acbe3c05cb996b789e8c2d381c953826f.tar.gz
gitea-1e6fa57acbe3c05cb996b789e8c2d381c953826f.zip
Use single shared random string generation function (#15741)
* Use single shared random string generation function - Replace 3 functions that do the same with 1 shared one - Use crypto/rand over math/rand for a stronger RNG - Output only alphanumerical for URL compatibilty Fixes: #15536 * use const string method * Update modules/avatar/avatar.go Co-authored-by: a1012112796 <1012112796@qq.com> Co-authored-by: a1012112796 <1012112796@qq.com>
Diffstat (limited to 'modules')
-rw-r--r--modules/avatar/avatar.go10
-rw-r--r--modules/avatar/avatar_test.go13
-rw-r--r--modules/context/secret.go100
-rw-r--r--modules/generate/generate.go32
-rw-r--r--modules/generate/generate_test.go24
-rw-r--r--modules/secret/secret.go19
-rw-r--r--modules/secret/secret_test.go2
-rw-r--r--modules/util/util.go27
-rw-r--r--modules/util/util_test.go38
9 files changed, 87 insertions, 178 deletions
diff --git a/modules/avatar/avatar.go b/modules/avatar/avatar.go
index 44b56c26ce..bb9c2e953b 100644
--- a/modules/avatar/avatar.go
+++ b/modules/avatar/avatar.go
@@ -12,10 +12,9 @@ import (
// Enable PNG support:
_ "image/png"
- "math/rand"
- "time"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/util"
"github.com/issue9/identicon"
"github.com/nfnt/resize"
@@ -29,8 +28,11 @@ const AvatarSize = 290
// in custom size (height and width).
func RandomImageSize(size int, data []byte) (image.Image, error) {
randExtent := len(palette.WebSafe) - 32
- rand.Seed(time.Now().UnixNano())
- colorIndex := rand.Intn(randExtent)
+ integer, err := util.RandomInt(int64(randExtent))
+ if err != nil {
+ return nil, fmt.Errorf("util.RandomInt: %v", err)
+ }
+ colorIndex := int(integer)
backColorIndex := colorIndex - 1
if backColorIndex < 0 {
backColorIndex = randExtent - 1
diff --git a/modules/avatar/avatar_test.go b/modules/avatar/avatar_test.go
index 8535605652..f48266c858 100644
--- a/modules/avatar/avatar_test.go
+++ b/modules/avatar/avatar_test.go
@@ -13,12 +13,17 @@ import (
"github.com/stretchr/testify/assert"
)
-func Test_RandomImage(t *testing.T) {
- _, err := RandomImage([]byte("gogs@local"))
+func Test_RandomImageSize(t *testing.T) {
+ _, err := RandomImageSize(0, []byte("gitea@local"))
+ assert.Error(t, err)
+
+ _, err = RandomImageSize(64, []byte("gitea@local"))
assert.NoError(t, err)
+}
- _, err = RandomImageSize(0, []byte("gogs@local"))
- assert.Error(t, err)
+func Test_RandomImage(t *testing.T) {
+ _, err := RandomImage([]byte("gitea@local"))
+ assert.NoError(t, err)
}
func Test_PrepareWithPNG(t *testing.T) {
diff --git a/modules/context/secret.go b/modules/context/secret.go
deleted file mode 100644
index fcb488d211..0000000000
--- a/modules/context/secret.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package context
-
-import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/rand"
- "crypto/sha256"
- "encoding/base64"
- "errors"
- "io"
-)
-
-// NewSecret creates a new secret
-func NewSecret() (string, error) {
- return NewSecretWithLength(32)
-}
-
-// NewSecretWithLength creates a new secret for a given length
-func NewSecretWithLength(length int64) (string, error) {
- return randomString(length)
-}
-
-func randomBytes(len int64) ([]byte, error) {
- b := make([]byte, len)
- if _, err := rand.Read(b); err != nil {
- return nil, err
- }
- return b, nil
-}
-
-func randomString(len int64) (string, error) {
- b, err := randomBytes(len)
- return base64.URLEncoding.EncodeToString(b), err
-}
-
-// 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
-}
-
-// EncryptSecret encrypts a string with given key into a hex string
-func EncryptSecret(key string, str string) (string, error) {
- keyHash := sha256.Sum256([]byte(key))
- plaintext := []byte(str)
- ciphertext, err := AesEncrypt(keyHash[:], plaintext)
- if err != nil {
- return "", err
- }
- return base64.StdEncoding.EncodeToString(ciphertext), nil
-}
-
-// DecryptSecret decrypts a previously encrypted hex string
-func DecryptSecret(key string, cipherhex string) (string, error) {
- keyHash := sha256.Sum256([]byte(key))
- ciphertext, err := base64.StdEncoding.DecodeString(cipherhex)
- if err != nil {
- return "", err
- }
- plaintext, err := AesDecrypt(keyHash[:], ciphertext)
- if err != nil {
- return "", err
- }
- return string(plaintext), nil
-}
diff --git a/modules/generate/generate.go b/modules/generate/generate.go
index 304ad87f21..96589d3fb9 100644
--- a/modules/generate/generate.go
+++ b/modules/generate/generate.go
@@ -9,31 +9,12 @@ import (
"crypto/rand"
"encoding/base64"
"io"
- "math/big"
"time"
+ "code.gitea.io/gitea/modules/util"
"github.com/dgrijalva/jwt-go"
)
-// GetRandomString generate random string by specify chars.
-func GetRandomString(n int) (string, error) {
- const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
-
- buffer := make([]byte, n)
- max := big.NewInt(int64(len(alphanum)))
-
- for i := 0; i < n; i++ {
- index, err := randomInt(max)
- if err != nil {
- return "", err
- }
-
- buffer[i] = alphanum[index]
- }
-
- return string(buffer), nil
-}
-
// NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN.
func NewInternalToken() (string, error) {
secretBytes := make([]byte, 32)
@@ -69,19 +50,10 @@ func NewJwtSecret() (string, error) {
// NewSecretKey generate a new value intended to be used by SECRET_KEY.
func NewSecretKey() (string, error) {
- secretKey, err := GetRandomString(64)
+ secretKey, err := util.RandomString(64)
if err != nil {
return "", err
}
return secretKey, nil
}
-
-func randomInt(max *big.Int) (int, error) {
- rand, err := rand.Int(rand.Reader, max)
- if err != nil {
- return 0, err
- }
-
- return int(rand.Int64()), nil
-}
diff --git a/modules/generate/generate_test.go b/modules/generate/generate_test.go
deleted file mode 100644
index 1cacfe6681..0000000000
--- a/modules/generate/generate_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package generate
-
-import (
- "os"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestMain(m *testing.M) {
- retVal := m.Run()
-
- os.Exit(retVal)
-}
-
-func TestGetRandomString(t *testing.T) {
- randomString, err := GetRandomString(4)
- assert.NoError(t, err)
- assert.Len(t, randomString, 4)
-}
diff --git a/modules/secret/secret.go b/modules/secret/secret.go
index 2b6e22cc6c..7a06730c39 100644
--- a/modules/secret/secret.go
+++ b/modules/secret/secret.go
@@ -13,29 +13,18 @@ import (
"encoding/hex"
"errors"
"io"
+
+ "code.gitea.io/gitea/modules/util"
)
// New creats a new secret
func New() (string, error) {
- return NewWithLength(32)
+ return NewWithLength(44)
}
// NewWithLength creates a new secret for a given length
func NewWithLength(length int64) (string, error) {
- return randomString(length)
-}
-
-func randomBytes(len int64) ([]byte, error) {
- b := make([]byte, len)
- if _, err := rand.Read(b); err != nil {
- return nil, err
- }
- return b, nil
-}
-
-func randomString(len int64) (string, error) {
- b, err := randomBytes(len)
- return base64.URLEncoding.EncodeToString(b), err
+ return util.RandomString(length)
}
// AesEncrypt encrypts text and given key with AES.
diff --git a/modules/secret/secret_test.go b/modules/secret/secret_test.go
index 6531ffbebc..f3a88eecc8 100644
--- a/modules/secret/secret_test.go
+++ b/modules/secret/secret_test.go
@@ -13,7 +13,7 @@ import (
func TestNew(t *testing.T) {
result, err := New()
assert.NoError(t, err)
- assert.True(t, len(result) > 32)
+ assert.True(t, len(result) == 44)
result2, err := New()
assert.NoError(t, err)
diff --git a/modules/util/util.go b/modules/util/util.go
index 9de1710ac7..d26e6f13e4 100644
--- a/modules/util/util.go
+++ b/modules/util/util.go
@@ -6,7 +6,9 @@ package util
import (
"bytes"
+ "crypto/rand"
"errors"
+ "math/big"
"strings"
)
@@ -124,3 +126,28 @@ func MergeInto(dict map[string]interface{}, values ...interface{}) (map[string]i
return dict, nil
}
+
+// RandomInt returns a random integer between 0 and limit, inclusive
+func RandomInt(limit int64) (int64, error) {
+ int, err := rand.Int(rand.Reader, big.NewInt(limit))
+ if err != nil {
+ return 0, err
+ }
+ return int.Int64(), nil
+}
+
+const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+
+// RandomString generates a random alphanumerical string
+func RandomString(length int64) (string, error) {
+ bytes := make([]byte, length)
+ limit := int64(len(letters))
+ for i := range bytes {
+ num, err := RandomInt(limit)
+ if err != nil {
+ return "", err
+ }
+ bytes[i] = letters[num]
+ }
+ return string(bytes), nil
+}
diff --git a/modules/util/util_test.go b/modules/util/util_test.go
index 1d4f23de90..f82671787c 100644
--- a/modules/util/util_test.go
+++ b/modules/util/util_test.go
@@ -5,6 +5,7 @@
package util
import (
+ "regexp"
"strings"
"testing"
@@ -118,3 +119,40 @@ func Test_NormalizeEOL(t *testing.T) {
assert.Equal(t, []byte("mix\nand\nmatch\n."), NormalizeEOL([]byte("mix\r\nand\rmatch\n.")))
}
+
+func Test_RandomInt(t *testing.T) {
+ int, err := RandomInt(255)
+ assert.True(t, int >= 0)
+ assert.True(t, int <= 255)
+ assert.NoError(t, err)
+}
+
+func Test_RandomString(t *testing.T) {
+ str1, err := RandomString(32)
+ assert.NoError(t, err)
+ matches, err := regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
+ assert.NoError(t, err)
+ assert.True(t, matches)
+
+ str2, err := RandomString(32)
+ assert.NoError(t, err)
+ matches, err = regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
+ assert.NoError(t, err)
+ assert.True(t, matches)
+
+ assert.NotEqual(t, str1, str2)
+
+ str3, err := RandomString(256)
+ assert.NoError(t, err)
+ matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str3)
+ assert.NoError(t, err)
+ assert.True(t, matches)
+
+ str4, err := RandomString(256)
+ assert.NoError(t, err)
+ matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str4)
+ assert.NoError(t, err)
+ assert.True(t, matches)
+
+ assert.NotEqual(t, str3, str4)
+}