2
* Copyright (C) 2003-2007 Justin Karneges <justin@affinix.com>
3
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23
#include "qca_plugin.h"
24
#include "qca_textfilter.h"
26
#include "qca_keystore.h"
27
#include "qcaprovider.h"
29
// for qAddPostRoutine
30
#include <QCoreApplication>
34
#include <QVariantMap>
35
#include <QWaitCondition>
49
bool botan_init(int prealloc, bool mmap);
53
Provider *create_default_provider();
55
//----------------------------------------------------------------------------
57
//----------------------------------------------------------------------------
66
ProviderManager *manager;
71
QVariantMap properties;
73
QMap<QString,QVariantMap> config;
83
manager = new ProviderManager;
88
KeyStoreManager::shutdown();
97
void ensure_first_scan()
120
KeyStoreManager::scan();
124
Q_GLOBAL_STATIC(QMutex, global_mutex)
125
static Global *global = 0;
127
static bool features_have(const QStringList &have, const QStringList &want)
129
foreach(const QString &i, want)
131
if(!have.contains(i))
137
void init(MemoryMode mode, int prealloc)
139
QMutexLocker locker(global_mutex());
146
bool allow_mmap_fallback = false;
147
bool drop_root = false;
148
if(mode == Practical)
150
allow_mmap_fallback = true;
153
else if(mode == Locking)
156
bool secmem = botan_init(prealloc, allow_mmap_fallback);
166
global->secmem = secmem;
169
// for maximum setuid safety, qca should be initialized before qapp:
171
// int main(int argc, char **argv)
173
// QCA::Initializer init;
174
// QCoreApplication app(argc, argv);
178
// however, the above code has the unfortunate side-effect of causing
179
// qapp to deinit before qca, which can cause problems with any
180
// plugins that have active objects (notably KeyStore). we'll use a
181
// post routine to force qca to deinit first.
182
qAddPostRoutine(deinit);
184
global->manager->setDefault(create_default_provider()); // manager owns it
194
QMutexLocker locker(global_mutex());
198
if(global->refs == 0)
206
static bool global_check()
214
QMutex *global_random_mutex()
216
return &global->rng_mutex;
219
Random *global_random()
222
global->rng = new Random;
226
bool haveSecureMemory()
231
return global->secmem;
234
bool haveSecureRandom()
239
QMutexLocker locker(global_random_mutex());
240
if(global_random()->provider()->name() != "default")
246
bool isSupported(const QStringList &features, const QString &provider)
252
if(!provider.isEmpty())
254
Provider *p = global->manager->find(provider);
257
// ok, try scanning for new stuff
259
p = global->manager->find(provider);
262
if(p && features_have(p->features(), features))
268
if(features_have(global->manager->allFeatures(), features))
271
// ok, try scanning for new stuff
274
if(features_have(global->manager->allFeatures(), features))
280
bool isSupported(const char *features, const QString &provider)
282
return isSupported(QString(features).split(',', QString::SkipEmptyParts), provider);
285
QStringList supportedFeatures()
288
return QStringList();
290
// query all features
292
return global->manager->allFeatures();
295
QStringList defaultFeatures()
298
return QStringList();
300
return global->manager->find("default")->features();
303
ProviderList providers()
306
return ProviderList();
308
global->ensure_first_scan();
310
return global->manager->providers();
313
bool insertProvider(Provider *p, int priority)
318
global->ensure_first_scan();
320
return global->manager->add(p, priority);
323
void setProviderPriority(const QString &name, int priority)
328
global->ensure_first_scan();
330
global->manager->changePriority(name, priority);
333
int providerPriority(const QString &name)
338
global->ensure_first_scan();
340
return global->manager->getPriority(name);
343
Provider *findProvider(const QString &name)
348
global->ensure_first_scan();
350
return global->manager->find(name);
353
Provider *defaultProvider()
358
return global->manager->find("default");
361
void scanForPlugins()
370
void unloadAllPlugins()
375
// if the global_rng was owned by a plugin, then delete it
376
global->rng_mutex.lock();
377
if(global->rng && (global->rng->provider() != global->manager->find("default")))
382
global->rng_mutex.unlock();
384
global->manager->unloadAll();
387
QString pluginDiagnosticText()
392
return global->manager->diagnosticText();
395
void clearPluginDiagnosticText()
400
global->manager->clearDiagnosticText();
403
void appendPluginDiagnosticText(const QString &text)
408
global->manager->appendDiagnosticText(text);
411
void setProperty(const QString &name, const QVariant &value)
416
QMutexLocker locker(&global->prop_mutex);
418
global->properties[name] = value;
421
QVariant getProperty(const QString &name)
426
QMutexLocker locker(&global->prop_mutex);
428
return global->properties.value(name);
431
static bool configIsValid(const QVariantMap &config)
433
if(!config.contains("formtype"))
435
QMapIterator<QString,QVariant> it(config);
439
const QVariant &v = it.value();
440
if(v.type() != QVariant::String && v.type() != QVariant::Int && v.type() != QVariant::Bool)
446
static QVariantMap readConfig(const QString &name)
448
QSettings settings("Affinix", "QCA2");
449
settings.beginGroup("ProviderConfig");
450
QStringList providerNames = settings.value("providerNames").toStringList();
451
if(!providerNames.contains(name))
452
return QVariantMap();
454
settings.beginGroup(name);
455
QStringList keys = settings.childKeys();
457
foreach(QString key, keys)
458
map[key] = settings.value(key);
461
if(!configIsValid(map))
462
return QVariantMap();
466
static bool writeConfig(const QString &name, const QVariantMap &config, bool systemWide = false)
468
QSettings settings(QSettings::NativeFormat, systemWide ? QSettings::SystemScope : QSettings::UserScope, "Affinix", "QCA2");
469
settings.beginGroup("ProviderConfig");
472
settings.setValue("version", 2);
474
// add the entry if needed
475
QStringList providerNames = settings.value("providerNames").toStringList();
476
if(!providerNames.contains(name))
477
providerNames += name;
478
settings.setValue("providerNames", providerNames);
480
settings.beginGroup(name);
481
QMapIterator<QString,QVariant> it(config);
485
settings.setValue(it.key(), it.value());
489
if(settings.status() == QSettings::NoError)
494
void setProviderConfig(const QString &name, const QVariantMap &config)
499
if(!configIsValid(config))
502
global->config_mutex.lock();
503
global->config[name] = config;
504
global->config_mutex.unlock();
506
Provider *p = findProvider(name);
508
p->configChanged(config);
511
QVariantMap getProviderConfig(const QString &name)
514
return QVariantMap();
518
global->config_mutex.lock();
520
// try loading from persistent storage
521
conf = readConfig(name);
523
// if not, load the one from memory
525
conf = global->config.value(name);
527
global->config_mutex.unlock();
529
// if provider doesn't exist or doesn't have a valid config form,
530
// use the config we loaded
531
Provider *p = findProvider(name);
534
QVariantMap pconf = p->defaultConfig();
535
if(!configIsValid(pconf))
538
// if the config loaded was empty, use the provider's config
542
// if the config formtype doesn't match the provider's formtype,
543
// then use the provider's
544
if(pconf["formtype"] != conf["formtype"])
547
// otherwise, use the config loaded
551
void saveProviderConfig(const QString &name)
556
QMutexLocker locker(&global->config_mutex);
558
QVariantMap conf = global->config.value(name);
562
writeConfig(name, conf);
565
QVariantMap getProviderConfig_internal(Provider *p)
568
QString name = p->name();
570
global->config_mutex.lock();
572
// try loading from persistent storage
573
conf = readConfig(name);
575
// if not, load the one from memory
577
conf = global->config.value(name);
579
global->config_mutex.unlock();
581
// if provider doesn't exist or doesn't have a valid config form,
582
// use the config we loaded
583
QVariantMap pconf = p->defaultConfig();
584
if(!configIsValid(pconf))
587
// if the config loaded was empty, use the provider's config
591
// if the config formtype doesn't match the provider's formtype,
592
// then use the provider's
593
if(pconf["formtype"] != conf["formtype"])
596
// otherwise, use the config loaded
600
QString globalRandomProvider()
602
QMutexLocker locker(global_random_mutex());
603
return global_random()->provider()->name();
606
void setGlobalRandomProvider(const QString &provider)
608
QMutexLocker locker(global_random_mutex());
610
global->rng = new Random(provider);
615
return global->logger;
618
bool haveSystemStore()
620
// ensure the system store is loaded
621
KeyStoreManager::start("default");
623
ksm.waitForBusyFinished();
625
QStringList list = ksm.keyStores();
626
for(int n = 0; n < list.count(); ++n)
628
KeyStore ks(list[n], &ksm);
629
if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates())
635
CertificateCollection systemStore()
637
// ensure the system store is loaded
638
KeyStoreManager::start("default");
640
ksm.waitForBusyFinished();
642
CertificateCollection col;
643
QStringList list = ksm.keyStores();
644
for(int n = 0; n < list.count(); ++n)
646
KeyStore ks(list[n], &ksm);
649
if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates())
652
QList<KeyStoreEntry> entries = ks.entryList();
653
for(int i = 0; i < entries.count(); ++i)
655
if(entries[i].type() == KeyStoreEntry::TypeCertificate)
656
col.addCertificate(entries[i].certificate());
657
else if(entries[i].type() == KeyStoreEntry::TypeCRL)
658
col.addCRL(entries[i].crl());
671
QMutexLocker locker(&global->name_mutex);
673
return global->app_name;
676
void setAppName(const QString &s)
681
QMutexLocker locker(&global->name_mutex);
683
global->app_name = s;
686
QString arrayToHex(const QByteArray &a)
688
return Hex().arrayToString(a);
691
QByteArray hexToArray(const QString &str)
693
return Hex().stringToArray(str).toByteArray();
696
static Provider *getProviderForType(const QString &type, const QString &provider)
699
bool scanned = false;
700
if(!provider.isEmpty())
702
// try using specific provider
703
p = global->manager->findFor(provider, type);
706
// maybe this provider is new, so scan and try again
709
p = global->manager->findFor(provider, type);
714
// try using some other provider
715
p = global->manager->findFor(QString(), type);
716
if((!p || p->name() == "default") && !scanned)
718
// maybe there are new providers, so scan and try again
719
// before giving up or using default
722
p = global->manager->findFor(QString(), type);
729
static inline Provider::Context *doCreateContext(Provider *p, const QString &type)
731
return p->createContext(type);
734
Provider::Context *getContext(const QString &type, const QString &provider)
741
p = getProviderForType(type, provider);
746
return doCreateContext(p, type);
749
Provider::Context *getContext(const QString &type, Provider *_p)
756
p = global->manager->find(_p);
761
return doCreateContext(p, type);
764
//----------------------------------------------------------------------------
766
//----------------------------------------------------------------------------
767
Initializer::Initializer(MemoryMode m, int prealloc)
772
Initializer::~Initializer()
777
//----------------------------------------------------------------------------
779
//----------------------------------------------------------------------------
780
Provider::~Provider()
784
void Provider::init()
788
void Provider::deinit()
792
int Provider::version() const
797
QString Provider::credit() const
802
QVariantMap Provider::defaultConfig() const
804
return QVariantMap();
807
void Provider::configChanged(const QVariantMap &)
811
Provider::Context::Context(Provider *parent, const QString &type)
818
Provider::Context::Context(const Context &from)
821
_provider = from._provider;
825
Provider::Context::~Context()
829
Provider *Provider::Context::provider() const
834
QString Provider::Context::type() const
839
bool Provider::Context::sameProvider(const Context *c) const
841
return (c->provider() == _provider);
844
//----------------------------------------------------------------------------
846
//----------------------------------------------------------------------------
847
BasicContext::BasicContext(Provider *parent, const QString &type)
848
:Context(parent, type)
850
moveToThread(0); // no thread association
853
BasicContext::BasicContext(const BasicContext &from)
856
moveToThread(0); // no thread association
859
BasicContext::~BasicContext()
863
//----------------------------------------------------------------------------
865
//----------------------------------------------------------------------------
866
QStringList InfoContext::supportedHashTypes() const
868
return QStringList();
871
QStringList InfoContext::supportedCipherTypes() const
873
return QStringList();
876
QStringList InfoContext::supportedMACTypes() const
878
return QStringList();
881
//----------------------------------------------------------------------------
883
//----------------------------------------------------------------------------
884
PKeyBase::PKeyBase(Provider *p, const QString &type)
885
:BasicContext(p, type)
889
int PKeyBase::maximumEncryptSize(EncryptionAlgorithm) const
894
SecureArray PKeyBase::encrypt(const SecureArray &, EncryptionAlgorithm)
896
return SecureArray();
899
bool PKeyBase::decrypt(const SecureArray &, SecureArray *, EncryptionAlgorithm)
904
void PKeyBase::startSign(SignatureAlgorithm, SignatureFormat)
908
void PKeyBase::startVerify(SignatureAlgorithm, SignatureFormat)
912
void PKeyBase::update(const MemoryRegion &)
916
QByteArray PKeyBase::endSign()
921
bool PKeyBase::endVerify(const QByteArray &)
926
SymmetricKey PKeyBase::deriveKey(const PKeyBase &)
928
return SymmetricKey();
931
//----------------------------------------------------------------------------
933
//----------------------------------------------------------------------------
934
QByteArray PKeyContext::publicToDER() const
939
QString PKeyContext::publicToPEM() const
944
ConvertResult PKeyContext::publicFromDER(const QByteArray &)
949
ConvertResult PKeyContext::publicFromPEM(const QString &)
954
SecureArray PKeyContext::privateToDER(const SecureArray &, PBEAlgorithm) const
956
return SecureArray();
959
QString PKeyContext::privateToPEM(const SecureArray &, PBEAlgorithm) const
964
ConvertResult PKeyContext::privateFromDER(const SecureArray &, const SecureArray &)
969
ConvertResult PKeyContext::privateFromPEM(const QString &, const SecureArray &)
974
//----------------------------------------------------------------------------
975
// KeyStoreEntryContext
976
//----------------------------------------------------------------------------
977
bool KeyStoreEntryContext::isAvailable() const
982
KeyBundle KeyStoreEntryContext::keyBundle() const
987
Certificate KeyStoreEntryContext::certificate() const
989
return Certificate();
992
CRL KeyStoreEntryContext::crl() const
997
PGPKey KeyStoreEntryContext::pgpSecretKey() const
1002
PGPKey KeyStoreEntryContext::pgpPublicKey() const
1007
bool KeyStoreEntryContext::ensureAccess()
1012
//----------------------------------------------------------------------------
1013
// KeyStoreListContext
1014
//----------------------------------------------------------------------------
1015
void KeyStoreListContext::start()
1017
QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection);
1020
void KeyStoreListContext::setUpdatesEnabled(bool)
1024
bool KeyStoreListContext::isReadOnly(int) const
1029
KeyStoreEntryContext *KeyStoreListContext::entry(int id, const QString &entryId)
1031
KeyStoreEntryContext *out = 0;
1032
QList<KeyStoreEntryContext*> list = entryList(id);
1033
for(int n = 0; n < list.count(); ++n)
1035
if(list[n]->id() == entryId)
1037
out = list.takeAt(n);
1045
KeyStoreEntryContext *KeyStoreListContext::entryPassive(const QString &serialized)
1047
Q_UNUSED(serialized);
1051
QString KeyStoreListContext::writeEntry(int, const KeyBundle &)
1056
QString KeyStoreListContext::writeEntry(int, const Certificate &)
1061
QString KeyStoreListContext::writeEntry(int, const CRL &)
1066
QString KeyStoreListContext::writeEntry(int, const PGPKey &)
1071
bool KeyStoreListContext::removeEntry(int, const QString &)
1076
//----------------------------------------------------------------------------
1078
//----------------------------------------------------------------------------
1079
void TLSContext::setMTU(int)
1083
//----------------------------------------------------------------------------
1085
//----------------------------------------------------------------------------
1086
QString MessageContext::diagnosticText() const
1091
//----------------------------------------------------------------------------
1093
//----------------------------------------------------------------------------
1094
void SMSContext::setTrustedCertificates(const CertificateCollection &)
1098
void SMSContext::setUntrustedCertificates(const CertificateCollection &)
1102
void SMSContext::setPrivateKeys(const QList<SecureMessageKey> &)
1106
//----------------------------------------------------------------------------
1107
// BufferedComputation
1108
//----------------------------------------------------------------------------
1109
BufferedComputation::~BufferedComputation()
1113
MemoryRegion BufferedComputation::process(const MemoryRegion &a)
1120
//----------------------------------------------------------------------------
1122
//----------------------------------------------------------------------------
1127
MemoryRegion Filter::process(const MemoryRegion &a)
1130
MemoryRegion buf = update(a);
1132
return MemoryRegion();
1133
MemoryRegion fin = final();
1135
return MemoryRegion();
1136
if(buf.isSecure() || fin.isSecure())
1137
return (SecureArray(buf) + SecureArray(fin));
1139
return (buf.toByteArray() + fin.toByteArray());
1142
//----------------------------------------------------------------------------
1144
//----------------------------------------------------------------------------
1145
class Algorithm::Private : public QSharedData
1148
Provider::Context *c;
1150
Private(Provider::Context *context)
1153
//printf("** [%p] Algorithm Created\n", c);
1156
Private(const Private &from) : QSharedData(from)
1158
c = from.c->clone();
1159
//printf("** [%p] Algorithm Copied (to [%p])\n", from.c, c);
1164
//printf("** [%p] Algorithm Destroyed\n", c);
1169
Algorithm::Algorithm()
1173
Algorithm::Algorithm(const QString &type, const QString &provider)
1175
change(type, provider);
1178
Algorithm::Algorithm(const Algorithm &from)
1183
Algorithm::~Algorithm()
1187
Algorithm & Algorithm::operator=(const Algorithm &from)
1193
QString Algorithm::type() const
1196
return d->c->type();
1201
Provider *Algorithm::provider() const
1204
return d->c->provider();
1209
Provider::Context *Algorithm::context()
1217
const Provider::Context *Algorithm::context() const
1225
void Algorithm::change(Provider::Context *c)
1233
void Algorithm::change(const QString &type, const QString &provider)
1236
change(getContext(type, provider));
1241
Provider::Context *Algorithm::takeContext()
1245
Provider::Context *c = d->c; // should cause a detach
1254
//----------------------------------------------------------------------------
1256
//----------------------------------------------------------------------------
1257
SymmetricKey::SymmetricKey()
1261
SymmetricKey::SymmetricKey(int size)
1263
set(Random::randomArray(size));
1266
SymmetricKey::SymmetricKey(const SecureArray &a)
1271
SymmetricKey::SymmetricKey(const QByteArray &a)
1273
set(SecureArray(a));
1276
/* from libgcrypt-1.2.0 */
1277
static unsigned char desWeakKeyTable[64][8] =
1279
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/
1280
{ 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
1281
{ 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
1282
{ 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
1283
{ 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/
1284
{ 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
1285
{ 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
1286
{ 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
1287
{ 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/
1288
{ 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
1289
{ 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
1290
{ 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
1291
{ 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/
1292
{ 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
1293
{ 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
1294
{ 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
1295
{ 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
1296
{ 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/
1297
{ 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
1298
{ 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
1299
{ 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
1300
{ 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/
1301
{ 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
1302
{ 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
1303
{ 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
1304
{ 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/
1305
{ 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
1306
{ 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
1307
{ 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
1308
{ 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/
1309
{ 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
1310
{ 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
1311
{ 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
1312
{ 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
1313
{ 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/
1314
{ 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
1315
{ 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
1316
{ 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
1317
{ 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/
1318
{ 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
1319
{ 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
1320
{ 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
1321
{ 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/
1322
{ 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
1323
{ 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
1324
{ 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
1325
{ 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/
1326
{ 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
1327
{ 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
1328
{ 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
1329
{ 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
1330
{ 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/
1331
{ 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
1332
{ 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
1333
{ 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
1334
{ 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/
1335
{ 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
1336
{ 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
1337
{ 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
1338
{ 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/
1339
{ 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
1340
{ 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
1341
{ 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
1342
{ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe } /*w*/
1345
bool SymmetricKey::isWeakDESKey()
1348
return false; // dubious
1349
SecureArray workingCopy(8);
1350
// clear parity bits
1351
for(uint i = 0; i < 8; i++)
1352
workingCopy[i] = (data()[i]) & 0xfe;
1354
for(int n = 0; n < 64; n++)
1356
if(memcmp(workingCopy.data(), desWeakKeyTable[n], 8) == 0)
1362
//----------------------------------------------------------------------------
1363
// InitializationVector
1364
//----------------------------------------------------------------------------
1365
InitializationVector::InitializationVector()
1369
InitializationVector::InitializationVector(int size)
1371
set(Random::randomArray(size));
1374
InitializationVector::InitializationVector(const SecureArray &a)
1379
InitializationVector::InitializationVector(const QByteArray &a)
1381
set(SecureArray(a));
1384
//----------------------------------------------------------------------------
1386
//----------------------------------------------------------------------------
1387
class Event::Private : public QSharedData
1392
PasswordStyle style;
1403
Event::Event(const Event &from)
1412
Event & Event::operator=(const Event &from)
1418
bool Event::isNull() const
1420
return (d ? false : true);
1423
Event::Type Event::type() const
1428
Event::Source Event::source() const
1433
Event::PasswordStyle Event::passwordStyle() const
1438
KeyStoreInfo Event::keyStoreInfo() const
1443
KeyStoreEntry Event::keyStoreEntry() const
1448
QString Event::fileName() const
1453
void *Event::ptr() const
1458
void Event::setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
1463
d->source = KeyStore;
1465
d->ksi = keyStoreInfo;
1466
d->kse = keyStoreEntry;
1467
d->fname = QString();
1471
void Event::setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr)
1478
d->ksi = KeyStoreInfo();
1479
d->kse = KeyStoreEntry();
1480
d->fname = fileName;
1484
void Event::setToken(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
1489
d->source = KeyStore;
1490
d->style = StylePassword;
1491
d->ksi = keyStoreInfo;
1492
d->kse = keyStoreEntry;
1493
d->fname = QString();
1497
//----------------------------------------------------------------------------
1499
//----------------------------------------------------------------------------
1500
class HandlerBase : public QObject
1504
HandlerBase(QObject *parent = 0) : QObject(parent)
1509
virtual void ask(int id, const QCA::Event &e) = 0;
1512
class AskerBase : public QObject
1516
AskerBase(QObject *parent = 0) : QObject(parent)
1520
virtual void set_accepted(const SecureArray &password) = 0;
1521
virtual void set_rejected() = 0;
1524
static void handler_add(HandlerBase *h, int pos = -1);
1525
static void handler_remove(HandlerBase *h);
1526
static void handler_accept(HandlerBase *h, int id, const SecureArray &password);
1527
static void handler_reject(HandlerBase *h, int id);
1528
static bool asker_ask(AskerBase *a, const Event &e);
1529
static void asker_cancel(AskerBase *a);
1531
Q_GLOBAL_STATIC(QMutex, g_event_mutex)
1534
static EventGlobal *g_event = 0;
1555
QList<HandlerItem> handlers;
1556
QList<AskerItem> askers;
1562
qRegisterMetaType<Event>("QCA::Event");
1563
qRegisterMetaType<SecureArray>("QCA::SecureArray");
1567
int findHandlerItem(HandlerBase *h)
1569
for(int n = 0; n < handlers.count(); ++n)
1571
if(handlers[n].h == h)
1577
int findAskerItem(AskerBase *a)
1579
for(int n = 0; n < askers.count(); ++n)
1581
if(askers[n].a == a)
1587
int findAskerItemById(int id)
1589
for(int n = 0; n < askers.count(); ++n)
1591
if(askers[n].id == id)
1597
void ask(int asker_at)
1599
AskerItem &i = askers[asker_at];
1601
g_event->handlers[i.handler_pos].ids += i.id;
1602
QMetaObject::invokeMethod(handlers[i.handler_pos].h, "ask",
1603
Qt::QueuedConnection, Q_ARG(int, i.id),
1604
Q_ARG(QCA::Event, i.event));
1607
void reject(int asker_at)
1609
AskerItem &i = askers[asker_at];
1611
// look for the next usable handler
1613
for(int n = i.handler_pos + 1; n < g_event->handlers.count(); ++n)
1615
// handler and asker can't be in the same thread
1616
//Q_ASSERT(g_event->handlers[n].h->thread() != i.a->thread());
1617
//if(g_event->handlers[n].h->thread() != i.a->thread())
1624
// if there is one, try it
1627
i.handler_pos = pos;
1630
// if not, send official reject
1633
AskerBase *asker = i.a;
1634
askers.removeAt(asker_at);
1636
asker->set_rejected();
1641
void handler_add(HandlerBase *h, int pos)
1643
QMutexLocker locker(g_event_mutex());
1645
g_event = new EventGlobal;
1647
EventGlobal::HandlerItem i;
1652
g_event->handlers.insert(pos, i);
1654
// adjust handler positions
1655
for(int n = 0; n < g_event->askers.count(); ++n)
1657
if(g_event->askers[n].handler_pos >= pos)
1658
g_event->askers[n].handler_pos++;
1662
g_event->handlers += i;
1665
void handler_remove(HandlerBase *h)
1667
QMutexLocker locker(g_event_mutex());
1671
int at = g_event->findHandlerItem(h);
1676
QList<int> ids = g_event->handlers[at].ids;
1677
g_event->handlers.removeAt(at);
1679
// adjust handler positions within askers
1680
for(int n = 0; n < g_event->askers.count(); ++n)
1682
if(g_event->askers[n].handler_pos >= at)
1683
g_event->askers[n].handler_pos--;
1686
// reject all askers
1687
foreach(int id, ids)
1689
int asker_at = g_event->findAskerItemById(id);
1690
Q_ASSERT(asker_at != -1);
1692
g_event->reject(asker_at);
1695
if(g_event->handlers.isEmpty())
1702
void handler_accept(HandlerBase *h, int id, const SecureArray &password)
1704
QMutexLocker locker(g_event_mutex());
1708
int at = g_event->findHandlerItem(h);
1712
int asker_at = g_event->findAskerItemById(id);
1713
Q_ASSERT(asker_at != -1);
1717
g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id);
1719
AskerBase *asker = g_event->askers[asker_at].a;
1720
asker->set_accepted(password);
1723
void handler_reject(HandlerBase *h, int id)
1725
QMutexLocker locker(g_event_mutex());
1729
int at = g_event->findHandlerItem(h);
1733
int asker_at = g_event->findAskerItemById(id);
1734
Q_ASSERT(asker_at != -1);
1738
g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id);
1740
g_event->reject(asker_at);
1743
bool asker_ask(AskerBase *a, const Event &e)
1745
QMutexLocker locker(g_event_mutex());
1750
for(int n = 0; n < g_event->handlers.count(); ++n)
1752
// handler and asker can't be in the same thread
1753
//Q_ASSERT(g_event->handlers[n].h->thread() != a->thread());
1754
//if(g_event->handlers[n].h->thread() != a->thread())
1763
EventGlobal::AskerItem i;
1765
i.id = g_event->next_id++;
1767
i.handler_pos = pos;
1768
g_event->askers += i;
1769
int asker_at = g_event->askers.count() - 1;
1771
g_event->ask(asker_at);
1775
void asker_cancel(AskerBase *a)
1777
QMutexLocker locker(g_event_mutex());
1780
int at = g_event->findAskerItem(a);
1784
for(int n = 0; n < g_event->handlers.count(); ++n)
1785
g_event->handlers[n].ids.removeAll(g_event->askers[at].id);
1787
g_event->askers.removeAt(at);
1790
//----------------------------------------------------------------------------
1792
//----------------------------------------------------------------------------
1793
class EventHandler::Private : public HandlerBase
1799
QList<int> activeIds;
1801
Private(EventHandler *_q) : HandlerBase(_q), q(_q)
1807
virtual void ask(int id, const QCA::Event &e)
1810
emit q->eventReady(id, e);
1814
EventHandler::EventHandler(QObject *parent)
1817
d = new Private(this);
1820
EventHandler::~EventHandler()
1824
foreach(int id, d->activeIds)
1825
handler_reject(d, id);
1833
void EventHandler::start()
1839
void EventHandler::submitPassword(int id, const SecureArray &password)
1841
if(!d->activeIds.contains(id))
1844
d->activeIds.removeAll(id);
1845
handler_accept(d, id, password);
1848
void EventHandler::tokenOkay(int id)
1850
if(!d->activeIds.contains(id))
1853
d->activeIds.removeAll(id);
1854
handler_accept(d, id, SecureArray());
1857
void EventHandler::reject(int id)
1859
if(!d->activeIds.contains(id))
1862
d->activeIds.removeAll(id);
1863
handler_reject(d, id);
1866
//----------------------------------------------------------------------------
1868
//----------------------------------------------------------------------------
1869
class AskerPrivate : public AskerBase
1873
enum Type { Password, Token };
1876
PasswordAsker *passwordAsker;
1877
TokenAsker *tokenAsker;
1883
SecureArray password;
1887
AskerPrivate(PasswordAsker *parent) : AskerBase(parent)
1889
passwordAsker = parent;
1897
AskerPrivate(TokenAsker *parent) : AskerBase(parent)
1900
tokenAsker = parent;
1907
void ask(const Event &e)
1914
if(!asker_ask(this, e))
1917
QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
1927
virtual void set_accepted(const SecureArray &_password)
1929
QMutexLocker locker(&m);
1931
password = _password;
1936
QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
1939
virtual void set_rejected()
1941
QMutexLocker locker(&m);
1946
QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
1949
void waitForResponse()
1951
QMutexLocker locker(&m);
1960
virtual void emitResponseReady() = 0;
1963
class PasswordAsker::Private : public AskerPrivate
1966
Private(PasswordAsker *_q) : AskerPrivate(_q)
1970
virtual void emitResponseReady()
1972
emit passwordAsker->responseReady();
1976
PasswordAsker::PasswordAsker(QObject *parent)
1979
d = new Private(this);
1982
PasswordAsker::~PasswordAsker()
1987
void PasswordAsker::ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
1990
e.setPasswordKeyStore(pstyle, keyStoreInfo, keyStoreEntry, ptr);
1994
void PasswordAsker::ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr)
1997
e.setPasswordData(pstyle, fileName, ptr);
2001
void PasswordAsker::cancel()
2006
void PasswordAsker::waitForResponse()
2008
d->waitForResponse();
2011
bool PasswordAsker::accepted() const
2016
SecureArray PasswordAsker::password() const
2021
//----------------------------------------------------------------------------
2023
//----------------------------------------------------------------------------
2024
class TokenAsker::Private : public AskerPrivate
2027
Private(TokenAsker *_q) : AskerPrivate(_q)
2031
virtual void emitResponseReady()
2033
emit tokenAsker->responseReady();
2037
TokenAsker::TokenAsker(QObject *parent)
2040
d = new Private(this);
2043
TokenAsker::~TokenAsker()
2048
void TokenAsker::ask(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
2051
e.setToken(keyStoreInfo, keyStoreEntry, ptr);
2055
void TokenAsker::cancel()
2060
void TokenAsker::waitForResponse()
2062
d->waitForResponse();
2065
bool TokenAsker::accepted() const
2072
#include "qca_core.moc"