-
-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rekey results in invalid database #165
Comments
The same problem happens going from |
It found the issues in utelle/SQLite3MultipleCiphers#165
And various other combinations where other errors like I've commited a script that does this random testing. Run it with |
Typically, The rekey function uses a modified vacuum procedure internally , if the cipher scheme should be changed at the same time. I have to analyze, what goes wrong for the various cipher combinations. It could well be that certain combinations don't work at all due to some SQLite restriction. SQLCipher for example doesn't support Of course, I will further investigate this issue, but it will not have highest priority. Just changing the passphrase should always work, and for changing the cipher scheme there is the alternative of |
I refer to the docs:
Unless an error is returned, it means the action is supported! Things that are not supported must error, and I am fine with that. For the record the vast majority of rekeying does work. |
You can run unencrypted to sqlcipher legacy=3 via rekey SQLError: Rekeying failed. Pagesize cannot be changed for an encrypted database. (good response) However memory is leaked. unencrypted to sqlcipher via rekey No error, database is ok rc4 to sqlcipher via rekey Rekey goes fine, accessing the database gives CorruptError (rekey should either refuse, or succeed and not corrupt) rc4 to sqlcipher legacy=3 via rekey Rekey gives SQLITE_ERROR without setting sqlite3_errmsg. |
sqlcipher legacy=3 uses a page size of 1024 in contrast to the default page size of 4096. Not sure, why the change in page size is sometimes detected and sometimes not. I will check the code. |
I find the regular page_size differing from legacy_page_size confusing. If both are set, which takes priority? Why does legacy_page_size even exist? Also although the documentation says legacy_page_size must be a power of 2,. the pragma happily accepts any values from 1 through 65536 inclusive, like 5432;. BTW my original assumption was the cryptography was using its own pages within the SQLite pages - ie a cryptography block size that could be independent of the SQLite page size, which in turn is independent of the filesystem block size. |
Yes, it is confusing, although I tried hard to explain it in the documentation. The problem is that the SQLite database header contains information about the page size of the database file. This information is read by SQLite before the encryption extension has a chance to initialize the required cipher scheme. Therefore the official SQLite Encryption Extension (SEE) leaves exactly 8 bytes of the database header unencrypted, so that the page size can determined, before initializing SEE. Typically a cipher scheme needs to know the page size to be able to locate the reserved bytes per page. However, the original versions of SQLCipher, sqleet, and (very early) versions of wxSQLite3 encrypt the complete header. This prevents SQLite from determining the correct page size, so that typically the default page size (currently 4096) will be used. In most cases this works, because the database actually has the default page size, but for example prior versions of SQLCipher used a page size of 1024.
First, the legacy page size will be set, but it can be overwritten by a
Different legacy cipher schemes use different page sizes. Specifying the default legacy page size spares the user from explicitly issuing a
You are right. This should be corrected. SQLite's
No, the actual page size must be a power of 2. Cipher schemes (or VFSes, to be more generic) are allowed to reserve up to 255 bytes per page for their own use (for example, for nonce, HMACs or other data). SQLite will then use |
You've explained why the page size needs to be known before first access in many cipher configurations. But not why legacy_page_size exists. I don't see how having it spares you from a page_size pragma - if you need to set the page size in advance, why are there two different pragmas that have the same effect? |
Only for legacy cipher schemes. Otherwise SQLite knows the page size from the database header.
It is required for setting the page size of a database which is encrypted with a legacy cipher scheme.
Sorry, my explanation was unfortunately not correct regarding The parameter
Pragma statements can currently only be used to change the configuration of the currently selected cipher. However, the default configuration of any supported cipher scheme can be adjusted via SQL functions. This can be useful, if an application has to deal with many databases which are attached to a database connection. |
This has been fixed in commit 56ac1e2. Now only valid page sizes are accepted. Otherwise the value is not changed. |
Commit efdb694 should fix the issue. If there are still cases for which rekeying results in corrupted databases, please reopen. |
Running |
Good.
Yes, I haven't tracked down yet this issue. Just a few minutes ago I tested on Linux. Here is the result I see on screen:
Obviously, there still is at least one bug somewhere, but at the moment I don't know why there is a crash. The second run produced the following error:
No idea, why SQLite tries to open a WAL pager. |
Found another corrupt database, which also causes an assertion failure in debug build
Note that |
You can do the running having gdb automatically break on those assertion failures:
|
Yes, just as for Thanks for the sample. This will help to analyze what is going wrong and where. For the situation where the I'm quite confident that I will manage to resolve this issue within the next couple of days. Thanks for the hint how to use gdb to catch assertions. |
I finally found the cause for the pager assertion. The HMAC size for HMAC algorithm SHA256 of SQLCipher was reported incorrectly. Thus, the HMAC was written partially outside of the page buffer bounds. Commit 02b69ad fixes this. At least in my development environment, the test sample |
When the final execute happens I get
SQLError: attached databases must use the same text encoding as main database
which it not right.The text was updated successfully, but these errors were encountered: