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
|
||||
}
|
||||
|
||||
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 {
|
||||
err := b.SaveAccount(acc)
|
||||
if err != nil {
|
||||
|
|
|
@ -19,3 +19,15 @@ func InitializeDB(path, password string) (*sql.DB, error) {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 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"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "github.com/mutecomm/go-sqlcipher" // We require go sqlcipher that overrides default implementation
|
||||
)
|
||||
|
@ -18,6 +19,55 @@ const (
|
|||
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) {
|
||||
db, err := sql.Open("sqlite3", path)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue