summaryrefslogtreecommitdiffstats
path: root/Plugins/DbSqliteCipher/dbsqlitecipher.cpp
blob: 13fa346ce7935c7b39b35313e6a596967643614b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "dbsqlitecipher.h"
#include "sqlitestudio.h"
#include "services/extralicensemanager.h"
#include "common/unused.h"
#include "dbsqlitecipherinstance.h"
#include "services/notifymanager.h"
#include <limits>

DbSqliteCipher::DbSqliteCipher()
{
}

QString DbSqliteCipher::getLabel() const
{
    return "SQLCipher";
}

bool DbSqliteCipher::checkIfDbServedByPlugin(Db* db) const
{
    return (db && dynamic_cast<DbSqliteCipherInstance*>(db));
}

Db* DbSqliteCipher::getInstance(const QString& name, const QString& path, const QHash<QString, QVariant>& options, QString* errorMessage)
{
    UNUSED(errorMessage);

    if (!initValid)
        return nullptr;

    Db* db = new DbSqliteCipherInstance(name, path, options);

    if (!db->openForProbing())
    {
        delete db;
        return nullptr;
    }

    SqlQueryPtr results = db->exec("SELECT * FROM sqlite_master");
    if (results->isError())
    {
        delete db;
        return nullptr;
    }

    db->closeQuiet();
    return db;
}

QList<DbPluginOption> DbSqliteCipher::getOptionsList() const
{
    static const QStringList ciphers = {"aes-128-cbc", "aes-128-cfb", "aes-128-cfb1", "aes-128-cfb8", "aes-128-ctr", "aes-128-ecb", "aes-128-gcm", "aes-128-ofb",
                                        "aes-128-xts", "aes-192-cbc", "aes-192-cfb", "aes-192-cfb1", "aes-192-cfb8", "aes-192-ctr", "aes-192-ecb", "aes-192-gcm",
                                        "aes-192-ofb", "aes-256-cbc", "aes-256-cfb", "aes-256-cfb1", "aes-256-cfb8", "aes-256-ctr", "aes-256-ecb", "aes-256-gcm",
                                        "aes-256-ofb", "aes-256-xts", "aes128", "aes192", "aes256", "bf", "bf-cbc", "bf-cfb", "bf-ecb", "bf-ofb", "blowfish",
                                        "camellia-128-cbc", "camellia-128-cfb", "camellia-128-cfb1", "camellia-128-cfb8", "camellia-128-ecb", "camellia-128-ofb",
                                        "camellia-192-cbc", "camellia-192-cfb", "camellia-192-cfb1", "camellia-192-cfb8", "camellia-192-ecb", "camellia-192-ofb",
                                        "camellia-256-cbc", "camellia-256-cfb", "camellia-256-cfb1", "camellia-256-cfb8", "camellia-256-ecb", "camellia-256-ofb",
                                        "camellia128", "camellia192", "camellia256", "cast", "cast-cbc", "cast5-cbc", "cast5-cfb", "cast5-ecb", "cast5-ofb", "des",
                                        "des-cbc", "des-cfb", "des-cfb1", "des-cfb8", "des-ecb", "des-ede", "des-ede-cbc", "des-ede-cfb", "des-ede-ofb", "des-ede3",
                                        "des-ede3-cbc", "des-ede3-cfb", "des-ede3-cfb1", "des-ede3-cfb8", "des-ede3-ofb", "des-ofb", "des3", "desx", "desx-cbc",
                                        "id-aes128-GCM", "id-aes192-GCM", "id-aes256-GCM", "rc2", "rc2-40-cbc", "rc2-64-cbc", "rc2-cbc", "rc2-cfb", "rc2-ecb",
                                        "rc2-ofb", "rc4", "rc4-40", "rc4-hmac-md5", "seed", "seed-cbc", "seed-cfb", "seed-ecb", "seed-ofb"};

    QList<DbPluginOption> opts;

    DbPluginOption opt;
    opt.type = DbPluginOption::PASSWORD;
    opt.key = PASSWORD_OPT;
    opt.label = tr("Password (key)");
    opt.toolTip = tr("Leave empty to create or connect to decrypted database.");
    opt.placeholderText = tr("Encryption password");
    opts << opt;

    opt.type = DbPluginOption::CHOICE;
    opt.key = CIPHER_OPT;
    opt.label = tr("Cipher");
    opt.toolTip = tr("Must be the same as the one used when creating the database. %1 is the default one.").arg(DEF_CIPHER);
    opt.choiceValues = ciphers;
    opt.defaultValue = DEF_CIPHER;
    opt.choiceReadOnly = true;
    opts << opt;

    opt.type = DbPluginOption::INT;
    opt.key = KDF_ITER_OPT;
    opt.label = tr("KDF iterations");
    opt.defaultValue = DEF_KDF_ITER;
    opt.minValue = 0;
    opt.maxValue = std::numeric_limits<int>::max();
    opt.toolTip = tr("Must be the same as the one used when creating the database. %1 is the default.").arg(QString::number(DEF_KDF_ITER));
    opts << opt;

    opt.type = DbPluginOption::INT;
    opt.key = CIPHER_PAGE_SIZE_OPT;
    opt.label = tr("Cipher page size");
    opt.defaultValue = DEF_CIPHER_PAGE_SIZE;
    opt.minValue = 0;
    opt.maxValue = std::numeric_limits<int>::max();
    opt.toolTip = tr("Must be the same as the one used when creating the database. %1 is the default.").arg(QString::number(DEF_CIPHER_PAGE_SIZE));
    opts << opt;

    opt.type = DbPluginOption::BOOL;
    opt.key = CIPHER_1_1_OPT;
    opt.label = tr("1.1 compatibility");
    opt.defaultValue = false;
    opt.toolTip = tr("Enabling this option disables HMAC checks introduced in SQLCipher 2.0, thus making the connection compatible with SQLCipher 1.1.x.");
    opts << opt;

    return opts;
}

QString DbSqliteCipher::generateDbName(const QVariant& baseValue)
{
    QFileInfo file(baseValue.toString());
    return file.baseName();
}

bool DbSqliteCipher::init()
{
    Q_INIT_RESOURCE(dbsqlitecipher);

    if (!SQLITESTUDIO->getExtraLicenseManager()->addLicense(LICENSE_TITLE, ":/license/sqlcipher.txt"))
    {
        qCritical() << "Could not register SQLCipher license.";
        return false;
    }

    if (!SQLITESTUDIO->getExtraLicenseManager()->addLicense(OPENSSL_TITLE, ":/license/openssl_lic.txt"))
    {
        qCritical() << "Could not register OpenSSL license.";
        return false;
    }

    initValid = true;
    return true;
}

void DbSqliteCipher::deinit()
{
    SQLITESTUDIO->getExtraLicenseManager()->removeLicense(LICENSE_TITLE);
    Q_CLEANUP_RESOURCE(dbsqlitecipher);
}