Browse code

Add GenerateNonCryptoID function to avoid entropy exhaustion

Signed-off-by: Alexander Morozov <lk4d4@docker.com>

Alexander Morozov authored on 2015/07/29 09:16:06
Showing 1 changed files
... ...
@@ -7,6 +7,8 @@ import (
7 7
 	"io"
8 8
 	"regexp"
9 9
 	"strconv"
10
+
11
+	"github.com/docker/docker/pkg/random"
10 12
 )
11 13
 
12 14
 const shortLen = 12
... ...
@@ -30,20 +32,36 @@ func TruncateID(id string) string {
30 30
 	return id[:trimTo]
31 31
 }
32 32
 
33
-// GenerateRandomID returns an unique id.
34
-func GenerateRandomID() string {
33
+func generateID(crypto bool) string {
34
+	b := make([]byte, 32)
35
+	var r io.Reader = random.Reader
36
+	if crypto {
37
+		r = rand.Reader
38
+	}
35 39
 	for {
36
-		id := make([]byte, 32)
37
-		if _, err := io.ReadFull(rand.Reader, id); err != nil {
40
+		if _, err := io.ReadFull(r, b); err != nil {
38 41
 			panic(err) // This shouldn't happen
39 42
 		}
40
-		value := hex.EncodeToString(id)
43
+		id := hex.EncodeToString(b)
41 44
 		// if we try to parse the truncated for as an int and we don't have
42 45
 		// an error then the value is all numberic and causes issues when
43 46
 		// used as a hostname. ref #3869
44
-		if _, err := strconv.ParseInt(TruncateID(value), 10, 64); err == nil {
47
+		if _, err := strconv.ParseInt(TruncateID(id), 10, 64); err == nil {
45 48
 			continue
46 49
 		}
47
-		return value
50
+		return id
48 51
 	}
49 52
 }
53
+
54
+// GenerateRandomID returns an unique id.
55
+func GenerateRandomID() string {
56
+	return generateID(true)
57
+
58
+}
59
+
60
+// GenerateNonCryptoID generates unique id without using cryptographically
61
+// secure sources of random.
62
+// It helps you to save entropy.
63
+func GenerateNonCryptoID() string {
64
+	return generateID(false)
65
+}