Fix potential non-random UUIDs

Use ReadFull to fetch random bytes from crypto/rand instead of calling
Read directly as Read may read less bytes than asked.

Fix satori/go.uuid#73
This commit is contained in:
Josselin Costanzi 2018-04-04 18:55:56 +02:00
parent 36e9d2ebbd
commit 75cca531ea
2 changed files with 19 additions and 3 deletions

View File

@ -165,7 +165,7 @@ func (g *rfc4122Generator) NewV3(ns UUID, name string) UUID {
// NewV4 returns random generated UUID.
func (g *rfc4122Generator) NewV4() (UUID, error) {
u := UUID{}
if _, err := g.rand.Read(u[:]); err != nil {
if _, err := io.ReadFull(g.rand, u[:]); err != nil {
return Nil, err
}
u.SetVersion(V4)
@ -188,7 +188,7 @@ func (g *rfc4122Generator) getClockSequence() (uint64, uint16, error) {
var err error
g.clockSequenceOnce.Do(func() {
buf := make([]byte, 2)
if _, err = g.rand.Read(buf); err != nil {
if _, err = io.ReadFull(g.rand, buf); err != nil {
return
}
g.clockSequence = binary.BigEndian.Uint16(buf)
@ -222,7 +222,7 @@ func (g *rfc4122Generator) getHardwareAddr() ([]byte, error) {
// Initialize hardwareAddr randomly in case
// of real network interfaces absence.
if _, err = g.rand.Read(g.hardwareAddr[:]); err != nil {
if _, err = io.ReadFull(g.rand, g.hardwareAddr[:]); err != nil {
return
}
// Set multicast bit as recommended by RFC 4122

View File

@ -22,9 +22,11 @@
package uuid
import (
"bytes"
"crypto/rand"
"fmt"
"net"
"testing/iotest"
"time"
. "gopkg.in/check.v1"
@ -195,6 +197,20 @@ func (s *genTestSuite) TestNewV4FaultyRand(c *C) {
c.Assert(u1, Equals, Nil)
}
func (s *genTestSuite) TestNewV4PartialRead(c *C) {
g := &rfc4122Generator{
epochFunc: time.Now,
hwAddrFunc: defaultHWAddrFunc,
rand: iotest.OneByteReader(rand.Reader),
}
u1, err := g.NewV4()
zeros := bytes.Count(u1.Bytes(), []byte{0})
mostlyZeros := zeros >= 10
c.Assert(err, IsNil)
c.Assert(mostlyZeros, Equals, false)
}
func (s *genTestSuite) BenchmarkNewV4(c *C) {
for i := 0; i < c.N; i++ {
NewV4()