mirror of
https://github.com/aljazceru/lspd.git
synced 2025-12-19 06:44:23 +01:00
notification signature is a lightning signed msg
This commit is contained in:
1
go.mod
1
go.mod
@@ -156,6 +156,7 @@ require (
|
|||||||
github.com/stretchr/objx v0.5.0 // indirect
|
github.com/stretchr/objx v0.5.0 // indirect
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // 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/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/ulikunitz/xz v0.5.10 // indirect
|
||||||
github.com/wk8/go-ordered-map/v2 v2.1.8
|
github.com/wk8/go-ordered-map/v2 v2.1.8
|
||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
"github.com/breez/lntest"
|
"github.com/breez/lntest"
|
||||||
"github.com/breez/lspd/config"
|
"github.com/breez/lspd/config"
|
||||||
|
"github.com/breez/lspd/lightning"
|
||||||
"github.com/breez/lspd/notifications"
|
"github.com/breez/lspd/notifications"
|
||||||
lspd "github.com/breez/lspd/rpc"
|
lspd "github.com/breez/lspd/rpc"
|
||||||
"github.com/btcsuite/btcd/btcec/v2"
|
"github.com/btcsuite/btcd/btcec/v2"
|
||||||
@@ -24,6 +25,7 @@ import (
|
|||||||
ecies "github.com/ecies/go/v2"
|
ecies "github.com/ecies/go/v2"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/tv42/zbase32"
|
||||||
"google.golang.org/grpc/metadata"
|
"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 {
|
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[:])
|
second := sha256.Sum256(first[:])
|
||||||
sig, err := ecdsa.SignCompact(b.Node().PrivateKey(), second[:], true)
|
sig, err := ecdsa.SignCompact(b.Node().PrivateKey(), second[:], true)
|
||||||
assert.NoError(b.Harness().T, err)
|
assert.NoError(b.Harness().T, err)
|
||||||
|
|
||||||
request := notifications.SubscribeNotificationsRequest{
|
request := notifications.SubscribeNotificationsRequest{
|
||||||
Url: url,
|
Url: url,
|
||||||
Signature: sig,
|
Signature: zbase32.EncodeToString(sig),
|
||||||
}
|
}
|
||||||
serialized, err := proto.Marshal(&request)
|
serialized, err := proto.Marshal(&request)
|
||||||
lntest.CheckError(l.Harness().T, err)
|
lntest.CheckError(l.Harness().T, err)
|
||||||
|
|||||||
38
lightning/verify_message.go
Normal file
38
lightning/verify_message.go
Normal 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
|
||||||
|
}
|
||||||
@@ -73,7 +73,7 @@ type SubscribeNotificationsRequest struct {
|
|||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
|
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() {
|
func (x *SubscribeNotificationsRequest) Reset() {
|
||||||
@@ -115,11 +115,11 @@ func (x *SubscribeNotificationsRequest) GetUrl() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SubscribeNotificationsRequest) GetSignature() []byte {
|
func (x *SubscribeNotificationsRequest) GetSignature() string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Signature
|
return x.Signature
|
||||||
}
|
}
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubscribeNotificationsReply struct {
|
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,
|
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,
|
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,
|
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, 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,
|
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,
|
0x6f, 0x6e, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0x84, 0x01, 0x0a, 0x0d, 0x4e, 0x6f, 0x74,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ message EncryptedNotificationRequest {
|
|||||||
|
|
||||||
message SubscribeNotificationsRequest {
|
message SubscribeNotificationsRequest {
|
||||||
string url = 1;
|
string url = 1;
|
||||||
bytes signature = 2;
|
string signature = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SubscribeNotificationsReply {
|
message SubscribeNotificationsReply {
|
||||||
|
|||||||
@@ -2,18 +2,16 @@ package notifications
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/breez/lspd/lightning"
|
||||||
lspdrpc "github.com/breez/lspd/rpc"
|
lspdrpc "github.com/breez/lspd/rpc"
|
||||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
|
||||||
ecies "github.com/ecies/go/v2"
|
ecies "github.com/ecies/go/v2"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrInvalidSignature = fmt.Errorf("invalid signature")
|
|
||||||
var ErrInternal = fmt.Errorf("internal error")
|
var ErrInternal = fmt.Errorf("internal error")
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
@@ -48,18 +46,9 @@ func (s *server) SubscribeNotifications(
|
|||||||
return nil, fmt.Errorf("proto.Unmarshal(%x) error: %w", data, err)
|
return nil, fmt.Errorf("proto.Unmarshal(%x) error: %w", data, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
first := sha256.Sum256([]byte(request.Url))
|
pubkey, err := lightning.VerifyMessage([]byte(request.Url), request.Signature)
|
||||||
second := sha256.Sum256(first[:])
|
|
||||||
pubkey, wasCompressed, err := ecdsa.RecoverCompact(
|
|
||||||
request.Signature,
|
|
||||||
second[:],
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrInvalidSignature
|
return nil, err
|
||||||
}
|
|
||||||
|
|
||||||
if !wasCompressed {
|
|
||||||
return nil, ErrInvalidSignature
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.store.Register(ctx, hex.EncodeToString(pubkey.SerializeCompressed()), request.Url)
|
err = s.store.Register(ctx, hex.EncodeToString(pubkey.SerializeCompressed()), request.Url)
|
||||||
|
|||||||
Reference in New Issue
Block a user