From 02e9cf6fd62a3eca00a3562ddb798f337f1a4269 Mon Sep 17 00:00:00 2001 From: unwired01 Date: Mon, 4 Dec 2023 10:01:15 +0200 Subject: [PATCH] Adding passphrase --- cmd/kaspawallet/daemon/server/send.go | 3 ++- cmd/kaspawallet/daemon/server/sign.go | 7 ++++--- .../daemon/server/split_transaction_test.go | 4 ++-- cmd/kaspawallet/dump_unencrypted_data.go | 4 +++- cmd/kaspawallet/keys/create.go | 8 +++++++- cmd/kaspawallet/keys/get_password.go | 4 ++++ cmd/kaspawallet/libkaspawallet/bip39.go | 8 ++++---- cmd/kaspawallet/libkaspawallet/sign.go | 10 +++++----- cmd/kaspawallet/libkaspawallet/transaction_test.go | 12 ++++++------ cmd/kaspawallet/send.go | 3 ++- cmd/kaspawallet/sign.go | 3 ++- 11 files changed, 41 insertions(+), 25 deletions(-) diff --git a/cmd/kaspawallet/daemon/server/send.go b/cmd/kaspawallet/daemon/server/send.go index 68ff8ca74..be90bb893 100644 --- a/cmd/kaspawallet/daemon/server/send.go +++ b/cmd/kaspawallet/daemon/server/send.go @@ -17,7 +17,8 @@ func (s *server) Send(_ context.Context, request *pb.SendRequest) (*pb.SendRespo return nil, err } - signedTransactions, err := s.signTransactions(unsignedTransactions, request.Password) + //TODO fix passphrase + signedTransactions, err := s.signTransactions(unsignedTransactions, request.Password, "") if err != nil { return nil, err } diff --git a/cmd/kaspawallet/daemon/server/sign.go b/cmd/kaspawallet/daemon/server/sign.go index 5a9c2d080..26ca7a3f7 100644 --- a/cmd/kaspawallet/daemon/server/sign.go +++ b/cmd/kaspawallet/daemon/server/sign.go @@ -12,21 +12,22 @@ func (s *server) Sign(_ context.Context, request *pb.SignRequest) (*pb.SignRespo s.lock.Lock() defer s.lock.Unlock() - signedTransactions, err := s.signTransactions(request.UnsignedTransactions, request.Password) + //TODO: fix SignRequest pashphrase + signedTransactions, err := s.signTransactions(request.UnsignedTransactions, request.Password, "") if err != nil { return nil, err } return &pb.SignResponse{SignedTransactions: signedTransactions}, nil } -func (s *server) signTransactions(unsignedTransactions [][]byte, password string) ([][]byte, error) { +func (s *server) signTransactions(unsignedTransactions [][]byte, password string, passphrase string) ([][]byte, error) { mnemonics, err := s.keysFile.DecryptMnemonics(password) if err != nil { return nil, err } signedTransactions := make([][]byte, len(unsignedTransactions)) for i, unsignedTransaction := range unsignedTransactions { - signedTransaction, err := libkaspawallet.Sign(s.params, mnemonics, unsignedTransaction, s.keysFile.ECDSA) + signedTransaction, err := libkaspawallet.Sign(s.params, mnemonics, []string{passphrase}, unsignedTransaction, s.keysFile.ECDSA) if err != nil { return nil, err } diff --git a/cmd/kaspawallet/daemon/server/split_transaction_test.go b/cmd/kaspawallet/daemon/server/split_transaction_test.go index 6d87470d3..5e597a578 100644 --- a/cmd/kaspawallet/daemon/server/split_transaction_test.go +++ b/cmd/kaspawallet/daemon/server/split_transaction_test.go @@ -43,12 +43,12 @@ func TestEstimateMassAfterSignatures(t *testing.T) { t.Fatalf("Error from estimateMassAfterSignatures: %s", err) } - signedTxStep1Bytes, err := libkaspawallet.Sign(params, mnemonics[:1], unsignedTransactionBytes, false) + signedTxStep1Bytes, err := libkaspawallet.Sign(params, mnemonics[:1], []string{""}, unsignedTransactionBytes, false) if err != nil { t.Fatalf("Sign: %+v", err) } - signedTxStep2Bytes, err := libkaspawallet.Sign(params, mnemonics[1:2], signedTxStep1Bytes, false) + signedTxStep2Bytes, err := libkaspawallet.Sign(params, mnemonics[1:2], []string{""}, signedTxStep1Bytes, false) if err != nil { t.Fatalf("Sign: %+v", err) } diff --git a/cmd/kaspawallet/dump_unencrypted_data.go b/cmd/kaspawallet/dump_unencrypted_data.go index a01f6d4e9..250a7ca8b 100644 --- a/cmd/kaspawallet/dump_unencrypted_data.go +++ b/cmd/kaspawallet/dump_unencrypted_data.go @@ -33,10 +33,12 @@ func dumpUnencryptedData(conf *dumpUnencryptedDataConfig) error { return err } + mnemonicPublicKeys := make(map[string]struct{}) for i, mnemonic := range mnemonics { + passphrase := keys.GetPassphrase("Passphrase:") fmt.Printf("Mnemonic #%d:\n%s\n\n", i+1, mnemonic) - publicKey, err := libkaspawallet.MasterPublicKeyFromMnemonic(conf.NetParams(), mnemonic, len(keysFile.ExtendedPublicKeys) > 1) + publicKey, err := libkaspawallet.MasterPublicKeyFromMnemonic(conf.NetParams(), mnemonic, passphrase, len(keysFile.ExtendedPublicKeys) > 1) if err != nil { return err } diff --git a/cmd/kaspawallet/keys/create.go b/cmd/kaspawallet/keys/create.go index 43402e065..ae37530d5 100644 --- a/cmd/kaspawallet/keys/create.go +++ b/cmd/kaspawallet/keys/create.go @@ -65,7 +65,13 @@ func encryptedMnemonicExtendedPublicKeyPairs(params *dagconfig.Params, mnemonics extendedPublicKeys = make([]string, 0, len(mnemonics)) for _, mnemonic := range mnemonics { - extendedPublicKey, err := libkaspawallet.MasterPublicKeyFromMnemonic(params, mnemonic, isMultisig) + passphrase := []byte(GetPassword("Enter passphrase for the key file:")) + confirmPassphrase := []byte(GetPassphrase("Confirm passphrase:")) + + if subtle.ConstantTimeCompare(passphrase, confirmPassphrase) != 1 { + return nil, nil, errors.New("Passphrases are not identical") + } + extendedPublicKey, err := libkaspawallet.MasterPublicKeyFromMnemonic(params, mnemonic, string(passphrase), isMultisig) if err != nil { return nil, nil, err } diff --git a/cmd/kaspawallet/keys/get_password.go b/cmd/kaspawallet/keys/get_password.go index 9ae978493..a8e6f11fb 100644 --- a/cmd/kaspawallet/keys/get_password.go +++ b/cmd/kaspawallet/keys/get_password.go @@ -40,3 +40,7 @@ func GetPassword(prompt string) string { return string(p) } + +func GetPassphrase(prompt string) string { + return GetPassword(prompt); +} diff --git a/cmd/kaspawallet/libkaspawallet/bip39.go b/cmd/kaspawallet/libkaspawallet/bip39.go index 53acda51b..75db9e630 100644 --- a/cmd/kaspawallet/libkaspawallet/bip39.go +++ b/cmd/kaspawallet/libkaspawallet/bip39.go @@ -36,9 +36,9 @@ func defaultPath(isMultisig bool) string { } // MasterPublicKeyFromMnemonic returns the master public key with the correct derivation for the given mnemonic. -func MasterPublicKeyFromMnemonic(params *dagconfig.Params, mnemonic string, isMultisig bool) (string, error) { +func MasterPublicKeyFromMnemonic(params *dagconfig.Params, mnemonic string, passphrase string, isMultisig bool) (string, error) { path := defaultPath(isMultisig) - extendedKey, err := extendedKeyFromMnemonicAndPath(mnemonic, path, params) + extendedKey, err := extendedKeyFromMnemonicAndPath(mnemonic, path, passphrase, params) if err != nil { return "", err } @@ -51,8 +51,8 @@ func MasterPublicKeyFromMnemonic(params *dagconfig.Params, mnemonic string, isMu return extendedPublicKey.String(), nil } -func extendedKeyFromMnemonicAndPath(mnemonic string, path string, params *dagconfig.Params) (*bip32.ExtendedKey, error) { - seed := bip39.NewSeed(mnemonic, "") +func extendedKeyFromMnemonicAndPath(mnemonic string, path string, passphrase string, params *dagconfig.Params) (*bip32.ExtendedKey, error) { + seed := bip39.NewSeed(mnemonic, passphrase) version, err := versionFromParams(params) if err != nil { return nil, err diff --git a/cmd/kaspawallet/libkaspawallet/sign.go b/cmd/kaspawallet/libkaspawallet/sign.go index 98057ddb0..8acd752ed 100644 --- a/cmd/kaspawallet/libkaspawallet/sign.go +++ b/cmd/kaspawallet/libkaspawallet/sign.go @@ -28,14 +28,14 @@ func rawTxInSignature(extendedKey *bip32.ExtendedKey, tx *externalapi.DomainTran } // Sign signs the transaction with the given private keys -func Sign(params *dagconfig.Params, mnemonics []string, serializedPSTx []byte, ecdsa bool) ([]byte, error) { +func Sign(params *dagconfig.Params, mnemonics []string, passphrases []string, serializedPSTx []byte, ecdsa bool) ([]byte, error) { partiallySignedTransaction, err := serialization.DeserializePartiallySignedTransaction(serializedPSTx) if err != nil { return nil, err } - for _, mnemonic := range mnemonics { - err = sign(params, mnemonic, partiallySignedTransaction, ecdsa) + for i, mnemonic := range mnemonics { + err = sign(params, mnemonic, passphrases[i], partiallySignedTransaction, ecdsa) if err != nil { return nil, err } @@ -43,7 +43,7 @@ func Sign(params *dagconfig.Params, mnemonics []string, serializedPSTx []byte, e return serialization.SerializePartiallySignedTransaction(partiallySignedTransaction) } -func sign(params *dagconfig.Params, mnemonic string, partiallySignedTransaction *serialization.PartiallySignedTransaction, ecdsa bool) error { +func sign(params *dagconfig.Params, mnemonic string, passphrase string, partiallySignedTransaction *serialization.PartiallySignedTransaction, ecdsa bool) error { if isTransactionFullySigned(partiallySignedTransaction) { return nil } @@ -64,7 +64,7 @@ func sign(params *dagconfig.Params, mnemonic string, partiallySignedTransaction for i, partiallySignedInput := range partiallySignedTransaction.PartiallySignedInputs { isMultisig := len(partiallySignedInput.PubKeySignaturePairs) > 1 path := defaultPath(isMultisig) - extendedKey, err := extendedKeyFromMnemonicAndPath(mnemonic, path, params) + extendedKey, err := extendedKeyFromMnemonicAndPath(mnemonic, path, passphrase, params) if err != nil { return err } diff --git a/cmd/kaspawallet/libkaspawallet/transaction_test.go b/cmd/kaspawallet/libkaspawallet/transaction_test.go index 39a469994..f5f6db9de 100644 --- a/cmd/kaspawallet/libkaspawallet/transaction_test.go +++ b/cmd/kaspawallet/libkaspawallet/transaction_test.go @@ -125,7 +125,7 @@ func TestMultisig(t *testing.T) { t.Fatal("Unexpectedly succeed to extract a valid transaction out of unsigned transaction") } - signedTxStep1, err := libkaspawallet.Sign(params, mnemonics[:1], unsignedTransaction, ecdsa) + signedTxStep1, err := libkaspawallet.Sign(params, mnemonics[:1], []string{""}, unsignedTransaction, ecdsa) if err != nil { t.Fatalf("Sign: %+v", err) } @@ -139,7 +139,7 @@ func TestMultisig(t *testing.T) { t.Fatalf("Transaction is not expected to be fully signed") } - signedTxStep2, err := libkaspawallet.Sign(params, mnemonics[1:2], signedTxStep1, ecdsa) + signedTxStep2, err := libkaspawallet.Sign(params, mnemonics[1:2], []string{""}, signedTxStep1, ecdsa) if err != nil { t.Fatalf("Sign: %+v", err) } @@ -149,7 +149,7 @@ func TestMultisig(t *testing.T) { t.Fatalf("ExtractTransaction: %+v", err) } - signedTxOneStep, err := libkaspawallet.Sign(params, mnemonics[:2], unsignedTransaction, ecdsa) + signedTxOneStep, err := libkaspawallet.Sign(params, mnemonics[:2], []string{""}, unsignedTransaction, ecdsa) if err != nil { t.Fatalf("Sign: %+v", err) } @@ -286,7 +286,7 @@ func TestP2PK(t *testing.T) { t.Fatal("Unexpectedly succeed to extract a valid transaction out of unsigned transaction") } - signedTx, err := libkaspawallet.Sign(params, mnemonics, unsignedTransaction, ecdsa) + signedTx, err := libkaspawallet.Sign(params, mnemonics, []string{""}, unsignedTransaction, ecdsa) if err != nil { t.Fatalf("Sign: %+v", err) } @@ -434,7 +434,7 @@ func TestMaxSompi(t *testing.T) { t.Fatalf("CreateUnsignedTransactions: %+v", err) } - signedTxWithLargeInputAmount, err := libkaspawallet.Sign(params, mnemonics, unsignedTxWithLargeInputAmount, false) + signedTxWithLargeInputAmount, err := libkaspawallet.Sign(params, mnemonics, []string{""}, unsignedTxWithLargeInputAmount, false) if err != nil { t.Fatalf("Sign: %+v", err) } @@ -485,7 +485,7 @@ func TestMaxSompi(t *testing.T) { t.Fatalf("CreateUnsignedTransactions: %+v", err) } - signedTxWithLargeInputAndOutputAmount, err := libkaspawallet.Sign(params, mnemonics, unsignedTxWithLargeInputAndOutputAmount, false) + signedTxWithLargeInputAndOutputAmount, err := libkaspawallet.Sign(params, mnemonics, []string{""}, unsignedTxWithLargeInputAndOutputAmount, false) if err != nil { t.Fatalf("Sign: %+v", err) } diff --git a/cmd/kaspawallet/send.go b/cmd/kaspawallet/send.go index 3e20c2b97..b0b9e0cab 100644 --- a/cmd/kaspawallet/send.go +++ b/cmd/kaspawallet/send.go @@ -64,7 +64,8 @@ func send(conf *sendConfig) error { signedTransactions := make([][]byte, len(createUnsignedTransactionsResponse.UnsignedTransactions)) for i, unsignedTransaction := range createUnsignedTransactionsResponse.UnsignedTransactions { - signedTransaction, err := libkaspawallet.Sign(conf.NetParams(), mnemonics, unsignedTransaction, keysFile.ECDSA) + passphrase := keys.GetPassphrase("Passphrase:") + signedTransaction, err := libkaspawallet.Sign(conf.NetParams(), mnemonics, []string{passphrase}, unsignedTransaction, keysFile.ECDSA) if err != nil { return err } diff --git a/cmd/kaspawallet/sign.go b/cmd/kaspawallet/sign.go index c91f7043c..7a359e56e 100644 --- a/cmd/kaspawallet/sign.go +++ b/cmd/kaspawallet/sign.go @@ -47,8 +47,9 @@ func sign(conf *signConfig) error { updatedPartiallySignedTransactions := make([][]byte, len(partiallySignedTransactions)) for i, partiallySignedTransaction := range partiallySignedTransactions { + passphrase := keys.GetPassphrase("Passphrase:") updatedPartiallySignedTransactions[i], err = - libkaspawallet.Sign(conf.NetParams(), privateKeys, partiallySignedTransaction, keysFile.ECDSA) + libkaspawallet.Sign(conf.NetParams(), privateKeys, []string{passphrase}, partiallySignedTransaction, keysFile.ECDSA) if err != nil { return err }