Add export/import methods
This commit is contained in:
parent
fb6411af24
commit
b1a1a223c2
|
@ -400,6 +400,60 @@ func (b *GethStatusBackend) StartNodeWithAccount(acc multiaccounts.Account, pass
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *GethStatusBackend) ExportUnencryptedDatabase(acc multiaccounts.Account, password, directory string) error {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
if b.appDB != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(b.rootDataDir) == 0 {
|
||||||
|
return errors.New("root datadir wasn't provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migrate file path to fix issue https://github.com/status-im/status-go/issues/2027
|
||||||
|
oldPath := filepath.Join(b.rootDataDir, fmt.Sprintf("app-%x.sql", acc.KeyUID))
|
||||||
|
newPath := filepath.Join(b.rootDataDir, fmt.Sprintf("%s.db", acc.KeyUID))
|
||||||
|
|
||||||
|
_, err := os.Stat(oldPath)
|
||||||
|
if err == nil {
|
||||||
|
err := os.Rename(oldPath, newPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// rename journals as well, but ignore errors
|
||||||
|
_ = os.Rename(oldPath+"-shm", newPath+"-shm")
|
||||||
|
_ = os.Rename(oldPath+"-wal", newPath+"-wal")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = appdatabase.DecryptDatabase(newPath, directory, password)
|
||||||
|
if err != nil {
|
||||||
|
b.log.Error("failed to initialize db", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *GethStatusBackend) ImportUnencryptedDatabase(acc multiaccounts.Account, password, databasePath string) error {
|
||||||
|
b.mu.Lock()
|
||||||
|
defer b.mu.Unlock()
|
||||||
|
if b.appDB != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if len(b.rootDataDir) == 0 {
|
||||||
|
return errors.New("root datadir wasn't provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
path := filepath.Join(b.rootDataDir, fmt.Sprintf("%s.db", acc.KeyUID))
|
||||||
|
|
||||||
|
err := appdatabase.EncryptDatabase(databasePath, path, password)
|
||||||
|
if err != nil {
|
||||||
|
b.log.Error("failed to initialize db", "err", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (b *GethStatusBackend) SaveAccountAndStartNodeWithKey(acc multiaccounts.Account, password string, settings accounts.Settings, nodecfg *params.NodeConfig, subaccs []accounts.Account, keyHex string) error {
|
func (b *GethStatusBackend) SaveAccountAndStartNodeWithKey(acc multiaccounts.Account, password string, settings accounts.Settings, nodecfg *params.NodeConfig, subaccs []accounts.Account, keyHex string) error {
|
||||||
err := b.SaveAccount(acc)
|
err := b.SaveAccount(acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -19,3 +19,15 @@ func InitializeDB(path, password string) (*sql.DB, error) {
|
||||||
}
|
}
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecryptDatabase creates an unencrypted copy of the database and copies it
|
||||||
|
// over to the given directory
|
||||||
|
func DecryptDatabase(oldPath, newPath, password string) error {
|
||||||
|
return sqlite.DecryptDB(oldPath, newPath, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptDatabase creates an encrypted copy of the database and copies it to the
|
||||||
|
// user path
|
||||||
|
func EncryptDatabase(oldPath, newPath, password string) error {
|
||||||
|
return sqlite.EncryptDB(oldPath, newPath, password)
|
||||||
|
}
|
||||||
|
|
|
@ -628,3 +628,31 @@ func MultiformatDeserializePublicKey(key, outBase string) string {
|
||||||
|
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExportUnencryptedDatabase exports the database unencrypted to the given path
|
||||||
|
func ExportUnencryptedDatabase(accountData, password, databasePath string) string {
|
||||||
|
var account multiaccounts.Account
|
||||||
|
err := json.Unmarshal([]byte(accountData), &account)
|
||||||
|
if err != nil {
|
||||||
|
return makeJSONResponse(err)
|
||||||
|
}
|
||||||
|
err = statusBackend.ExportUnencryptedDatabase(account, password, databasePath)
|
||||||
|
if err != nil {
|
||||||
|
return makeJSONResponse(err)
|
||||||
|
}
|
||||||
|
return makeJSONResponse(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImportUnencryptedDatabase imports the database unencrypted to the given directory
|
||||||
|
func ImportUnencryptedDatabase(accountData, password, databasePath string) string {
|
||||||
|
var account multiaccounts.Account
|
||||||
|
err := json.Unmarshal([]byte(accountData), &account)
|
||||||
|
if err != nil {
|
||||||
|
return makeJSONResponse(err)
|
||||||
|
}
|
||||||
|
err = statusBackend.ImportUnencryptedDatabase(account, password, databasePath)
|
||||||
|
if err != nil {
|
||||||
|
return makeJSONResponse(err)
|
||||||
|
}
|
||||||
|
return makeJSONResponse(nil)
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
_ "github.com/mutecomm/go-sqlcipher" // We require go sqlcipher that overrides default implementation
|
_ "github.com/mutecomm/go-sqlcipher" // We require go sqlcipher that overrides default implementation
|
||||||
)
|
)
|
||||||
|
@ -18,6 +19,55 @@ const (
|
||||||
WALMode = "wal"
|
WALMode = "wal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DecryptDB completely removes the encryption from the db
|
||||||
|
func DecryptDB(oldPath, newPath, key string) error {
|
||||||
|
|
||||||
|
db, err := openDB(oldPath, key)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec(`ATTACH DATABASE '` + newPath + `' AS plaintext KEY ''`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec(`SELECT sqlcipher_export('plaintext')`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = db.Exec(`DETACH DATABASE plaintext`)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// EncryptDB takes a plaintext database and adds encryption
|
||||||
|
func EncryptDB(unencryptedPath, encryptedPath, key string) error {
|
||||||
|
|
||||||
|
_ = os.Remove(encryptedPath)
|
||||||
|
|
||||||
|
db, err := OpenUnecryptedDB(unencryptedPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec(`ATTACH DATABASE '` + encryptedPath + `' AS encrypted KEY '` + key + `'`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec(fmt.Sprintf("PRAGMA encrypted.kdf_iter = '%d'", kdfIterationsNumber))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.Exec(`SELECT sqlcipher_export('encrypted')`)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = db.Exec(`DETACH DATABASE encrypted`)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func openDB(path, key string) (*sql.DB, error) {
|
func openDB(path, key string) (*sql.DB, error) {
|
||||||
db, err := sql.Open("sqlite3", path)
|
db, err := sql.Open("sqlite3", path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue