Go · 2112 bytes Raw Blame History
1 // SPDX-License-Identifier: AGPL-3.0-or-later
2
3 package password
4
5 import (
6 "strings"
7 "testing"
8 )
9
10 // fastParams keeps the test suite quick — argon2id with default cost takes
11 // hundreds of ms. Real defaults are exercised by the e2e auth integration test.
12 func fastParams() Params {
13 return Params{Memory: 16 * 1024, Time: 1, Threads: 1, SaltLen: 16, KeyLen: 32}
14 }
15
16 func TestHashAndVerify_RoundTrip(t *testing.T) {
17 t.Parallel()
18 p := fastParams()
19 enc, err := Hash("correct horse battery staple", p)
20 if err != nil {
21 t.Fatalf("Hash: %v", err)
22 }
23 if !strings.HasPrefix(enc, "$argon2id$v=19$") {
24 t.Fatalf("PHC prefix wrong: %s", enc)
25 }
26 ok, err := Verify("correct horse battery staple", enc)
27 if err != nil {
28 t.Fatalf("Verify: %v", err)
29 }
30 if !ok {
31 t.Fatal("Verify returned false for correct password")
32 }
33 bad, err := Verify("wrong password........", enc)
34 if err != nil {
35 t.Fatalf("Verify wrong: %v", err)
36 }
37 if bad {
38 t.Fatal("Verify returned true for wrong password")
39 }
40 }
41
42 func TestHash_RejectsTooShort(t *testing.T) {
43 t.Parallel()
44 if _, err := Hash("short", fastParams()); err == nil {
45 t.Fatal("expected error for short password")
46 }
47 }
48
49 func TestVerify_RejectsMalformed(t *testing.T) {
50 t.Parallel()
51 cases := []string{
52 "",
53 "not-a-phc-string",
54 "$bcrypt$v=10$xxx", // wrong algo
55 "$argon2id$v=18$m=65536,t=3,p=2$AAAAAAAAAAAAAAAA$AAAAAA", // version mismatch
56 "$argon2id$v=19$bad-params$AAAAAAAAAAAAAAAA$AAAAAA",
57 }
58 for _, c := range cases {
59 if _, err := Verify("anything", c); err == nil {
60 t.Errorf("expected error for %q", c)
61 }
62 }
63 }
64
65 func TestVerifyAgainstDummy_DoesNotPanic(t *testing.T) {
66 t.Parallel()
67 MustGenerateDummy(fastParams())
68 VerifyAgainstDummy("anything")
69 }
70
71 func TestEncodeDecode_RoundTrip(t *testing.T) {
72 t.Parallel()
73 p := fastParams()
74 enc, err := Hash("ten-character-password", p)
75 if err != nil {
76 t.Fatalf("Hash: %v", err)
77 }
78 got, _, _, err := decode(enc)
79 if err != nil {
80 t.Fatalf("decode: %v", err)
81 }
82 if got.Memory != p.Memory || got.Time != p.Time || got.Threads != p.Threads {
83 t.Fatalf("params mismatch: got %+v want %+v", got, p)
84 }
85 }
86