Page MenuHome GnuPG

Keyboxd: SQL database disk image is malformed
Open, NormalPublic

Description

Original reported in the Gpg4win Forum:

If I try to import or create a key I get a SQL database disk image is malformed error
How do i find the sql disk image?

See below error log

C:/Projects/HMCTS/Steven Oliver-Public.asc (imported with gpg)

gpg: DBG: kbx_client_data_cmd: finished command with error: SQL database disk image is malformed

gpg: keydb_get_keyblock failed: Value not found

gpg: error writing keyring ‘[keyboxd]’: SQL database disk image is malformed

gpg: error reading ‘-&12’: SQL database disk image is malformed

gpg: import from ‘-&12’ failed: SQL database disk image is malformed

gpg: Total number processed: 0

C:/Projects/HMCTS/Steven Oliver-Public.asc (imported with gpgsm)

gpgsm: total number processed: 0

gpgsm: error importing certificate: End of file

We probably need some way to recover from that or find out how this could have happened and prevent this in the future.

Event Timeline

aheinecke triaged this task as Normal priority.Aug 23 2023, 11:46 AM
aheinecke created this task.

The copy of the database we received for this case is not damaged. A possible problem might be insufficient rights to read the database. For example created with an Admin account and then later used by a different user.

The copy of the database we received for this case is not damaged. A possible problem might be insufficient rights to read the database. For example created with an Admin account and then later used by a different user.

No, for me it shows as damaged. Lets have a look together today.

You are right - issuing an SQL statement returns the rrror. Hwoever, the selfcheck from sqlitebrowser does not show any errors.

And actually only for the pubkey table.

For reference this is the code used to fill the pubkey table:

static gpg_error_t
store_into_pubkey (enum kbxd_store_modes mode,
                   enum pubkey_types pktype, const unsigned char *ubid,
                   const void *blob, size_t bloblen)
{
  gpg_error_t err;
  const char *sqlstr;
  sqlite3_stmt *stmt = NULL;

  if (mode == KBXD_STORE_UPDATE)
    sqlstr = ("UPDATE pubkey set keyblob = ?3, type = ?2 WHERE ubid = ?1");
  else if (mode == KBXD_STORE_INSERT)
    sqlstr = ("INSERT INTO pubkey(ubid,type,keyblob) VALUES(?1,?2,?3)");
  else /* Auto */
    sqlstr = ("INSERT OR REPLACE INTO pubkey(ubid,type,keyblob)"
              " VALUES(?1,?2,?3)");
  err = run_sql_prepare (sqlstr, NULL, NULL, &stmt);
  if (err)
    goto leave;
  err = run_sql_bind_blob (stmt, 1, ubid, UBID_LEN);
  if (err)
    goto leave;
  err = run_sql_bind_int (stmt, 2, (int)pktype);
  if (err)
    goto leave;
  err = run_sql_bind_blob (stmt, 3, blob, bloblen);
  if (err)
    goto leave;

  err = run_sql_step (stmt);

 leave:
  if (stmt)
    sqlite3_finalize (stmt);
  return err;
}

This uses simple helper function with the transient flag. However, the statement is finalized with the function so the buffers are still valid. Is there another thread disturbing us? We use SQLITE_OPEN_NOMUTEX so that we can use out own nPth based mutexes.