code.vegaprotocol.io/vega@v0.79.0/wallet/wallets/handler_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package wallets_test 17 18 import ( 19 "fmt" 20 "testing" 21 22 vgrand "code.vegaprotocol.io/vega/libs/rand" 23 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 24 walletpb "code.vegaprotocol.io/vega/protos/vega/wallet/v1" 25 "code.vegaprotocol.io/vega/wallet/wallet" 26 "code.vegaprotocol.io/vega/wallet/wallets" 27 28 "github.com/golang/mock/gomock" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 ) 32 33 const ( 34 TestRecoveryPhrase1 = "swing ceiling chaos green put insane ripple desk match tip melt usual shrug turkey renew icon parade veteran lens govern path rough page render" 35 TestRecoveryPhrase2 = "green put insane ripple desk match tip melt usual shrug turkey renew icon parade veteran lens govern path rough page render swing ceiling chaos" 36 ) 37 38 type testHandler struct { 39 *wallets.Handler 40 ctrl *gomock.Controller 41 store *mockedStore 42 } 43 44 func getTestHandler(t *testing.T) *testHandler { 45 t.Helper() 46 ctrl := gomock.NewController(t) 47 store := newMockedStore() 48 h := wallets.NewHandler(store) 49 return &testHandler{ 50 Handler: h, 51 ctrl: ctrl, 52 store: store, 53 } 54 } 55 56 func TestHandler(t *testing.T) { 57 t.Run("Creating a wallet succeeds", testHandlerCreatingWalletSucceeds) 58 t.Run("Creating an already existing wallet fails", testHandlerCreatingAlreadyExistingWalletFails) 59 t.Run("Importing a wallet succeeds", testHandlerImportingWalletSucceeds) 60 t.Run("Importing a wallet with invalid recovery phrase fails", testHandlerImportingWalletWithInvalidRecoveryPhraseFails) 61 t.Run("Importing an already existing wallet fails", testHandlerImportingAlreadyExistingWalletFails) 62 t.Run("Verifying wallet existence succeeds", testHandlerVerifyingWalletExistenceSucceeds) 63 t.Run("Verifying wallet non existence succeeds", testHandlerVerifyingWalletNonExistenceSucceeds) 64 t.Run("Recreating a wallet with same name fails", testHandlerRecreatingWalletWithSameNameFails) 65 t.Run("Recreating a wallet with same name and different passphrase fails", testHandlerRecreatingWalletWithSameNameButDifferentPassphraseFails) 66 t.Run("Login to existing wallet succeeds", testHandlerLoginToExistingWalletSucceeds) 67 t.Run("Login to non-existing wallet fails", testHandlerLoginToNonExistingWalletFails) 68 t.Run("Generating new key pair securely succeeds", testHandlerGeneratingNewKeyPairSecurelySucceeds) 69 t.Run("Generating new key pair securely with invalid name fails", testHandlerGeneratingNewKeyPairSecurelyWithInvalidNameFails) 70 t.Run("Generating new key pair securely without wallet fails", testHandlerGeneratingNewKeyPairSecurelyWithoutWalletFails) 71 t.Run("Generating new key pair succeeds", testHandlerGeneratingNewKeyPairSucceeds) 72 t.Run("Generating new key pair with custom name succeeds", testHandlerGeneratingNewKeyPairWithCustomNameSucceeds) 73 t.Run("Generating new key pair with invalid name fails", testHandlerGeneratingNewKeyPairWithInvalidNameFails) 74 t.Run("Generating new key pair without wallet fails", testHandlerGeneratingNewKeyPairWithoutWalletFails) 75 t.Run("Listing public keys succeeds", testHandlerListingPublicKeysSucceeds) 76 t.Run("Listing public keys with invalid name fails", testHandlerListingPublicKeysWithInvalidNameFails) 77 t.Run("Listing public keys without wallet fails", testHandlerListingPublicKeysWithoutWalletFails) 78 t.Run("Listing key pairs succeeds", testHandlerListingKeyPairsSucceeds) 79 t.Run("Listing key pairs with invalid name fails", testHandlerListingKeyPairsWithInvalidNameFails) 80 t.Run("Listing key pairs without wallet fails", testHandlerListingKeyPairsWithoutWalletFails) 81 t.Run("Getting public key succeeds", testHandlerGettingPublicKeySucceeds) 82 t.Run("Getting public key without wallet fails", testHandlerGettingPublicKeyWithoutWalletFails) 83 t.Run("Getting public key with invalid name fails", testHandlerGettingPublicKeyWithInvalidNameFails) 84 t.Run("Getting non-existing public key fails", testGettingNonExistingPublicKeyFails) 85 t.Run("Tainting key pair succeeds", testHandlerTaintingKeyPairSucceeds) 86 t.Run("Tainting key pair with invalid name fails", testHandlerTaintingKeyPairWithInvalidNameFails) 87 t.Run("Tainting key pair without wallet fails", testHandlerTaintingKeyPairWithoutWalletFails) 88 t.Run("Tainting key pair that is already tainted fails", testHandlerTaintingKeyThatIsAlreadyTaintedFails) 89 t.Run("Updating key pair metadata succeeds", testHandlerUpdatingKeyPairMetaSucceeds) 90 t.Run("Updating key pair metadata with invalid passphrase fails", testHandlerUpdatingKeyPairMetaWithInvalidPassphraseFails) 91 t.Run("Updating key pair metadata with invalid name fails", testHandlerUpdatingKeyPairMetaWithInvalidNameFails) 92 t.Run("Updating key pair metadata without wallet fails", testHandlerUpdatingKeyPairMetaWithoutWalletFails) 93 t.Run("Updating key pair metadata with non-existing public key fails", testHandlerUpdatingKeyPairMetaWithNonExistingPublicKeyFails) 94 t.Run("Get wallet path succeeds", testHandlerGettingWalletPathSucceeds) 95 t.Run("Signing transaction request succeeds", testHandlerSigningTxSucceeds) 96 t.Run("Signing transaction request with tainted key fails", testHandlerSigningTxWithTaintedKeyFails) 97 t.Run("Signing and verifying a message succeeds", testHandlerSigningAndVerifyingMessageSucceeds) 98 } 99 100 func testHandlerCreatingWalletSucceeds(t *testing.T) { 101 h := getTestHandler(t) 102 defer h.ctrl.Finish() 103 104 // given 105 name := vgrand.RandomStr(5) 106 passphrase := vgrand.RandomStr(5) 107 108 // when 109 recoveryPhrase, err := h.CreateWallet(name, passphrase) 110 111 // then 112 require.NoError(t, err) 113 assert.NotEmpty(t, recoveryPhrase) 114 } 115 116 func testHandlerCreatingAlreadyExistingWalletFails(t *testing.T) { 117 h := getTestHandler(t) 118 defer h.ctrl.Finish() 119 120 // given 121 name := vgrand.RandomStr(5) 122 passphrase := vgrand.RandomStr(5) 123 124 // when 125 recoveryPhrase, err := h.CreateWallet(name, passphrase) 126 127 // then 128 require.NoError(t, err) 129 assert.NotEmpty(t, recoveryPhrase) 130 131 // when 132 recoveryPhrase, err = h.CreateWallet(name, passphrase) 133 134 // then 135 require.Error(t, err, wallet.ErrWalletAlreadyExists) 136 assert.Empty(t, recoveryPhrase) 137 } 138 139 func testHandlerImportingWalletSucceeds(t *testing.T) { 140 tcs := []struct { 141 name string 142 version uint32 143 }{ 144 { 145 name: "version 1", 146 version: 1, 147 }, { 148 name: "version 2", 149 version: 2, 150 }, 151 } 152 153 for _, tc := range tcs { 154 t.Run(tc.name, func(tt *testing.T) { 155 h := getTestHandler(t) 156 defer h.ctrl.Finish() 157 158 // given 159 name := vgrand.RandomStr(5) 160 passphrase := vgrand.RandomStr(5) 161 162 // when 163 err := h.ImportWallet(name, passphrase, TestRecoveryPhrase1, tc.version) 164 165 // then 166 require.NoError(t, err) 167 }) 168 } 169 } 170 171 func testHandlerImportingWalletWithInvalidRecoveryPhraseFails(t *testing.T) { 172 tcs := []struct { 173 name string 174 version uint32 175 }{ 176 { 177 name: "version 1", 178 version: 1, 179 }, { 180 name: "version 2", 181 version: 2, 182 }, 183 } 184 185 for _, tc := range tcs { 186 t.Run(tc.name, func(tt *testing.T) { 187 h := getTestHandler(t) 188 defer h.ctrl.Finish() 189 190 // given 191 name := vgrand.RandomStr(5) 192 passphrase := vgrand.RandomStr(5) 193 194 // when 195 err := h.ImportWallet(name, passphrase, "this is not a valid recoveryPhrase", tc.version) 196 197 // then 198 require.ErrorIs(t, err, wallet.ErrInvalidRecoveryPhrase) 199 }) 200 } 201 } 202 203 func testHandlerImportingAlreadyExistingWalletFails(t *testing.T) { 204 tcs := []struct { 205 name string 206 version uint32 207 }{ 208 { 209 name: "version 1", 210 version: 1, 211 }, { 212 name: "version 2", 213 version: 2, 214 }, 215 } 216 for _, tc := range tcs { 217 t.Run(tc.name, func(tt *testing.T) { 218 h := getTestHandler(t) 219 defer h.ctrl.Finish() 220 221 // given 222 name := vgrand.RandomStr(5) 223 passphrase := vgrand.RandomStr(5) 224 225 // when 226 err := h.ImportWallet(name, passphrase, TestRecoveryPhrase1, tc.version) 227 228 // then 229 require.NoError(t, err) 230 231 // when 232 err = h.ImportWallet(name, passphrase, TestRecoveryPhrase2, tc.version) 233 234 // then 235 require.Error(t, err, wallet.ErrWalletAlreadyExists) 236 }) 237 } 238 } 239 240 func testHandlerVerifyingWalletExistenceSucceeds(t *testing.T) { 241 h := getTestHandler(t) 242 defer h.ctrl.Finish() 243 244 // given 245 name := vgrand.RandomStr(5) 246 passphrase := vgrand.RandomStr(5) 247 248 // when 249 recoveryPhrase, err := h.CreateWallet(name, passphrase) 250 251 // then 252 require.NoError(t, err) 253 assert.NotEmpty(t, recoveryPhrase) 254 255 // when 256 exists := h.WalletExists(name) 257 258 // then 259 assert.True(t, exists) 260 } 261 262 func testHandlerVerifyingWalletNonExistenceSucceeds(t *testing.T) { 263 h := getTestHandler(t) 264 defer h.ctrl.Finish() 265 266 // given 267 name := vgrand.RandomStr(5) 268 269 // when 270 exists := h.WalletExists(name) 271 272 // then 273 assert.False(t, exists) 274 } 275 276 func testHandlerRecreatingWalletWithSameNameFails(t *testing.T) { 277 h := getTestHandler(t) 278 defer h.ctrl.Finish() 279 280 // given 281 name := vgrand.RandomStr(5) 282 passphrase := vgrand.RandomStr(5) 283 284 // when 285 recoveryPhrase, err := h.CreateWallet(name, passphrase) 286 287 // then 288 require.NoError(t, err) 289 assert.NotEmpty(t, recoveryPhrase) 290 291 // when 292 recoveryPhrase, err = h.CreateWallet(name, passphrase) 293 294 // then 295 require.ErrorIs(t, err, wallet.ErrWalletAlreadyExists) 296 assert.Empty(t, recoveryPhrase) 297 } 298 299 func testHandlerRecreatingWalletWithSameNameButDifferentPassphraseFails(t *testing.T) { 300 h := getTestHandler(t) 301 defer h.ctrl.Finish() 302 303 // given 304 name := vgrand.RandomStr(5) 305 passphrase := vgrand.RandomStr(5) 306 othPassphrase := "different-passphrase" 307 308 // when 309 recoveryPhrase, err := h.CreateWallet(name, passphrase) 310 311 // then 312 require.NoError(t, err) 313 assert.NotEmpty(t, recoveryPhrase) 314 315 // when 316 recoveryPhrase, err = h.CreateWallet(name, othPassphrase) 317 318 // then 319 require.ErrorIs(t, err, wallet.ErrWalletAlreadyExists) 320 assert.Empty(t, recoveryPhrase) 321 } 322 323 func testHandlerLoginToExistingWalletSucceeds(t *testing.T) { 324 h := getTestHandler(t) 325 defer h.ctrl.Finish() 326 327 // given 328 passphrase := vgrand.RandomStr(5) 329 name := vgrand.RandomStr(5) 330 331 // when 332 recoveryPhrase, err := h.CreateWallet(name, passphrase) 333 334 // then 335 require.NoError(t, err) 336 assert.NotEmpty(t, recoveryPhrase) 337 338 // then 339 err = h.LoginWallet(name, passphrase) 340 341 require.NoError(t, err) 342 } 343 344 func testHandlerLoginToNonExistingWalletFails(t *testing.T) { 345 h := getTestHandler(t) 346 defer h.ctrl.Finish() 347 348 // given 349 passphrase := vgrand.RandomStr(5) 350 name := vgrand.RandomStr(5) 351 352 // when 353 err := h.LoginWallet(name, passphrase) 354 355 // then 356 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 357 } 358 359 func testHandlerGeneratingNewKeyPairSecurelySucceeds(t *testing.T) { 360 h := getTestHandler(t) 361 defer h.ctrl.Finish() 362 363 // given 364 passphrase := vgrand.RandomStr(5) 365 name := vgrand.RandomStr(5) 366 367 // when 368 recoveryPhrase, err := h.CreateWallet(name, passphrase) 369 370 // then 371 require.NoError(t, err) 372 assert.NotEmpty(t, recoveryPhrase) 373 374 // when 375 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 376 377 // then 378 require.NoError(t, err) 379 assert.NotEmpty(t, key) 380 381 // when 382 keys, err := h.ListPublicKeys(name) 383 384 // then 385 require.NoError(t, err) 386 assert.Len(t, keys, 1) 387 assert.Equal(t, key, keys[0].Key()) 388 assert.False(t, keys[0].IsTainted()) 389 assert.Len(t, keys[0].Metadata(), 1) 390 assert.Contains(t, keys[0].Metadata(), wallet.Metadata{Key: "name", Value: "Key 1"}) 391 } 392 393 func testHandlerGeneratingNewKeyPairSecurelyWithInvalidNameFails(t *testing.T) { 394 h := getTestHandler(t) 395 defer h.ctrl.Finish() 396 397 // given 398 passphrase := vgrand.RandomStr(5) 399 name := vgrand.RandomStr(5) 400 otherName := vgrand.RandomStr(5) 401 402 // when 403 recoveryPhrase, err := h.CreateWallet(name, passphrase) 404 405 // then 406 require.NoError(t, err) 407 assert.NotEmpty(t, recoveryPhrase) 408 409 // when 410 key, err := h.SecureGenerateKeyPair(otherName, passphrase, []wallet.Metadata{}) 411 412 // then 413 assert.EqualError(t, err, fmt.Sprintf("couldn't unlock wallet %q: wallet does not exist", otherName)) 414 assert.Empty(t, key) 415 } 416 417 func testHandlerGeneratingNewKeyPairSecurelyWithoutWalletFails(t *testing.T) { 418 h := getTestHandler(t) 419 defer h.ctrl.Finish() 420 421 // given 422 name := vgrand.RandomStr(5) 423 passphrase := vgrand.RandomStr(5) 424 425 // when 426 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 427 428 // then 429 assert.EqualError(t, err, fmt.Sprintf("couldn't unlock wallet %q: wallet does not exist", name)) 430 assert.Empty(t, key) 431 } 432 433 func testHandlerGeneratingNewKeyPairSucceeds(t *testing.T) { 434 h := getTestHandler(t) 435 defer h.ctrl.Finish() 436 437 // given 438 passphrase := vgrand.RandomStr(5) 439 name := vgrand.RandomStr(5) 440 441 // when 442 recoveryPhrase, err := h.CreateWallet(name, passphrase) 443 444 // then 445 require.NoError(t, err) 446 assert.NotEmpty(t, recoveryPhrase) 447 448 // when 449 keyPair, err := h.GenerateKeyPair(name, passphrase, nil) 450 451 // then 452 require.NoError(t, err) 453 assert.NotEmpty(t, keyPair.PublicKey()) 454 assert.NotEmpty(t, keyPair.PrivateKey()) 455 assert.False(t, keyPair.IsTainted()) 456 assert.Len(t, keyPair.Metadata(), 1) 457 assert.Contains(t, keyPair.Metadata(), wallet.Metadata{Key: "name", Value: "Key 1"}) 458 459 // when 460 keys, err := h.ListPublicKeys(name) 461 462 // then 463 require.NoError(t, err) 464 assert.Len(t, keys, 1) 465 assert.Equal(t, keyPair.PublicKey(), keys[0].Key()) 466 assert.False(t, keys[0].IsTainted()) 467 } 468 469 func testHandlerGeneratingNewKeyPairWithCustomNameSucceeds(t *testing.T) { 470 h := getTestHandler(t) 471 defer h.ctrl.Finish() 472 473 // given 474 passphrase := vgrand.RandomStr(5) 475 name := vgrand.RandomStr(5) 476 meta := []wallet.Metadata{ 477 { 478 Key: "name", 479 Value: "crypto-cutie", 480 }, 481 } 482 483 // when 484 recoveryPhrase, err := h.CreateWallet(name, passphrase) 485 486 // then 487 require.NoError(t, err) 488 assert.NotEmpty(t, recoveryPhrase) 489 490 // when 491 keyPair1, err := h.GenerateKeyPair(name, passphrase, meta) 492 493 // then 494 require.NoError(t, err) 495 assert.NotEmpty(t, keyPair1.PublicKey()) 496 assert.NotEmpty(t, keyPair1.PrivateKey()) 497 assert.False(t, keyPair1.IsTainted()) 498 assert.Len(t, keyPair1.Metadata(), 1) 499 assert.Contains(t, keyPair1.Metadata(), wallet.Metadata{Key: "name", Value: "crypto-cutie"}) 500 501 // when 502 keyPair2, err := h.GenerateKeyPair(name, passphrase, []wallet.Metadata{}) 503 504 // then 505 require.NoError(t, err) 506 assert.NotEmpty(t, keyPair2.PublicKey()) 507 assert.NotEmpty(t, keyPair2.PrivateKey()) 508 assert.False(t, keyPair2.IsTainted()) 509 assert.Len(t, keyPair2.Metadata(), 1) 510 assert.Contains(t, keyPair2.Metadata(), wallet.Metadata{Key: "name", Value: "Key 2"}) 511 512 // when 513 keys, err := h.ListPublicKeys(name) 514 515 // then 516 require.NoError(t, err) 517 assert.Len(t, keys, 2) 518 assert.Equal(t, keyPair1.PublicKey(), keys[0].Key()) 519 assert.False(t, keys[0].IsTainted()) 520 assert.Equal(t, keyPair2.PublicKey(), keys[1].Key()) 521 assert.False(t, keys[1].IsTainted()) 522 } 523 524 func testHandlerGeneratingNewKeyPairWithInvalidNameFails(t *testing.T) { 525 h := getTestHandler(t) 526 defer h.ctrl.Finish() 527 528 // given 529 passphrase := vgrand.RandomStr(5) 530 name := vgrand.RandomStr(5) 531 otherName := vgrand.RandomStr(5) 532 533 // when 534 recoveryPhrase, err := h.CreateWallet(name, passphrase) 535 536 // then 537 require.NoError(t, err) 538 assert.NotEmpty(t, recoveryPhrase) 539 540 // when 541 keyPair, err := h.GenerateKeyPair(otherName, passphrase, nil) 542 543 // then 544 assert.EqualError(t, err, fmt.Sprintf("couldn't unlock wallet %q: wallet does not exist", otherName)) 545 assert.Empty(t, keyPair) 546 } 547 548 func testHandlerGeneratingNewKeyPairWithoutWalletFails(t *testing.T) { 549 h := getTestHandler(t) 550 defer h.ctrl.Finish() 551 552 // given 553 name := vgrand.RandomStr(5) 554 passphrase := vgrand.RandomStr(5) 555 556 // when 557 keyPair, err := h.GenerateKeyPair(name, passphrase, nil) 558 559 // then 560 assert.EqualError(t, err, fmt.Sprintf("couldn't unlock wallet %q: wallet does not exist", name)) 561 assert.Empty(t, keyPair) 562 } 563 564 func testHandlerListingPublicKeysSucceeds(t *testing.T) { 565 h := getTestHandler(t) 566 defer h.ctrl.Finish() 567 568 // given 569 passphrase := vgrand.RandomStr(5) 570 name := vgrand.RandomStr(5) 571 572 // when 573 recoveryPhrase, err := h.CreateWallet(name, passphrase) 574 575 // then 576 require.NoError(t, err) 577 assert.NotEmpty(t, recoveryPhrase) 578 579 // when 580 keyPair, err := h.GenerateKeyPair(name, passphrase, nil) 581 582 // then 583 require.NoError(t, err) 584 assert.NotNil(t, keyPair) 585 586 // when 587 publicKeys, err := h.ListPublicKeys(name) 588 589 // then 590 require.NoError(t, err) 591 assert.Len(t, publicKeys, 1) 592 returnedPublicKey := publicKeys[0] 593 assert.Equal(t, keyPair.PublicKey(), returnedPublicKey.Key()) 594 assert.Equal(t, keyPair.IsTainted(), returnedPublicKey.IsTainted()) 595 assert.Equal(t, keyPair.AlgorithmName(), returnedPublicKey.AlgorithmName()) 596 assert.Equal(t, keyPair.AlgorithmVersion(), returnedPublicKey.AlgorithmVersion()) 597 assert.Equal(t, keyPair.Metadata(), returnedPublicKey.Metadata()) 598 } 599 600 func testHandlerListingPublicKeysWithInvalidNameFails(t *testing.T) { 601 h := getTestHandler(t) 602 defer h.ctrl.Finish() 603 604 // given 605 passphrase := vgrand.RandomStr(5) 606 name := vgrand.RandomStr(5) 607 otherName := vgrand.RandomStr(5) 608 609 // when 610 recoveryPhrase, err := h.CreateWallet(name, passphrase) 611 612 // then 613 require.NoError(t, err) 614 assert.NotEmpty(t, recoveryPhrase) 615 616 // when 617 key, err := h.ListPublicKeys(otherName) 618 619 // then 620 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 621 assert.Empty(t, key) 622 } 623 624 func testHandlerListingPublicKeysWithoutWalletFails(t *testing.T) { 625 h := getTestHandler(t) 626 defer h.ctrl.Finish() 627 628 // given 629 name := vgrand.RandomStr(5) 630 631 // when 632 key, err := h.ListPublicKeys(name) 633 634 // then 635 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 636 assert.Empty(t, key) 637 } 638 639 func testHandlerListingKeyPairsSucceeds(t *testing.T) { 640 h := getTestHandler(t) 641 defer h.ctrl.Finish() 642 643 // given 644 passphrase := vgrand.RandomStr(5) 645 name := vgrand.RandomStr(5) 646 647 // when 648 recoveryPhrase, err := h.CreateWallet(name, passphrase) 649 650 // then 651 require.NoError(t, err) 652 assert.NotEmpty(t, recoveryPhrase) 653 654 // when 655 keyPair, err := h.GenerateKeyPair(name, passphrase, nil) 656 657 // then 658 require.NoError(t, err) 659 assert.NotNil(t, keyPair) 660 661 // when 662 publicKeys, err := h.ListKeyPairs(name) 663 664 // then 665 require.NoError(t, err) 666 assert.Len(t, publicKeys, 1) 667 returnedPublicKey := publicKeys[0] 668 assert.Equal(t, keyPair.PublicKey(), returnedPublicKey.PublicKey()) 669 assert.Equal(t, keyPair.PrivateKey(), returnedPublicKey.PrivateKey()) 670 assert.Equal(t, keyPair.IsTainted(), returnedPublicKey.IsTainted()) 671 assert.Equal(t, keyPair.AlgorithmName(), returnedPublicKey.AlgorithmName()) 672 assert.Equal(t, keyPair.AlgorithmVersion(), returnedPublicKey.AlgorithmVersion()) 673 assert.Equal(t, keyPair.Metadata(), returnedPublicKey.Metadata()) 674 } 675 676 func testHandlerListingKeyPairsWithInvalidNameFails(t *testing.T) { 677 h := getTestHandler(t) 678 defer h.ctrl.Finish() 679 680 // given 681 passphrase := vgrand.RandomStr(5) 682 name := vgrand.RandomStr(5) 683 otherName := vgrand.RandomStr(5) 684 685 // when 686 recoveryPhrase, err := h.CreateWallet(name, passphrase) 687 688 // then 689 require.NoError(t, err) 690 assert.NotEmpty(t, recoveryPhrase) 691 692 // when 693 key, err := h.ListKeyPairs(otherName) 694 695 // then 696 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 697 assert.Empty(t, key) 698 } 699 700 func testHandlerListingKeyPairsWithoutWalletFails(t *testing.T) { 701 h := getTestHandler(t) 702 defer h.ctrl.Finish() 703 704 // given 705 name := vgrand.RandomStr(5) 706 707 // when 708 key, err := h.ListKeyPairs(name) 709 710 // then 711 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 712 assert.Empty(t, key) 713 } 714 715 func testHandlerGettingPublicKeyWithoutWalletFails(t *testing.T) { 716 h := getTestHandler(t) 717 defer h.ctrl.Finish() 718 719 // given 720 name := vgrand.RandomStr(5) 721 722 // when 723 key, err := h.GetPublicKey(name, name) 724 725 // then 726 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 727 assert.Empty(t, key) 728 } 729 730 func testHandlerGettingPublicKeySucceeds(t *testing.T) { 731 h := getTestHandler(t) 732 defer h.ctrl.Finish() 733 734 // given 735 passphrase := vgrand.RandomStr(5) 736 name := vgrand.RandomStr(5) 737 738 // when 739 recoveryPhrase, err := h.CreateWallet(name, passphrase) 740 741 // then 742 require.NoError(t, err) 743 assert.NotEmpty(t, recoveryPhrase) 744 745 // when 746 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 747 748 // then 749 require.NoError(t, err) 750 assert.NotEmpty(t, key) 751 752 // when 753 keyPair, err := h.GetPublicKey(name, key) 754 755 require.NoError(t, err) 756 assert.Equal(t, key, keyPair.Key()) 757 } 758 759 func testHandlerGettingPublicKeyWithInvalidNameFails(t *testing.T) { 760 h := getTestHandler(t) 761 defer h.ctrl.Finish() 762 763 // given 764 passphrase := vgrand.RandomStr(5) 765 name := vgrand.RandomStr(5) 766 otherName := vgrand.RandomStr(5) 767 768 // when 769 recoveryPhrase, err := h.CreateWallet(name, passphrase) 770 771 // then 772 require.NoError(t, err) 773 assert.NotEmpty(t, recoveryPhrase) 774 775 // when 776 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 777 778 // then 779 require.NoError(t, err) 780 assert.NotEmpty(t, key) 781 782 // when 783 keyPair, err := h.GetPublicKey(otherName, key) 784 785 // then 786 assert.ErrorIs(t, err, wallets.ErrWalletDoesNotExists) 787 assert.Nil(t, keyPair) 788 } 789 790 func testGettingNonExistingPublicKeyFails(t *testing.T) { 791 h := getTestHandler(t) 792 defer h.ctrl.Finish() 793 794 // given 795 passphrase := vgrand.RandomStr(5) 796 name := vgrand.RandomStr(5) 797 798 // when 799 recoveryPhrase, err := h.CreateWallet(name, passphrase) 800 801 // then 802 require.NoError(t, err) 803 assert.NotEmpty(t, recoveryPhrase) 804 805 // when 806 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 807 808 // then 809 require.NoError(t, err) 810 assert.NotEmpty(t, key) 811 812 // when 813 keyPair, err := h.GetPublicKey(name, "non-existing-pub-key") 814 assert.ErrorIs(t, err, wallet.ErrPubKeyDoesNotExist) 815 assert.Nil(t, keyPair) 816 } 817 818 func testHandlerTaintingKeyPairSucceeds(t *testing.T) { 819 h := getTestHandler(t) 820 defer h.ctrl.Finish() 821 822 // given 823 passphrase := vgrand.RandomStr(5) 824 name := vgrand.RandomStr(5) 825 826 // when 827 recoveryPhrase, err := h.CreateWallet(name, passphrase) 828 829 // then 830 require.NoError(t, err) 831 assert.NotEmpty(t, recoveryPhrase) 832 833 // when 834 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 835 836 // then 837 require.NoError(t, err) 838 assert.NotEmpty(t, key) 839 840 // when 841 publicKey, err := h.GetPublicKey(name, key) 842 843 // then 844 require.NoError(t, err) 845 assert.NotNil(t, publicKey) 846 assert.False(t, publicKey.IsTainted()) 847 848 // when 849 err = h.TaintKey(name, key, passphrase) 850 851 // then 852 require.NoError(t, err) 853 assert.True(t, h.store.GetKey(name, key).IsTainted()) 854 } 855 856 func testHandlerTaintingKeyPairWithInvalidNameFails(t *testing.T) { 857 h := getTestHandler(t) 858 defer h.ctrl.Finish() 859 860 // given 861 passphrase := vgrand.RandomStr(5) 862 name := vgrand.RandomStr(5) 863 864 otherName := "other name" 865 866 // when 867 recoveryPhrase, err := h.CreateWallet(name, passphrase) 868 869 // then 870 require.NoError(t, err) 871 assert.NotEmpty(t, recoveryPhrase) 872 873 // when 874 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 875 876 // then 877 require.NoError(t, err) 878 assert.NotEmpty(t, key) 879 880 // when 881 keyPair, err := h.GetPublicKey(name, key) 882 883 // then 884 require.NoError(t, err) 885 assert.NotNil(t, keyPair) 886 assert.False(t, keyPair.IsTainted()) 887 888 // when 889 err = h.TaintKey(otherName, key, passphrase) 890 891 // then 892 assert.Error(t, err) 893 } 894 895 func testHandlerTaintingKeyPairWithoutWalletFails(t *testing.T) { 896 h := getTestHandler(t) 897 defer h.ctrl.Finish() 898 899 // given 900 passphrase := vgrand.RandomStr(5) 901 name := vgrand.RandomStr(5) 902 903 // when 904 err := h.TaintKey(name, "non-existing-pub-key", passphrase) 905 906 // then 907 assert.EqualError(t, err, fmt.Sprintf("couldn't unlock wallet %q: wallet does not exist", name)) 908 } 909 910 func testHandlerTaintingKeyThatIsAlreadyTaintedFails(t *testing.T) { 911 h := getTestHandler(t) 912 defer h.ctrl.Finish() 913 914 // given 915 passphrase := vgrand.RandomStr(5) 916 name := vgrand.RandomStr(5) 917 918 // when 919 recoveryPhrase, err := h.CreateWallet(name, passphrase) 920 921 // then 922 require.NoError(t, err) 923 assert.NotEmpty(t, recoveryPhrase) 924 925 // when 926 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 927 928 // then 929 require.NoError(t, err) 930 assert.NotEmpty(t, key) 931 932 // when 933 keyPair, err := h.GetPublicKey(name, key) 934 935 // then 936 require.NoError(t, err) 937 assert.NotNil(t, keyPair) 938 assert.False(t, keyPair.IsTainted()) 939 940 // when 941 err = h.TaintKey(name, key, passphrase) 942 943 // then 944 require.NoError(t, err) 945 assert.True(t, h.store.GetKey(name, key).IsTainted()) 946 947 // when 948 err = h.TaintKey(name, key, passphrase) 949 950 // then 951 assert.ErrorIs(t, err, wallet.ErrPubKeyAlreadyTainted) 952 } 953 954 func testHandlerUpdatingKeyPairMetaSucceeds(t *testing.T) { 955 h := getTestHandler(t) 956 defer h.ctrl.Finish() 957 958 // given 959 passphrase := vgrand.RandomStr(5) 960 name := vgrand.RandomStr(5) 961 962 meta := []wallet.Metadata{{Key: "primary", Value: "yes"}} 963 964 // when 965 recoveryPhrase, err := h.CreateWallet(name, passphrase) 966 967 // then 968 require.NoError(t, err) 969 assert.NotEmpty(t, recoveryPhrase) 970 971 // when 972 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 973 974 // then 975 require.NoError(t, err) 976 assert.NotEmpty(t, key) 977 978 // when 979 err = h.UpdateMeta(name, key, passphrase, meta) 980 981 // then 982 require.NoError(t, err) 983 updatedKp := h.store.GetKey(name, key) 984 assert.Len(t, updatedKp.Metadata(), 2) 985 assert.Equal(t, updatedKp.Metadata()[0].Key, "primary") 986 assert.Equal(t, updatedKp.Metadata()[0].Value, "yes") 987 assert.Equal(t, updatedKp.Metadata()[1].Key, "name") 988 assert.Equal(t, updatedKp.Metadata()[1].Value, "Key 1") 989 } 990 991 func testHandlerUpdatingKeyPairMetaWithInvalidPassphraseFails(t *testing.T) { 992 h := getTestHandler(t) 993 defer h.ctrl.Finish() 994 995 // given 996 passphrase := vgrand.RandomStr(5) 997 othPassphrase := "other-passphrase" 998 name := vgrand.RandomStr(5) 999 1000 meta := []wallet.Metadata{{Key: "primary", Value: "yes"}} 1001 1002 // when 1003 recoveryPhrase, err := h.CreateWallet(name, passphrase) 1004 1005 // then 1006 require.NoError(t, err) 1007 assert.NotEmpty(t, recoveryPhrase) 1008 1009 // when 1010 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 1011 1012 // then 1013 require.NoError(t, err) 1014 assert.NotEmpty(t, key) 1015 1016 // when 1017 err = h.UpdateMeta(name, key, othPassphrase, meta) 1018 1019 // then 1020 assert.Error(t, err) 1021 assert.NotContains(t, h.store.GetKey(name, key).Metadata(), wallet.Metadata{Key: "primary", Value: "yes"}) 1022 } 1023 1024 func testHandlerUpdatingKeyPairMetaWithInvalidNameFails(t *testing.T) { 1025 h := getTestHandler(t) 1026 defer h.ctrl.Finish() 1027 1028 // given 1029 passphrase := vgrand.RandomStr(5) 1030 name := vgrand.RandomStr(5) 1031 otherName := "other name" 1032 meta := []wallet.Metadata{{Key: "primary", Value: "yes"}} 1033 1034 // when 1035 recoveryPhrase, err := h.CreateWallet(name, passphrase) 1036 1037 // then 1038 require.NoError(t, err) 1039 assert.NotEmpty(t, recoveryPhrase) 1040 1041 // when 1042 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 1043 1044 // then 1045 require.NoError(t, err) 1046 assert.NotEmpty(t, key) 1047 1048 // when 1049 err = h.UpdateMeta(otherName, key, passphrase, meta) 1050 1051 // then 1052 assert.Error(t, err) 1053 assert.NotContains(t, h.store.GetKey(name, key).Metadata(), wallet.Metadata{Key: "primary", Value: "yes"}) 1054 } 1055 1056 func testHandlerUpdatingKeyPairMetaWithoutWalletFails(t *testing.T) { 1057 h := getTestHandler(t) 1058 defer h.ctrl.Finish() 1059 1060 // given 1061 passphrase := vgrand.RandomStr(5) 1062 name := vgrand.RandomStr(5) 1063 pubKey := "non-existing-public-key" 1064 meta := []wallet.Metadata{{Key: "primary", Value: "yes"}} 1065 1066 // when 1067 err := h.UpdateMeta(name, pubKey, passphrase, meta) 1068 1069 // then 1070 assert.Error(t, err) 1071 } 1072 1073 func testHandlerUpdatingKeyPairMetaWithNonExistingPublicKeyFails(t *testing.T) { 1074 h := getTestHandler(t) 1075 defer h.ctrl.Finish() 1076 1077 // given 1078 passphrase := vgrand.RandomStr(5) 1079 name := vgrand.RandomStr(5) 1080 pubKey := "non-existing-public-key" 1081 meta := []wallet.Metadata{{Key: "primary", Value: "yes"}} 1082 1083 // when 1084 recoveryPhrase, err := h.CreateWallet(name, passphrase) 1085 1086 // then 1087 require.NoError(t, err) 1088 assert.NotEmpty(t, recoveryPhrase) 1089 1090 // when 1091 key, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 1092 1093 // then 1094 require.NoError(t, err) 1095 assert.NotEmpty(t, key) 1096 1097 // when 1098 err = h.UpdateMeta(name, pubKey, passphrase, meta) 1099 1100 // then 1101 assert.Error(t, err) 1102 } 1103 1104 func testHandlerGettingWalletPathSucceeds(t *testing.T) { 1105 h := getTestHandler(t) 1106 defer h.ctrl.Finish() 1107 1108 // given 1109 name := vgrand.RandomStr(5) 1110 1111 // when 1112 path, err := h.GetWalletPath(name) 1113 1114 // then 1115 require.NoError(t, err) 1116 assert.NotEmpty(t, path) 1117 } 1118 1119 func testHandlerSigningTxSucceeds(t *testing.T) { 1120 h := getTestHandler(t) 1121 defer h.ctrl.Finish() 1122 1123 // given 1124 passphrase := vgrand.RandomStr(5) 1125 name := vgrand.RandomStr(5) 1126 1127 // when 1128 recoveryPhrase, err := h.CreateWallet(name, passphrase) 1129 1130 // then 1131 require.NoError(t, err) 1132 assert.NotEmpty(t, recoveryPhrase) 1133 1134 // when 1135 pubKey, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 1136 1137 // then 1138 require.NoError(t, err) 1139 assert.NotEmpty(t, pubKey) 1140 1141 // given 1142 req := &walletpb.SubmitTransactionRequest{ 1143 PubKey: pubKey, 1144 Command: &walletpb.SubmitTransactionRequest_OrderCancellation{ 1145 OrderCancellation: &commandspb.OrderCancellation{}, 1146 }, 1147 } 1148 1149 // when 1150 tx, err := h.SignTx(name, req, 42, vgrand.RandomStr(5)) 1151 1152 // then 1153 require.NoError(t, err) 1154 assert.Equal(t, commandspb.TxVersion(3), tx.Version) 1155 assert.NotEmpty(t, tx.From) 1156 assert.Equal(t, tx.GetPubKey(), pubKey) 1157 assert.NotEmpty(t, tx.InputData) 1158 assert.NotNil(t, tx.Signature) 1159 key := h.store.GetKey(name, pubKey) 1160 assert.Equal(t, key.AlgorithmVersion(), tx.Signature.Version) 1161 assert.Equal(t, key.AlgorithmName(), tx.Signature.Algo) 1162 assert.NotEmpty(t, tx.Signature.Value) 1163 } 1164 1165 func testHandlerSigningTxWithTaintedKeyFails(t *testing.T) { 1166 h := getTestHandler(t) 1167 defer h.ctrl.Finish() 1168 1169 // given 1170 passphrase := vgrand.RandomStr(5) 1171 name := vgrand.RandomStr(5) 1172 1173 // when 1174 recoveryPhrase, err := h.CreateWallet(name, passphrase) 1175 1176 // then 1177 require.NoError(t, err) 1178 assert.NotEmpty(t, recoveryPhrase) 1179 1180 // when 1181 pubKey, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 1182 1183 // then 1184 require.NoError(t, err) 1185 assert.NotEmpty(t, pubKey) 1186 1187 // when 1188 err = h.TaintKey(name, pubKey, passphrase) 1189 1190 // then 1191 require.NoError(t, err) 1192 assert.True(t, h.store.GetKey(name, pubKey).IsTainted()) 1193 1194 // given 1195 req := &walletpb.SubmitTransactionRequest{ 1196 PubKey: pubKey, 1197 Command: &walletpb.SubmitTransactionRequest_OrderCancellation{ 1198 OrderCancellation: &commandspb.OrderCancellation{}, 1199 }, 1200 } 1201 1202 // when 1203 tx, err := h.SignTx(name, req, 42, vgrand.RandomStr(5)) 1204 1205 // then 1206 assert.Error(t, err) 1207 assert.Nil(t, tx) 1208 } 1209 1210 func testHandlerSigningAndVerifyingMessageSucceeds(t *testing.T) { 1211 h := getTestHandler(t) 1212 defer h.ctrl.Finish() 1213 1214 // given 1215 passphrase := vgrand.RandomStr(5) 1216 name := vgrand.RandomStr(5) 1217 1218 // when 1219 recoveryPhrase, err := h.CreateWallet(name, passphrase) 1220 1221 // then 1222 require.NoError(t, err) 1223 assert.NotEmpty(t, recoveryPhrase) 1224 1225 // when 1226 pubKey, err := h.SecureGenerateKeyPair(name, passphrase, []wallet.Metadata{}) 1227 1228 // then 1229 require.NoError(t, err) 1230 assert.NotEmpty(t, pubKey) 1231 1232 // given 1233 data := []byte("Je ne connaîtrai pas la peur car la peur tue l'esprit. La peur est la petite mort qui conduit à l'oblitération totale.") 1234 1235 // when 1236 sig, err := h.SignAny(name, data, pubKey) 1237 1238 // then 1239 require.NoError(t, err) 1240 assert.NotEmpty(t, sig) 1241 1242 // when 1243 verified, err := h.VerifyAny(data, sig, pubKey) 1244 1245 // then 1246 require.NoError(t, err) 1247 assert.True(t, verified) 1248 }