refactor: remove math/big, fix RNG bias, optimize builds, and bump Go version
This commit is contained in:
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -5,7 +5,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -15,7 +14,7 @@ import (
|
|||||||
var allowedCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_+[]\\{}|;':,./<>?")
|
var allowedCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_+[]\\{}|;':,./<>?")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.3.4"
|
Version = "1.3.5"
|
||||||
symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?"
|
symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?"
|
||||||
chunkSize = 16 // The size of each chunk of the password to be generated by the worker goroutines
|
chunkSize = 16 // The size of each chunk of the password to be generated by the worker goroutines
|
||||||
)
|
)
|
||||||
@@ -40,7 +39,7 @@ func matchArguments(args []string) string {
|
|||||||
"\nFor help (this output): gopass -h\n" +
|
"\nFor help (this output): gopass -h\n" +
|
||||||
"For version: gopass -v\n"
|
"For version: gopass -v\n"
|
||||||
default:
|
default:
|
||||||
err := error(nil)
|
var err error
|
||||||
size, err = strconv.Atoi(args[0])
|
size, err = strconv.Atoi(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "Invalid first argument (\"" + args[0] + "\") supplied! (Type gopass -h for help)"
|
return "Invalid first argument (\"" + args[0] + "\") supplied! (Type gopass -h for help)"
|
||||||
@@ -95,21 +94,52 @@ func generatePassword(size int) string {
|
|||||||
numWorkers := runtime.NumCPU()
|
numWorkers := runtime.NumCPU()
|
||||||
|
|
||||||
// Launch the worker goroutines
|
// Launch the worker goroutines
|
||||||
for i := 0; i < numWorkers; i++ {
|
for range numWorkers {
|
||||||
go func() {
|
go func() {
|
||||||
allowedLen := len(allowedCharacters)
|
allowedLen := len(allowedCharacters)
|
||||||
|
|
||||||
|
// Calculate the rejection limit to avoid modulo bias.
|
||||||
|
// Any random byte value > maxByte must be discarded.
|
||||||
|
maxByte := 255 - (256 % allowedLen)
|
||||||
|
|
||||||
|
// Create a buffer for random bytes.
|
||||||
|
// We read enough bytes for the whole chunk at once (plus some extra
|
||||||
|
// in case of rejections) to reduce system calls.
|
||||||
|
randBuf := make([]byte, chunkSize*2)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Generate a chunk of the password
|
// Fill the buffer initially
|
||||||
|
if _, err := rand.Read(randBuf); err != nil {
|
||||||
|
println("Error securely generating random character chunk!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bufIdx := 0
|
||||||
|
|
||||||
chunk := make([]rune, chunkSize)
|
chunk := make([]rune, chunkSize)
|
||||||
for i := range chunk {
|
for i := range chunk {
|
||||||
index, err := rand.Int(rand.Reader, big.NewInt(int64(allowedLen)))
|
for {
|
||||||
if err != nil {
|
// If we exhausted the buffer due to rejections, refill it
|
||||||
println("Error securely generating random character chunk!")
|
if bufIdx >= len(randBuf) {
|
||||||
return
|
if _, err := rand.Read(randBuf); err != nil {
|
||||||
}
|
println("Error securely generating random character chunk!")
|
||||||
chunk[i] = allowedCharacters[index.Int64()]
|
return
|
||||||
}
|
}
|
||||||
|
bufIdx = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
b := randBuf[bufIdx]
|
||||||
|
bufIdx++
|
||||||
|
|
||||||
|
// If the byte causes bias, discard and retry
|
||||||
|
if int(b) > maxByte {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safe to map to character set
|
||||||
|
chunk[i] = allowedCharacters[int(b)%allowedLen]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
// Send the chunk of the password to the main goroutine
|
// Send the chunk of the password to the main goroutine
|
||||||
passChan <- chunk
|
passChan <- chunk
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# The current version number of the program
|
# The current version number of the program
|
||||||
VERSION := 1.3.4
|
VERSION := 1.3.5
|
||||||
|
|
||||||
# List of OS and architecture combinations to build
|
# List of OS and architecture combinations to build
|
||||||
BUILD_OS_ARCH := \
|
BUILD_OS_ARCH := \
|
||||||
@@ -24,64 +24,64 @@ all: $(BUILD_OS_ARCH)
|
|||||||
darwin/amd64:
|
darwin/amd64:
|
||||||
GOOS=darwin \
|
GOOS=darwin \
|
||||||
GOARCH=amd64 \
|
GOARCH=amd64 \
|
||||||
go build -ldflags="-s -w" -o "gopass-darwin-amd64-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-darwin-amd64-$(VERSION)" main.go
|
||||||
|
|
||||||
freebsd/386:
|
freebsd/386:
|
||||||
GOOS=freebsd \
|
GOOS=freebsd \
|
||||||
GOARCH=386 \
|
GOARCH=386 \
|
||||||
go build -ldflags="-s -w" -o "gopass-freebsd-386-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-freebsd-386-$(VERSION)" main.go
|
||||||
|
|
||||||
freebsd/amd64:
|
freebsd/amd64:
|
||||||
GOOS=freebsd \
|
GOOS=freebsd \
|
||||||
GOARCH=amd64 \
|
GOARCH=amd64 \
|
||||||
go build -ldflags="-s -w" -o "gopass-freebsd-amd64-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-freebsd-amd64-$(VERSION)" main.go
|
||||||
|
|
||||||
freebsd/arm:
|
freebsd/arm:
|
||||||
GOOS=freebsd \
|
GOOS=freebsd \
|
||||||
GOARCH=arm \
|
GOARCH=arm \
|
||||||
go build -ldflags="-s -w" -o "gopass-freebsd-arm-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-freebsd-arm-$(VERSION)" main.go
|
||||||
|
|
||||||
linux/386:
|
linux/386:
|
||||||
GOOS=linux \
|
GOOS=linux \
|
||||||
GOARCH=386 \
|
GOARCH=386 \
|
||||||
go build -ldflags="-s -w" -o "gopass-linux-386-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-linux-386-$(VERSION)" main.go
|
||||||
|
|
||||||
linux/amd64:
|
linux/amd64:
|
||||||
GOOS=linux \
|
GOOS=linux \
|
||||||
GOARCH=amd64 \
|
GOARCH=amd64 \
|
||||||
go build -ldflags="-s -w" -o "gopass-linux-amd64-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-linux-amd64-$(VERSION)" main.go
|
||||||
|
|
||||||
linux/arm:
|
linux/arm:
|
||||||
GOOS=linux \
|
GOOS=linux \
|
||||||
GOARCH=arm \
|
GOARCH=arm \
|
||||||
go build -ldflags="-s -w" -o "gopass-linux-arm-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-linux-arm-$(VERSION)" main.go
|
||||||
|
|
||||||
plan9/386:
|
plan9/386:
|
||||||
GOOS=plan9 \
|
GOOS=plan9 \
|
||||||
GOARCH=386 \
|
GOARCH=386 \
|
||||||
go build -ldflags="-s -w" -o "gopass-plan9-386-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-plan9-386-$(VERSION)" main.go
|
||||||
|
|
||||||
plan9/amd64:
|
plan9/amd64:
|
||||||
GOOS=plan9 \
|
GOOS=plan9 \
|
||||||
GOARCH=amd64 \
|
GOARCH=amd64 \
|
||||||
go build -ldflags="-s -w" -o "gopass-plan9-amd64-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-plan9-amd64-$(VERSION)" main.go
|
||||||
|
|
||||||
plan9/arm:
|
plan9/arm:
|
||||||
GOOS=plan9 \
|
GOOS=plan9 \
|
||||||
GOARCH=arm \
|
GOARCH=arm \
|
||||||
go build -ldflags="-s -w" -o "gopass-plan9-arm-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-plan9-arm-$(VERSION)" main.go
|
||||||
|
|
||||||
windows/386:
|
windows/386:
|
||||||
GOOS=windows \
|
GOOS=windows \
|
||||||
GOARCH=386 \
|
GOARCH=386 \
|
||||||
go build -ldflags="-s -w" -o "gopass-windows-386-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-windows-386-$(VERSION)" main.go
|
||||||
|
|
||||||
windows/amd64:
|
windows/amd64:
|
||||||
GOOS=windows \
|
GOOS=windows \
|
||||||
GOARCH=amd64 \
|
GOARCH=amd64 \
|
||||||
go build -ldflags="-s -w" -o "gopass-windows-amd64-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-windows-amd64-$(VERSION)" main.go
|
||||||
|
|
||||||
windows/arm:
|
windows/arm:
|
||||||
GOOS=windows \
|
GOOS=windows \
|
||||||
GOARCH=arm \
|
GOARCH=arm \
|
||||||
go build -ldflags="-s -w" -o "gopass-windows-arm-$(VERSION)" main.go
|
go build -trimpath -buildvcs=false -ldflags="-s -w" -o "gopass-windows-arm-$(VERSION)" main.go
|
||||||
|
|||||||
Reference in New Issue
Block a user