rpc: modify SignMessage+VerifyMessage to bind msg to LN context
In this commit, we modify the SignMessage+VerifyMessage slightly in order to bind the message we're signing to our specific context. We do this by pre-pending the ascii text "Lightning Signed Message:" to the msg before we run it through dsha256. Adding this prefix binds the message to our context in order to avoid accidentally signing a sighash or the like.
This commit is contained in:
parent
86fd9e361e
commit
c54a91f44d
@ -67,8 +67,9 @@ func (n *nodeSigner) SignDigestCompact(hash []byte) ([]byte, error) {
|
|||||||
isCompressedKey := true
|
isCompressedKey := true
|
||||||
|
|
||||||
// btcec.SignCompact returns a pubkey-recoverable signature
|
// btcec.SignCompact returns a pubkey-recoverable signature
|
||||||
sig, err := btcec.SignCompact(btcec.S256(), n.privKey, hash,
|
sig, err := btcec.SignCompact(
|
||||||
isCompressedKey)
|
btcec.S256(), n.privKey, hash, isCompressedKey,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't sign the hash: %v", err)
|
return nil, fmt.Errorf("can't sign the hash: %v", err)
|
||||||
}
|
}
|
||||||
|
23
rpcserver.go
23
rpcserver.go
@ -520,10 +520,18 @@ func (r *rpcServer) NewWitnessAddress(ctx context.Context,
|
|||||||
return &lnrpc.NewAddressResponse{Address: addr.String()}, nil
|
return &lnrpc.NewAddressResponse{Address: addr.String()}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// signedMsgPrefix is a special prefix that we'll prepend to any
|
||||||
|
// messages we sign/verify. We do this to ensure that we don't
|
||||||
|
// accidentally sign a sighash, or other sensitive material. By
|
||||||
|
// prepending this fragment, we mind message signing to our particular
|
||||||
|
// context.
|
||||||
|
signedMsgPrefix = []byte("Lightning Signed Message:")
|
||||||
|
)
|
||||||
|
|
||||||
// SignMessage signs a message with the resident node's private key. The
|
// SignMessage signs a message with the resident node's private key. The
|
||||||
// returned signature string is zbase32 encoded and pubkey recoverable,
|
// returned signature string is zbase32 encoded and pubkey recoverable, meaning
|
||||||
// meaning that only the message digest and signature are needed for
|
// that only the message digest and signature are needed for verification.
|
||||||
// verification.
|
|
||||||
func (r *rpcServer) SignMessage(ctx context.Context,
|
func (r *rpcServer) SignMessage(ctx context.Context,
|
||||||
in *lnrpc.SignMessageRequest) (*lnrpc.SignMessageResponse, error) {
|
in *lnrpc.SignMessageRequest) (*lnrpc.SignMessageResponse, error) {
|
||||||
|
|
||||||
@ -531,6 +539,7 @@ func (r *rpcServer) SignMessage(ctx context.Context,
|
|||||||
return nil, fmt.Errorf("need a message to sign")
|
return nil, fmt.Errorf("need a message to sign")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in.Msg = append(signedMsgPrefix, in.Msg...)
|
||||||
sigBytes, err := r.server.nodeSigner.SignCompact(in.Msg)
|
sigBytes, err := r.server.nodeSigner.SignCompact(in.Msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -540,9 +549,9 @@ func (r *rpcServer) SignMessage(ctx context.Context,
|
|||||||
return &lnrpc.SignMessageResponse{Signature: sig}, nil
|
return &lnrpc.SignMessageResponse{Signature: sig}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyMessage verifies a signature over a msg. The signature must be
|
// VerifyMessage verifies a signature over a msg. The signature must be zbase32
|
||||||
// zbase32 encoded and signed by an active node in the resident node's
|
// encoded and signed by an active node in the resident node's channel
|
||||||
// channel database. In addition to returning the validity of the signature,
|
// database. In addition to returning the validity of the signature,
|
||||||
// VerifyMessage also returns the recovered pubkey from the signature.
|
// VerifyMessage also returns the recovered pubkey from the signature.
|
||||||
func (r *rpcServer) VerifyMessage(ctx context.Context,
|
func (r *rpcServer) VerifyMessage(ctx context.Context,
|
||||||
in *lnrpc.VerifyMessageRequest) (*lnrpc.VerifyMessageResponse, error) {
|
in *lnrpc.VerifyMessageRequest) (*lnrpc.VerifyMessageResponse, error) {
|
||||||
@ -558,6 +567,7 @@ func (r *rpcServer) VerifyMessage(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The signature is over the double-sha256 hash of the message.
|
// The signature is over the double-sha256 hash of the message.
|
||||||
|
in.Msg = append(signedMsgPrefix, in.Msg...)
|
||||||
digest := chainhash.DoubleHashB(in.Msg)
|
digest := chainhash.DoubleHashB(in.Msg)
|
||||||
|
|
||||||
// RecoverCompact both recovers the pubkey and validates the signature.
|
// RecoverCompact both recovers the pubkey and validates the signature.
|
||||||
@ -572,6 +582,7 @@ func (r *rpcServer) VerifyMessage(ctx context.Context,
|
|||||||
|
|
||||||
// Query the channel graph to ensure a node in the network with active
|
// Query the channel graph to ensure a node in the network with active
|
||||||
// channels signed the message.
|
// channels signed the message.
|
||||||
|
//
|
||||||
// TODO(phlip9): Require valid nodes to have capital in active channels.
|
// TODO(phlip9): Require valid nodes to have capital in active channels.
|
||||||
graph := r.server.chanDB.ChannelGraph()
|
graph := r.server.chanDB.ChannelGraph()
|
||||||
_, active, err := graph.HasLightningNode(pub)
|
_, active, err := graph.HasLightningNode(pub)
|
||||||
|
Loading…
Reference in New Issue
Block a user