Skip to content

Commit

Permalink
Merge pull request #100 from lightsparkdev/validation
Browse files Browse the repository at this point in the history
Add validation to sample remote signer
  • Loading branch information
zhenlu authored May 2, 2024
2 parents 2ba6451 + f62a9af commit 0760bd0
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 5 deletions.
1 change: 1 addition & 0 deletions examples/remote-signing-server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/btcsuite/btcd v0.24.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcutil v1.1.5 // indirect
github.com/btcsuite/btcd/btcutil/psbt v1.1.9 // indirect
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/bytedance/sonic v1.9.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions examples/remote-signing-server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9Ur
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8=
github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00=
github.com/btcsuite/btcd/btcutil/psbt v1.1.9 h1:UmfOIiWMZcVMOLaN+lxbbLSuoINGS1WmK1TZNI0b4yk=
github.com/btcsuite/btcd/btcutil/psbt v1.1.9/go.mod h1:ehBEvU91lxSlXtA+zZz3iFYx7Yq9eqnKx4/kSrnsvMY=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ=
Expand Down
4 changes: 2 additions & 2 deletions examples/remote-signing-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func main() {
case objects.WebhookEventTypeRemoteSigning:
if config.RespondDirectly {
resp, err := remotesigning.GraphQLResponseForRemoteSigningWebhook(
remotesigning.PositiveValidator{}, *event, config.MasterSeed)
remotesigning.HashValidator{}, *event, config.MasterSeed)
if err != nil {
log.Printf("ERROR: Unable to handle remote signing webhook: %s", err)
c.AbortWithStatus(http.StatusInternalServerError)
Expand All @@ -80,7 +80,7 @@ func main() {
}
} else {
resp, err := remotesigning.HandleRemoteSigningWebhook(
lsClient, remotesigning.PositiveValidator{}, *event, config.MasterSeed)
lsClient, remotesigning.HashValidator{}, *event, config.MasterSeed)
if err != nil {
log.Printf("ERROR: Unable to handle remote signing webhook: %s", err)
c.AbortWithStatus(http.StatusInternalServerError)
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (

require (
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcutil v1.1.5 // indirect
github.com/btcsuite/btcd/btcutil v1.1.5
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect
Expand All @@ -24,6 +24,7 @@ require (

require (
github.com/btcsuite/btcd v0.24.0
github.com/btcsuite/btcd/btcutil/psbt v1.1.9
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9Ur
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8=
github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00=
github.com/btcsuite/btcd/btcutil/psbt v1.1.9 h1:UmfOIiWMZcVMOLaN+lxbbLSuoINGS1WmK1TZNI0b4yk=
github.com/btcsuite/btcd/btcutil/psbt v1.1.9/go.mod h1:ehBEvU91lxSlXtA+zZz3iFYx7Yq9eqnKx4/kSrnsvMY=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ=
Expand Down
62 changes: 61 additions & 1 deletion remotesigning/validation.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package remotesigning

import (
"bytes"
"encoding/hex"
"errors"
"regexp"

"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
)

Expand All @@ -26,6 +29,63 @@ func GetPaymentHashFromScript(scriptHex string) (*string, error) {
if len(match) > 0 {
return &match[1], nil
} else {
return nil, errors.New("No match found")
return nil, errors.New("no match found")
}
}

func CalculateWitnessHash(amount int64, script string, transaction string) (*string, error) {
decodedTx, err := hex.DecodeString(transaction)
if err != nil {
return nil, err
}

tx, err := btcutil.NewTxFromBytes(decodedTx)
if err != nil {
return nil ,err
}

decodedScript, err := hex.DecodeString(script)
if err != nil {
return nil ,err
}

prevOutFetcher := txscript.NewCannedPrevOutputFetcher(
decodedScript, amount,
)

txhash := txscript.NewTxSigHashes(tx.MsgTx(), prevOutFetcher)
hash, err := txscript.CalcWitnessSigHash(decodedScript, txhash, txscript.SigHashAll, tx.MsgTx(), 0, amount)
if err != nil {
return nil, err
}

result := hex.EncodeToString(hash)

return &result, nil
}

func CalculateWitnessHashPSBT(transaction string) (*string, error) {
transactionBytes, err := hex.DecodeString(transaction)
if err != nil {
return nil, err
}
// Reader for the PSBT.
psbtBytes := []byte(transactionBytes)
r := bytes.NewReader(psbtBytes)

// Create instance of a PSBT.
p, err := psbt.NewFromRawBytes(r, false)
if err != nil {
return nil, err
}
prevOutFetcher := txscript.NewCannedPrevOutputFetcher(
p.Inputs[0].WitnessUtxo.PkScript, int64(p.Inputs[0].WitnessUtxo.Value),
)
sigHashes := txscript.NewTxSigHashes(p.UnsignedTx, prevOutFetcher)
hash, err := txscript.CalcWitnessSigHash(p.Inputs[0].WitnessScript, sigHashes, txscript.SigHashAll, p.UnsignedTx, 0, int64(p.Inputs[0].WitnessUtxo.Value))
if err != nil {
return nil, err
}
result := hex.EncodeToString(hash)
return &result, nil
}
38 changes: 37 additions & 1 deletion remotesigning/validator.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
// Copyright ©, 2023-present, Lightspark Group, Inc. - All Rights Reserved
package remotesigning

import "github.com/lightsparkdev/go-sdk/webhooks"
import (
"strings"

"github.com/lightsparkdev/go-sdk/webhooks"
)

// Validator an interface which decides whether to sign or reject a remote signing webhook event.
type Validator interface {
Expand All @@ -13,3 +17,35 @@ type PositiveValidator struct{}
func (v PositiveValidator) ShouldSign(webhooks.WebhookEvent) bool {
return true
}

type HashValidator struct {}

func (v HashValidator) ShouldSign(webhookEvent webhooks.WebhookEvent) bool {
request, err := ParseDeriveAndSignRequest(webhookEvent)
if err != nil {
// Only validate DeriveAndSignRequest events
return true
}

for _, signing := range request.SigningJobs {
if strings.HasSuffix(signing.DerivationPath, "/2") {
msg, err := CalculateWitnessHashPSBT(*signing.Transaction)
if err != nil {
return false
}
if strings.Compare(*msg, signing.Message) != 0 {
return false
}
} else {
msg, err := CalculateWitnessHash(*signing.Amount, *signing.Script, *signing.Transaction)
if err != nil {
return false
}
if strings.Compare(*msg, signing.Message) != 0 {
return false
}
}
}

return true
}

0 comments on commit 0760bd0

Please sign in to comment.