Skip to content

Instantly share code, notes, and snippets.

@gsalgado
Created September 11, 2014 15:39
Show Gist options
  • Save gsalgado/a78436b2251423f7d8c5 to your computer and use it in GitHub Desktop.
Save gsalgado/a78436b2251423f7d8c5 to your computer and use it in GitHub Desktop.
diff --git a/waddrmgr/address.go b/waddrmgr/address.go
index c517355..e00e423 100644
--- a/waddrmgr/address.go
+++ b/waddrmgr/address.go
@@ -25,7 +25,6 @@ import (
"github.com/monetas/btcec"
"github.com/monetas/btcutil"
"github.com/monetas/btcutil/hdkeychain"
- "github.com/monetas/btcwallet/snacl"
)
// zero sets all bytes in the passed slice to zero. This is used to
@@ -139,7 +138,7 @@ var _ ManagedPubKeyAddress = (*managedAddress)(nil)
// The returned clear text private key will always be a copy that may be safely
// used by the caller without worrying about it being zeroed during an address
// lock.
-func (a *managedAddress) unlock(key *snacl.CryptoKey) ([]byte, error) {
+func (a *managedAddress) unlock(key EncryptorDecryptor) ([]byte, error) {
// Protect concurrent access to clear text private key.
a.privKeyMutex.Lock()
defer a.privKeyMutex.Unlock()
@@ -402,7 +401,7 @@ var _ ManagedScriptAddress = (*scriptAddress)(nil)
// invalid or the encrypted script is not available. The returned clear text
// script will always be a copy that may be safely used by the caller without
// worrying about it being zeroed during an address lock.
-func (a *scriptAddress) unlock(key *snacl.CryptoKey) ([]byte, error) {
+func (a *scriptAddress) unlock(key EncryptorDecryptor) ([]byte, error) {
// Protect concurrent access to clear text script.
a.scriptMutex.Lock()
defer a.scriptMutex.Unlock()
diff --git a/waddrmgr/manager.go b/waddrmgr/manager.go
index bc6b686..6f8949b 100644
--- a/waddrmgr/manager.go
+++ b/waddrmgr/manager.go
@@ -162,6 +162,26 @@ func defaultNewSecretKey(passphrase *[]byte) (*snacl.SecretKey, error) {
// paths.
var newSecretKey = defaultNewSecretKey
+type EncryptorDecryptor interface {
+ Encrypt(in []byte) ([]byte, error)
+ Decrypt(in []byte) ([]byte, error)
+ Bytes() []byte
+ CopyBytesFrom([]byte)
+ Zero()
+}
+
+type CryptoKey struct {
+ snacl.CryptoKey
+}
+
+func (ck *CryptoKey) Bytes() []byte {
+ return ck.CryptoKey[:]
+}
+
+func (ck *CryptoKey) CopyBytesFrom(src []byte) {
+ copy(ck.CryptoKey[:], src)
+}
+
// Manager represents a concurrency safe crypto currency address manager and
// key store.
type Manager struct {
@@ -195,20 +215,20 @@ type Manager struct {
// cryptoKeyPub is the key used to encrypt public extended keys and
// addresses.
- cryptoKeyPub *snacl.CryptoKey
+ cryptoKeyPub EncryptorDecryptor
// cryptoKeyPriv is the key used to encrypt private data such as the
// master hierarchical deterministic extended key.
//
// This key will be zeroed when the address manager is locked.
cryptoKeyPrivEncrypted []byte
- cryptoKeyPriv *snacl.CryptoKey
+ cryptoKeyPriv EncryptorDecryptor
// cryptoKeyScript is the key used to encrypt script data.
//
// This key will be zeroed when the address manager is locked.
cryptoKeyScriptEncrypted []byte
- cryptoKeyScript *snacl.CryptoKey
+ cryptoKeyScript EncryptorDecryptor
// deriveOnUnlock is a list of private keys which needs to be derived
// on the next unlock. This occurs when a public address is derived
@@ -706,7 +726,7 @@ func (m *Manager) ChangePassphrase(oldPassphrase, newPassphrase []byte, private
} else {
// Re-encrypt the crypto public key using the new master public
// key.
- encryptedPub, err := newMasterKey.Encrypt(m.cryptoKeyPub[:])
+ encryptedPub, err := newMasterKey.Encrypt(m.cryptoKeyPub.Bytes())
if err != nil {
str := "failed to encrypt crypto public key"
return managerError(ErrCrypto, str, err)
@@ -1048,7 +1068,7 @@ func (m *Manager) Unlock(passphrase []byte) error {
str := "failed to decrypt crypto private key"
return managerError(ErrCrypto, str, err)
}
- copy(m.cryptoKeyPriv[:], decryptedKey)
+ m.cryptoKeyPriv.CopyBytesFrom(decryptedKey)
zero(decryptedKey)
// Use the crypto private key to decrypt all of the account private
@@ -1393,7 +1413,7 @@ func (m *Manager) SyncedTo() BlockStamp {
// newManager returns a new locked address manager with the given parameters.
func newManager(db *managerDB, net *btcnet.Params, masterKeyPub *snacl.SecretKey,
- masterKeyPriv *snacl.SecretKey, cryptoKeyPub *snacl.CryptoKey,
+ masterKeyPriv *snacl.SecretKey, cryptoKeyPub *CryptoKey,
cryptoKeyPrivEncrypted, cryptoKeyScriptEncrypted []byte) *Manager {
return &Manager{
@@ -1407,9 +1427,9 @@ func newManager(db *managerDB, net *btcnet.Params, masterKeyPub *snacl.SecretKey
masterKeyPriv: masterKeyPriv,
cryptoKeyPub: cryptoKeyPub,
cryptoKeyPrivEncrypted: cryptoKeyPrivEncrypted,
- cryptoKeyPriv: &snacl.CryptoKey{},
+ cryptoKeyPriv: &CryptoKey{},
cryptoKeyScriptEncrypted: cryptoKeyScriptEncrypted,
- cryptoKeyScript: &snacl.CryptoKey{},
+ cryptoKeyScript: &CryptoKey{},
}
}
@@ -1543,13 +1563,13 @@ func loadManager(db *managerDB, pubPassphrase []byte, net *btcnet.Params) (*Mana
}
// Use the master public key to decrypt the crypto public key.
- var cryptoKeyPub snacl.CryptoKey
+ cryptoKeyPub := CryptoKey{}
cryptoKeyPubCT, err := masterKeyPub.Decrypt(cryptoKeyPubEnc)
if err != nil {
str := "failed to decrypt crypto public key"
return nil, managerError(ErrCrypto, str, err)
}
- copy(cryptoKeyPub[:], cryptoKeyPubCT)
+ cryptoKeyPub.CopyBytesFrom(cryptoKeyPubCT)
zero(cryptoKeyPubCT)
// TODO(davec): Load up syncedTo from db.
@@ -1673,11 +1693,12 @@ func Create(dbPath string, seed, pubPassphrase, privPassphrase []byte, net *btcn
// Generate new crypto public, private, and script keys. These keys are
// used to protect the actual public and private data such as addresses,
// extended keys, and scripts.
- cryptoKeyPub, err := snacl.GenerateCryptoKey()
+ snaclCryptoKeyPub, err := snacl.GenerateCryptoKey()
if err != nil {
str := "failed to generate crypto public key"
return nil, managerError(ErrCrypto, str, err)
}
+ cryptoKeyPub := &CryptoKey{*snaclCryptoKeyPub}
cryptoKeyPriv, err := snacl.GenerateCryptoKey()
if err != nil {
str := "failed to generate crypto private key"
@@ -1690,7 +1711,7 @@ func Create(dbPath string, seed, pubPassphrase, privPassphrase []byte, net *btcn
}
// Encrypt the crypto keys with the associated master keys.
- cryptoKeyPubEnc, err := masterKeyPub.Encrypt(cryptoKeyPub[:])
+ cryptoKeyPubEnc, err := masterKeyPub.Encrypt(cryptoKeyPub.Bytes())
if err != nil {
str := "failed to encrypt crypto public key"
return nil, managerError(ErrCrypto, str, err)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment