aboutsummaryrefslogtreecommitdiff
path: root/internal/player/hardening_password_params_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/player/hardening_password_params_test.go')
-rw-r--r--internal/player/hardening_password_params_test.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/internal/player/hardening_password_params_test.go b/internal/player/hardening_password_params_test.go
new file mode 100644
index 0000000..4c171f1
--- /dev/null
+++ b/internal/player/hardening_password_params_test.go
@@ -0,0 +1,62 @@
+package player
+
+// Regression: Argon2id parameters parsed from a stored hash must be bounded
+// before they reach argon2.IDKey. A hand-edited or corrupted account file
+// (e.g. argon2id:1:4294967295:...) must fail the check, not request a
+// multi-TiB allocation that kills the process.
+
+import (
+ "crypto/sha256"
+ "encoding/base64"
+ "encoding/hex"
+ "testing"
+)
+
+func TestCheckPasswordRejectsOutOfRangeArgonParams(t *testing.T) {
+ // Enormous memory cost (0xFFFFFFFF KiB) with an otherwise well-formed
+ // hash: must be rejected before hashing.
+ huge := "argon2id:1:4294967295:2:AAAAAAAAAAAAAAAAAAAAAA:0011223344556677889900112233445566778899001122334455667788990011"
+ if CheckPassword("pw", huge) {
+ t.Fatal("out-of-range Argon2 memory cost was accepted")
+ }
+
+ // Negative values would wrap through uint32 under a naive conversion.
+ negative := "argon2id:-1:-1:-1:AAAAAAAAAAAAAAAAAAAAAA:0011223344556677889900112233445566778899001122334455667788990011"
+ if CheckPassword("pw", negative) {
+ t.Fatal("negative Argon2 parameters were accepted")
+ }
+
+ // Absurd time cost is bounded too.
+ slow := "argon2id:4294967295:65536:2:AAAAAAAAAAAAAAAAAAAAAA:0011223344556677889900112233445566778899001122334455667788990011"
+ if CheckPassword("pw", slow) {
+ t.Fatal("out-of-range Argon2 time cost was accepted")
+ }
+}
+
+func TestCheckPasswordAcceptsNormalAndLegacyHashes(t *testing.T) {
+ hashed, err := HashPassword("s3cret")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !CheckPassword("s3cret", hashed) {
+ t.Fatal("valid Argon2id hash rejected")
+ }
+ if CheckPassword("wrong", hashed) {
+ t.Fatal("wrong password accepted")
+ }
+
+ // Legacy single-pass sha256 hashes must keep verifying so old accounts
+ // can still log in and be upgraded.
+ salt := []byte("sixteen-byte-slt")
+ sum := sha256.Sum256(append(append([]byte{}, salt...), []byte("pw")...))
+ legacy := "sha256:" + base64.RawStdEncoding.EncodeToString(salt) + ":" + hex.EncodeToString(sum[:])
+ if !CheckPassword("pw", legacy) {
+ t.Fatal("legacy sha256 hash rejected")
+ }
+ if CheckPassword("nope", legacy) {
+ t.Fatal("wrong password accepted against legacy sha256 hash")
+ }
+ if !NeedsRehash(legacy) {
+ t.Fatal("legacy sha256 hash not flagged for rehash")
+ }
+}