~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to third-party/qca/qca/src/qca_core.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
 
3
 * Copyright (C) 2004,2005  Brad Hards <bradh@frogmouth.net>
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 */
 
20
 
 
21
#include "qca_core.h"
 
22
 
 
23
#include "qca_plugin.h"
 
24
#include "qca_textfilter.h"
 
25
#include "qca_cert.h"
 
26
#include "qca_keystore.h"
 
27
#include "qcaprovider.h"
 
28
 
 
29
// for qAddPostRoutine
 
30
#include <QCoreApplication>
 
31
 
 
32
#include <QMutex>
 
33
#include <QSettings>
 
34
#include <QVariantMap>
 
35
#include <QWaitCondition>
 
36
 
 
37
#ifdef Q_OS_UNIX
 
38
# include <unistd.h>
 
39
#endif
 
40
 
 
41
int qcaVersion()
 
42
{
 
43
        return QCA_VERSION;
 
44
}
 
45
 
 
46
namespace QCA {
 
47
 
 
48
// from qca_tools
 
49
bool botan_init(int prealloc, bool mmap);
 
50
void botan_deinit();
 
51
 
 
52
// from qca_default
 
53
Provider *create_default_provider();
 
54
 
 
55
//----------------------------------------------------------------------------
 
56
// Global
 
57
//----------------------------------------------------------------------------
 
58
class Global
 
59
{
 
60
public:
 
61
        int refs;
 
62
        bool secmem;
 
63
        bool first_scan;
 
64
        QString app_name;
 
65
        QMutex name_mutex;
 
66
        ProviderManager *manager;
 
67
        QMutex scan_mutex;
 
68
        Random *rng;
 
69
        QMutex rng_mutex;
 
70
        Logger *logger;
 
71
        QVariantMap properties;
 
72
        QMutex prop_mutex;
 
73
        QMap<QString,QVariantMap> config;
 
74
        QMutex config_mutex;
 
75
 
 
76
        Global()
 
77
        {
 
78
                refs = 0;
 
79
                secmem = false;
 
80
                first_scan = false;
 
81
                rng = 0;
 
82
                logger = new Logger;
 
83
                manager = new ProviderManager;
 
84
        }
 
85
 
 
86
        ~Global()
 
87
        {
 
88
                KeyStoreManager::shutdown();
 
89
                delete rng;
 
90
                rng = 0;
 
91
                delete manager;
 
92
                manager = 0;
 
93
                delete logger;
 
94
                logger = 0;
 
95
        }
 
96
 
 
97
        void ensure_first_scan()
 
98
        {
 
99
                scan_mutex.lock();
 
100
                if(!first_scan)
 
101
                {
 
102
                        first_scan = true;
 
103
                        manager->scan();
 
104
                        scan_mutex.unlock();
 
105
                        return;
 
106
                }
 
107
                scan_mutex.unlock();
 
108
        }
 
109
 
 
110
        void scan()
 
111
        {
 
112
                scan_mutex.lock();
 
113
                first_scan = true;
 
114
                manager->scan();
 
115
                scan_mutex.unlock();
 
116
        }
 
117
 
 
118
        void ksm_scan()
 
119
        {
 
120
                KeyStoreManager::scan();
 
121
        }
 
122
};
 
123
 
 
124
Q_GLOBAL_STATIC(QMutex, global_mutex)
 
125
static Global *global = 0;
 
126
 
 
127
static bool features_have(const QStringList &have, const QStringList &want)
 
128
{
 
129
        foreach(const QString &i, want)
 
130
        {
 
131
                if(!have.contains(i))
 
132
                        return false;
 
133
        }
 
134
        return true;
 
135
}
 
136
 
 
137
void init(MemoryMode mode, int prealloc)
 
138
{
 
139
        QMutexLocker locker(global_mutex());
 
140
        if(global)
 
141
        {
 
142
                ++(global->refs);
 
143
                return;
 
144
        }
 
145
 
 
146
        bool allow_mmap_fallback = false;
 
147
        bool drop_root = false;
 
148
        if(mode == Practical)
 
149
        {
 
150
                allow_mmap_fallback = true;
 
151
                drop_root = true;
 
152
        }
 
153
        else if(mode == Locking)
 
154
                drop_root = true;
 
155
 
 
156
        bool secmem = botan_init(prealloc, allow_mmap_fallback);
 
157
 
 
158
        if(drop_root)
 
159
        {
 
160
#ifdef Q_OS_UNIX
 
161
                setuid(getuid());
 
162
#endif
 
163
        }
 
164
 
 
165
        global = new Global;
 
166
        global->secmem = secmem;
 
167
        ++(global->refs);
 
168
 
 
169
        // for maximum setuid safety, qca should be initialized before qapp:
 
170
        //
 
171
        //   int main(int argc, char **argv)
 
172
        //   {
 
173
        //       QCA::Initializer init;
 
174
        //       QCoreApplication app(argc, argv);
 
175
        //       return 0;
 
176
        //   }
 
177
        //
 
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);
 
183
 
 
184
        global->manager->setDefault(create_default_provider()); // manager owns it
 
185
}
 
186
 
 
187
void init()
 
188
{
 
189
        init(Practical, 64);
 
190
}
 
191
 
 
192
void deinit()
 
193
{
 
194
        QMutexLocker locker(global_mutex());
 
195
        if(!global)
 
196
                return;
 
197
        --(global->refs);
 
198
        if(global->refs == 0)
 
199
        {
 
200
                delete global;
 
201
                global = 0;
 
202
                botan_deinit();
 
203
        }
 
204
}
 
205
 
 
206
static bool global_check()
 
207
{
 
208
        Q_ASSERT(global);
 
209
        if(!global)
 
210
                return false;
 
211
        return true;
 
212
}
 
213
 
 
214
QMutex *global_random_mutex()
 
215
{
 
216
        return &global->rng_mutex;
 
217
}
 
218
 
 
219
Random *global_random()
 
220
{
 
221
        if(!global->rng)
 
222
                global->rng = new Random;
 
223
        return global->rng;
 
224
}
 
225
 
 
226
bool haveSecureMemory()
 
227
{
 
228
        if(!global_check())
 
229
                return false;
 
230
 
 
231
        return global->secmem;
 
232
}
 
233
 
 
234
bool haveSecureRandom()
 
235
{
 
236
        if(!global_check())
 
237
                return false;
 
238
 
 
239
        QMutexLocker locker(global_random_mutex());
 
240
        if(global_random()->provider()->name() != "default")
 
241
                return true;
 
242
 
 
243
        return false;
 
244
}
 
245
 
 
246
bool isSupported(const QStringList &features, const QString &provider)
 
247
{
 
248
        if(!global_check())
 
249
                return false;
 
250
 
 
251
        // single
 
252
        if(!provider.isEmpty())
 
253
        {
 
254
                Provider *p = global->manager->find(provider);
 
255
                if(!p)
 
256
                {
 
257
                        // ok, try scanning for new stuff
 
258
                        global->scan();
 
259
                        p = global->manager->find(provider);
 
260
                }
 
261
 
 
262
                if(p && features_have(p->features(), features))
 
263
                        return true;
 
264
        }
 
265
        // all
 
266
        else
 
267
        {
 
268
                if(features_have(global->manager->allFeatures(), features))
 
269
                        return true;
 
270
 
 
271
                // ok, try scanning for new stuff
 
272
                global->scan();
 
273
 
 
274
                if(features_have(global->manager->allFeatures(), features))
 
275
                        return true;
 
276
        }
 
277
        return false;
 
278
}
 
279
 
 
280
bool isSupported(const char *features, const QString &provider)
 
281
{
 
282
        return isSupported(QString(features).split(',', QString::SkipEmptyParts), provider);
 
283
}
 
284
 
 
285
QStringList supportedFeatures()
 
286
{
 
287
        if(!global_check())
 
288
                return QStringList();
 
289
 
 
290
        // query all features
 
291
        global->scan();
 
292
        return global->manager->allFeatures();
 
293
}
 
294
 
 
295
QStringList defaultFeatures()
 
296
{
 
297
        if(!global_check())
 
298
                return QStringList();
 
299
 
 
300
        return global->manager->find("default")->features();
 
301
}
 
302
 
 
303
ProviderList providers()
 
304
{
 
305
        if(!global_check())
 
306
                return ProviderList();
 
307
 
 
308
        global->ensure_first_scan();
 
309
 
 
310
        return global->manager->providers();
 
311
}
 
312
 
 
313
bool insertProvider(Provider *p, int priority)
 
314
{
 
315
        if(!global_check())
 
316
                return false;
 
317
 
 
318
        global->ensure_first_scan();
 
319
 
 
320
        return global->manager->add(p, priority);
 
321
}
 
322
 
 
323
void setProviderPriority(const QString &name, int priority)
 
324
{
 
325
        if(!global_check())
 
326
                return;
 
327
 
 
328
        global->ensure_first_scan();
 
329
 
 
330
        global->manager->changePriority(name, priority);
 
331
}
 
332
 
 
333
int providerPriority(const QString &name)
 
334
{
 
335
        if(!global_check())
 
336
                return -1;
 
337
 
 
338
        global->ensure_first_scan();
 
339
 
 
340
        return global->manager->getPriority(name);
 
341
}
 
342
 
 
343
Provider *findProvider(const QString &name)
 
344
{
 
345
        if(!global_check())
 
346
                return 0;
 
347
 
 
348
        global->ensure_first_scan();
 
349
 
 
350
        return global->manager->find(name);
 
351
}
 
352
 
 
353
Provider *defaultProvider()
 
354
{
 
355
        if(!global_check())
 
356
                return 0;
 
357
 
 
358
        return global->manager->find("default");
 
359
}
 
360
 
 
361
void scanForPlugins()
 
362
{
 
363
        if(!global_check())
 
364
                return;
 
365
 
 
366
        global->scan();
 
367
        global->ksm_scan();
 
368
}
 
369
 
 
370
void unloadAllPlugins()
 
371
{
 
372
        if(!global_check())
 
373
                return;
 
374
 
 
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")))
 
378
        {
 
379
                delete global->rng;
 
380
                global->rng = 0;
 
381
        }
 
382
        global->rng_mutex.unlock();
 
383
 
 
384
        global->manager->unloadAll();
 
385
}
 
386
 
 
387
QString pluginDiagnosticText()
 
388
{
 
389
        if(!global_check())
 
390
                return QString();
 
391
 
 
392
        return global->manager->diagnosticText();
 
393
}
 
394
 
 
395
void clearPluginDiagnosticText()
 
396
{
 
397
        if(!global_check())
 
398
                return;
 
399
 
 
400
        global->manager->clearDiagnosticText();
 
401
}
 
402
 
 
403
void appendPluginDiagnosticText(const QString &text)
 
404
{
 
405
        if(!global_check())
 
406
                return;
 
407
 
 
408
        global->manager->appendDiagnosticText(text);
 
409
}
 
410
 
 
411
void setProperty(const QString &name, const QVariant &value)
 
412
{
 
413
        if(!global_check())
 
414
                return;
 
415
 
 
416
        QMutexLocker locker(&global->prop_mutex);
 
417
 
 
418
        global->properties[name] = value;
 
419
}
 
420
 
 
421
QVariant getProperty(const QString &name)
 
422
{
 
423
        if(!global_check())
 
424
                return QVariant();
 
425
 
 
426
        QMutexLocker locker(&global->prop_mutex);
 
427
 
 
428
        return global->properties.value(name);
 
429
}
 
430
 
 
431
static bool configIsValid(const QVariantMap &config)
 
432
{
 
433
        if(!config.contains("formtype"))
 
434
                return false;
 
435
        QMapIterator<QString,QVariant> it(config);
 
436
        while(it.hasNext())
 
437
        {
 
438
                it.next();
 
439
                const QVariant &v = it.value();
 
440
                if(v.type() != QVariant::String && v.type() != QVariant::Int && v.type() != QVariant::Bool)
 
441
                        return false;
 
442
        }
 
443
        return true;
 
444
}
 
445
 
 
446
static QVariantMap readConfig(const QString &name)
 
447
{
 
448
        QSettings settings("Affinix", "QCA2");
 
449
        settings.beginGroup("ProviderConfig");
 
450
        QStringList providerNames = settings.value("providerNames").toStringList();
 
451
        if(!providerNames.contains(name))
 
452
                return QVariantMap();
 
453
 
 
454
        settings.beginGroup(name);
 
455
        QStringList keys = settings.childKeys();
 
456
        QVariantMap map;
 
457
        foreach(QString key, keys)
 
458
                map[key] = settings.value(key);
 
459
        settings.endGroup();
 
460
 
 
461
        if(!configIsValid(map))
 
462
                return QVariantMap();
 
463
        return map;
 
464
}
 
465
 
 
466
static bool writeConfig(const QString &name, const QVariantMap &config, bool systemWide = false)
 
467
{
 
468
        QSettings settings(QSettings::NativeFormat, systemWide ? QSettings::SystemScope : QSettings::UserScope, "Affinix", "QCA2");
 
469
        settings.beginGroup("ProviderConfig");
 
470
 
 
471
        // version
 
472
        settings.setValue("version", 2);
 
473
 
 
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);
 
479
 
 
480
        settings.beginGroup(name);
 
481
        QMapIterator<QString,QVariant> it(config);
 
482
        while(it.hasNext())
 
483
        {
 
484
                it.next();
 
485
                settings.setValue(it.key(), it.value());
 
486
        }
 
487
        settings.endGroup();
 
488
 
 
489
        if(settings.status() == QSettings::NoError)
 
490
                return true;
 
491
        return false;
 
492
}
 
493
 
 
494
void setProviderConfig(const QString &name, const QVariantMap &config)
 
495
{
 
496
        if(!global_check())
 
497
                return;
 
498
 
 
499
        if(!configIsValid(config))
 
500
                return;
 
501
 
 
502
        global->config_mutex.lock();
 
503
        global->config[name] = config;
 
504
        global->config_mutex.unlock();
 
505
 
 
506
        Provider *p = findProvider(name);
 
507
        if(p)
 
508
                p->configChanged(config);
 
509
}
 
510
 
 
511
QVariantMap getProviderConfig(const QString &name)
 
512
{
 
513
        if(!global_check())
 
514
                return QVariantMap();
 
515
 
 
516
        QVariantMap conf;
 
517
 
 
518
        global->config_mutex.lock();
 
519
 
 
520
        // try loading from persistent storage
 
521
        conf = readConfig(name);
 
522
 
 
523
        // if not, load the one from memory
 
524
        if(conf.isEmpty())
 
525
                conf = global->config.value(name);
 
526
 
 
527
        global->config_mutex.unlock();
 
528
 
 
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);
 
532
        if(!p)
 
533
                return conf;
 
534
        QVariantMap pconf = p->defaultConfig();
 
535
        if(!configIsValid(pconf))
 
536
                return conf;
 
537
 
 
538
        // if the config loaded was empty, use the provider's config
 
539
        if(conf.isEmpty())
 
540
                return pconf;
 
541
 
 
542
        // if the config formtype doesn't match the provider's formtype,
 
543
        //   then use the provider's
 
544
        if(pconf["formtype"] != conf["formtype"])
 
545
                return pconf;
 
546
 
 
547
        // otherwise, use the config loaded
 
548
        return conf;
 
549
}
 
550
 
 
551
void saveProviderConfig(const QString &name)
 
552
{
 
553
        if(!global_check())
 
554
                return;
 
555
 
 
556
        QMutexLocker locker(&global->config_mutex);
 
557
 
 
558
        QVariantMap conf = global->config.value(name);
 
559
        if(conf.isEmpty())
 
560
                return;
 
561
 
 
562
        writeConfig(name, conf);
 
563
}
 
564
 
 
565
QVariantMap getProviderConfig_internal(Provider *p)
 
566
{
 
567
        QVariantMap conf;
 
568
        QString name = p->name();
 
569
 
 
570
        global->config_mutex.lock();
 
571
 
 
572
        // try loading from persistent storage
 
573
        conf = readConfig(name);
 
574
 
 
575
        // if not, load the one from memory
 
576
        if(conf.isEmpty())
 
577
                conf = global->config.value(name);
 
578
 
 
579
        global->config_mutex.unlock();
 
580
 
 
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))
 
585
                return conf;
 
586
 
 
587
        // if the config loaded was empty, use the provider's config
 
588
        if(conf.isEmpty())
 
589
                return pconf;
 
590
 
 
591
        // if the config formtype doesn't match the provider's formtype,
 
592
        //   then use the provider's
 
593
        if(pconf["formtype"] != conf["formtype"])
 
594
                return pconf;
 
595
 
 
596
        // otherwise, use the config loaded
 
597
        return conf;
 
598
}
 
599
 
 
600
QString globalRandomProvider()
 
601
{
 
602
        QMutexLocker locker(global_random_mutex());
 
603
        return global_random()->provider()->name();
 
604
}
 
605
 
 
606
void setGlobalRandomProvider(const QString &provider)
 
607
{
 
608
        QMutexLocker locker(global_random_mutex());
 
609
        delete global->rng;
 
610
        global->rng = new Random(provider);
 
611
}
 
612
 
 
613
Logger *logger()
 
614
{
 
615
        return global->logger;
 
616
}
 
617
 
 
618
bool haveSystemStore()
 
619
{
 
620
        // ensure the system store is loaded
 
621
        KeyStoreManager::start("default");
 
622
        KeyStoreManager ksm;
 
623
        ksm.waitForBusyFinished();
 
624
 
 
625
        QStringList list = ksm.keyStores();
 
626
        for(int n = 0; n < list.count(); ++n)
 
627
        {
 
628
                KeyStore ks(list[n], &ksm);
 
629
                if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates())
 
630
                        return true;
 
631
        }
 
632
        return false;
 
633
}
 
634
 
 
635
CertificateCollection systemStore()
 
636
{
 
637
        // ensure the system store is loaded
 
638
        KeyStoreManager::start("default");
 
639
        KeyStoreManager ksm;
 
640
        ksm.waitForBusyFinished();
 
641
 
 
642
        CertificateCollection col;
 
643
        QStringList list = ksm.keyStores();
 
644
        for(int n = 0; n < list.count(); ++n)
 
645
        {
 
646
                KeyStore ks(list[n], &ksm);
 
647
 
 
648
                // system store
 
649
                if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates())
 
650
                {
 
651
                        // extract contents
 
652
                        QList<KeyStoreEntry> entries = ks.entryList();
 
653
                        for(int i = 0; i < entries.count(); ++i)
 
654
                        {
 
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());
 
659
                        }
 
660
                        break;
 
661
                }
 
662
        }
 
663
        return col;
 
664
}
 
665
 
 
666
QString appName()
 
667
{
 
668
        if(!global_check())
 
669
                return QString();
 
670
 
 
671
        QMutexLocker locker(&global->name_mutex);
 
672
 
 
673
        return global->app_name;
 
674
}
 
675
 
 
676
void setAppName(const QString &s)
 
677
{
 
678
        if(!global_check())
 
679
                return;
 
680
 
 
681
        QMutexLocker locker(&global->name_mutex);
 
682
 
 
683
        global->app_name = s;
 
684
}
 
685
 
 
686
QString arrayToHex(const QByteArray &a)
 
687
{
 
688
        return Hex().arrayToString(a);
 
689
}
 
690
 
 
691
QByteArray hexToArray(const QString &str)
 
692
{
 
693
        return Hex().stringToArray(str).toByteArray();
 
694
}
 
695
 
 
696
static Provider *getProviderForType(const QString &type, const QString &provider)
 
697
{
 
698
        Provider *p = 0;
 
699
        bool scanned = false;
 
700
        if(!provider.isEmpty())
 
701
        {
 
702
                // try using specific provider
 
703
                p = global->manager->findFor(provider, type);
 
704
                if(!p)
 
705
                {
 
706
                        // maybe this provider is new, so scan and try again
 
707
                        global->scan();
 
708
                        scanned = true;
 
709
                        p = global->manager->findFor(provider, type);
 
710
                }
 
711
        }
 
712
        if(!p)
 
713
        {
 
714
                // try using some other provider
 
715
                p = global->manager->findFor(QString(), type);
 
716
                if((!p || p->name() == "default") && !scanned)
 
717
                {
 
718
                        // maybe there are new providers, so scan and try again
 
719
                        //   before giving up or using default
 
720
                        global->scan();
 
721
                        scanned = true;
 
722
                        p = global->manager->findFor(QString(), type);
 
723
                }
 
724
        }
 
725
 
 
726
        return p;
 
727
}
 
728
 
 
729
static inline Provider::Context *doCreateContext(Provider *p, const QString &type)
 
730
{
 
731
        return p->createContext(type);
 
732
}
 
733
 
 
734
Provider::Context *getContext(const QString &type, const QString &provider)
 
735
{
 
736
        if(!global_check())
 
737
                return 0;
 
738
 
 
739
        Provider *p;
 
740
        {
 
741
                p = getProviderForType(type, provider);
 
742
                if(!p)
 
743
                        return 0;
 
744
        }
 
745
 
 
746
        return doCreateContext(p, type);
 
747
}
 
748
 
 
749
Provider::Context *getContext(const QString &type, Provider *_p)
 
750
{
 
751
        if(!global_check())
 
752
                return 0;
 
753
 
 
754
        Provider *p;
 
755
        {
 
756
                p = global->manager->find(_p);
 
757
                if(!p)
 
758
                        return 0;
 
759
        }
 
760
 
 
761
        return doCreateContext(p, type);
 
762
}
 
763
 
 
764
//----------------------------------------------------------------------------
 
765
// Initializer
 
766
//----------------------------------------------------------------------------
 
767
Initializer::Initializer(MemoryMode m, int prealloc)
 
768
{
 
769
        init(m, prealloc);
 
770
}
 
771
 
 
772
Initializer::~Initializer()
 
773
{
 
774
        deinit();
 
775
}
 
776
 
 
777
//----------------------------------------------------------------------------
 
778
// Provider
 
779
//----------------------------------------------------------------------------
 
780
Provider::~Provider()
 
781
{
 
782
}
 
783
 
 
784
void Provider::init()
 
785
{
 
786
}
 
787
 
 
788
void Provider::deinit()
 
789
{
 
790
}
 
791
 
 
792
int Provider::version() const
 
793
{
 
794
        return 0;
 
795
}
 
796
 
 
797
QString Provider::credit() const
 
798
{
 
799
        return QString();
 
800
}
 
801
 
 
802
QVariantMap Provider::defaultConfig() const
 
803
{
 
804
        return QVariantMap();
 
805
}
 
806
 
 
807
void Provider::configChanged(const QVariantMap &)
 
808
{
 
809
}
 
810
 
 
811
Provider::Context::Context(Provider *parent, const QString &type)
 
812
:QObject()
 
813
{
 
814
        _provider = parent;
 
815
        _type = type;
 
816
}
 
817
 
 
818
Provider::Context::Context(const Context &from)
 
819
:QObject()
 
820
{
 
821
        _provider = from._provider;
 
822
        _type = from._type;
 
823
}
 
824
 
 
825
Provider::Context::~Context()
 
826
{
 
827
}
 
828
 
 
829
Provider *Provider::Context::provider() const
 
830
{
 
831
        return _provider;
 
832
}
 
833
 
 
834
QString Provider::Context::type() const
 
835
{
 
836
        return _type;
 
837
}
 
838
 
 
839
bool Provider::Context::sameProvider(const Context *c) const
 
840
{
 
841
        return (c->provider() == _provider);
 
842
}
 
843
 
 
844
//----------------------------------------------------------------------------
 
845
// BasicContext
 
846
//----------------------------------------------------------------------------
 
847
BasicContext::BasicContext(Provider *parent, const QString &type)
 
848
:Context(parent, type)
 
849
{
 
850
        moveToThread(0); // no thread association
 
851
}
 
852
 
 
853
BasicContext::BasicContext(const BasicContext &from)
 
854
:Context(from)
 
855
{
 
856
        moveToThread(0); // no thread association
 
857
}
 
858
 
 
859
BasicContext::~BasicContext()
 
860
{
 
861
}
 
862
 
 
863
//----------------------------------------------------------------------------
 
864
// InfoContext
 
865
//----------------------------------------------------------------------------
 
866
QStringList InfoContext::supportedHashTypes() const
 
867
{
 
868
        return QStringList();
 
869
}
 
870
 
 
871
QStringList InfoContext::supportedCipherTypes() const
 
872
{
 
873
        return QStringList();
 
874
}
 
875
 
 
876
QStringList InfoContext::supportedMACTypes() const
 
877
{
 
878
        return QStringList();
 
879
}
 
880
 
 
881
//----------------------------------------------------------------------------
 
882
// PKeyBase
 
883
//----------------------------------------------------------------------------
 
884
PKeyBase::PKeyBase(Provider *p, const QString &type)
 
885
:BasicContext(p, type)
 
886
{
 
887
}
 
888
 
 
889
int PKeyBase::maximumEncryptSize(EncryptionAlgorithm) const
 
890
{
 
891
        return 0;
 
892
}
 
893
 
 
894
SecureArray PKeyBase::encrypt(const SecureArray &, EncryptionAlgorithm)
 
895
{
 
896
        return SecureArray();
 
897
}
 
898
 
 
899
bool PKeyBase::decrypt(const SecureArray &, SecureArray *, EncryptionAlgorithm)
 
900
{
 
901
        return false;
 
902
}
 
903
 
 
904
void PKeyBase::startSign(SignatureAlgorithm, SignatureFormat)
 
905
{
 
906
}
 
907
 
 
908
void PKeyBase::startVerify(SignatureAlgorithm, SignatureFormat)
 
909
{
 
910
}
 
911
 
 
912
void PKeyBase::update(const MemoryRegion &)
 
913
{
 
914
}
 
915
 
 
916
QByteArray PKeyBase::endSign()
 
917
{
 
918
        return QByteArray();
 
919
}
 
920
 
 
921
bool PKeyBase::endVerify(const QByteArray &)
 
922
{
 
923
        return false;
 
924
}
 
925
 
 
926
SymmetricKey PKeyBase::deriveKey(const PKeyBase &)
 
927
{
 
928
        return SymmetricKey();
 
929
}
 
930
 
 
931
//----------------------------------------------------------------------------
 
932
// PKeyContext
 
933
//----------------------------------------------------------------------------
 
934
QByteArray PKeyContext::publicToDER() const
 
935
{
 
936
        return QByteArray();
 
937
}
 
938
 
 
939
QString PKeyContext::publicToPEM() const
 
940
{
 
941
        return QString();
 
942
}
 
943
 
 
944
ConvertResult PKeyContext::publicFromDER(const QByteArray &)
 
945
{
 
946
        return ErrorDecode;
 
947
}
 
948
 
 
949
ConvertResult PKeyContext::publicFromPEM(const QString &)
 
950
{
 
951
        return ErrorDecode;
 
952
}
 
953
 
 
954
SecureArray PKeyContext::privateToDER(const SecureArray &, PBEAlgorithm) const
 
955
{
 
956
        return SecureArray();
 
957
}
 
958
 
 
959
QString PKeyContext::privateToPEM(const SecureArray &, PBEAlgorithm) const
 
960
{
 
961
        return QString();
 
962
}
 
963
 
 
964
ConvertResult PKeyContext::privateFromDER(const SecureArray &, const SecureArray &)
 
965
{
 
966
        return ErrorDecode;
 
967
}
 
968
 
 
969
ConvertResult PKeyContext::privateFromPEM(const QString &, const SecureArray &)
 
970
{
 
971
        return ErrorDecode;
 
972
}
 
973
 
 
974
//----------------------------------------------------------------------------
 
975
// KeyStoreEntryContext
 
976
//----------------------------------------------------------------------------
 
977
bool KeyStoreEntryContext::isAvailable() const
 
978
{
 
979
        return true;
 
980
}
 
981
 
 
982
KeyBundle KeyStoreEntryContext::keyBundle() const
 
983
{
 
984
        return KeyBundle();
 
985
}
 
986
 
 
987
Certificate KeyStoreEntryContext::certificate() const
 
988
{
 
989
        return Certificate();
 
990
}
 
991
 
 
992
CRL KeyStoreEntryContext::crl() const
 
993
{
 
994
        return CRL();
 
995
}
 
996
 
 
997
PGPKey KeyStoreEntryContext::pgpSecretKey() const
 
998
{
 
999
        return PGPKey();
 
1000
}
 
1001
 
 
1002
PGPKey KeyStoreEntryContext::pgpPublicKey() const
 
1003
{
 
1004
        return PGPKey();
 
1005
}
 
1006
 
 
1007
bool KeyStoreEntryContext::ensureAccess()
 
1008
{
 
1009
        return true;
 
1010
}
 
1011
 
 
1012
//----------------------------------------------------------------------------
 
1013
// KeyStoreListContext
 
1014
//----------------------------------------------------------------------------
 
1015
void KeyStoreListContext::start()
 
1016
{
 
1017
        QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection);
 
1018
}
 
1019
 
 
1020
void KeyStoreListContext::setUpdatesEnabled(bool)
 
1021
{
 
1022
}
 
1023
 
 
1024
bool KeyStoreListContext::isReadOnly(int) const
 
1025
{
 
1026
        return true;
 
1027
}
 
1028
 
 
1029
KeyStoreEntryContext *KeyStoreListContext::entry(int id, const QString &entryId)
 
1030
{
 
1031
        KeyStoreEntryContext *out = 0;
 
1032
        QList<KeyStoreEntryContext*> list = entryList(id);
 
1033
        for(int n = 0; n < list.count(); ++n)
 
1034
        {
 
1035
                if(list[n]->id() == entryId)
 
1036
                {
 
1037
                        out = list.takeAt(n);
 
1038
                        break;
 
1039
                }
 
1040
        }
 
1041
        qDeleteAll(list);
 
1042
        return out;
 
1043
}
 
1044
 
 
1045
KeyStoreEntryContext *KeyStoreListContext::entryPassive(const QString &serialized)
 
1046
{
 
1047
        Q_UNUSED(serialized);
 
1048
        return 0;
 
1049
}
 
1050
 
 
1051
QString KeyStoreListContext::writeEntry(int, const KeyBundle &)
 
1052
{
 
1053
        return QString();
 
1054
}
 
1055
 
 
1056
QString KeyStoreListContext::writeEntry(int, const Certificate &)
 
1057
{
 
1058
        return QString();
 
1059
}
 
1060
 
 
1061
QString KeyStoreListContext::writeEntry(int, const CRL &)
 
1062
{
 
1063
        return QString();
 
1064
}
 
1065
 
 
1066
QString KeyStoreListContext::writeEntry(int, const PGPKey &)
 
1067
{
 
1068
        return QString();
 
1069
}
 
1070
 
 
1071
bool KeyStoreListContext::removeEntry(int, const QString &)
 
1072
{
 
1073
        return false;
 
1074
}
 
1075
 
 
1076
//----------------------------------------------------------------------------
 
1077
// TLSContext
 
1078
//----------------------------------------------------------------------------
 
1079
void TLSContext::setMTU(int)
 
1080
{
 
1081
}
 
1082
 
 
1083
//----------------------------------------------------------------------------
 
1084
// MessageContext
 
1085
//----------------------------------------------------------------------------
 
1086
QString MessageContext::diagnosticText() const
 
1087
{
 
1088
        return QString();
 
1089
}
 
1090
 
 
1091
//----------------------------------------------------------------------------
 
1092
// SMSContext
 
1093
//----------------------------------------------------------------------------
 
1094
void SMSContext::setTrustedCertificates(const CertificateCollection &)
 
1095
{
 
1096
}
 
1097
 
 
1098
void SMSContext::setUntrustedCertificates(const CertificateCollection &)
 
1099
{
 
1100
}
 
1101
 
 
1102
void SMSContext::setPrivateKeys(const QList<SecureMessageKey> &)
 
1103
{
 
1104
}
 
1105
 
 
1106
//----------------------------------------------------------------------------
 
1107
// BufferedComputation
 
1108
//----------------------------------------------------------------------------
 
1109
BufferedComputation::~BufferedComputation()
 
1110
{
 
1111
}
 
1112
 
 
1113
MemoryRegion BufferedComputation::process(const MemoryRegion &a)
 
1114
{
 
1115
        clear();
 
1116
        update(a);
 
1117
        return final();
 
1118
}
 
1119
 
 
1120
//----------------------------------------------------------------------------
 
1121
// Filter
 
1122
//----------------------------------------------------------------------------
 
1123
Filter::~Filter()
 
1124
{
 
1125
}
 
1126
 
 
1127
MemoryRegion Filter::process(const MemoryRegion &a)
 
1128
{
 
1129
        clear();
 
1130
        MemoryRegion buf = update(a);
 
1131
        if(!ok())
 
1132
                return MemoryRegion();
 
1133
        MemoryRegion fin = final();
 
1134
        if(!ok())
 
1135
                return MemoryRegion();
 
1136
        if(buf.isSecure() || fin.isSecure())
 
1137
                return (SecureArray(buf) + SecureArray(fin));
 
1138
        else
 
1139
                return (buf.toByteArray() + fin.toByteArray());
 
1140
}
 
1141
 
 
1142
//----------------------------------------------------------------------------
 
1143
// Algorithm
 
1144
//----------------------------------------------------------------------------
 
1145
class Algorithm::Private : public QSharedData
 
1146
{
 
1147
public:
 
1148
        Provider::Context *c;
 
1149
 
 
1150
        Private(Provider::Context *context)
 
1151
        {
 
1152
                c = context;
 
1153
                //printf("** [%p] Algorithm Created\n", c);
 
1154
        }
 
1155
 
 
1156
        Private(const Private &from) : QSharedData(from)
 
1157
        {
 
1158
                c = from.c->clone();
 
1159
                //printf("** [%p] Algorithm Copied (to [%p])\n", from.c, c);
 
1160
        }
 
1161
 
 
1162
        ~Private()
 
1163
        {
 
1164
                //printf("** [%p] Algorithm Destroyed\n", c);
 
1165
                delete c;
 
1166
        }
 
1167
};
 
1168
 
 
1169
Algorithm::Algorithm()
 
1170
{
 
1171
}
 
1172
 
 
1173
Algorithm::Algorithm(const QString &type, const QString &provider)
 
1174
{
 
1175
        change(type, provider);
 
1176
}
 
1177
 
 
1178
Algorithm::Algorithm(const Algorithm &from)
 
1179
{
 
1180
        *this = from;
 
1181
}
 
1182
 
 
1183
Algorithm::~Algorithm()
 
1184
{
 
1185
}
 
1186
 
 
1187
Algorithm & Algorithm::operator=(const Algorithm &from)
 
1188
{
 
1189
        d = from.d;
 
1190
        return *this;
 
1191
}
 
1192
 
 
1193
QString Algorithm::type() const
 
1194
{
 
1195
        if(d)
 
1196
                return d->c->type();
 
1197
        else
 
1198
                return QString();
 
1199
}
 
1200
 
 
1201
Provider *Algorithm::provider() const
 
1202
{
 
1203
        if(d)
 
1204
                return d->c->provider();
 
1205
        else
 
1206
                return 0;
 
1207
}
 
1208
 
 
1209
Provider::Context *Algorithm::context()
 
1210
{
 
1211
        if(d)
 
1212
                return d->c;
 
1213
        else
 
1214
                return 0;
 
1215
}
 
1216
 
 
1217
const Provider::Context *Algorithm::context() const
 
1218
{
 
1219
        if(d)
 
1220
                return d->c;
 
1221
        else
 
1222
                return 0;
 
1223
}
 
1224
 
 
1225
void Algorithm::change(Provider::Context *c)
 
1226
{
 
1227
        if(c)
 
1228
                d = new Private(c);
 
1229
        else
 
1230
                d = 0;
 
1231
}
 
1232
 
 
1233
void Algorithm::change(const QString &type, const QString &provider)
 
1234
{
 
1235
        if(!type.isEmpty())
 
1236
                change(getContext(type, provider));
 
1237
        else
 
1238
                change(0);
 
1239
}
 
1240
 
 
1241
Provider::Context *Algorithm::takeContext()
 
1242
{
 
1243
        if(d)
 
1244
        {
 
1245
                Provider::Context *c = d->c; // should cause a detach
 
1246
                d->c = 0;
 
1247
                d = 0;
 
1248
                return c;
 
1249
        }
 
1250
        else
 
1251
                return 0;
 
1252
}
 
1253
 
 
1254
//----------------------------------------------------------------------------
 
1255
// SymmetricKey
 
1256
//----------------------------------------------------------------------------
 
1257
SymmetricKey::SymmetricKey()
 
1258
{
 
1259
}
 
1260
 
 
1261
SymmetricKey::SymmetricKey(int size)
 
1262
{
 
1263
        set(Random::randomArray(size));
 
1264
}
 
1265
 
 
1266
SymmetricKey::SymmetricKey(const SecureArray &a)
 
1267
{
 
1268
        set(a);
 
1269
}
 
1270
 
 
1271
SymmetricKey::SymmetricKey(const QByteArray &a)
 
1272
{
 
1273
        set(SecureArray(a));
 
1274
}
 
1275
 
 
1276
/* from libgcrypt-1.2.0 */
 
1277
static unsigned char desWeakKeyTable[64][8] =
 
1278
{
 
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*/
 
1343
};
 
1344
 
 
1345
bool SymmetricKey::isWeakDESKey()
 
1346
{
 
1347
        if(size() != 8)
 
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;
 
1353
 
 
1354
        for(int n = 0; n < 64; n++)
 
1355
        {
 
1356
                if(memcmp(workingCopy.data(), desWeakKeyTable[n], 8) == 0)
 
1357
                        return true;
 
1358
        }
 
1359
        return false;
 
1360
}
 
1361
 
 
1362
//----------------------------------------------------------------------------
 
1363
// InitializationVector
 
1364
//----------------------------------------------------------------------------
 
1365
InitializationVector::InitializationVector()
 
1366
{
 
1367
}
 
1368
 
 
1369
InitializationVector::InitializationVector(int size)
 
1370
{
 
1371
        set(Random::randomArray(size));
 
1372
}
 
1373
 
 
1374
InitializationVector::InitializationVector(const SecureArray &a)
 
1375
{
 
1376
        set(a);
 
1377
}
 
1378
 
 
1379
InitializationVector::InitializationVector(const QByteArray &a)
 
1380
{
 
1381
        set(SecureArray(a));
 
1382
}
 
1383
 
 
1384
//----------------------------------------------------------------------------
 
1385
// Event
 
1386
//----------------------------------------------------------------------------
 
1387
class Event::Private : public QSharedData
 
1388
{
 
1389
public:
 
1390
        Type type;
 
1391
        Source source;
 
1392
        PasswordStyle style;
 
1393
        KeyStoreInfo ksi;
 
1394
        KeyStoreEntry kse;
 
1395
        QString fname;
 
1396
        void *ptr;
 
1397
};
 
1398
 
 
1399
Event::Event()
 
1400
{
 
1401
}
 
1402
 
 
1403
Event::Event(const Event &from)
 
1404
:d(from.d)
 
1405
{
 
1406
}
 
1407
 
 
1408
Event::~Event()
 
1409
{
 
1410
}
 
1411
 
 
1412
Event & Event::operator=(const Event &from)
 
1413
{
 
1414
        d = from.d;
 
1415
        return *this;
 
1416
}
 
1417
 
 
1418
bool Event::isNull() const
 
1419
{
 
1420
        return (d ? false : true);
 
1421
}
 
1422
 
 
1423
Event::Type Event::type() const
 
1424
{
 
1425
        return d->type;
 
1426
}
 
1427
 
 
1428
Event::Source Event::source() const
 
1429
{
 
1430
        return d->source;
 
1431
}
 
1432
 
 
1433
Event::PasswordStyle Event::passwordStyle() const
 
1434
{
 
1435
        return d->style;
 
1436
}
 
1437
 
 
1438
KeyStoreInfo Event::keyStoreInfo() const
 
1439
{
 
1440
        return d->ksi;
 
1441
}
 
1442
 
 
1443
KeyStoreEntry Event::keyStoreEntry() const
 
1444
{
 
1445
        return d->kse;
 
1446
}
 
1447
 
 
1448
QString Event::fileName() const
 
1449
{
 
1450
        return d->fname;
 
1451
}
 
1452
 
 
1453
void *Event::ptr() const
 
1454
{
 
1455
        return d->ptr;
 
1456
}
 
1457
 
 
1458
void Event::setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
 
1459
{
 
1460
        if(!d)
 
1461
                d = new Private;
 
1462
        d->type = Password;
 
1463
        d->source = KeyStore;
 
1464
        d->style = pstyle;
 
1465
        d->ksi = keyStoreInfo;
 
1466
        d->kse = keyStoreEntry;
 
1467
        d->fname = QString();
 
1468
        d->ptr = ptr;
 
1469
}
 
1470
 
 
1471
void Event::setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr)
 
1472
{
 
1473
        if(!d)
 
1474
                d = new Private;
 
1475
        d->type = Password;
 
1476
        d->source = Data;
 
1477
        d->style = pstyle;
 
1478
        d->ksi = KeyStoreInfo();
 
1479
        d->kse = KeyStoreEntry();
 
1480
        d->fname = fileName;
 
1481
        d->ptr = ptr;
 
1482
}
 
1483
 
 
1484
void Event::setToken(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
 
1485
{
 
1486
        if(!d)
 
1487
                d = new Private;
 
1488
        d->type = Token;
 
1489
        d->source = KeyStore;
 
1490
        d->style = StylePassword;
 
1491
        d->ksi = keyStoreInfo;
 
1492
        d->kse = keyStoreEntry;
 
1493
        d->fname = QString();
 
1494
        d->ptr = ptr;
 
1495
}
 
1496
 
 
1497
//----------------------------------------------------------------------------
 
1498
// EventGlobal
 
1499
//----------------------------------------------------------------------------
 
1500
class HandlerBase : public QObject
 
1501
{
 
1502
        Q_OBJECT
 
1503
public:
 
1504
        HandlerBase(QObject *parent = 0) : QObject(parent)
 
1505
        {
 
1506
        }
 
1507
 
 
1508
protected slots:
 
1509
        virtual void ask(int id, const QCA::Event &e) = 0;
 
1510
};
 
1511
 
 
1512
class AskerBase : public QObject
 
1513
{
 
1514
        Q_OBJECT
 
1515
public:
 
1516
        AskerBase(QObject *parent = 0) : QObject(parent)
 
1517
        {
 
1518
        }
 
1519
 
 
1520
        virtual void set_accepted(const SecureArray &password) = 0;
 
1521
        virtual void set_rejected() = 0;
 
1522
};
 
1523
 
 
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);
 
1530
 
 
1531
Q_GLOBAL_STATIC(QMutex, g_event_mutex)
 
1532
 
 
1533
class EventGlobal;
 
1534
static EventGlobal *g_event = 0;
 
1535
 
 
1536
class EventGlobal
 
1537
{
 
1538
public:
 
1539
        class HandlerItem
 
1540
        {
 
1541
        public:
 
1542
                HandlerBase *h;
 
1543
                QList<int> ids;
 
1544
        };
 
1545
 
 
1546
        class AskerItem
 
1547
        {
 
1548
        public:
 
1549
                AskerBase *a;
 
1550
                int id;
 
1551
                Event event;
 
1552
                int handler_pos;
 
1553
        };
 
1554
 
 
1555
        QList<HandlerItem> handlers;
 
1556
        QList<AskerItem> askers;
 
1557
 
 
1558
        int next_id;
 
1559
 
 
1560
        EventGlobal()
 
1561
        {
 
1562
                qRegisterMetaType<Event>("QCA::Event");
 
1563
                qRegisterMetaType<SecureArray>("QCA::SecureArray");
 
1564
                next_id = 0;
 
1565
        }
 
1566
 
 
1567
        int findHandlerItem(HandlerBase *h)
 
1568
        {
 
1569
                for(int n = 0; n < handlers.count(); ++n)
 
1570
                {
 
1571
                        if(handlers[n].h == h)
 
1572
                                return n;
 
1573
                }
 
1574
                return -1;
 
1575
        }
 
1576
 
 
1577
        int findAskerItem(AskerBase *a)
 
1578
        {
 
1579
                for(int n = 0; n < askers.count(); ++n)
 
1580
                {
 
1581
                        if(askers[n].a == a)
 
1582
                                return n;
 
1583
                }
 
1584
                return -1;
 
1585
        }
 
1586
 
 
1587
        int findAskerItemById(int id)
 
1588
        {
 
1589
                for(int n = 0; n < askers.count(); ++n)
 
1590
                {
 
1591
                        if(askers[n].id == id)
 
1592
                                return n;
 
1593
                }
 
1594
                return -1;
 
1595
        }
 
1596
 
 
1597
        void ask(int asker_at)
 
1598
        {
 
1599
                AskerItem &i = askers[asker_at];
 
1600
 
 
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));
 
1605
        }
 
1606
 
 
1607
        void reject(int asker_at)
 
1608
        {
 
1609
                AskerItem &i = askers[asker_at];
 
1610
 
 
1611
                // look for the next usable handler
 
1612
                int pos = -1;
 
1613
                for(int n = i.handler_pos + 1; n < g_event->handlers.count(); ++n)
 
1614
                {
 
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())
 
1618
                        //{
 
1619
                                pos = n;
 
1620
                                break;
 
1621
                        //}
 
1622
                }
 
1623
 
 
1624
                // if there is one, try it
 
1625
                if(pos != -1)
 
1626
                {
 
1627
                        i.handler_pos = pos;
 
1628
                        ask(asker_at);
 
1629
                }
 
1630
                // if not, send official reject
 
1631
                else
 
1632
                {
 
1633
                        AskerBase *asker = i.a;
 
1634
                        askers.removeAt(asker_at);
 
1635
 
 
1636
                        asker->set_rejected();
 
1637
                }
 
1638
        }
 
1639
};
 
1640
 
 
1641
void handler_add(HandlerBase *h, int pos)
 
1642
{
 
1643
        QMutexLocker locker(g_event_mutex());
 
1644
        if(!g_event)
 
1645
                g_event = new EventGlobal;
 
1646
 
 
1647
        EventGlobal::HandlerItem i;
 
1648
        i.h = h;
 
1649
 
 
1650
        if(pos != -1)
 
1651
        {
 
1652
                g_event->handlers.insert(pos, i);
 
1653
 
 
1654
                // adjust handler positions
 
1655
                for(int n = 0; n < g_event->askers.count(); ++n)
 
1656
                {
 
1657
                        if(g_event->askers[n].handler_pos >= pos)
 
1658
                                g_event->askers[n].handler_pos++;
 
1659
                }
 
1660
        }
 
1661
        else
 
1662
                g_event->handlers += i;
 
1663
}
 
1664
 
 
1665
void handler_remove(HandlerBase *h)
 
1666
{
 
1667
        QMutexLocker locker(g_event_mutex());
 
1668
        Q_ASSERT(g_event);
 
1669
        if(!g_event)
 
1670
                return;
 
1671
        int at = g_event->findHandlerItem(h);
 
1672
        Q_ASSERT(at != -1);
 
1673
        if(at == -1)
 
1674
                return;
 
1675
 
 
1676
        QList<int> ids = g_event->handlers[at].ids;
 
1677
        g_event->handlers.removeAt(at);
 
1678
 
 
1679
        // adjust handler positions within askers
 
1680
        for(int n = 0; n < g_event->askers.count(); ++n)
 
1681
        {
 
1682
                if(g_event->askers[n].handler_pos >= at)
 
1683
                        g_event->askers[n].handler_pos--;
 
1684
        }
 
1685
 
 
1686
        // reject all askers
 
1687
        foreach(int id, ids)
 
1688
        {
 
1689
                int asker_at = g_event->findAskerItemById(id);
 
1690
                Q_ASSERT(asker_at != -1);
 
1691
 
 
1692
                g_event->reject(asker_at);
 
1693
        }
 
1694
 
 
1695
        if(g_event->handlers.isEmpty())
 
1696
        {
 
1697
                delete g_event;
 
1698
                g_event = 0;
 
1699
        }
 
1700
}
 
1701
 
 
1702
void handler_accept(HandlerBase *h, int id, const SecureArray &password)
 
1703
{
 
1704
        QMutexLocker locker(g_event_mutex());
 
1705
        Q_ASSERT(g_event);
 
1706
        if(!g_event)
 
1707
                return;
 
1708
        int at = g_event->findHandlerItem(h);
 
1709
        Q_ASSERT(at != -1);
 
1710
        if(at == -1)
 
1711
                return;
 
1712
        int asker_at = g_event->findAskerItemById(id);
 
1713
        Q_ASSERT(asker_at != -1);
 
1714
        if(asker_at == -1)
 
1715
                return;
 
1716
 
 
1717
        g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id);
 
1718
 
 
1719
        AskerBase *asker = g_event->askers[asker_at].a;
 
1720
        asker->set_accepted(password);
 
1721
}
 
1722
 
 
1723
void handler_reject(HandlerBase *h, int id)
 
1724
{
 
1725
        QMutexLocker locker(g_event_mutex());
 
1726
        Q_ASSERT(g_event);
 
1727
        if(!g_event)
 
1728
                return;
 
1729
        int at = g_event->findHandlerItem(h);
 
1730
        Q_ASSERT(at != -1);
 
1731
        if(at == -1)
 
1732
                return;
 
1733
        int asker_at = g_event->findAskerItemById(id);
 
1734
        Q_ASSERT(asker_at != -1);
 
1735
        if(asker_at == -1)
 
1736
                return;
 
1737
 
 
1738
        g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id);
 
1739
 
 
1740
        g_event->reject(asker_at);
 
1741
}
 
1742
 
 
1743
bool asker_ask(AskerBase *a, const Event &e)
 
1744
{
 
1745
        QMutexLocker locker(g_event_mutex());
 
1746
        if(!g_event)
 
1747
                return false;
 
1748
 
 
1749
        int pos = -1;
 
1750
        for(int n = 0; n < g_event->handlers.count(); ++n)
 
1751
        {
 
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())
 
1755
                //{
 
1756
                        pos = n;
 
1757
                        break;
 
1758
                //}
 
1759
        }
 
1760
        if(pos == -1)
 
1761
                return false;
 
1762
 
 
1763
        EventGlobal::AskerItem i;
 
1764
        i.a = a;
 
1765
        i.id = g_event->next_id++;
 
1766
        i.event = e;
 
1767
        i.handler_pos = pos;
 
1768
        g_event->askers += i;
 
1769
        int asker_at = g_event->askers.count() - 1;
 
1770
 
 
1771
        g_event->ask(asker_at);
 
1772
        return true;
 
1773
}
 
1774
 
 
1775
void asker_cancel(AskerBase *a)
 
1776
{
 
1777
        QMutexLocker locker(g_event_mutex());
 
1778
        if(!g_event)
 
1779
                return;
 
1780
        int at = g_event->findAskerItem(a);
 
1781
        if(at == -1)
 
1782
                return;
 
1783
 
 
1784
        for(int n = 0; n < g_event->handlers.count(); ++n)
 
1785
                g_event->handlers[n].ids.removeAll(g_event->askers[at].id);
 
1786
 
 
1787
        g_event->askers.removeAt(at);
 
1788
}
 
1789
 
 
1790
//----------------------------------------------------------------------------
 
1791
// EventHandler
 
1792
//----------------------------------------------------------------------------
 
1793
class EventHandler::Private : public HandlerBase
 
1794
{
 
1795
        Q_OBJECT
 
1796
public:
 
1797
        EventHandler *q;
 
1798
        bool started;
 
1799
        QList<int> activeIds;
 
1800
 
 
1801
        Private(EventHandler *_q) : HandlerBase(_q), q(_q)
 
1802
        {
 
1803
                started = false;
 
1804
        }
 
1805
 
 
1806
public slots:
 
1807
        virtual void ask(int id, const QCA::Event &e)
 
1808
        {
 
1809
                activeIds += id;
 
1810
                emit q->eventReady(id, e);
 
1811
        }
 
1812
};
 
1813
 
 
1814
EventHandler::EventHandler(QObject *parent)
 
1815
:QObject(parent)
 
1816
{
 
1817
        d = new Private(this);
 
1818
}
 
1819
 
 
1820
EventHandler::~EventHandler()
 
1821
{
 
1822
        if(d->started)
 
1823
        {
 
1824
                foreach(int id, d->activeIds)
 
1825
                        handler_reject(d, id);
 
1826
 
 
1827
                handler_remove(d);
 
1828
        }
 
1829
 
 
1830
        delete d;
 
1831
}
 
1832
 
 
1833
void EventHandler::start()
 
1834
{
 
1835
        d->started = true;
 
1836
        handler_add(d);
 
1837
}
 
1838
 
 
1839
void EventHandler::submitPassword(int id, const SecureArray &password)
 
1840
{
 
1841
        if(!d->activeIds.contains(id))
 
1842
                return;
 
1843
 
 
1844
        d->activeIds.removeAll(id);
 
1845
        handler_accept(d, id, password);
 
1846
}
 
1847
 
 
1848
void EventHandler::tokenOkay(int id)
 
1849
{
 
1850
        if(!d->activeIds.contains(id))
 
1851
                return;
 
1852
 
 
1853
        d->activeIds.removeAll(id);
 
1854
        handler_accept(d, id, SecureArray());
 
1855
}
 
1856
 
 
1857
void EventHandler::reject(int id)
 
1858
{
 
1859
        if(!d->activeIds.contains(id))
 
1860
                return;
 
1861
 
 
1862
        d->activeIds.removeAll(id);
 
1863
        handler_reject(d, id);
 
1864
}
 
1865
 
 
1866
//----------------------------------------------------------------------------
 
1867
// PasswordAsker
 
1868
//----------------------------------------------------------------------------
 
1869
class AskerPrivate : public AskerBase
 
1870
{
 
1871
        Q_OBJECT
 
1872
public:
 
1873
        enum Type { Password, Token };
 
1874
 
 
1875
        Type type;
 
1876
        PasswordAsker *passwordAsker;
 
1877
        TokenAsker *tokenAsker;
 
1878
 
 
1879
        QMutex m;
 
1880
        QWaitCondition w;
 
1881
 
 
1882
        bool accepted;
 
1883
        SecureArray password;
 
1884
        bool waiting;
 
1885
        bool done;
 
1886
 
 
1887
        AskerPrivate(PasswordAsker *parent) : AskerBase(parent)
 
1888
        {
 
1889
                passwordAsker = parent;
 
1890
                tokenAsker = 0;
 
1891
                type = Password;
 
1892
                accepted = false;
 
1893
                waiting = false;
 
1894
                done = true;
 
1895
        }
 
1896
 
 
1897
        AskerPrivate(TokenAsker *parent) : AskerBase(parent)
 
1898
        {
 
1899
                passwordAsker = 0;
 
1900
                tokenAsker = parent;
 
1901
                type = Token;
 
1902
                accepted = false;
 
1903
                waiting = false;
 
1904
                done = true;
 
1905
        }
 
1906
 
 
1907
        void ask(const Event &e)
 
1908
        {
 
1909
                accepted = false;
 
1910
                waiting = false;
 
1911
                done = false;
 
1912
                password.clear();
 
1913
 
 
1914
                if(!asker_ask(this, e))
 
1915
                {
 
1916
                        done = true;
 
1917
                        QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
 
1918
                }
 
1919
        }
 
1920
 
 
1921
        void cancel()
 
1922
        {
 
1923
                if(!done)
 
1924
                        asker_cancel(this);
 
1925
        }
 
1926
 
 
1927
        virtual void set_accepted(const SecureArray &_password)
 
1928
        {
 
1929
                QMutexLocker locker(&m);
 
1930
                accepted = true;
 
1931
                password = _password;
 
1932
                done = true;
 
1933
                if(waiting)
 
1934
                        w.wakeOne();
 
1935
                else
 
1936
                        QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
 
1937
        }
 
1938
 
 
1939
        virtual void set_rejected()
 
1940
        {
 
1941
                QMutexLocker locker(&m);
 
1942
                done = true;
 
1943
                if(waiting)
 
1944
                        w.wakeOne();
 
1945
                else
 
1946
                        QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
 
1947
        }
 
1948
 
 
1949
        void waitForResponse()
 
1950
        {
 
1951
                QMutexLocker locker(&m);
 
1952
                if(done)
 
1953
                        return;
 
1954
                waiting = true;
 
1955
                w.wait(&m);
 
1956
                waiting = false;
 
1957
        }
 
1958
 
 
1959
public slots:
 
1960
        virtual void emitResponseReady() = 0;
 
1961
};
 
1962
 
 
1963
class PasswordAsker::Private : public AskerPrivate
 
1964
{
 
1965
public:
 
1966
        Private(PasswordAsker *_q) : AskerPrivate(_q)
 
1967
        {
 
1968
        }
 
1969
 
 
1970
        virtual void emitResponseReady()
 
1971
        {
 
1972
                emit passwordAsker->responseReady();
 
1973
        }
 
1974
};
 
1975
 
 
1976
PasswordAsker::PasswordAsker(QObject *parent)
 
1977
:QObject(parent)
 
1978
{
 
1979
        d = new Private(this);
 
1980
}
 
1981
 
 
1982
PasswordAsker::~PasswordAsker()
 
1983
{
 
1984
        delete d;
 
1985
}
 
1986
 
 
1987
void PasswordAsker::ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
 
1988
{
 
1989
        Event e;
 
1990
        e.setPasswordKeyStore(pstyle, keyStoreInfo, keyStoreEntry, ptr);
 
1991
        d->ask(e);
 
1992
}
 
1993
 
 
1994
void PasswordAsker::ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr)
 
1995
{
 
1996
        Event e;
 
1997
        e.setPasswordData(pstyle, fileName, ptr);
 
1998
        d->ask(e);
 
1999
}
 
2000
 
 
2001
void PasswordAsker::cancel()
 
2002
{
 
2003
        d->cancel();
 
2004
}
 
2005
 
 
2006
void PasswordAsker::waitForResponse()
 
2007
{
 
2008
        d->waitForResponse();
 
2009
}
 
2010
 
 
2011
bool PasswordAsker::accepted() const
 
2012
{
 
2013
        return d->accepted;
 
2014
}
 
2015
 
 
2016
SecureArray PasswordAsker::password() const
 
2017
{
 
2018
        return d->password;
 
2019
}
 
2020
 
 
2021
//----------------------------------------------------------------------------
 
2022
// TokenAsker
 
2023
//----------------------------------------------------------------------------
 
2024
class TokenAsker::Private : public AskerPrivate
 
2025
{
 
2026
public:
 
2027
        Private(TokenAsker *_q) : AskerPrivate(_q)
 
2028
        {
 
2029
        }
 
2030
 
 
2031
        virtual void emitResponseReady()
 
2032
        {
 
2033
                emit tokenAsker->responseReady();
 
2034
        }
 
2035
};
 
2036
 
 
2037
TokenAsker::TokenAsker(QObject *parent)
 
2038
:QObject(parent)
 
2039
{
 
2040
        d = new Private(this);
 
2041
}
 
2042
 
 
2043
TokenAsker::~TokenAsker()
 
2044
{
 
2045
        delete d;
 
2046
}
 
2047
 
 
2048
void TokenAsker::ask(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
 
2049
{
 
2050
        Event e;
 
2051
        e.setToken(keyStoreInfo, keyStoreEntry, ptr);
 
2052
        d->ask(e);
 
2053
}
 
2054
 
 
2055
void TokenAsker::cancel()
 
2056
{
 
2057
        d->cancel();
 
2058
}
 
2059
 
 
2060
void TokenAsker::waitForResponse()
 
2061
{
 
2062
        d->waitForResponse();
 
2063
}
 
2064
 
 
2065
bool TokenAsker::accepted() const
 
2066
{
 
2067
        return d->accepted;
 
2068
}
 
2069
 
 
2070
}
 
2071
 
 
2072
#include "qca_core.moc"