Skip to content

Commit

Permalink
Shadowed SignAnnouncement {ChannelUpdate, NodeAnnouncement}.
Browse files Browse the repository at this point in the history
ChannelAnnouncement not encountered by integration tests.
  • Loading branch information
ksedgwic committed Aug 17, 2020
1 parent a6bd869 commit d62fdd6
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 2 deletions.
24 changes: 23 additions & 1 deletion netann/sign.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package netann

import (
"bytes"
"encoding/hex"
"fmt"

"github.com/btcsuite/btcd/btcec"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/remotesigner"
)

// SignAnnouncement signs any type of gossip message that is announced on the
Expand All @@ -33,5 +36,24 @@ func SignAnnouncement(signer lnwallet.MessageSigner, pubKey *btcec.PublicKey,
return nil, fmt.Errorf("unable to get data to sign: %v", err)
}

return signer.SignMessage(pubKey, data)
lclSignature, err := signer.SignMessage(pubKey, data)
if err != nil {
return nil, err
}

rmtSignature, err := remotesigner.SignAnnouncement(pubKey, msg)
if err != nil {
return nil, err
}

if !bytes.Equal(lclSignature.Serialize(), rmtSignature.Serialize()) {
log.Errorf(
"SignAnnouncement: "+
"remotesigner signature mismatch lcl %s != rmt %s",
hex.EncodeToString(lclSignature.Serialize()),
hex.EncodeToString(rmtSignature.Serialize()))
return nil, fmt.Errorf("remote signature msimatch")
}

return lclSignature, nil
}
4 changes: 4 additions & 0 deletions remotesigner/ecdh.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,7 @@ func (rs *RemoteSignerECDH) ECDH(pubKey *btcec.PublicKey) ([32]byte, error) {

return secretLocal, nil
}

// A compile time check to ensure that RemoteSignerECDH implements the
// PubKeyECDH interface.
var _ keychain.SingleKeyECDH = (*RemoteSignerECDH)(nil)
108 changes: 107 additions & 1 deletion remotesigner/interface.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package remotesigner

import (
"bytes"
"context"
"encoding/hex"
"fmt"
Expand All @@ -9,6 +10,8 @@ import (
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcutil/hdkeychain"
"github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwire"
"google.golang.org/grpc"
)

Expand Down Expand Up @@ -109,7 +112,7 @@ func SetNodeID(serializedPubKey [33]byte) error {
// interface calls.
if !state.nodeIDValid {
log.Debugf("SetNodeID: setting nodeID: %s",
hex.EncodeToString(state.nodeID[:]))
hex.EncodeToString(serializedPubKey[:]))
state.nodeID = serializedPubKey
state.nodeIDValid = true
} else {
Expand Down Expand Up @@ -146,3 +149,106 @@ func ECDH(pubKey *btcec.PublicKey) ([32]byte, error) {
copy(secret[:], rsp.SharedSecret.Data)
return secret, nil
}

func SignAnnouncement(pubKey *btcec.PublicKey,
msg lnwire.Message) (input.Signature, error) {
if !state.nodeIDValid {
return nil, ErrRemoteSignerNodeIDNotSet
}

err := validateLocalNodePublicKey(pubKey)
if err != nil {
return nil, err
}

switch m := msg.(type) {
case *lnwire.ChannelAnnouncement:
return signChannelAnnouncement(pubKey, m)
case *lnwire.ChannelUpdate:
return signChannelUpdate(pubKey, m)
case *lnwire.NodeAnnouncement:
return signNodeAnnouncement(pubKey, m)
default:
return nil, fmt.Errorf("can't remotesign %T message", m)
}
}

func signChannelAnnouncement(pubKey *btcec.PublicKey,
msg *lnwire.ChannelAnnouncement) (input.Signature, error) {
if !state.nodeIDValid {
return nil, ErrRemoteSignerNodeIDNotSet
}
log.Debugf("SignChannelAnnouncement: pubKey %s, msg %v",
hex.EncodeToString(pubKey.SerializeCompressed()), msg)

return nil, fmt.Errorf("SignChannelAnnouncement UNIMPLEMENTED")
}

func signChannelUpdate(pubKey *btcec.PublicKey,
msg *lnwire.ChannelUpdate) (input.Signature, error) {
if !state.nodeIDValid {
return nil, ErrRemoteSignerNodeIDNotSet
}
log.Debugf("SignChannelUpdate: pubKey %s, msg %v",
hex.EncodeToString(pubKey.SerializeCompressed()), msg)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

data, err := msg.DataToSign()
if err != nil {
return nil, err
}

log.Debugf("SignChannelUpdate: DataToSign %s", hex.EncodeToString(data))

rsp, err := state.client.SignChannelUpdate(ctx,
&SignChannelUpdateRequest{
NodeId: &NodeId{Data: state.nodeID[:]},
ChannelUpdate: data[:],
})
if err != nil {
return nil, err
}
return btcec.ParseDERSignature(rsp.Signature.Data, btcec.S256())
}

func signNodeAnnouncement(pubKey *btcec.PublicKey,
msg *lnwire.NodeAnnouncement) (input.Signature, error) {
if !state.nodeIDValid {
return nil, ErrRemoteSignerNodeIDNotSet
}
log.Debugf("SignNodeAnnouncement: pubKey %s, msg %v",
hex.EncodeToString(pubKey.SerializeCompressed()), msg)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()

data, err := msg.DataToSign()
if err != nil {
return nil, err
}

log.Debugf("SignNodeAnnouncement: DataToSign %s", hex.EncodeToString(data))

rsp, err := state.client.SignNodeAnnouncement(ctx,
&SignNodeAnnouncementRequest{
NodeId: &NodeId{Data: state.nodeID[:]},
NodeAnnouncement: data[:],
})
if err != nil {
return nil, err
}
return btcec.ParseDERSignature(rsp.Signature.Data, btcec.S256())
}

func validateLocalNodePublicKey(pubKey *btcec.PublicKey) error {
if !bytes.Equal(pubKey.SerializeCompressed(), state.nodeID[:]) {
log.Errorf("validateLocalNodePublicKey failed: "+
"pubKey %s != state.nodeID %s",
hex.EncodeToString(pubKey.SerializeCompressed()),
state.nodeID[:])
return fmt.Errorf("remotesigner nodeid pubkey mismatch")
}
return nil
}

0 comments on commit d62fdd6

Please sign in to comment.