Skip to content
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

Tests fail due to invalid sqlite database #150

Open
belamu opened this issue Dec 28, 2024 · 0 comments
Open

Tests fail due to invalid sqlite database #150

belamu opened this issue Dec 28, 2024 · 0 comments

Comments

@belamu
Copy link

belamu commented Dec 28, 2024

Desktop:

  • OS and version: NixOS
  • Terminal/shell used: bash

Describe the bug
Current sqlcipher cannot open the sqlite database tests/data/sql/db.sqlite:

$ sqlcipher tests/data/sql/db.sqlite 
SQLite version 3.46.1 2024-08-13 09:16:08 (SQLCipher 4.6.1 community)
sqlite> pragma key='secret';
ok
sqlite> .schema
2024-12-28 20:17:48.585: ERROR CORE sqlcipher_page_cipher: hmac check failed for pgno=1
2024-12-28 20:17:48.585: ERROR CORE sqlite3Codec: error decrypting page 1 data: 1
2024-12-28 20:17:48.585: ERROR CORE sqlcipher_codec_ctx_set_error 1
Error: file is not a database

I noticed this while trying to run the tests within nix package build.
Since rye needs to download further files which is not allowed in a nix pipeline, I ran python3 -m pytest which in principle worked but gave the following error trace:

pytest output
============================= test session starts ==============================
platform linux -- Python 3.12.7, pytest-8.3.3, pluggy-1.5.0
rootdir: /build/source
configfile: pyproject.toml
collected 2 items                                                              

tests/test_integration.py F                                              [ 50%]
tests/test_utils.py .                                                    [100%]

=================================== FAILURES ===================================
_______________________________ test_integration _______________________________

    def test_integration():
        from sigexport.main import main
    
        root = Path(__file__).resolve().parents[0]
        dest = Path(tempfile.TemporaryDirectory().name)
        source = root / "data"
    
>       main(
            None,  # type: ignore
            dest=dest,
            source=source,
            old=None,
            paginate=100,
            chats="",
            list_chats=False,
            include_empty=False,
            verbose=True,
        )

tests/test_integration.py:132: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
sigexport/main.py:74: in main
    convos, contacts = data.fetch_data(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

source_dir = PosixPath('/build/source/tests/data')
password = <typer.models.OptionInfo object at 0x7ffff601d0a0>
key = <typer.models.OptionInfo object at 0x7ffff6662f30>, chats = ''
include_empty = False

    def fetch_data(
        source_dir: Path,
        password: Optional[str],
        key: Optional[str],
        chats: str,
        include_empty: bool,
    ) -> tuple[models.Convos, models.Contacts]:
        """Load SQLite data into dicts."""
        db_file = source_dir / "sql" / "db.sqlite"
        signal_config = source_dir / "config.json"
    
        if key is None:
            try:
                key = crypto.get_key(signal_config, password)
            except Exception:
                secho("Failed to decrypt Signal password", fg=colors.RED)
                raise Exit(1)
    
        log(f"Fetching data from {db_file}\n")
        contacts: models.Contacts = {}
        convos: models.Convos = {}
        chats_list = chats.split(",") if len(chats) > 0 else []
    
        db = dbapi2.connect(str(db_file))
        c = db.cursor()
        # param binding doesn't work for pragmas, so use a direct string concat
        c.execute(f"PRAGMA KEY = \"x'{key}'\"")
        c.execute("PRAGMA cipher_page_size = 4096")
        c.execute("PRAGMA kdf_iter = 64000")
        c.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA512")
        c.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512")
    
        query = "SELECT type, id, serviceId, e164, name, profileName, members FROM conversations"
>       c.execute(query)
E       sqlcipher3.dbapi2.DatabaseError: file is not a database

sigexport/data.py:47: DatabaseError
----------------------------- Captured stdout call -----------------------------
Fetching data from /build/source/tests/data/sql/db.sqlite

----------------------------- Captured stderr call -----------------------------
2024-12-28 19:00:32.024: ERROR CORE sqlcipher_page_cipher: hmac check failed for pgno=1
2024-12-28 19:00:32.024: ERROR CORE sqlite3Codec: error decrypting page 1 data: 1
2024-12-28 19:00:32.024: ERROR CORE sqlcipher_codec_ctx_set_error 1
=========================== short test summary info ============================
FAILED tests/test_integration.py::test_integration - sqlcipher3.dbapi2.DatabaseError: file is not a database
========================= 1 failed, 1 passed in 0.74s ==========================
error: builder for '/nix/store/3wzf78l0j3ywpadli7jhvlddxm5382y0-signal-export-3.2.2.drv' failed with exit code 1;
       last 25 log lines:
       >     
       >         db = dbapi2.connect(str(db_file))
       >         c = db.cursor()
       >         # param binding doesn't work for pragmas, so use a direct string concat
       >         c.execute(f"PRAGMA KEY = \"x'{key}'\"")
       >         c.execute("PRAGMA cipher_page_size = 4096")
       >         c.execute("PRAGMA kdf_iter = 64000")
       >         c.execute("PRAGMA cipher_hmac_algorithm = HMAC_SHA512")
       >         c.execute("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA512")
       >     
       >         query = "SELECT type, id, serviceId, e164, name, profileName, members FROM conversations"
       > >       c.execute(query)
       > E       sqlcipher3.dbapi2.DatabaseError: file is not a database
       >
       > sigexport/data.py:47: DatabaseError
       > ----------------------------- Captured stdout call -----------------------------
       > Fetching data from /build/source/tests/data/sql/db.sqlite
       >
       > ----------------------------- Captured stderr call -----------------------------
       > 2024-12-28 19:00:32.024: ERROR CORE sqlcipher_page_cipher: hmac check failed for pgno=1
       > 2024-12-28 19:00:32.024: ERROR CORE sqlite3Codec: error decrypting page 1 data: 1
       > 2024-12-28 19:00:32.024: ERROR CORE sqlcipher_codec_ctx_set_error 1
       > =========================== short test summary info ============================
       > FAILED tests/test_integration.py::test_integration - sqlcipher3.dbapi2.DatabaseError: file is not a database
       > ========================= 1 failed, 1 passed in 0.74s ==========================

By the way, the test does not test the newer functionality of encrypted key. Maybe I get around to adapt it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant