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
5package s2k
6
7import (
8	"bytes"
9	"crypto"
10	_ "crypto/md5"
11	"crypto/rand"
12	"crypto/sha1"
13	_ "crypto/sha256"
14	_ "crypto/sha512"
15	"encoding/hex"
16	"testing"
17
18	_ "golang.org/x/crypto/ripemd160"
19)
20
21var saltedTests = []struct {
22	in, out string
23}{
24	{"hello", "10295ac1"},
25	{"world", "ac587a5e"},
26	{"foo", "4dda8077"},
27	{"bar", "bd8aac6b9ea9cae04eae6a91c6133b58b5d9a61c14f355516ed9370456"},
28	{"x", "f1d3f289"},
29	{"xxxxxxxxxxxxxxxxxxxxxxx", "e00d7b45"},
30}
31
32func TestSalted(t *testing.T) {
33	h := sha1.New()
34	salt := [4]byte{1, 2, 3, 4}
35
36	for i, test := range saltedTests {
37		expected, _ := hex.DecodeString(test.out)
38		out := make([]byte, len(expected))
39		Salted(out, h, []byte(test.in), salt[:])
40		if !bytes.Equal(expected, out) {
41			t.Errorf("#%d, got: %x want: %x", i, out, expected)
42		}
43	}
44}
45
46var iteratedTests = []struct {
47	in, out string
48}{
49	{"hello", "83126105"},
50	{"world", "6fa317f9"},
51	{"foo", "8fbc35b9"},
52	{"bar", "2af5a99b54f093789fd657f19bd245af7604d0f6ae06f66602a46a08ae"},
53	{"x", "5a684dfe"},
54	{"xxxxxxxxxxxxxxxxxxxxxxx", "18955174"},
55}
56
57func TestIterated(t *testing.T) {
58	h := sha1.New()
59	salt := [4]byte{4, 3, 2, 1}
60
61	for i, test := range iteratedTests {
62		expected, _ := hex.DecodeString(test.out)
63		out := make([]byte, len(expected))
64		Iterated(out, h, []byte(test.in), salt[:], 31)
65		if !bytes.Equal(expected, out) {
66			t.Errorf("#%d, got: %x want: %x", i, out, expected)
67		}
68	}
69}
70
71var parseTests = []struct {
72	spec, in, out string
73}{
74	/* Simple with SHA1 */
75	{"0002", "hello", "aaf4c61d"},
76	/* Salted with SHA1 */
77	{"01020102030405060708", "hello", "f4f7d67e"},
78	/* Iterated with SHA1 */
79	{"03020102030405060708f1", "hello", "f2a57b7c"},
80}
81
82func TestParse(t *testing.T) {
83	for i, test := range parseTests {
84		spec, _ := hex.DecodeString(test.spec)
85		buf := bytes.NewBuffer(spec)
86		f, err := Parse(buf)
87		if err != nil {
88			t.Errorf("%d: Parse returned error: %s", i, err)
89			continue
90		}
91
92		expected, _ := hex.DecodeString(test.out)
93		out := make([]byte, len(expected))
94		f(out, []byte(test.in))
95		if !bytes.Equal(out, expected) {
96			t.Errorf("%d: output got: %x want: %x", i, out, expected)
97		}
98		if testing.Short() {
99			break
100		}
101	}
102}
103
104func TestSerialize(t *testing.T) {
105	hashes := []crypto.Hash{crypto.MD5, crypto.SHA1, crypto.RIPEMD160,
106		crypto.SHA256, crypto.SHA384, crypto.SHA512, crypto.SHA224}
107	testCounts := []int{-1, 0, 1024, 65536, 4063232, 65011712}
108	for _, h := range hashes {
109		for _, c := range testCounts {
110			testSerializeConfig(t, &Config{Hash: h, S2KCount: c})
111		}
112	}
113}
114
115func testSerializeConfig(t *testing.T, c *Config) {
116	t.Logf("Running testSerializeConfig() with config: %+v", c)
117
118	buf := bytes.NewBuffer(nil)
119	key := make([]byte, 16)
120	passphrase := []byte("testing")
121	err := Serialize(buf, key, rand.Reader, passphrase, c)
122	if err != nil {
123		t.Errorf("failed to serialize: %s", err)
124		return
125	}
126
127	f, err := Parse(buf)
128	if err != nil {
129		t.Errorf("failed to reparse: %s", err)
130		return
131	}
132	key2 := make([]byte, len(key))
133	f(key2, passphrase)
134	if !bytes.Equal(key2, key) {
135		t.Errorf("keys don't match: %x (serialied) vs %x (parsed)", key, key2)
136	}
137}
138