Skip to content

Commit 379a988

Browse files
committed
Prepare release of version 1.9.0
- Based on SQLite version 3.47.0 - Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes)
1 parent 06838d2 commit 379a988

26 files changed

+16359
-7986
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- Based on SQLite version 3.47.0
13+
- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes)
14+
1015
### Fixed
1116

1217
- Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour.

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ dnl Copyright (C) 2019-2024 Ulrich Telle <[email protected]>
44
dnl
55
dnl This file is covered by the same licence as the entire SQLite3 Multiple Ciphers package.
66

7-
AC_INIT([sqlite3mc], [1.8.7], [[email protected]])
7+
AC_INIT([sqlite3mc], [1.9.0], [[email protected]])
88

99
dnl This is the version tested with, might work with earlier ones.
1010
AC_PREREQ([2.69])

readme.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ The code was mainly developed under Windows, but was tested under Linux as well.
1010

1111
## Version information
1212

13-
* 1.8.7 - *August 2024*
14-
- Based on SQLite version 3.46.1
13+
* 1.9.0 - *October 2024*
14+
- Based on SQLite version 3.47.0
15+
- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes)
16+
- Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour.
1517

1618
For further version information please consult the [CHANGELOG](CHANGELOG.md).
1719

scripts/patchshell.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,7 @@ die() {
1717
sed -e '/^ sputf(stdout, "SQLite version/{n;N;d}' "$INPUT" \
1818
| sed '/#ifdef SQLITE_CUSTOM_INCLUDE/!{p;d;};n;n;n;a #if SQLITE3MC_USE_MINIZ != 0 && !defined(SQLITE_ENABLE_COMPRESS)\n#include "miniz.c"\n#ifdef SQLITE_HAVE_ZLIB\n#undef SQLITE_HAVE_ZLIB\n#endif\n#define SQLITE_HAVE_ZLIB 1\n#endif\n' \
1919
| sed '/#include <zlib.h>/c #include "zlibwrap.h"' \
20-
| sed '/^ sputf(stdout, "SQLite version/c \ extern char* sqlite3mc_version();\n sputf(stdout, "SQLite version \%s \%.19s%s" \/\*extra-version-info\*\/\n " (\%s)\\n" \/\*SQLite3-Multiple-Ciphers-version-info\*\/\n "Enter \\".help\\" for usage hints.\\n\",\n sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET, sqlite3mc_version());' \
21-
| sed '/^ sqlite3_libversion(), sqlite3_sourceid());/a \ extern char* sqlite3mc_version();\n oputf("\%s\\n", sqlite3mc_version());'
20+
| sed '/^ sqlite3_fprintf(stdout,$/c \ extern char* sqlite3mc_version();\n sqlite3_fprintf(stdout,' \
21+
| sed '/^ "SQLite version/c \ "SQLite version \%s \%.19s%s" \/\*extra-version-info\*\/\n " (\%s)\\n" \/\*SQLite3-Multiple-Ciphers-version-info\*\/' \
22+
| sed '/^ sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);/c \ sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET, sqlite3mc_version());' \
23+
| sed '/^ sqlite3_libversion(), sqlite3_sourceid());/a \ extern char* sqlite3mc_version();\n sqlite3_fprintf(p->out, "\%s\\n", sqlite3mc_version());'

src/cipher_ascon.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** Purpose: Implementation of cipher Ascon
44
** Author: Ulrich Telle
55
** Created: 2023-11-13
6-
** Copyright: (c) 2023-2023 Ulrich Telle
6+
** Copyright: (c) 2023-2024 Ulrich Telle
77
** License: MIT
88
*/
99

@@ -114,21 +114,18 @@ GetSaltAscon128Cipher(void* cipher)
114114
}
115115

116116
static void
117-
GenerateKeyAscon128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
117+
GenerateKeyAscon128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
118118
{
119119
Ascon128Cipher* ascon128Cipher = (Ascon128Cipher*) cipher;
120120
int bypass = 0;
121121

122-
Pager *pPager = pBt->pPager;
123-
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;
124-
125122
int keyOnly = 1;
126-
if (rekey || fd == NULL || sqlite3OsRead(fd, ascon128Cipher->m_salt, SALTLENGTH_ASCON128, 0) != SQLITE_OK)
123+
if (rekey || cipherSalt == NULL)
127124
{
128125
chacha20_rng(ascon128Cipher->m_salt, SALTLENGTH_ASCON128);
129126
keyOnly = 0;
130127
}
131-
else if (cipherSalt != NULL)
128+
else
132129
{
133130
memcpy(ascon128Cipher->m_salt, cipherSalt, SALTLENGTH_ASCON128);
134131
}

src/cipher_chacha20.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** Purpose: Implementation of cipher ChaCha20 - Poly1305
44
** Author: Ulrich Telle
55
** Created: 2020-02-02
6-
** Copyright: (c) 2006-2020 Ulrich Telle
6+
** Copyright: (c) 2006-2024 Ulrich Telle
77
** License: MIT
88
*/
99

@@ -140,21 +140,18 @@ GetSaltChaCha20Cipher(void* cipher)
140140
}
141141

142142
static void
143-
GenerateKeyChaCha20Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
143+
GenerateKeyChaCha20Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
144144
{
145145
ChaCha20Cipher* chacha20Cipher = (ChaCha20Cipher*) cipher;
146146
int bypass = 0;
147147

148-
Pager *pPager = pBt->pPager;
149-
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;
150-
151148
int keyOnly = 1;
152-
if (rekey || fd == NULL || sqlite3OsRead(fd, chacha20Cipher->m_salt, SALTLENGTH_CHACHA20, 0) != SQLITE_OK)
149+
if (rekey || cipherSalt == NULL)
153150
{
154151
chacha20_rng(chacha20Cipher->m_salt, SALTLENGTH_CHACHA20);
155152
keyOnly = 0;
156153
}
157-
else if (cipherSalt != NULL)
154+
else
158155
{
159156
memcpy(chacha20Cipher->m_salt, cipherSalt, SALTLENGTH_CHACHA20);
160157
}

src/cipher_common.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** Purpose: Implementation of SQLite codecs
44
** Author: Ulrich Telle
55
** Created: 2020-02-02
6-
** Copyright: (c) 2006-2022 Ulrich Telle
6+
** Copyright: (c) 2006-2024 Ulrich Telle
77
** License: MIT
88
*/
99

@@ -144,7 +144,7 @@ sqlite3mcGetCipherType(sqlite3* db)
144144
{
145145
CodecParameter* codecParams = (db != NULL) ? sqlite3mcGetCodecParams(db) : globalCodecParameterTable;
146146
CipherParams* cipherParamTable = (codecParams != NULL) ? codecParams[0].m_params : commonParams;
147-
int cipherType = CODEC_TYPE;
147+
int cipherType = CODEC_TYPE_UNKNOWN;
148148
CipherParams* cipher = cipherParamTable;
149149
for (; cipher->m_name[0] != 0; ++cipher)
150150
{
@@ -246,6 +246,10 @@ sqlite3mcCodecSetup(Codec* codec, int cipherType, char* userPassword, int passwo
246246
{
247247
int rc = SQLITE_OK;
248248
CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL);
249+
if (cipherType <= CODEC_TYPE_UNKNOWN)
250+
{
251+
return SQLITE_ERROR;
252+
}
249253
codec->m_isEncrypted = 1;
250254
codec->m_hmacCheck = sqlite3mcGetCipherParameter(globalParams, "hmac_check");
251255
codec->m_walLegacy = sqlite3mcGetCipherParameter(globalParams, "mc_legacy_wal");
@@ -271,6 +275,10 @@ sqlite3mcSetupWriteCipher(Codec* codec, int cipherType, char* userPassword, int
271275
{
272276
int rc = SQLITE_OK;
273277
CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL);
278+
if (cipherType <= CODEC_TYPE_UNKNOWN)
279+
{
280+
return SQLITE_ERROR;
281+
}
274282
if (codec->m_writeCipher != NULL)
275283
{
276284
globalCodecDescriptorTable[codec->m_writeCipherType-1].m_freeCipher(codec->m_writeCipher);
@@ -589,16 +597,30 @@ sqlite3mcPadPassword(char* password, int pswdlen, unsigned char pswd[32])
589597
}
590598
}
591599

600+
SQLITE_PRIVATE unsigned char* mcReadDatabaseHeader(Codec* codec, unsigned char* dbHeader)
601+
{
602+
Pager* pPager = codec->m_btShared->pPager;
603+
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;
604+
if (fd == NULL || sqlite3OsRead(fd, dbHeader, KEYSALT_LENGTH, 0) != SQLITE_OK)
605+
return NULL;
606+
else
607+
return dbHeader;
608+
}
609+
592610
SQLITE_PRIVATE void
593611
sqlite3mcGenerateReadKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt)
594612
{
595-
globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, codec->m_btShared, userPassword, passwordLength, 0, cipherSalt);
613+
unsigned char dbHeader[KEYSALT_LENGTH];
614+
unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt;
615+
globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, userPassword, passwordLength, 0, pDbHeader);
596616
}
597617

598618
SQLITE_PRIVATE void
599619
sqlite3mcGenerateWriteKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt)
600620
{
601-
globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, codec->m_btShared, userPassword, passwordLength, 1, cipherSalt);
621+
unsigned char dbHeader[KEYSALT_LENGTH];
622+
unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt;
623+
globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, userPassword, passwordLength, 1, pDbHeader);
602624
}
603625

604626
SQLITE_PRIVATE int

src/cipher_config.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** Purpose: Configuration of SQLite codecs
44
** Author: Ulrich Telle
55
** Created: 2020-03-02
6-
** Copyright: (c) 2006-2023 Ulrich Telle
6+
** Copyright: (c) 2006-2024 Ulrich Telle
77
** License: MIT
88
*/
99

@@ -788,11 +788,11 @@ sqlite3mcConfigureFromUri(sqlite3* db, const char *zDbName, int configDefault)
788788
if (value >= 0)
789789
{
790790
/* Configure cipher parameter if it was given in the URI */
791-
char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name;
791+
const char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name;
792792
sqlite3mc_config_cipher(db, cipherName, param, value);
793793
if (configDefault)
794794
{
795-
sqlite3_free(param);
795+
sqlite3_free((char*) param);
796796
}
797797
}
798798
}

src/cipher_sds_rc4.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
** Purpose: Implementation of cipher System.Data.SQLite3 RC4
44
** Author: Ulrich Telle
55
** Created: 2020-02-02
6-
** Copyright: (c) 2006-2020 Ulrich Telle
6+
** Copyright: (c) 2006-2024 Ulrich Telle
77
** License: MIT
88
*/
99

@@ -116,7 +116,7 @@ GetSaltRC4Cipher(void* cipher)
116116
}
117117

118118
static void
119-
GenerateKeyRC4Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
119+
GenerateKeyRC4Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
120120
{
121121
RC4Cipher* rc4Cipher = (RC4Cipher*) cipher;
122122
unsigned char digest[SHA1_DIGEST_SIZE];

src/cipher_sqlcipher.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -240,18 +240,15 @@ GetSaltSQLCipherCipher(void* cipher)
240240
}
241241

242242
static void
243-
GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
243+
GenerateKeySQLCipherCipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
244244
{
245245
SQLCipherCipher* sqlCipherCipher = (SQLCipherCipher*) cipher;
246246

247-
Pager *pPager = pBt->pPager;
248-
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;
249-
250-
if (rekey || fd == NULL || sqlite3OsRead(fd, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, 0) != SQLITE_OK)
247+
if (rekey || cipherSalt == NULL)
251248
{
252249
chacha20_rng(sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER);
253250
}
254-
else if (cipherSalt != NULL)
251+
else
255252
{
256253
memcpy(sqlCipherCipher->m_salt, cipherSalt, SALTLENGTH_SQLCIPHER);
257254
}

0 commit comments

Comments
 (0)