Skip to content

Commit

Permalink
Fix issue utelle#164
Browse files Browse the repository at this point in the history
- Incorrect number of reserved bytes values could cause assertions
- Check for valid values of config parameter plaintext_header_size
- Use correct HMAC size for SQLCipher HMAC algorithm SHA256
- Ensure that error messages are returnde correctly from rekey
  • Loading branch information
utelle committed Jun 7, 2024
1 parent efdb694 commit 02b69ad
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Cleaned up white space
- Added SQLITE_PRIVATE for several internal functions
- The cipher configuration parameter `legacy_page_size` now accepts only valid page sizes
- The cipher configuration parameter `plaintext_header_size` now accepts only values that are multiples of 16

### Fixed

- Fixed issue [#156](../../issues/156)) - corrupted database if MMAP_SIZE > 0 was used
- Fixed issue [#158](../../issues/158)) - add check to verify compatibility of source and target database in backup operation
- Fixed issue [#160](../../issues/160)) - fix accessing memory out of array bounds
- Fixed issue [#162](../../issues/162)) - fix loading/storing misaligned data
- Fixed issue [#164](../../issues/164)) - fix return of error messages from rekey
- Fixed issue [#165](../../issues/165)) - fix rekey function by enforcing page size and number of reserved bytes per page
- Fixed issue [#166](../../issues/166)) - missing attribute SQLITE_PRIVATE for several internal functions

Expand Down
8 changes: 4 additions & 4 deletions src/cipher_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,22 +428,22 @@ sqlite3mcGetPageSizeWriteCipher(Codec* codec)
SQLITE_PRIVATE int
sqlite3mcGetReservedReadCipher(Codec* codec)
{
int reserved = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType-1].m_getReserved(codec->m_readCipher) : -1;
int reserved = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType-1].m_getReserved(codec->m_readCipher) : 0;
return reserved;
}

SQLITE_PRIVATE int
sqlite3mcGetReservedWriteCipher(Codec* codec)
{
int reserved = (codec->m_hasWriteCipher && codec->m_writeCipher != NULL) ? globalCodecDescriptorTable[codec->m_writeCipherType-1].m_getReserved(codec->m_writeCipher) : -1;
int reserved = (codec->m_hasWriteCipher && codec->m_writeCipher != NULL) ? globalCodecDescriptorTable[codec->m_writeCipherType-1].m_getReserved(codec->m_writeCipher) : 0;
return reserved;
}

SQLITE_PRIVATE int
sqlite3mcReservedEqual(Codec* codec)
{
int readReserved = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType-1].m_getReserved(codec->m_readCipher) : -1;
int writeReserved = (codec->m_hasWriteCipher && codec->m_writeCipher != NULL) ? globalCodecDescriptorTable[codec->m_writeCipherType-1].m_getReserved(codec->m_writeCipher) : -1;
int readReserved = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType-1].m_getReserved(codec->m_readCipher) : 0;
int writeReserved = (codec->m_hasWriteCipher && codec->m_writeCipher != NULL) ? globalCodecDescriptorTable[codec->m_writeCipherType-1].m_getReserved(codec->m_writeCipher) : 0;
return (readReserved == writeReserved);
}

Expand Down
12 changes: 8 additions & 4 deletions src/cipher_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,16 @@ sqlite3mc_cipher_name(int cipherIndex)
}

static
int checkLegacyPageSize(const char* paramName, int pageSize)
int checkParameterValue(const char* paramName, int value)
{
int ok = 1;
if (sqlite3_stricmp(paramName, "legacy_page_size") == 0 && pageSize > 0)
if (sqlite3_stricmp(paramName, "legacy_page_size") == 0 && value > 0)
{
ok = pageSize >= 512 && pageSize <= SQLITE_MAX_PAGE_SIZE && ((pageSize - 1) & pageSize) == 0;
ok = value >= 512 && value <= SQLITE_MAX_PAGE_SIZE && ((value - 1) & value) == 0;
}
if (ok && sqlite3_stricmp(paramName, "plaintext_header_size") == 0 && value > 0)
{
ok = value % 16 == 0;
}
return ok;
}
Expand Down Expand Up @@ -306,7 +310,7 @@ sqlite3mc_config_cipher(sqlite3* db, const char* cipherName, const char* paramNa
if (!hasMinPrefix && !hasMaxPrefix)
{
if (newValue >= 0 && newValue >= param->m_minValue && newValue <= param->m_maxValue &&
checkLegacyPageSize(paramName, newValue))
checkParameterValue(paramName, newValue))
{
if (hasDefaultPrefix)
{
Expand Down
2 changes: 2 additions & 0 deletions src/cipher_sqlcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,8 @@ GetHmacSizeSQLCipherCipher(int algorithm)
hmacSize = SHA1_DIGEST_SIZE;
break;
case SQLCIPHER_HMAC_ALGORITHM_SHA256:
hmacSize = SHA256_DIGEST_SIZE;
break;
case SQLCIPHER_HMAC_ALGORITHM_SHA512:
default:
hmacSize = SHA512_DIGEST_SIZE;
Expand Down
26 changes: 9 additions & 17 deletions src/codecext.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
Codec* codec;
int codecAllocated = 0;
int rc = SQLITE_ERROR;
char* err = NULL;

if (zKey != NULL && nKey < 0)
{
/* Key is zero-terminated string */
Expand Down Expand Up @@ -450,22 +452,17 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
if (nReserved != nReservedWriteCipher)
{
/* Use VACUUM to change the number of reserved bytes */
char* err = NULL;
sqlite3mcSetReadReserved(codec, nReserved);
sqlite3mcSetWriteReserved(codec, nReservedWriteCipher);
rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, nReservedWriteCipher);
if (rc != SQLITE_OK && err != NULL)
{
sqlite3ErrorWithMsg(db, rc, err);
}
goto leave_rekey;
}
}
else
{
/* Pagesize cannot be changed for an encrypted database */
rc = SQLITE_ERROR;
sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Pagesize cannot be changed for an encrypted database.");
err = "Rekeying failed. Pagesize cannot be changed for an encrypted database.";
goto leave_rekey;
}
}
Expand All @@ -491,10 +488,6 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
sqlite3mcSetReadReserved(codec, nReserved);
sqlite3mcSetWriteReserved(codec, 0);
rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, 0);
if (rc != SQLITE_OK && err != NULL)
{
sqlite3ErrorWithMsg(db, rc, err);
}
goto leave_rekey;
}
}
Expand All @@ -516,25 +509,21 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
sqlite3mcSetReadReserved(codec, nReserved);
sqlite3mcSetWriteReserved(codec, nReservedWriteCipher);
rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, nReservedWriteCipher);
if (rc != SQLITE_OK && err != NULL)
{
sqlite3ErrorWithMsg(db, rc, err);
}
goto leave_rekey;
}
}
else
{
/* Pagesize cannot be changed for an encrypted database */
rc = SQLITE_ERROR;
sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Pagesize cannot be changed for an encrypted database.");
err = "Rekeying failed. Pagesize cannot be changed for an encrypted database.";
goto leave_rekey;
}
}
else
{
/* Setup of write cipher failed */
sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Setup of write cipher failed.");
err = "Rekeying failed. Setup of write cipher failed.";
goto leave_rekey;
}
}
Expand Down Expand Up @@ -599,7 +588,6 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
{
sqlite3mcSetIsEncrypted(codec, 0);
}
mcReportCodecError(sqlite3mcGetBtShared(codec), rc);
}
else
{
Expand All @@ -622,6 +610,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey)
/* Remove codec for unencrypted database */
sqlite3mcSetCodec(db, zDbName, dbFileName, NULL);
}
if (rc != SQLITE_OK && err != NULL)
{
sqlite3ErrorWithMsg(db, rc, err);
}
return rc;
}

Expand Down

0 comments on commit 02b69ad

Please sign in to comment.