diff --git a/bin/gopass-darwin-amd64-1.3.4 b/bin/gopass-darwin-amd64-1.3.4 deleted file mode 100755 index f94508c..0000000 Binary files a/bin/gopass-darwin-amd64-1.3.4 and /dev/null differ diff --git a/bin/gopass-darwin-amd64-1.3.5 b/bin/gopass-darwin-amd64-1.3.5 new file mode 100755 index 0000000..4ff2ced Binary files /dev/null and b/bin/gopass-darwin-amd64-1.3.5 differ diff --git a/bin/gopass-freebsd-386-1.3.4 b/bin/gopass-freebsd-386-1.3.4 deleted file mode 100755 index 13b8160..0000000 Binary files a/bin/gopass-freebsd-386-1.3.4 and /dev/null differ diff --git a/bin/gopass-freebsd-386-1.3.5 b/bin/gopass-freebsd-386-1.3.5 new file mode 100755 index 0000000..04a3306 Binary files /dev/null and b/bin/gopass-freebsd-386-1.3.5 differ diff --git a/bin/gopass-freebsd-amd64-1.3.4 b/bin/gopass-freebsd-amd64-1.3.4 deleted file mode 100755 index 2c85182..0000000 Binary files a/bin/gopass-freebsd-amd64-1.3.4 and /dev/null differ diff --git a/bin/gopass-freebsd-amd64-1.3.5 b/bin/gopass-freebsd-amd64-1.3.5 new file mode 100755 index 0000000..131a893 Binary files /dev/null and b/bin/gopass-freebsd-amd64-1.3.5 differ diff --git a/bin/gopass-freebsd-arm-1.3.4 b/bin/gopass-freebsd-arm-1.3.4 deleted file mode 100755 index a102399..0000000 Binary files a/bin/gopass-freebsd-arm-1.3.4 and /dev/null differ diff --git a/bin/gopass-freebsd-arm-1.3.5 b/bin/gopass-freebsd-arm-1.3.5 new file mode 100755 index 0000000..87e25b4 Binary files /dev/null and b/bin/gopass-freebsd-arm-1.3.5 differ diff --git a/bin/gopass-linux-386-1.3.4 b/bin/gopass-linux-386-1.3.4 deleted file mode 100755 index 4f519b0..0000000 Binary files a/bin/gopass-linux-386-1.3.4 and /dev/null differ diff --git a/bin/gopass-linux-386-1.3.5 b/bin/gopass-linux-386-1.3.5 new file mode 100755 index 0000000..7d9b2ca Binary files /dev/null and b/bin/gopass-linux-386-1.3.5 differ diff --git a/bin/gopass-linux-amd64-1.3.4 b/bin/gopass-linux-amd64-1.3.4 deleted file mode 100755 index be495c8..0000000 Binary files a/bin/gopass-linux-amd64-1.3.4 and /dev/null differ diff --git a/bin/gopass-linux-amd64-1.3.5 b/bin/gopass-linux-amd64-1.3.5 new file mode 100755 index 0000000..3715df8 Binary files /dev/null and b/bin/gopass-linux-amd64-1.3.5 differ diff --git a/bin/gopass-linux-arm-1.3.4 b/bin/gopass-linux-arm-1.3.4 deleted file mode 100755 index ef0139e..0000000 Binary files a/bin/gopass-linux-arm-1.3.4 and /dev/null differ diff --git a/bin/gopass-linux-arm-1.3.5 b/bin/gopass-linux-arm-1.3.5 new file mode 100755 index 0000000..a306e1b Binary files /dev/null and b/bin/gopass-linux-arm-1.3.5 differ diff --git a/bin/gopass-plan9-386-1.3.4 b/bin/gopass-plan9-386-1.3.4 deleted file mode 100755 index 47d1bfd..0000000 Binary files a/bin/gopass-plan9-386-1.3.4 and /dev/null differ diff --git a/bin/gopass-plan9-386-1.3.5 b/bin/gopass-plan9-386-1.3.5 new file mode 100755 index 0000000..7afd447 Binary files /dev/null and b/bin/gopass-plan9-386-1.3.5 differ diff --git a/bin/gopass-plan9-amd64-1.3.4 b/bin/gopass-plan9-amd64-1.3.4 deleted file mode 100755 index 9b93731..0000000 Binary files a/bin/gopass-plan9-amd64-1.3.4 and /dev/null differ diff --git a/bin/gopass-plan9-amd64-1.3.5 b/bin/gopass-plan9-amd64-1.3.5 new file mode 100755 index 0000000..188611f Binary files /dev/null and b/bin/gopass-plan9-amd64-1.3.5 differ diff --git a/bin/gopass-plan9-arm-1.3.4 b/bin/gopass-plan9-arm-1.3.4 deleted file mode 100755 index 6a48be2..0000000 Binary files a/bin/gopass-plan9-arm-1.3.4 and /dev/null differ diff --git a/bin/gopass-plan9-arm-1.3.5 b/bin/gopass-plan9-arm-1.3.5 new file mode 100755 index 0000000..f7a17c3 Binary files /dev/null and b/bin/gopass-plan9-arm-1.3.5 differ diff --git a/bin/gopass-windows-386-1.3.4 b/bin/gopass-windows-386-1.3.4 deleted file mode 100755 index a1a0a82..0000000 Binary files a/bin/gopass-windows-386-1.3.4 and /dev/null differ diff --git a/bin/gopass-windows-386-1.3.5 b/bin/gopass-windows-386-1.3.5 new file mode 100755 index 0000000..52be2df Binary files /dev/null and b/bin/gopass-windows-386-1.3.5 differ diff --git a/bin/gopass-windows-amd64-1.3.4 b/bin/gopass-windows-amd64-1.3.4 deleted file mode 100755 index 1f90197..0000000 Binary files a/bin/gopass-windows-amd64-1.3.4 and /dev/null differ diff --git a/bin/gopass-windows-amd64-1.3.5 b/bin/gopass-windows-amd64-1.3.5 new file mode 100755 index 0000000..5ea5f65 Binary files /dev/null and b/bin/gopass-windows-amd64-1.3.5 differ diff --git a/bin/gopass-windows-arm-1.3.4 b/bin/gopass-windows-arm-1.3.4 deleted file mode 100755 index 76f1a4e..0000000 Binary files a/bin/gopass-windows-arm-1.3.4 and /dev/null differ diff --git a/bin/gopass-windows-arm-1.3.5 b/bin/gopass-windows-arm-1.3.5 new file mode 100755 index 0000000..c01baf1 Binary files /dev/null and b/bin/gopass-windows-arm-1.3.5 differ diff --git a/go.mod b/go.mod index 89388a7..5659a5f 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module GoPass -go 1.24.1 +go 1.25.5 diff --git a/main.go b/main.go index a9c6f4c..2317a87 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,6 @@ package main import ( "crypto/rand" "fmt" - "math/big" "os" "runtime" "strconv" @@ -15,7 +14,7 @@ import ( var allowedCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`~!@#$%^&*()_+[]\\{}|;':,./<>?") const ( - Version = "1.3.4" + Version = "1.3.5" symbols = "`~!@#$%^&*()_+[]\\{}|;':,./<>?" 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" + "For version: gopass -v\n" default: - err := error(nil) + var err error size, err = strconv.Atoi(args[0]) if err != nil { return "Invalid first argument (\"" + args[0] + "\") supplied! (Type gopass -h for help)" @@ -95,21 +94,52 @@ func generatePassword(size int) string { numWorkers := runtime.NumCPU() // Launch the worker goroutines - for i := 0; i < numWorkers; i++ { + for range numWorkers { go func() { 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 { - // 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) for i := range chunk { - index, err := rand.Int(rand.Reader, big.NewInt(int64(allowedLen))) - if err != nil { - println("Error securely generating random character chunk!") - return - } - chunk[i] = allowedCharacters[index.Int64()] - } + for { + // If we exhausted the buffer due to rejections, refill it + if bufIdx >= len(randBuf) { + if _, err := rand.Read(randBuf); err != nil { + println("Error securely generating random character chunk!") + 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 passChan <- chunk } diff --git a/makefile b/makefile index 11c71ef..d49933e 100644 --- a/makefile +++ b/makefile @@ -1,5 +1,5 @@ # The current version number of the program -VERSION := 1.3.4 +VERSION := 1.3.5 # List of OS and architecture combinations to build BUILD_OS_ARCH := \ @@ -24,64 +24,64 @@ all: $(BUILD_OS_ARCH) darwin/amd64: GOOS=darwin \ 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: GOOS=freebsd \ 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: GOOS=freebsd \ 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: GOOS=freebsd \ 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: GOOS=linux \ 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: GOOS=linux \ 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: GOOS=linux \ 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: GOOS=plan9 \ 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: GOOS=plan9 \ 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: GOOS=plan9 \ 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: GOOS=windows \ 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: GOOS=windows \ 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: GOOS=windows \ 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