Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1456)

Side by Side Diff: src/pkg/crypto/bcrypt/bcrypt_test.go

Issue 4964078: code review 4964078: crypto/bcrypt: new package (Closed)
Patch Set: diff -r d21944c38c39 https://go.googlecode.com/hg/ Created 12 years, 6 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pkg/crypto/bcrypt/bcrypt.go ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package bcrypt
6
7 import (
8 "bytes"
9 "os"
10 "testing"
11 )
12
13 func TestBcryptingIsEasy(t *testing.T) {
14 pass := []byte("mypassword")
15 hp, err := GenerateFromPassword(pass, 0)
16 if err != nil {
17 t.Fatalf("GenerateFromPassword error: %s", err)
18 }
19
20 if CompareHashAndPassword(hp, pass) != nil {
21 t.Errorf("%v should hash %s correctly", hp, pass)
22 }
23
24 notPass := "notthepass"
25 err = CompareHashAndPassword(hp, []byte(notPass))
26 if err != MismatchedHashAndPasswordError {
27 t.Errorf("%v and %s should be mismatched", hp, notPass)
28 }
29 }
30
31 func TestBcryptingIsCorrect(t *testing.T) {
32 pass := []byte("allmine")
33 salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
34 expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt. wU1qD4aFDcga")
35
36 hash, err := bcrypt(pass, 10, salt)
37 if err != nil {
38 t.Fatalf("bcrypt blew up: %v", err)
39 }
40 if !bytes.HasSuffix(expectedHash, hash) {
41 t.Errorf("%v should be the suffix of %v", hash, expectedHash)
42 }
43
44 h, err := newFromHash(expectedHash)
45 if err != nil {
46 t.Errorf("Unable to parse %s: %v", string(expectedHash), err)
47 }
48
49 // This is not the safe way to compare these hashes. We do this only for
50 // testing clarity. Use bcrypt.CompareHashAndPassword()
51 if err == nil && !bytes.Equal(expectedHash, h.Hash()) {
52 t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHas h)
53 }
54 }
55
56 func TestTooLongPasswordsWork(t *testing.T) {
57 salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
58 // One byte over the usual 56 byte limit that blowfish has
59 tooLongPass := []byte("0123456789012345678901234567890123456789012345678 90123456")
60 tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZt d869sO8zfsHuw7C")
61 hash, err := bcrypt(tooLongPass, 10, salt)
62 if err != nil {
63 t.Fatalf("bcrypt blew up on long password: %v", err)
64 }
65 if !bytes.HasSuffix(tooLongExpected, hash) {
66 t.Errorf("%v should be the suffix of %v", hash, tooLongExpected)
67 }
68 }
69
70 type InvalidHashTest struct {
71 err os.Error
72 hash []byte
73 }
74
75 var invalidTests = []InvalidHashTest{
76 {HashTooShortError, []byte("$2a$10$fooo")},
77 {HashTooShortError, []byte("$2a")},
78 {HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhh hhhhhhhhhhhhhhhhhhhhhhhhhh")},
79 {InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhh hhhhhhhhhhhhhhhhhhhhhhhhhh")},
80 {InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhh hhhhhhhhhhhhhhhhhhh")},
81 }
82
83 func TestInvalidHashErrors(t *testing.T) {
84 check := func(name string, expected, err os.Error) {
85 if err == nil {
86 t.Errorf("%s: Should have returned an error", name)
87 }
88 if err != nil && err != expected {
89 t.Errorf("%s gave err %v but should have given %v", name , err.String(), expected.String())
90 }
91 }
92 for _, iht := range invalidTests {
93 _, err := newFromHash(iht.hash)
94 check("newFromHash", iht.err, err)
95 err = CompareHashAndPassword(iht.hash, []byte("anything"))
96 check("CompareHashAndPassword", iht.err, err)
97 }
98 }
99
100 func TestUnpaddedBase64EncodingWorks(t *testing.T) {
101 original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 3 2, 30, 109, 243, 30}
102 encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe")
103
104 encoded := base64Encode(original)
105
106 if !bytes.Equal(encodedOriginal, encoded) {
107 t.Errorf("Encoded %v should have equaled %v", encoded, encodedOr iginal)
108 }
109
110 decoded, err := base64Decode(encodedOriginal)
111 if err != nil {
112 t.Fatalf("base64Decode blew up: %s", err)
113 }
114
115 if !bytes.Equal(decoded, original) {
116 t.Errorf("Decoded %v should have equaled %v", decoded, original)
117 }
118 }
119
120 func TestCost(t *testing.T) {
121 pass := []byte("mypassword")
122
123 for c := 0; c < MinCost; c++ {
124 p, _ := newFromPassword(pass, c)
125 if p.cost != uint32(DefaultCost) {
126 t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost)
127 }
128 }
129
130 p, _ := newFromPassword(pass, 14)
131 if p.cost != 14 {
132 t.Errorf("newFromPassword should default cost to 14, but was %d" , p.cost)
133 }
134
135 hp, _ := newFromHash(p.Hash())
136 if p.cost != hp.cost {
137 t.Errorf("newFromHash should maintain the cost at %d, but was %d ", p.cost, hp.cost)
138 }
139
140 _, err := newFromPassword(pass, 32)
141 if err == nil {
142 t.Fatalf("newFromPassword: should return a cost error")
143 }
144 if err != InvalidCostError(32) {
145 t.Errorf("newFromPassword: should return cost error, got %#v", e rr)
146 }
147 }
148
149 func TestCostReturnsWithLeadingZeroes(t *testing.T) {
150 hp, _ := newFromPassword([]byte("abcdefgh"), 7)
151 cost := hp.Hash()[4:7]
152 expected := []byte("07$")
153
154 if !bytes.Equal(expected, cost) {
155 t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected)
156 }
157 }
158
159 func TestMinorNotRequired(t *testing.T) {
160 noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU 1qD4aFDcga")
161 h, err := newFromHash(noMinorHash)
162 if err != nil {
163 t.Fatalf("No minor hash blew up: %s", err)
164 }
165 if h.minor != 0 {
166 t.Errorf("Should leave minor version at 0, but was %d", h.minor)
167 }
168
169 if !bytes.Equal(noMinorHash, h.Hash()) {
170 t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash())
171 }
172 }
173
174 func BenchmarkEqual(b *testing.B) {
175 b.StopTimer()
176 passwd := []byte("somepasswordyoulike")
177 hash, _ := GenerateFromPassword(passwd, 10)
178 b.StartTimer()
179 for i := 0; i < b.N; i++ {
180 CompareHashAndPassword(hash, passwd)
181 }
182 }
183
184 func BenchmarkGeneration(b *testing.B) {
185 b.StopTimer()
186 passwd := []byte("mylongpassword1234")
187 b.StartTimer()
188 for i := 0; i < b.N; i++ {
189 GenerateFromPassword(passwd, 10)
190 }
191 }
OLDNEW
« no previous file with comments | « src/pkg/crypto/bcrypt/bcrypt.go ('k') | no next file » | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b