utelle / wxsqlite3

wxSQLite3 - SQLite3 database wrapper for wxWidgets (including SQLite3 encryption extension)
http://utelle.github.io/wxsqlite3
Other
589 stars 178 forks source link

Problem with ReKey database in memory #84

Closed TNikolay closed 4 years ago

TNikolay commented 4 years ago

I have a strange problem. I am not sure is this SQLite or wxSQLite3 issue, but maybe you can help?

If we trying to create a database in memory, Restore the database from file and call ReKey() we get the following error

(26) SQLITE_NOTADB When attempting to open a file, the SQLITE_NOTADB error indicates that the file being opened does not appear to be an SQLite database file.

` try { wxString testDBName = wxGetCwd() + wxS("/1.db"); wxSQLite3Database* db = new wxSQLite3Database(); db->Open(":memory:"); db->Restore(testDBName);

  db->ReKey(L"1");

  db->Close();
  delete db;

  if (!m_testMode)
  {
      // Loop until user enters q or Q
      char c(' ');
      while (c != 'q' && c != 'Q')
      {
          cout << "Press q then enter to quit: ";
          cin >> c;
      }
  }

} catch (wxSQLite3Exception& e) { cerr << e.GetErrorCode() << ":" << (const char*)(e.GetMessage().mb_str()) << endl; m_rc = e.GetErrorCode(); } return 0;

Where 1.db is any not-encrypted valid database file. This works perfectly with the previous version (wxsqlite3-3.5.3).

If we try to open the database was encrypted in the previous version - all ok, we can change a password. But if the database was not encrypted earlier - we get the error.

If we just try to open the database from file db->Open(testDBName); all ok. The problem only with the database in memory.

Any advice?

utelle commented 4 years ago

Well, the problem arises from a combination of several effects:

1) a limitation of the SQLite encryption extension Since the wxSQLite3 encryption extension is based on the codec API as implemented by SQLite itself, it has the same limitation. Those can be found at the bottom of the SQLite SEE documentation page: a) TEMP tables are not encrypted. b) In-memory (":memory:") databases are not encrypted.

2) the default encryption scheme changed for wxSQLite3 version 4.x While wxSQLite3 versions before version 4.0 supported only AES-128-bit (or AES-256-bit) encryption, newer versions support additional encryption schemes, which can be selected at runtime. The new default is ChaCha20, which offers better security. However, wxSQLite3 can be compiled with the old default by selecting the codec type accordingly through the compile time symbol CODEC_TYPE.

In fact, when you executed your code with the old wxSQLite3 version 3.5.3, nothing happened internally. That is, applying the rekey method had no effect at all.

Now, with the new version the rekey method has to take special action due to the default encryption scheme ChaCha20. That is, internally a special vacuum command is executed, which fails, because memory databases are not encrypted.

Conclusion: do not apply the rekey method on memory databases.

TNikolay commented 4 years ago

Thank you so much for your help. I have fixed the problem, just delete ReKey, db->Backup(dbpath, dbpassword) is enough.

And thanks again for the great library...