Skip to content

Commit

Permalink
Prepare release of version 1.9.0
Browse files Browse the repository at this point in the history
- Based on SQLite version 3.47.0
- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes)
  • Loading branch information
utelle committed Oct 21, 2024
1 parent 06838d2 commit 379a988
Show file tree
Hide file tree
Showing 26 changed files with 16,359 additions and 7,986 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Based on SQLite version 3.47.0
- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes)

### Fixed

- 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.
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dnl Copyright (C) 2019-2024 Ulrich Telle <[email protected]>
dnl
dnl This file is covered by the same licence as the entire SQLite3 Multiple Ciphers package.

AC_INIT([sqlite3mc], [1.8.7], [[email protected]])
AC_INIT([sqlite3mc], [1.9.0], [[email protected]])

dnl This is the version tested with, might work with earlier ones.
AC_PREREQ([2.69])
Expand Down
6 changes: 4 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ The code was mainly developed under Windows, but was tested under Linux as well.

## Version information

* 1.8.7 - *August 2024*
- Based on SQLite version 3.46.1
* 1.9.0 - *October 2024*
- Based on SQLite version 3.47.0
- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes)
- 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.

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

Expand Down
6 changes: 4 additions & 2 deletions scripts/patchshell.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ die() {
sed -e '/^ sputf(stdout, "SQLite version/{n;N;d}' "$INPUT" \
| 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' \
| sed '/#include <zlib.h>/c #include "zlibwrap.h"' \
| 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());' \
| sed '/^ sqlite3_libversion(), sqlite3_sourceid());/a \ extern char* sqlite3mc_version();\n oputf("\%s\\n", sqlite3mc_version());'
| sed '/^ sqlite3_fprintf(stdout,$/c \ extern char* sqlite3mc_version();\n sqlite3_fprintf(stdout,' \
| sed '/^ "SQLite version/c \ "SQLite version \%s \%.19s%s" \/\*extra-version-info\*\/\n " (\%s)\\n" \/\*SQLite3-Multiple-Ciphers-version-info\*\/' \
| sed '/^ sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);/c \ sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET, sqlite3mc_version());' \
| sed '/^ sqlite3_libversion(), sqlite3_sourceid());/a \ extern char* sqlite3mc_version();\n sqlite3_fprintf(p->out, "\%s\\n", sqlite3mc_version());'
11 changes: 4 additions & 7 deletions src/cipher_ascon.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Implementation of cipher Ascon
** Author: Ulrich Telle
** Created: 2023-11-13
** Copyright: (c) 2023-2023 Ulrich Telle
** Copyright: (c) 2023-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -114,21 +114,18 @@ GetSaltAscon128Cipher(void* cipher)
}

static void
GenerateKeyAscon128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
GenerateKeyAscon128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
{
Ascon128Cipher* ascon128Cipher = (Ascon128Cipher*) cipher;
int bypass = 0;

Pager *pPager = pBt->pPager;
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;

int keyOnly = 1;
if (rekey || fd == NULL || sqlite3OsRead(fd, ascon128Cipher->m_salt, SALTLENGTH_ASCON128, 0) != SQLITE_OK)
if (rekey || cipherSalt == NULL)
{
chacha20_rng(ascon128Cipher->m_salt, SALTLENGTH_ASCON128);
keyOnly = 0;
}
else if (cipherSalt != NULL)
else
{
memcpy(ascon128Cipher->m_salt, cipherSalt, SALTLENGTH_ASCON128);
}
Expand Down
11 changes: 4 additions & 7 deletions src/cipher_chacha20.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Implementation of cipher ChaCha20 - Poly1305
** Author: Ulrich Telle
** Created: 2020-02-02
** Copyright: (c) 2006-2020 Ulrich Telle
** Copyright: (c) 2006-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -140,21 +140,18 @@ GetSaltChaCha20Cipher(void* cipher)
}

static void
GenerateKeyChaCha20Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
GenerateKeyChaCha20Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
{
ChaCha20Cipher* chacha20Cipher = (ChaCha20Cipher*) cipher;
int bypass = 0;

Pager *pPager = pBt->pPager;
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;

int keyOnly = 1;
if (rekey || fd == NULL || sqlite3OsRead(fd, chacha20Cipher->m_salt, SALTLENGTH_CHACHA20, 0) != SQLITE_OK)
if (rekey || cipherSalt == NULL)
{
chacha20_rng(chacha20Cipher->m_salt, SALTLENGTH_CHACHA20);
keyOnly = 0;
}
else if (cipherSalt != NULL)
else
{
memcpy(chacha20Cipher->m_salt, cipherSalt, SALTLENGTH_CHACHA20);
}
Expand Down
30 changes: 26 additions & 4 deletions src/cipher_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Implementation of SQLite codecs
** Author: Ulrich Telle
** Created: 2020-02-02
** Copyright: (c) 2006-2022 Ulrich Telle
** Copyright: (c) 2006-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -144,7 +144,7 @@ sqlite3mcGetCipherType(sqlite3* db)
{
CodecParameter* codecParams = (db != NULL) ? sqlite3mcGetCodecParams(db) : globalCodecParameterTable;
CipherParams* cipherParamTable = (codecParams != NULL) ? codecParams[0].m_params : commonParams;
int cipherType = CODEC_TYPE;
int cipherType = CODEC_TYPE_UNKNOWN;
CipherParams* cipher = cipherParamTable;
for (; cipher->m_name[0] != 0; ++cipher)
{
Expand Down Expand Up @@ -246,6 +246,10 @@ sqlite3mcCodecSetup(Codec* codec, int cipherType, char* userPassword, int passwo
{
int rc = SQLITE_OK;
CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL);
if (cipherType <= CODEC_TYPE_UNKNOWN)
{
return SQLITE_ERROR;
}
codec->m_isEncrypted = 1;
codec->m_hmacCheck = sqlite3mcGetCipherParameter(globalParams, "hmac_check");
codec->m_walLegacy = sqlite3mcGetCipherParameter(globalParams, "mc_legacy_wal");
Expand All @@ -271,6 +275,10 @@ sqlite3mcSetupWriteCipher(Codec* codec, int cipherType, char* userPassword, int
{
int rc = SQLITE_OK;
CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL);
if (cipherType <= CODEC_TYPE_UNKNOWN)
{
return SQLITE_ERROR;
}
if (codec->m_writeCipher != NULL)
{
globalCodecDescriptorTable[codec->m_writeCipherType-1].m_freeCipher(codec->m_writeCipher);
Expand Down Expand Up @@ -589,16 +597,30 @@ sqlite3mcPadPassword(char* password, int pswdlen, unsigned char pswd[32])
}
}

SQLITE_PRIVATE unsigned char* mcReadDatabaseHeader(Codec* codec, unsigned char* dbHeader)
{
Pager* pPager = codec->m_btShared->pPager;
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;
if (fd == NULL || sqlite3OsRead(fd, dbHeader, KEYSALT_LENGTH, 0) != SQLITE_OK)
return NULL;
else
return dbHeader;
}

SQLITE_PRIVATE void
sqlite3mcGenerateReadKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt)
{
globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, codec->m_btShared, userPassword, passwordLength, 0, cipherSalt);
unsigned char dbHeader[KEYSALT_LENGTH];
unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt;
globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, userPassword, passwordLength, 0, pDbHeader);
}

SQLITE_PRIVATE void
sqlite3mcGenerateWriteKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt)
{
globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, codec->m_btShared, userPassword, passwordLength, 1, cipherSalt);
unsigned char dbHeader[KEYSALT_LENGTH];
unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt;
globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, userPassword, passwordLength, 1, pDbHeader);
}

SQLITE_PRIVATE int
Expand Down
6 changes: 3 additions & 3 deletions src/cipher_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Configuration of SQLite codecs
** Author: Ulrich Telle
** Created: 2020-03-02
** Copyright: (c) 2006-2023 Ulrich Telle
** Copyright: (c) 2006-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -788,11 +788,11 @@ sqlite3mcConfigureFromUri(sqlite3* db, const char *zDbName, int configDefault)
if (value >= 0)
{
/* Configure cipher parameter if it was given in the URI */
char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name;
const char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name;
sqlite3mc_config_cipher(db, cipherName, param, value);
if (configDefault)
{
sqlite3_free(param);
sqlite3_free((char*) param);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/cipher_sds_rc4.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Implementation of cipher System.Data.SQLite3 RC4
** Author: Ulrich Telle
** Created: 2020-02-02
** Copyright: (c) 2006-2020 Ulrich Telle
** Copyright: (c) 2006-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -116,7 +116,7 @@ GetSaltRC4Cipher(void* cipher)
}

static void
GenerateKeyRC4Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
GenerateKeyRC4Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
{
RC4Cipher* rc4Cipher = (RC4Cipher*) cipher;
unsigned char digest[SHA1_DIGEST_SIZE];
Expand Down
9 changes: 3 additions & 6 deletions src/cipher_sqlcipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,18 +240,15 @@ GetSaltSQLCipherCipher(void* cipher)
}

static void
GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
GenerateKeySQLCipherCipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
{
SQLCipherCipher* sqlCipherCipher = (SQLCipherCipher*) cipher;

Pager *pPager = pBt->pPager;
sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL;

if (rekey || fd == NULL || sqlite3OsRead(fd, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, 0) != SQLITE_OK)
if (rekey || cipherSalt == NULL)
{
chacha20_rng(sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER);
}
else if (cipherSalt != NULL)
else
{
memcpy(sqlCipherCipher->m_salt, cipherSalt, SALTLENGTH_SQLCIPHER);
}
Expand Down
4 changes: 2 additions & 2 deletions src/cipher_wxaes128.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Implementation of cipher wxSQLite3 AES 128-bit
** Author: Ulrich Telle
** Created: 2020-02-02
** Copyright: (c) 2006-2020 Ulrich Telle
** Copyright: (c) 2006-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -130,7 +130,7 @@ GetSaltAES128Cipher(void* cipher)
}

static void
GenerateKeyAES128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
GenerateKeyAES128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
{
AES128Cipher* aesCipher = (AES128Cipher*) cipher;
unsigned char userPad[32];
Expand Down
4 changes: 2 additions & 2 deletions src/cipher_wxaes256.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
** Purpose: Implementation of cipher wxSQLite3 AES 256-bit
** Author: Ulrich Telle
** Created: 2020-02-02
** Copyright: (c) 2006-2020 Ulrich Telle
** Copyright: (c) 2006-2024 Ulrich Telle
** License: MIT
*/

Expand Down Expand Up @@ -136,7 +136,7 @@ GetSaltAES256Cipher(void* cipher)
}

static void
GenerateKeyAES256Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
GenerateKeyAES256Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt)
{
AES256Cipher* aesCipher = (AES256Cipher*) cipher;
unsigned char userPad[32];
Expand Down
13 changes: 10 additions & 3 deletions src/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
** modification-time of the target file is set to this value before
** returning.
**
** If three or more arguments are passed to this function and an
** If five or more arguments are passed to this function and an
** error is encountered, an exception is raised.
**
** READFILE(FILE):
Expand Down Expand Up @@ -110,6 +110,13 @@ SQLITE_EXTENSION_INIT1
#include <time.h>
#include <errno.h>

/* When used as part of the CLI, the sqlite3_stdio.h module will have
** been included before this one. In that case use the sqlite3_stdio.h
** #defines. If not, create our own for fopen().
*/
#ifndef _SQLITE3_STDIO_H_
# define sqlite3_fopen fopen
#endif

/*
** Structure of the fsdir() table-valued function
Expand Down Expand Up @@ -142,7 +149,7 @@ static void readFileContents(sqlite3_context *ctx, const char *zName){
sqlite3 *db;
int mxBlob;

in = fopen(zName, "rb");
in = sqlite3_fopen(zName, "rb");
if( in==0 ){
/* File does not exist or is unreadable. Leave the result set to NULL. */
return;
Expand Down Expand Up @@ -397,7 +404,7 @@ static int writeFile(
sqlite3_int64 nWrite = 0;
const char *z;
int rc = 0;
FILE *out = fopen(zFile, "wb");
FILE *out = sqlite3_fopen(zFile, "wb");
if( out==0 ) return 1;
z = (const char*)sqlite3_value_blob(pData);
if( z ){
Expand Down
Loading

0 comments on commit 379a988

Please sign in to comment.