plain_test.go 7.43 KB
Newer Older
1
// Copyright 2014 The go-ethereum Authors
2
// This file is part of the go-ethereum library.
3
//
4
// The go-ethereum library is free software: you can redistribute it and/or modify
5 6 7 8
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
9
// The go-ethereum library is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 13 14
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
15
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16

17
package keystore
18 19

import (
20
	"crypto/rand"
21 22
	"encoding/hex"
	"fmt"
23
	"path/filepath"
24
	"reflect"
25
	"strings"
26
	"testing"
27 28

	"github.com/ethereum/go-ethereum/common"
29
	"github.com/ethereum/go-ethereum/crypto"
30 31
)

32
func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) {
33
	d := t.TempDir()
34
	if encrypted {
35
		ks = &keyStorePassphrase{d, veryLightScryptN, veryLightScryptP, true}
36 37 38 39 40 41
	} else {
		ks = &keyStorePlain{d}
	}
	return d, ks
}

42
func TestKeyStorePlain(t *testing.T) {
43
	_, ks := tmpKeyStoreIface(t, false)
44

45
	pass := "" // not used but required by API
46
	k1, account, err := storeNewKey(ks, rand.Reader, pass)
47
	if err != nil {
48
		t.Fatal(err)
49
	}
50
	k2, err := ks.GetKey(k1.Address, account.URL.Path, pass)
51
	if err != nil {
52
		t.Fatal(err)
53
	}
54
	if !reflect.DeepEqual(k1.Address, k2.Address) {
55
		t.Fatal(err)
56 57
	}
	if !reflect.DeepEqual(k1.PrivateKey, k2.PrivateKey) {
58
		t.Fatal(err)
59 60 61 62
	}
}

func TestKeyStorePassphrase(t *testing.T) {
63
	_, ks := tmpKeyStoreIface(t, true)
64

65
	pass := "foo"
66
	k1, account, err := storeNewKey(ks, rand.Reader, pass)
67
	if err != nil {
68
		t.Fatal(err)
69
	}
70
	k2, err := ks.GetKey(k1.Address, account.URL.Path, pass)
71
	if err != nil {
72
		t.Fatal(err)
73
	}
74
	if !reflect.DeepEqual(k1.Address, k2.Address) {
75
		t.Fatal(err)
76 77
	}
	if !reflect.DeepEqual(k1.PrivateKey, k2.PrivateKey) {
78
		t.Fatal(err)
79 80 81 82
	}
}

func TestKeyStorePassphraseDecryptionFail(t *testing.T) {
83
	_, ks := tmpKeyStoreIface(t, true)
84

85
	pass := "foo"
86
	k1, account, err := storeNewKey(ks, rand.Reader, pass)
87
	if err != nil {
88
		t.Fatal(err)
89
	}
90
	if _, err = ks.GetKey(k1.Address, account.URL.Path, "bar"); err != ErrDecrypt {
91
		t.Fatalf("wrong error for invalid password\ngot %q\nwant %q", err, ErrDecrypt)
92 93
	}
}
Gustav Simonsson's avatar
Gustav Simonsson committed
94 95

func TestImportPreSaleKey(t *testing.T) {
96
	dir, ks := tmpKeyStoreIface(t, true)
97

Gustav Simonsson's avatar
Gustav Simonsson committed
98 99 100 101 102
	// file content of a presale key file generated with:
	// python pyethsaletool.py genwallet
	// with password "foo"
	fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}"
	pass := "foo"
103
	account, _, err := importPreSaleKey(ks, []byte(fileContent), pass)
Gustav Simonsson's avatar
Gustav Simonsson committed
104 105 106
	if err != nil {
		t.Fatal(err)
	}
107 108 109
	if account.Address != common.HexToAddress("d4584b5f6229b7be90727b0fc8c6b91bb427821f") {
		t.Errorf("imported account has wrong address %x", account.Address)
	}
110
	if !strings.HasPrefix(account.URL.Path, dir) {
111
		t.Errorf("imported account file not in keystore directory: %q", account.URL)
112
	}
Gustav Simonsson's avatar
Gustav Simonsson committed
113
}
114 115

// Test and utils for the key store tests in the Ethereum JSON tests;
116
// testdataKeyStoreTests/basic_tests.json
117 118 119 120 121 122 123 124 125 126 127 128 129
type KeyStoreTestV3 struct {
	Json     encryptedKeyJSONV3
	Password string
	Priv     string
}

type KeyStoreTestV1 struct {
	Json     encryptedKeyJSONV1
	Password string
	Priv     string
}

func TestV3_PBKDF2_1(t *testing.T) {
130
	t.Parallel()
131
	tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t)
132 133 134
	testDecryptV3(tests["wikipage_test_vector_pbkdf2"], t)
}

135 136 137 138 139 140 141 142
var testsSubmodule = filepath.Join("..", "..", "tests", "testdata", "KeyStoreTests")

func skipIfSubmoduleMissing(t *testing.T) {
	if !common.FileExist(testsSubmodule) {
		t.Skipf("can't find JSON tests from submodule at %s", testsSubmodule)
	}
}

143
func TestV3_PBKDF2_2(t *testing.T) {
144
	skipIfSubmoduleMissing(t)
145
	t.Parallel()
146
	tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t)
147 148 149 150
	testDecryptV3(tests["test1"], t)
}

func TestV3_PBKDF2_3(t *testing.T) {
151
	skipIfSubmoduleMissing(t)
152
	t.Parallel()
153
	tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t)
154 155 156 157
	testDecryptV3(tests["python_generated_test_with_odd_iv"], t)
}

func TestV3_PBKDF2_4(t *testing.T) {
158
	skipIfSubmoduleMissing(t)
159
	t.Parallel()
160
	tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t)
161 162 163 164
	testDecryptV3(tests["evilnonce"], t)
}

func TestV3_Scrypt_1(t *testing.T) {
165
	t.Parallel()
166
	tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t)
167 168 169 170
	testDecryptV3(tests["wikipage_test_vector_scrypt"], t)
}

func TestV3_Scrypt_2(t *testing.T) {
171
	skipIfSubmoduleMissing(t)
172
	t.Parallel()
173
	tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t)
174 175 176 177
	testDecryptV3(tests["test2"], t)
}

func TestV1_1(t *testing.T) {
178
	t.Parallel()
179
	tests := loadKeyStoreTestV1("testdata/v1_test_vector.json", t)
180 181 182 183
	testDecryptV1(tests["test1"], t)
}

func TestV1_2(t *testing.T) {
184
	t.Parallel()
185
	ks := &keyStorePassphrase{"testdata/v1", LightScryptN, LightScryptP, true}
186
	addr := common.HexToAddress("cb61d5a9c4896fb9658090b597ef0e7be6f7b67e")
187 188
	file := "testdata/v1/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e"
	k, err := ks.GetKey(addr, file, "g")
189 190 191
	if err != nil {
		t.Fatal(err)
	}
192
	privHex := hex.EncodeToString(crypto.FromECDSA(k.PrivateKey))
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
	expectedHex := "d1b1178d3529626a1a93e073f65028370d14c7eb0936eb42abef05db6f37ad7d"
	if privHex != expectedHex {
		t.Fatal(fmt.Errorf("Unexpected privkey: %v, expected %v", privHex, expectedHex))
	}
}

func testDecryptV3(test KeyStoreTestV3, t *testing.T) {
	privBytes, _, err := decryptKeyV3(&test.Json, test.Password)
	if err != nil {
		t.Fatal(err)
	}
	privHex := hex.EncodeToString(privBytes)
	if test.Priv != privHex {
		t.Fatal(fmt.Errorf("Decrypted bytes not equal to test, expected %v have %v", test.Priv, privHex))
	}
}

func testDecryptV1(test KeyStoreTestV1, t *testing.T) {
	privBytes, _, err := decryptKeyV1(&test.Json, test.Password)
	if err != nil {
		t.Fatal(err)
	}
	privHex := hex.EncodeToString(privBytes)
	if test.Priv != privHex {
		t.Fatal(fmt.Errorf("Decrypted bytes not equal to test, expected %v have %v", test.Priv, privHex))
	}
}

func loadKeyStoreTestV3(file string, t *testing.T) map[string]KeyStoreTestV3 {
	tests := make(map[string]KeyStoreTestV3)
	err := common.LoadJSON(file, &tests)
	if err != nil {
		t.Fatal(err)
	}
	return tests
}

func loadKeyStoreTestV1(file string, t *testing.T) map[string]KeyStoreTestV1 {
	tests := make(map[string]KeyStoreTestV1)
	err := common.LoadJSON(file, &tests)
	if err != nil {
		t.Fatal(err)
	}
	return tests
}
238 239

func TestKeyForDirectICAP(t *testing.T) {
240 241
	t.Parallel()
	key := NewKeyForDirectICAP(rand.Reader)
242 243 244 245
	if !strings.HasPrefix(key.Address.Hex(), "0x00") {
		t.Errorf("Expected first address byte to be zero, have: %s", key.Address.Hex())
	}
}
246 247 248 249 250 251 252 253 254 255 256 257

func TestV3_31_Byte_Key(t *testing.T) {
	t.Parallel()
	tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t)
	testDecryptV3(tests["31_byte_key"], t)
}

func TestV3_30_Byte_Key(t *testing.T) {
	t.Parallel()
	tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t)
	testDecryptV3(tests["30_byte_key"], t)
}