Switch blueprint commit to use a random SHA-1
Generating a SHA-1 based on time is not safe. A collision can easily be generated, and if parallel operations are used they will eventually collide. This reads random bytes and uses them for the SHA-1 hash. It will return an error if the rand.Read() fails.
This commit is contained in:
parent
c054015440
commit
642b90c977
2 changed files with 29 additions and 7 deletions
|
|
@ -4,9 +4,11 @@ package store
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
|
@ -223,6 +225,19 @@ func writeFileAtomically(filename string, data []byte, mode os.FileMode) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func randomSHA1String() (string, error) {
|
||||
hash := sha1.New()
|
||||
data := make([]byte, 20)
|
||||
n, err := rand.Read(data)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if n != 20 {
|
||||
return "", errors.New("randomSHA1String: short read from rand")
|
||||
}
|
||||
hash.Write(data)
|
||||
return hex.EncodeToString(hash.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func (s *Store) change(f func() error) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
|
@ -351,13 +366,10 @@ func bumpVersion(str string) string {
|
|||
|
||||
func (s *Store) PushBlueprint(bp blueprint.Blueprint, commitMsg string) {
|
||||
s.change(func() error {
|
||||
hash := sha1.New()
|
||||
// Hash timestamp to create unique hash
|
||||
hash.Write([]byte(time.Now().String()))
|
||||
// Get hash as a byte slice
|
||||
commitBytes := hash.Sum(nil)
|
||||
// Get hash as a hex string
|
||||
commit := hex.EncodeToString(commitBytes)
|
||||
commit, err := randomSHA1String()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
timestamp := time.Now().Format("2006-01-02T15:04:05Z")
|
||||
change := blueprint.Change{
|
||||
Commit: commit,
|
||||
|
|
|
|||
|
|
@ -28,3 +28,13 @@ func TestBumpVersion(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRandomSHA1String(t *testing.T) {
|
||||
hash, err := randomSHA1String()
|
||||
if err != nil {
|
||||
t.Fatalf("RandomSHA1String failed: %s", err)
|
||||
}
|
||||
if len(hash) != 40 {
|
||||
t.Fatalf("RandomSHA1String failed: hash is not 40 characters")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue