waddrmgr: add ability to store encrypt master HD priv/pub keys
In this commit, we create new key spaces to allow users to store the encrypted master priv/pub keys. This is required as in order to create new scopes, we must do hardened derivation from the root key.
This commit is contained in:
parent
e8755c2bc2
commit
946ca2da1e
1 changed files with 67 additions and 0 deletions
|
@ -229,6 +229,17 @@ var (
|
||||||
// flag, the master private key (encrypted), the master HD private key
|
// flag, the master private key (encrypted), the master HD private key
|
||||||
// (encrypted), and also versioning information.
|
// (encrypted), and also versioning information.
|
||||||
mainBucketName = []byte("main")
|
mainBucketName = []byte("main")
|
||||||
|
|
||||||
|
// masterHDPrivName is the name of the key that stores the master HD
|
||||||
|
// private key. This key is encrypted with the master private crypto
|
||||||
|
// encryption key. This resides under the main bucket.
|
||||||
|
masterHDPrivName = []byte("mhdpriv")
|
||||||
|
|
||||||
|
// masterHDPubName is the name of the key that stores the master HD
|
||||||
|
// public key. This key is encrypted with the master public crypto
|
||||||
|
// encryption key. This reside under the main bucket.
|
||||||
|
masterHDPubName = []byte("mhdpub")
|
||||||
|
|
||||||
// syncBucketName is the name of the bucket that stores the current
|
// syncBucketName is the name of the bucket that stores the current
|
||||||
// sync state of the root manager.
|
// sync state of the root manager.
|
||||||
syncBucketName = []byte("sync")
|
syncBucketName = []byte("sync")
|
||||||
|
@ -522,6 +533,62 @@ func putCoinTypeKeys(ns walletdb.ReadWriteBucket, scope *KeyScope,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// putMasterHDKeys stores the encrypted master HD keys in the top level main
|
||||||
|
// bucket. These are required in order to create any new manager scopes, as
|
||||||
|
// those are created via hardened derivation of the children of this key.
|
||||||
|
func putMasterHDKeys(ns walletdb.ReadWriteBucket, masterHDPrivEnc, masterHDPubEnc []byte) error {
|
||||||
|
// As this is the key for the root manager, we don't need to fetch any
|
||||||
|
// particular scope, and can insert directly within the main bucket.
|
||||||
|
bucket := ns.NestedReadWriteBucket(mainBucketName)
|
||||||
|
|
||||||
|
// Now that we have the main bucket, we can directly store each of the
|
||||||
|
// relevant keys. If we're in watch only mode, then some or all of
|
||||||
|
// these keys might not be available.
|
||||||
|
if masterHDPrivEnc != nil {
|
||||||
|
err := bucket.Put(masterHDPrivName, masterHDPrivEnc)
|
||||||
|
if err != nil {
|
||||||
|
str := "failed to store encrypted master HD private key"
|
||||||
|
return managerError(ErrDatabase, str, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if masterHDPubEnc != nil {
|
||||||
|
err := bucket.Put(masterHDPubName, masterHDPubEnc)
|
||||||
|
if err != nil {
|
||||||
|
str := "failed to store encrypted master HD public key"
|
||||||
|
return managerError(ErrDatabase, str, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetchMasterHDKeys attempts to fetch both the master HD private and public
|
||||||
|
// keys from the database. If this is a watch only wallet, then it's possible
|
||||||
|
// that the master private key isn't stored.
|
||||||
|
func fetchMasterHDKeys(ns walletdb.ReadBucket) ([]byte, []byte, error) {
|
||||||
|
bucket := ns.NestedReadBucket(mainBucketName)
|
||||||
|
|
||||||
|
var masterHDPrivEnc, masterHDPubEnc []byte
|
||||||
|
|
||||||
|
// First, we'll try to fetch the master private key. If this database
|
||||||
|
// is watch only, or the master has been neutered, then this won't be
|
||||||
|
// found on disk.
|
||||||
|
key := bucket.Get(masterHDPrivName)
|
||||||
|
if key != nil {
|
||||||
|
masterHDPrivEnc = make([]byte, len(key))
|
||||||
|
copy(masterHDPrivEnc[:], key)
|
||||||
|
}
|
||||||
|
|
||||||
|
key = bucket.Get(masterHDPubName)
|
||||||
|
if key != nil {
|
||||||
|
masterHDPubEnc = make([]byte, len(key))
|
||||||
|
copy(masterHDPubEnc[:], key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return masterHDPrivEnc, masterHDPubEnc, nil
|
||||||
|
}
|
||||||
|
|
||||||
// fetchCryptoKeys loads the encrypted crypto keys which are in turn used to
|
// fetchCryptoKeys loads the encrypted crypto keys which are in turn used to
|
||||||
// protect the extended keys, imported keys, and scripts. Any of the returned
|
// protect the extended keys, imported keys, and scripts. Any of the returned
|
||||||
// values can be nil, but in practice only the crypto private and script keys
|
// values can be nil, but in practice only the crypto private and script keys
|
||||||
|
|
Loading…
Reference in a new issue