Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cgo: Add verify message. #9

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 16 additions & 39 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,32 @@ name: Build and Test
on: [push, pull_request]
permissions:
contents: read

jobs:
build-go:
build:
name: Go CI
runs-on: ubuntu-latest
strategy:
matrix:
go: ['1.20', '1.21']
go: ["1.22", "1.23"]
steps:
- uses: awalsh128/cache-apt-pkgs-action@1850ee53f6e706525805321a3f2f863dcf73c962 #v1.3.0
with:
packages: git-restore-mtime libgtk-3-dev libwebkit2gtk-4.0-dev
version: 1.0

- name: Check out source
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Set up Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe #v4.1.0
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
with:
go-version: ${{ matrix.go }}

- name: Check out source
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0
with:
fetch-depth: 0
# Restore original file modification times for test cache reasons
- name: restore timestamps
run: git restore-mtime
- name: Install Linters
run: "curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2"
- name: Use test and module cache
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
- name: Use lint cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: go-test-${{ matrix.go }}-${{ github.sha }}
restore-keys: go-test-${{ matrix.go }}

~/.cache/golangci-lint
key: go-lint-${{ matrix.go }}-${{ hashFiles('./go.sum') }}
restore-keys: go-lint-${{ matrix.go }}
- name: Install Linters
run: "go install github.com/golangci/golangci-lint/cmd/[email protected]"
- name: Build
run: go build ./...
- name: Test
env:
GO111MODULE: "on"
run: |
./run_tests.sh

lint-docs:
name: Lint Markdown
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac #v4.0.0
- uses: DavidAnson/markdownlint-cli2-action@3aaa38e446fbd2c288af4291aa0f55d64651050f #v12.0.0
continue-on-error: true
with:
globs: |
*.md
sh ./run_tests.sh
4 changes: 2 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ run:
deadline: 10m

output:
format: github-actions,colored-line-number
formats: colored-line-number

linters:
disable-all: true
enable:
- asciicheck
- bidichk
- durationcheck
- exportloopref
- copyloopvar
- gofmt
- goimports
- gosimple
Expand Down
10 changes: 9 additions & 1 deletion asset/dcr/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dcr

import (
"context"
"encoding/binary"
"fmt"
"os"
"path/filepath"
Expand All @@ -10,6 +11,7 @@ import (
"decred.org/dcrwallet/v4/wallet"
_ "decred.org/dcrwallet/v4/wallet/drivers/bdb"
"decred.org/dcrwallet/v4/wallet/udb"
"github.com/decred/dcrd/crypto/blake256"
"github.com/decred/dcrd/hdkeychain/v3"
"github.com/decred/libwallet/asset"
)
Expand Down Expand Up @@ -89,8 +91,14 @@ func CreateWallet(ctx context.Context, params asset.CreateWalletParams, recovery
}
}()

// Adjust seed to create the same wallet as dex.
b := make([]byte, len(seed)+4)
copy(b, seed)
binary.BigEndian.PutUint32(b[len(seed):], 42)
s := blake256.Sum256(b)

// Initialize the newly created database for the wallet before opening.
err = wallet.Create(ctx, db, nil, params.Pass, seed, chainParams)
err = wallet.Create(ctx, db, nil, params.Pass, s[:], chainParams)
if err != nil {
return nil, fmt.Errorf("wallet.Create error: %w", err)
}
Expand Down
56 changes: 51 additions & 5 deletions cgo/addresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"

dcrwallet "decred.org/dcrwallet/v4/wallet"
"decred.org/dcrwallet/v4/wallet/udb"
"github.com/decred/dcrd/txscript/v4/stdaddr"
)
Expand All @@ -27,7 +28,7 @@ func currentReceiveAddress(cName *C.char) *C.char {
return errCResponse("w.CurrentAddress error: %v", err)
}

return successCResponse(addr.String())
return successCResponse("%s", addr)
}

//export newExternalAddress
Expand Down Expand Up @@ -55,7 +56,7 @@ func newExternalAddress(cName *C.char) *C.char {
return errCResponse("w.CurrentAddress error: %v", err)
}

return successCResponse(addr.String())
return successCResponse("%s", addr)
}

//export signMessage
Expand All @@ -70,6 +71,16 @@ func signMessage(cName, cMessage, cAddress, cPassword *C.char) *C.char {
return errCResponse("unable to decode address: %v", err)
}

// Addresses must have an associated secp256k1 private key and therefore
// must be P2PK or P2PKH (P2SH is not allowed).
switch addr.(type) {
case *stdaddr.AddressPubKeyEcdsaSecp256k1V0:
case *stdaddr.AddressPubKeyHashEcdsaSecp256k1V0:
// Valid address types, proceed to sign.
default:
return errCResponse("invalid address type: must be P2PK or P2PKH")
}

if err := w.MainWallet().Unlock(w.ctx, []byte(goString(cPassword)), nil); err != nil {
return errCResponse("cannot unlock wallet: %v", err)
}
Expand All @@ -81,7 +92,42 @@ func signMessage(cName, cMessage, cAddress, cPassword *C.char) *C.char {

sEnc := base64.StdEncoding.EncodeToString(sig)

return successCResponse(sEnc)
return successCResponse("%s", sEnc)
}

//export verifyMessage
func verifyMessage(cName, cMessage, cAddress, cSig *C.char) *C.char {
w, ok := loadedWallet(cName)
if !ok {
return errCResponse("wallet with name %q is not loaded", goString(cName))
}

addr, err := stdaddr.DecodeAddress(goString(cAddress), w.MainWallet().ChainParams())
if err != nil {
return errCResponse("unable to decode address: %v", err)
}

// Addresses must have an associated secp256k1 private key and therefore
// must be P2PK or P2PKH (P2SH is not allowed).
switch addr.(type) {
case *stdaddr.AddressPubKeyEcdsaSecp256k1V0:
case *stdaddr.AddressPubKeyHashEcdsaSecp256k1V0:
// Valid address types, proceed with verification.
default:
return errCResponse("invalid address type: must be P2PK or P2PKH")
}

sig, err := base64.StdEncoding.DecodeString(goString(cSig))
if err != nil {
return errCResponse("unable to decode signature: %v", err)
}

ok, err = dcrwallet.VerifyMessage(goString(cMessage), addr, sig, w.MainWallet().ChainParams())
Copy link

@dreacot dreacot Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// Addresses must have an associated secp256k1 private key and therefore
// must be P2PK or P2PKH (P2SH is not allowed).
switch addr.(type) {
case *stdaddr.AddressPubKeyEcdsaSecp256k1V0:
case *stdaddr.AddressPubKeyHashEcdsaSecp256k1V0:
	// Valid address types, proceed with verification.
default:
	return errCResponse("invalid address type: must be P2PK or P2PKH")
}

shouldn't we be checking to ensure the address is not P2SH?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah. I assumed it would error somewhere along the way anyhow but we can check.

if err != nil {
return errCResponse("unable to verify message: %v", err)
}

return successCResponse("%v", ok)
}

//export addresses
Expand Down Expand Up @@ -111,7 +157,7 @@ func addresses(cName *C.char) *C.char {
return errCResponse("unable to marshal addresses: %v", err)
}

return successCResponse(string(b))
return successCResponse("%s", b)
}

//export defaultPubkey
Expand All @@ -126,5 +172,5 @@ func defaultPubkey(cName *C.char) *C.char {
return errCResponse("unable to get default pubkey: %v", err)
}

return successCResponse(pubkey)
return successCResponse("%s", pubkey)
}
6 changes: 3 additions & 3 deletions cgo/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func syncWallet(cName, cPeers *C.char) *C.char {
},
}
if err := w.StartSync(w.ctx, ntfns, peers...); err != nil {
return errCResponse(err.Error())
return errCResponse("%v", err)
}
return successCResponse("sync started")
}
Expand Down Expand Up @@ -168,7 +168,7 @@ func syncWalletStatus(cName *C.char) *C.char {
if err != nil {
return errCResponse("unable to marshal sync status result: %v", err)
}
return successCResponse(string(b))
return successCResponse("%s", b)
}

//export rescanFromHeight
Expand Down Expand Up @@ -255,5 +255,5 @@ func birthState(cName *C.char) *C.char {
if err != nil {
return errCResponse("unable to marshal birth state result: %v", err)
}
return successCResponse(string(b))
return successCResponse("%s", b)
}
13 changes: 6 additions & 7 deletions cgo/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import "C"
import (
"encoding/hex"
"encoding/json"
"fmt"
"math"
"strconv"

Expand Down Expand Up @@ -73,7 +72,7 @@ func createSignedTransaction(cName, cCreateSignedTxJSONReq *C.char) *C.char {
if err != nil {
return errCResponse("unable to marshal sign send transaction result: %v", err)
}
return successCResponse(string(b))
return successCResponse("%s", b)
}

//export sendRawTransaction
Expand All @@ -86,7 +85,7 @@ func sendRawTransaction(cName, cTxHex *C.char) *C.char {
if err != nil {
return errCResponse("unable to sign send transaction: %v", err)
}
return successCResponse(txHash.String())
return successCResponse("%s", txHash)
}

//export listUnspents
Expand Down Expand Up @@ -126,7 +125,7 @@ func listUnspents(cName *C.char) *C.char {
if err != nil {
return errCResponse("unable to marshal list unspents result: %v", err)
}
return successCResponse(string(b))
return successCResponse("%s", b)
}

//export estimateFee
Expand All @@ -143,7 +142,7 @@ func estimateFee(cName, cNBlocks *C.char) *C.char {
if err != nil {
return errCResponse("unable to get fee from oracle: %v", err)
}
return successCResponse(fmt.Sprintf("%d", (uint64(txFee * 1e8))))
return successCResponse("%d", uint64(txFee*1e8))
}

//export listTransactions
Expand Down Expand Up @@ -182,7 +181,7 @@ func listTransactions(cName, cFrom, cCount *C.char) *C.char {
if err != nil {
return errCResponse("unable to marshal list transactions result: %v", err)
}
return successCResponse(string(b))
return successCResponse("%s", b)
}

//export bestBlock
Expand All @@ -200,5 +199,5 @@ func bestBlock(cName *C.char) *C.char {
if err != nil {
return errCResponse("unable to marshal best block result: %v", err)
}
return successCResponse(string(b))
return successCResponse("%s", b)
}
Loading