From be890ef9be421e142e0ce3a34beecdda77638711 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Tue, 28 Apr 2020 10:06:27 +0200 Subject: [PATCH] lnd+server+netann: use signing interface in node signer --- lnd.go | 14 +++++++++++++- netann/chan_status_manager_test.go | 4 +++- netann/channel_update_test.go | 14 ++++++++------ netann/node_signer.go | 30 ++++++++++++------------------ server.go | 12 +++++++++--- test_utils.go | 13 ++++++++----- 6 files changed, 53 insertions(+), 34 deletions(-) diff --git a/lnd.go b/lnd.go index f519e3f2..ed347aac 100644 --- a/lnd.go +++ b/lnd.go @@ -484,6 +484,18 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error { } idPrivKey.Curve = btcec.S256() + idKeyDesc, err := activeChainControl.keyRing.DeriveKey( + keychain.KeyLocator{ + Family: keychain.KeyFamilyNodeKey, + Index: 0, + }, + ) + if err != nil { + err := fmt.Errorf("error deriving node key: %v", err) + ltndLog.Error(err) + return err + } + if cfg.Tor.Active { srvrLog.Infof("Proxying all network traffic via Tor "+ "(stream_isolation=%v)! NOTE: Ensure the backend node "+ @@ -612,7 +624,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error { // connections. server, err := newServer( cfg, cfg.Listeners, chanDB, towerClientDB, activeChainControl, - idPrivKey, walletInitParams.ChansToRestore, chainedAcceptor, + idPrivKey, &idKeyDesc, walletInitParams.ChansToRestore, chainedAcceptor, torController, ) if err != nil { diff --git a/netann/chan_status_manager_test.go b/netann/chan_status_manager_test.go index f18774c3..2d155443 100644 --- a/netann/chan_status_manager_test.go +++ b/netann/chan_status_manager_test.go @@ -14,6 +14,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/netann" ) @@ -309,6 +310,7 @@ func newManagerCfg(t *testing.T, numChannels int, if err != nil { t.Fatalf("unable to generate key pair: %v", err) } + privKeySigner := &keychain.PrivKeyDigestSigner{PrivKey: privKey} graph := newMockGraph( t, numChannels, startEnabled, startEnabled, privKey.PubKey(), @@ -320,7 +322,7 @@ func newManagerCfg(t *testing.T, numChannels int, ChanEnableTimeout: 500 * time.Millisecond, ChanDisableTimeout: time.Second, OurPubKey: privKey.PubKey(), - MessageSigner: netann.NewNodeSigner(privKey), + MessageSigner: netann.NewNodeSigner(privKeySigner), IsChannelActive: htlcSwitch.HasActiveLink, ApplyChannelUpdate: graph.ApplyChannelUpdate, DB: graph, diff --git a/netann/channel_update_test.go b/netann/channel_update_test.go index 1fff1d51..5fc4beeb 100644 --- a/netann/channel_update_test.go +++ b/netann/channel_update_test.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/netann" @@ -30,7 +31,8 @@ func (m *mockSigner) SignMessage(pk *btcec.PublicKey, var _ lnwallet.MessageSigner = (*mockSigner)(nil) var ( - privKey, _ = btcec.NewPrivateKey(btcec.S256()) + privKey, _ = btcec.NewPrivateKey(btcec.S256()) + privKeySigner = &keychain.PrivKeyDigestSigner{PrivKey: privKey} pubKey = privKey.PubKey() @@ -52,35 +54,35 @@ var updateDisableTests = []updateDisableTest{ startEnabled: true, disable: true, startTime: time.Now(), - signer: netann.NewNodeSigner(privKey), + signer: netann.NewNodeSigner(privKeySigner), }, { name: "working signer enabled to enabled", startEnabled: true, disable: false, startTime: time.Now(), - signer: netann.NewNodeSigner(privKey), + signer: netann.NewNodeSigner(privKeySigner), }, { name: "working signer disabled to enabled", startEnabled: false, disable: false, startTime: time.Now(), - signer: netann.NewNodeSigner(privKey), + signer: netann.NewNodeSigner(privKeySigner), }, { name: "working signer disabled to disabled", startEnabled: false, disable: true, startTime: time.Now(), - signer: netann.NewNodeSigner(privKey), + signer: netann.NewNodeSigner(privKeySigner), }, { name: "working signer future monotonicity", startEnabled: true, disable: true, startTime: time.Now().Add(time.Hour), // must increment - signer: netann.NewNodeSigner(privKey), + signer: netann.NewNodeSigner(privKeySigner), }, { name: "failing signer", diff --git a/netann/node_signer.go b/netann/node_signer.go index 2b97c937..6cb87a29 100644 --- a/netann/node_signer.go +++ b/netann/node_signer.go @@ -6,25 +6,21 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/lightningnetwork/lnd/input" + "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" ) // NodeSigner is an implementation of the MessageSigner interface backed by the // identity private key of running lnd node. type NodeSigner struct { - privKey *btcec.PrivateKey + keySigner keychain.SingleKeyDigestSigner } // NewNodeSigner creates a new instance of the NodeSigner backed by the target // private key. -func NewNodeSigner(key *btcec.PrivateKey) *NodeSigner { - priv := &btcec.PrivateKey{} - priv.Curve = btcec.S256() - priv.PublicKey.X = key.X - priv.PublicKey.Y = key.Y - priv.D = key.D +func NewNodeSigner(keySigner keychain.SingleKeyDigestSigner) *NodeSigner { return &NodeSigner{ - privKey: priv, + keySigner: keySigner, } } @@ -36,13 +32,14 @@ func (n *NodeSigner) SignMessage(pubKey *btcec.PublicKey, // If this isn't our identity public key, then we'll exit early with an // error as we can't sign with this key. - if !pubKey.IsEqual(n.privKey.PubKey()) { + if !pubKey.IsEqual(n.keySigner.PubKey()) { return nil, fmt.Errorf("unknown public key") } // Otherwise, we'll sign the dsha256 of the target message. - digest := chainhash.DoubleHashB(msg) - sig, err := n.privKey.Sign(digest) + var digest [32]byte + copy(digest[:], chainhash.DoubleHashB(msg)) + sig, err := n.keySigner.SignDigest(digest) if err != nil { return nil, fmt.Errorf("can't sign the message: %v", err) } @@ -63,14 +60,11 @@ func (n *NodeSigner) SignCompact(msg []byte) ([]byte, error) { // SignDigestCompact signs the provided message digest under the resident // node's private key. The returned signature is a pubkey-recoverable signature. func (n *NodeSigner) SignDigestCompact(hash []byte) ([]byte, error) { + var digest [32]byte + copy(digest[:], hash) - // Should the signature reference a compressed public key or not. - isCompressedKey := true - - // btcec.SignCompact returns a pubkey-recoverable signature - sig, err := btcec.SignCompact( - btcec.S256(), n.privKey, hash, isCompressedKey, - ) + // keychain.SignDigestCompact returns a pubkey-recoverable signature. + sig, err := n.keySigner.SignDigestCompact(digest) if err != nil { return nil, fmt.Errorf("can't sign the hash: %v", err) } diff --git a/server.go b/server.go index d7f40901..a3a68ebc 100644 --- a/server.go +++ b/server.go @@ -41,6 +41,7 @@ import ( "github.com/lightningnetwork/lnd/htlcswitch/hop" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/invoices" + "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lnrpc" @@ -324,12 +325,17 @@ func noiseDial(idPriv *btcec.PrivateKey, // passed listener address. func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, towerClientDB *wtdb.ClientDB, cc *chainControl, - privKey *btcec.PrivateKey, + privKey *btcec.PrivateKey, nodeKeyDesc *keychain.KeyDescriptor, chansToRestore walletunlocker.ChannelsToRecover, chanPredicate chanacceptor.ChannelAcceptor, torController *tor.Controller) (*server, error) { - var err error + var ( + err error + nodeKeySigner = keychain.NewPubKeyDigestSigner( + *nodeKeyDesc, cc.keyRing, + ) + ) listeners := make([]net.Listener, len(listenAddrs)) for i, listenAddr := range listenAddrs { @@ -426,7 +432,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, chanDB *channeldb.DB, channelNotifier: channelnotifier.New(chanDB), identityECDH: privKey, - nodeSigner: netann.NewNodeSigner(privKey), + nodeSigner: netann.NewNodeSigner(nodeKeySigner), listenAddrs: listenAddrs, diff --git a/test_utils.go b/test_utils.go index 77b5700b..8155f2f7 100644 --- a/test_utils.go +++ b/test_utils.go @@ -103,10 +103,13 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, publTx chan *wire.MsgTx, updateChan func(a, b *channeldb.OpenChannel)) (*peer, *lnwallet.LightningChannel, *lnwallet.LightningChannel, func(), error) { - aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(btcec.S256(), - alicesPrivKey) - bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(btcec.S256(), - bobsPrivKey) + aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes( + btcec.S256(), alicesPrivKey, + ) + aliceKeySigner := &keychain.PrivKeyDigestSigner{PrivKey: aliceKeyPriv} + bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes( + btcec.S256(), bobsPrivKey, + ) channelCapacity := btcutil.Amount(10 * 1e8) channelBal := channelCapacity / 2 @@ -402,7 +405,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, publTx chan *wire.MsgTx, } s.htlcSwitch = htlcSwitch - nodeSignerAlice := netann.NewNodeSigner(aliceKeyPriv) + nodeSignerAlice := netann.NewNodeSigner(aliceKeySigner) const chanActiveTimeout = time.Minute