Skip to content

Commit edf4ae9

Browse files
committed
Add cipher parameter options.
1 parent f9a71d6 commit edf4ae9

1 file changed

Lines changed: 156 additions & 12 deletions

File tree

sqlitecipher/sqlitecipher.cpp

Lines changed: 156 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,22 @@ bool SQLiteCipherDriver::open(const QString & db, const QString &, const QString
821821
bool openUriOption = false;
822822
QString newPassword = QString::null;
823823
int cipher = -1;
824-
bool showCipherName = false;
824+
// AES128CBC
825+
bool aes128cbcLegacy = false;
826+
// AES256CBC
827+
bool aes256cbcLegacy = false;
828+
int aes256cbcKdfIter = 4001;
829+
// CHACHA20
830+
bool chacha20Legacy = false;
831+
int chacha20KdfIter = 64007;
832+
// SQLCIPHER
833+
bool sqlcipherLegacy = false;
834+
int sqlcipherKdfIter = 64000;
835+
int sqlcipherFastKdfIter = 2;
836+
bool sqlcipherHmacUse = true;
837+
int sqlcipherHmacPgno = 1;
838+
int sqlcipherHmacSaltMask = 0x3a;
839+
825840
#if QT_CONFIG(regularexpression)
826841
static const QLatin1String regexpConnectOption = QLatin1String("QSQLITE_ENABLE_REGEXP");
827842
bool defineRegexp = false;
@@ -833,8 +848,9 @@ bool SQLiteCipherDriver::open(const QString & db, const QString &, const QString
833848
if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
834849
bool ok;
835850
const int nt = option.midRef(21).toInt(&ok);
836-
if (ok)
851+
if (ok) {
837852
timeOut = nt;
853+
}
838854
}
839855
if (option.startsWith(QLatin1String("QSQLITE_UPDATE_KEY="))) {
840856
newPassword = option.mid(19);
@@ -844,6 +860,108 @@ bool SQLiteCipherDriver::open(const QString & db, const QString &, const QString
844860
QString cipherName = option.mid(19);
845861
cipher = _cipherNameToValue(cipherName);
846862
}
863+
if (option.startsWith(QLatin1String("AES128CBC_LEGACY="))) {
864+
bool ok;
865+
const int nl = option.mid(17).toInt(&ok);
866+
if (ok) {
867+
aes128cbcLegacy = nl;
868+
}
869+
}
870+
if (option.startsWith(QLatin1String("AES256CBC_LEGACY="))) {
871+
bool ok;
872+
const int nl = option.mid(17).toInt(&ok);
873+
if (ok) {
874+
aes256cbcLegacy = nl;
875+
}
876+
}
877+
if (option.startsWith(QLatin1String("AES256CBC_KDF_ITER="))) {
878+
bool ok;
879+
const int nk = option.mid(19).toInt(&ok);
880+
if (ok) {
881+
aes256cbcKdfIter = nk;
882+
if (aes256cbcKdfIter < 1) {
883+
aes256cbcKdfIter = 1;
884+
}
885+
}
886+
}
887+
if (option.startsWith(QLatin1String("CHACHA20_LEGACY="))) {
888+
bool ok;
889+
const int nl = option.mid(16).toInt(&ok);
890+
if (ok) {
891+
chacha20Legacy = nl;
892+
}
893+
}
894+
if (option.startsWith(QLatin1String("CHACHA20_KDF_ITER="))) {
895+
bool ok;
896+
const int nk = option.mid(18).toInt(&ok);
897+
if (ok) {
898+
chacha20KdfIter = nk;
899+
if (chacha20KdfIter < 1) {
900+
chacha20KdfIter = 1;
901+
}
902+
}
903+
}
904+
if (option.startsWith(QLatin1String("SQLCIPHER_LEGACY="))) {
905+
bool ok;
906+
const int nl = option.mid(17).toInt(&ok);
907+
if (ok) {
908+
sqlcipherLegacy = nl;
909+
}
910+
}
911+
if (option.startsWith(QLatin1String("SQLCIPHER_KDF_ITER="))) {
912+
bool ok;
913+
const int nk = option.mid(19).toInt(&ok);
914+
if (ok) {
915+
sqlcipherKdfIter = nk;
916+
if (sqlcipherKdfIter < 1) {
917+
sqlcipherKdfIter = 1;
918+
}
919+
}
920+
}
921+
if (option.startsWith(QLatin1String("SQLCIPHER_FAST_KDF_ITER="))) {
922+
bool ok;
923+
const int nf = option.mid(24).toInt(&ok);
924+
if (ok) {
925+
sqlcipherFastKdfIter = nf;
926+
if (sqlcipherFastKdfIter < 1) {
927+
sqlcipherFastKdfIter = 1;
928+
}
929+
}
930+
}
931+
if (option.startsWith(QLatin1String("SQLCIPHER_HMAC_USE="))) {
932+
bool ok;
933+
const int nh = option.mid(19).toInt(&ok);
934+
if (ok) {
935+
sqlcipherHmacUse = nh;
936+
}
937+
}
938+
if (option.startsWith(QLatin1String("SQLCIPHER_HMAC_PGNO="))) {
939+
bool ok;
940+
const int np = option.mid(20).toInt(&ok);
941+
if (ok) {
942+
sqlcipherHmacPgno = np;
943+
if (sqlcipherHmacPgno < 0) {
944+
sqlcipherHmacPgno = 0;
945+
}
946+
if (sqlcipherHmacPgno > 2) {
947+
sqlcipherHmacPgno = 2;
948+
}
949+
}
950+
}
951+
if (option.startsWith(QLatin1String("SQLCIPHER_HMAC_SALT_MASK="))) {
952+
bool ok;
953+
const int ns = option.mid(25).toInt(&ok);
954+
if (ok) {
955+
sqlcipherHmacSaltMask = ns;
956+
if (sqlcipherHmacSaltMask < 0) {
957+
sqlcipherHmacSaltMask = 0;
958+
}
959+
if (sqlcipherHmacSaltMask > 255) {
960+
sqlcipherHmacSaltMask = 255;
961+
}
962+
}
963+
}
964+
847965
if (option == QLatin1String("QSQLITE_OPEN_READONLY")) {
848966
openReadOnlyOption = true;
849967
} else if (option == QLatin1String("QSQLITE_OPEN_URI")) {
@@ -854,8 +972,6 @@ bool SQLiteCipherDriver::open(const QString & db, const QString &, const QString
854972
keyOp = CREATE_KEY;
855973
} else if (option == QLatin1String("QSQLITE_REMOVE_KEY")) {
856974
keyOp = REMOVE_KEY;
857-
} else if (option == QLatin1String("QSQLITE_SHOW_CIPHER")) {
858-
showCipherName = true;
859975
}
860976
#if QT_CONFIG(regularexpression)
861977
else if (option.startsWith(regexpConnectOption)) {
@@ -885,14 +1001,6 @@ bool SQLiteCipherDriver::open(const QString & db, const QString &, const QString
8851001
if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, nullptr) == SQLITE_OK) {
8861002
sqlite3_busy_timeout(d->access, timeOut);
8871003

888-
if (cipher > 0) {
889-
wxsqlite3_config(d->access, "cipher", cipher);
890-
}
891-
if (showCipherName) {
892-
int cipherType = wxsqlite3_config(d->access, "cipher", -1);
893-
qDebug() << "Current cipher is: " << _cipherValueToName(static_cast<QtSqliteCipher>(cipherType));
894-
}
895-
8961004
setOpen(true);
8971005
setOpenError(false);
8981006
#if QT_CONFIG(regularexpression)
@@ -902,6 +1010,42 @@ bool SQLiteCipherDriver::open(const QString & db, const QString &, const QString
9021010
NULL, &_q_regexp_cleanup);
9031011
}
9041012
#endif
1013+
if (cipher > 0) {
1014+
wxsqlite3_config(d->access, "cipher", cipher);
1015+
switch (cipher) {
1016+
case AES_128_CBC:
1017+
{
1018+
wxsqlite3_config_cipher(d->access, "aes128cbc", "legacy", aes128cbcLegacy ? 1 : 0);
1019+
break;
1020+
}
1021+
case AES_256_CBC:
1022+
{
1023+
wxsqlite3_config_cipher(d->access, "aes256cbc", "legacy", aes256cbcLegacy ? 1 : 0);
1024+
wxsqlite3_config_cipher(d->access, "aes256cbc", "kdf_iter", aes256cbcKdfIter);
1025+
break;
1026+
}
1027+
case CHACHA20:
1028+
{
1029+
wxsqlite3_config_cipher(d->access, "chacha20", "legacy", chacha20Legacy ? 1 : 0);
1030+
wxsqlite3_config_cipher(d->access, "chacha20", "kdf_iter", chacha20KdfIter);
1031+
break;
1032+
}
1033+
case SQLCIPHER:
1034+
{
1035+
wxsqlite3_config_cipher(d->access, "sqlcipher", "legacy", sqlcipherLegacy ? 1 : 0);
1036+
wxsqlite3_config_cipher(d->access, "sqlcipher", "kdf_iter", sqlcipherKdfIter);
1037+
wxsqlite3_config_cipher(d->access, "sqlcipher", "fast_kdf_iter", sqlcipherFastKdfIter);
1038+
wxsqlite3_config_cipher(d->access, "sqlcipher", "hmac_use", sqlcipherHmacUse ? 1 : 0);
1039+
wxsqlite3_config_cipher(d->access, "sqlcipher", "hmac_pgno", sqlcipherHmacPgno);
1040+
wxsqlite3_config_cipher(d->access, "sqlcipher", "hmac_salt_mask", sqlcipherHmacSaltMask);
1041+
break;
1042+
}
1043+
default:
1044+
// Do nothing
1045+
break;
1046+
}
1047+
}
1048+
9051049
if (!(password.isNull() || password.isEmpty())) {
9061050
switch (keyOp) {
9071051
case OPEN_WITH_KEY:

0 commit comments

Comments
 (0)