notification signature is a lightning signed msg

This commit is contained in:
Jesse de Wit
2023-11-09 12:02:53 +01:00
parent 743e880d9c
commit 6b0c288a0e
6 changed files with 52 additions and 22 deletions

1
go.mod
View File

@@ -156,6 +156,7 @@ require (
github.com/stretchr/objx v0.5.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/tv42/zbase32 v0.0.0-20220222190657-f76a9fc892fa
github.com/ulikunitz/xz v0.5.10 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect

View File

@@ -16,6 +16,7 @@ import (
"github.com/breez/lntest"
"github.com/breez/lspd/config"
"github.com/breez/lspd/lightning"
"github.com/breez/lspd/notifications"
lspd "github.com/breez/lspd/rpc"
"github.com/btcsuite/btcd/btcec/v2"
@@ -24,6 +25,7 @@ import (
ecies "github.com/ecies/go/v2"
"github.com/golang/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/tv42/zbase32"
"google.golang.org/grpc/metadata"
)
@@ -290,14 +292,14 @@ func RegisterPayment(l LspNode, paymentInfo *lspd.PaymentInformation, continueOn
}
func SubscribeNotifications(l LspNode, b BreezClient, url string, continueOnError bool) error {
first := sha256.Sum256([]byte(url))
msg := append(lightning.SignedMsgPrefix, []byte(url)...)
first := sha256.Sum256([]byte(msg))
second := sha256.Sum256(first[:])
sig, err := ecdsa.SignCompact(b.Node().PrivateKey(), second[:], true)
assert.NoError(b.Harness().T, err)
request := notifications.SubscribeNotificationsRequest{
Url: url,
Signature: sig,
Signature: zbase32.EncodeToString(sig),
}
serialized, err := proto.Marshal(&request)
lntest.CheckError(l.Harness().T, err)

View File

@@ -0,0 +1,38 @@
package lightning
import (
"crypto/sha256"
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/tv42/zbase32"
)
var ErrInvalidSignature = fmt.Errorf("invalid signature")
var SignedMsgPrefix = []byte("Lightning Signed Message:")
func VerifyMessage(message []byte, signature string) (*btcec.PublicKey, error) {
// The signature should be zbase32 encoded
sig, err := zbase32.DecodeString(signature)
if err != nil {
return nil, fmt.Errorf("failed to decode signature: %v", err)
}
msg := append(SignedMsgPrefix, message...)
first := sha256.Sum256(msg)
second := sha256.Sum256(first[:])
pubkey, wasCompressed, err := ecdsa.RecoverCompact(
sig,
second[:],
)
if err != nil {
return nil, ErrInvalidSignature
}
if !wasCompressed {
return nil, ErrInvalidSignature
}
return pubkey, nil
}

View File

@@ -73,7 +73,7 @@ type SubscribeNotificationsRequest struct {
unknownFields protoimpl.UnknownFields
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
Signature string `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"`
}
func (x *SubscribeNotificationsRequest) Reset() {
@@ -115,11 +115,11 @@ func (x *SubscribeNotificationsRequest) GetUrl() string {
return ""
}
func (x *SubscribeNotificationsRequest) GetSignature() []byte {
func (x *SubscribeNotificationsRequest) GetSignature() string {
if x != nil {
return x.Signature
}
return nil
return ""
}
type SubscribeNotificationsReply struct {
@@ -172,7 +172,7 @@ var file_notifications_proto_rawDesc = []byte{
0x63, 0x72, 0x69, 0x62, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x73,
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x53, 0x75, 0x62,
0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0x84, 0x01, 0x0a, 0x0d, 0x4e, 0x6f, 0x74,

View File

@@ -15,7 +15,7 @@ message EncryptedNotificationRequest {
message SubscribeNotificationsRequest {
string url = 1;
bytes signature = 2;
string signature = 2;
}
message SubscribeNotificationsReply {

View File

@@ -2,18 +2,16 @@ package notifications
import (
context "context"
"crypto/sha256"
"encoding/hex"
"fmt"
"log"
"github.com/breez/lspd/lightning"
lspdrpc "github.com/breez/lspd/rpc"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
ecies "github.com/ecies/go/v2"
"github.com/golang/protobuf/proto"
)
var ErrInvalidSignature = fmt.Errorf("invalid signature")
var ErrInternal = fmt.Errorf("internal error")
type server struct {
@@ -48,18 +46,9 @@ func (s *server) SubscribeNotifications(
return nil, fmt.Errorf("proto.Unmarshal(%x) error: %w", data, err)
}
first := sha256.Sum256([]byte(request.Url))
second := sha256.Sum256(first[:])
pubkey, wasCompressed, err := ecdsa.RecoverCompact(
request.Signature,
second[:],
)
pubkey, err := lightning.VerifyMessage([]byte(request.Url), request.Signature)
if err != nil {
return nil, ErrInvalidSignature
}
if !wasCompressed {
return nil, ErrInvalidSignature
return nil, err
}
err = s.store.Register(ctx, hex.EncodeToString(pubkey.SerializeCompressed()), request.Url)