Perform signature verifiction when generating addresses.
This change adds an additional check when creating a new wallet or extending the keypool. All public and private keypairs are parsed from their serialized forms, and an ecdsa signature is created and verified using the keypairs. If the verifiction fails at any point, the wallet creation or keypool extension is aborted to prevent any errors where an address is returned to a user, but any funds send to that address are unspendable due to a mismatched keypair.
This commit is contained in:
parent
eeb72db8b5
commit
c54af23849
3 changed files with 46 additions and 3 deletions
|
@ -444,7 +444,6 @@ func (a *Account) ActivePaymentAddresses() map[string]struct{} {
|
|||
// NewAddress returns a new payment address for an account.
|
||||
func (a *Account) NewAddress() (string, error) {
|
||||
a.mtx.Lock()
|
||||
defer a.mtx.Unlock()
|
||||
|
||||
// Get current block's height and hash.
|
||||
bs, err := GetCurBlock()
|
||||
|
@ -460,6 +459,7 @@ func (a *Account) NewAddress() (string, error) {
|
|||
|
||||
// Write updated wallet to disk.
|
||||
a.dirty = true
|
||||
a.mtx.Unlock()
|
||||
if err = a.writeDirtyToDisk(); err != nil {
|
||||
log.Errorf("cannot sync dirty wallet: %v", err)
|
||||
}
|
||||
|
@ -467,6 +467,8 @@ func (a *Account) NewAddress() (string, error) {
|
|||
// Request updates from btcd for new transactions sent to this address.
|
||||
a.ReqNewTxsForAddress(addr)
|
||||
|
||||
fmt.Println("after")
|
||||
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
|
|
3
cmd.go
3
cmd.go
|
@ -207,8 +207,7 @@ func main() {
|
|||
// Open default account
|
||||
err = accountstore.OpenAccount("", cfg)
|
||||
if err != nil {
|
||||
log.Errorf("cannot open account: %v", err)
|
||||
os.Exit(1)
|
||||
log.Warnf("cannot open default account: %v", err)
|
||||
}
|
||||
|
||||
// Read CA file to verify a btcd TLS connection.
|
||||
|
|
|
@ -402,6 +402,11 @@ func NewWallet(name, desc string, passphrase []byte, net btcwire.BitcoinNet,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Verify root address keypairs.
|
||||
if err := root.verifyKeypairs(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Compute AES key and encrypt root address.
|
||||
kdfp, err := computeKdfParameters(defaultKdfComputeTime, defaultKdfMaxMem)
|
||||
if err != nil {
|
||||
|
@ -754,6 +759,9 @@ func (w *Wallet) extendKeypool(n uint, aeskey []byte, bs *BlockStamp) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := newaddr.verifyKeypairs(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = newaddr.encrypt(aeskey); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1238,6 +1246,40 @@ func newRootBtcAddress(privKey, iv, chaincode []byte,
|
|||
return addr, err
|
||||
}
|
||||
|
||||
// verifyKeypairs creates a signature using the parsed private key and
|
||||
// verifies the signature with the parsed public key. If either of these
|
||||
// steps fail, the keypair generation failed and any funds sent to this
|
||||
// address will be unspendable. This step requires an unencrypted or
|
||||
// unlocked btcAddress.
|
||||
func (a *btcAddress) verifyKeypairs() error {
|
||||
// Parse public key.
|
||||
pubkey, err := btcec.ParsePubKey(a.pubKey, btcec.S256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(a.privKeyCT.key) != 32 {
|
||||
return errors.New("private key unavailable")
|
||||
}
|
||||
|
||||
privkey := &ecdsa.PrivateKey{
|
||||
PublicKey: *pubkey,
|
||||
D: new(big.Int).SetBytes(a.privKeyCT.key),
|
||||
}
|
||||
|
||||
data := "String to sign."
|
||||
r, s, err := ecdsa.Sign(rand.Reader, privkey, []byte(data))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ok := ecdsa.Verify(&privkey.PublicKey, []byte(data), r, s)
|
||||
if !ok {
|
||||
return errors.New("ecdsa verification failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFrom reads an encrypted address from an io.Reader.
|
||||
func (a *btcAddress) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var read int64
|
||||
|
|
Loading…
Add table
Reference in a new issue