|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | 3 | import * as chai from 'chai'; |
| 4 | +import sjcl from 'sjcl'; |
4 | 5 | import { Key } from '../src/lib/key'; |
5 | 6 |
|
6 | 7 | const should = chai.should(); |
@@ -572,4 +573,100 @@ describe('Key', function() { |
572 | 573 | should.exist(obj.fingerPrint); |
573 | 574 | }); |
574 | 575 | }); |
| 576 | + describe('Backward compatibility with sjcl', function() { |
| 577 | + describe('#checkPassword with sjcl encrypted key', function() { |
| 578 | + it('should check password on sjcl encrypted key', function() { |
| 579 | + const k = new Key({ |
| 580 | + seedType: 'mnemonic', |
| 581 | + seedData: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about' |
| 582 | + }); |
| 583 | + const password = 'testpassword'; |
| 584 | + const xPrivKey = k.get().xPrivKey; |
| 585 | + |
| 586 | + const obj = k.toObj(); |
| 587 | + obj.xPrivKeyEncrypted = sjcl.encrypt(password, xPrivKey); |
| 588 | + obj.xPrivKey = undefined; |
| 589 | + |
| 590 | + const k2 = new Key({ seedType: 'object', seedData: obj }); |
| 591 | + k2.checkPassword(password).should.equal(true); |
| 592 | + k2.checkPassword('wrongpassword').should.equal(false); |
| 593 | + }); |
| 594 | + }); |
| 595 | + |
| 596 | + describe('#get with sjcl encrypted key', function() { |
| 597 | + it('should decrypt sjcl encrypted mnemonic and privatekey', function() { |
| 598 | + const k = new Key({ |
| 599 | + seedType: 'mnemonic', |
| 600 | + seedData: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about' |
| 601 | + }); |
| 602 | + const password = 'testpassword'; |
| 603 | + const expectedMnemonic = k.get().mnemonic; |
| 604 | + const expectedXPrivKey = k.get().xPrivKey; |
| 605 | + |
| 606 | + const obj = k.toObj(); |
| 607 | + obj.xPrivKeyEncrypted = sjcl.encrypt(password, expectedXPrivKey); |
| 608 | + obj.mnemonicEncrypted = sjcl.encrypt(password, expectedMnemonic); |
| 609 | + obj.xPrivKey = undefined; |
| 610 | + obj.mnemonic = undefined; |
| 611 | + |
| 612 | + const k2 = new Key({ seedType: 'object', seedData: obj }); |
| 613 | + const decrypted = k2.get(password); |
| 614 | + decrypted.mnemonic.should.equal(expectedMnemonic); |
| 615 | + decrypted.xPrivKey.should.equal(expectedXPrivKey); |
| 616 | + }); |
| 617 | + }); |
| 618 | + |
| 619 | + describe('#decrypt with sjcl encrypted key', function() { |
| 620 | + it('should decrypt sjcl key', function() { |
| 621 | + const k = new Key({ |
| 622 | + seedType: 'mnemonic', |
| 623 | + seedData: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about' |
| 624 | + }); |
| 625 | + const password = 'testpassword'; |
| 626 | + const expectedXPrivKey = k.get().xPrivKey; |
| 627 | + const expectedMnemonic = k.get().mnemonic; |
| 628 | + |
| 629 | + const obj = k.toObj(); |
| 630 | + obj.xPrivKeyEncrypted = sjcl.encrypt(password, expectedXPrivKey); |
| 631 | + obj.mnemonicEncrypted = sjcl.encrypt(password, expectedMnemonic); |
| 632 | + obj.xPrivKey = undefined; |
| 633 | + obj.mnemonic = undefined; |
| 634 | + |
| 635 | + const k2 = new Key({ seedType: 'object', seedData: obj }); |
| 636 | + k2.isPrivKeyEncrypted().should.be.true; |
| 637 | + k2.decrypt(password); |
| 638 | + k2.isPrivKeyEncrypted().should.be.false; |
| 639 | + |
| 640 | + const decrypted = k2.toObj(); |
| 641 | + decrypted.xPrivKey.should.equal(expectedXPrivKey); |
| 642 | + decrypted.mnemonic.should.equal(expectedMnemonic); |
| 643 | + should.not.exist(decrypted.xPrivKeyEncrypted); |
| 644 | + should.not.exist(decrypted.mnemonicEncrypted); |
| 645 | + }); |
| 646 | + }); |
| 647 | + |
| 648 | + describe('#addKeyFromExistingPrivateKey with sjcl', function() { |
| 649 | + it('should create new algo key from sjcl encrypted existing key', function() { |
| 650 | + const k = new Key({ |
| 651 | + seedType: 'mnemonic', |
| 652 | + seedData: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about' |
| 653 | + }); |
| 654 | + const password = 'testpassword'; |
| 655 | + const expectedXPrivKey = k.get().xPrivKey; |
| 656 | + |
| 657 | + const obj = k.toObj(); |
| 658 | + obj.xPrivKeyEncrypted = sjcl.encrypt(password, expectedXPrivKey); |
| 659 | + obj.xPrivKey = undefined; |
| 660 | + obj.mnemonic = undefined; |
| 661 | + obj.mnemonicEncrypted = undefined; |
| 662 | + |
| 663 | + const k2 = new Key({ seedType: 'object', seedData: obj }); |
| 664 | + k2.addKeyByAlgorithm('EDDSA', { password, existingAlgo: 'ECDSA' }); |
| 665 | + |
| 666 | + should.exist(k2.fingerPrintEDDSA); |
| 667 | + const eddsaKey = k2.get(password, 'EDDSA'); |
| 668 | + should.exist(eddsaKey.xPrivKey); |
| 669 | + }); |
| 670 | + }); |
| 671 | + }); |
575 | 672 | }); |
0 commit comments