00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qca_core.h"
00023
00024 #include "qca_plugin.h"
00025 #include "qca_textfilter.h"
00026 #include "qca_cert.h"
00027 #include "qca_keystore.h"
00028 #include "qcaprovider.h"
00029
00030
00031 #include <QCoreApplication>
00032
00033 #include <QMutex>
00034 #include <QSettings>
00035 #include <QVariantMap>
00036 #include <QWaitCondition>
00037
00038 #ifdef Q_OS_UNIX
00039 # include <unistd.h>
00040 #endif
00041
00042 int qcaVersion()
00043 {
00044 return QCA_VERSION;
00045 }
00046
00047 namespace QCA {
00048
00049
00050 bool botan_init(int prealloc, bool mmap);
00051 void botan_deinit();
00052
00053
00054 Provider *create_default_provider();
00055
00056
00057
00058
00059 class Global
00060 {
00061 public:
00062 int refs;
00063 bool secmem;
00064 bool loaded;
00065 bool first_scan;
00066 QString app_name;
00067 QMutex name_mutex;
00068 ProviderManager *manager;
00069 QMutex scan_mutex;
00070 Random *rng;
00071 QMutex rng_mutex;
00072 Logger *logger;
00073 QVariantMap properties;
00074 QMutex prop_mutex;
00075 QMap<QString,QVariantMap> config;
00076 QMutex config_mutex;
00077 QMutex logger_mutex;
00078
00079 Global()
00080 {
00081 refs = 0;
00082 secmem = false;
00083 loaded = false;
00084 first_scan = false;
00085 rng = 0;
00086 logger = 0;
00087 manager = new ProviderManager;
00088 }
00089
00090 ~Global()
00091 {
00092 KeyStoreManager::shutdown();
00093 delete rng;
00094 rng = 0;
00095 delete manager;
00096 manager = 0;
00097 delete logger;
00098 logger = 0;
00099 }
00100
00101 void ensure_loaded()
00102 {
00103
00104 QMutexLocker locker(&scan_mutex);
00105 if(!loaded)
00106 {
00107 loaded = true;
00108 manager->setDefault(create_default_provider());
00109 }
00110 }
00111
00112 bool ensure_first_scan()
00113 {
00114 scan_mutex.lock();
00115 if(!first_scan)
00116 {
00117 first_scan = true;
00118 manager->scan();
00119 scan_mutex.unlock();
00120 return true;
00121 }
00122 scan_mutex.unlock();
00123 return false;
00124 }
00125
00126 void scan()
00127 {
00128 scan_mutex.lock();
00129 first_scan = true;
00130 manager->scan();
00131 scan_mutex.unlock();
00132 }
00133
00134 void ksm_scan()
00135 {
00136 KeyStoreManager::scan();
00137 }
00138
00139 Logger *get_logger()
00140 {
00141 QMutexLocker locker(&logger_mutex);
00142 if(!logger)
00143 {
00144 logger = new Logger;
00145
00146
00147
00148 logger->moveToThread(0);
00149 }
00150 return logger;
00151 }
00152
00153 void unloadAllPlugins()
00154 {
00155 KeyStoreManager::shutdown();
00156
00157
00158 rng_mutex.lock();
00159 if(rng && (rng->provider() != manager->find("default")))
00160 {
00161 delete rng;
00162 rng = 0;
00163 }
00164 rng_mutex.unlock();
00165
00166 manager->unloadAll();
00167 }
00168 };
00169
00170 Q_GLOBAL_STATIC(QMutex, global_mutex)
00171 static Global *global = 0;
00172
00173 static bool features_have(const QStringList &have, const QStringList &want)
00174 {
00175 foreach(const QString &i, want)
00176 {
00177 if(!have.contains(i))
00178 return false;
00179 }
00180 return true;
00181 }
00182
00183 void init(MemoryMode mode, int prealloc)
00184 {
00185 QMutexLocker locker(global_mutex());
00186 if(global)
00187 {
00188 ++(global->refs);
00189 return;
00190 }
00191
00192 bool allow_mmap_fallback = false;
00193 bool drop_root = false;
00194 if(mode == Practical)
00195 {
00196 allow_mmap_fallback = true;
00197 drop_root = true;
00198 }
00199 else if(mode == Locking)
00200 drop_root = true;
00201
00202 bool secmem = botan_init(prealloc, allow_mmap_fallback);
00203
00204 if(drop_root)
00205 {
00206 #ifdef Q_OS_UNIX
00207 setuid(getuid());
00208 #endif
00209 }
00210
00211 global = new Global;
00212 global->secmem = secmem;
00213 ++(global->refs);
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 qAddPostRoutine(deinit);
00229 }
00230
00231 void init()
00232 {
00233 init(Practical, 64);
00234 }
00235
00236 void deinit()
00237 {
00238 QMutexLocker locker(global_mutex());
00239 if(!global)
00240 return;
00241 --(global->refs);
00242 if(global->refs == 0)
00243 {
00244 delete global;
00245 global = 0;
00246 botan_deinit();
00247 }
00248 }
00249
00250 static bool global_check()
00251 {
00252 Q_ASSERT(global);
00253 if(!global)
00254 return false;
00255 return true;
00256 }
00257
00258 static bool global_check_load()
00259 {
00260 Q_ASSERT(global);
00261 if(!global)
00262 return false;
00263 global->ensure_loaded();
00264 return true;
00265 }
00266
00267 QMutex *global_random_mutex()
00268 {
00269 return &global->rng_mutex;
00270 }
00271
00272 Random *global_random()
00273 {
00274 if(!global->rng)
00275 global->rng = new Random;
00276 return global->rng;
00277 }
00278
00279 bool haveSecureMemory()
00280 {
00281 if(!global_check())
00282 return false;
00283
00284 return global->secmem;
00285 }
00286
00287 bool haveSecureRandom()
00288 {
00289 if(!global_check_load())
00290 return false;
00291
00292 QMutexLocker locker(global_random_mutex());
00293 if(global_random()->provider()->name() != "default")
00294 return true;
00295
00296 return false;
00297 }
00298
00299 bool isSupported(const QStringList &features, const QString &provider)
00300 {
00301 if(!global_check_load())
00302 return false;
00303
00304
00305 if(!provider.isEmpty())
00306 {
00307 Provider *p = global->manager->find(provider);
00308 if(!p)
00309 {
00310
00311 global->scan();
00312 p = global->manager->find(provider);
00313 }
00314
00315 if(p && features_have(p->features(), features))
00316 return true;
00317 }
00318
00319 else
00320 {
00321 if(features_have(global->manager->allFeatures(), features))
00322 return true;
00323
00324 global->manager->appendDiagnosticText(QString("Scanning to find features: %1\n").arg(features.join(" ")));
00325
00326
00327 global->scan();
00328
00329 if(features_have(global->manager->allFeatures(), features))
00330 return true;
00331 }
00332 return false;
00333 }
00334
00335 bool isSupported(const char *features, const QString &provider)
00336 {
00337 return isSupported(QString(features).split(',', QString::SkipEmptyParts), provider);
00338 }
00339
00340 QStringList supportedFeatures()
00341 {
00342 if(!global_check_load())
00343 return QStringList();
00344
00345
00346 global->scan();
00347 return global->manager->allFeatures();
00348 }
00349
00350 QStringList defaultFeatures()
00351 {
00352 if(!global_check_load())
00353 return QStringList();
00354
00355 return global->manager->find("default")->features();
00356 }
00357
00358 ProviderList providers()
00359 {
00360 if(!global_check_load())
00361 return ProviderList();
00362
00363 global->ensure_first_scan();
00364
00365 return global->manager->providers();
00366 }
00367
00368 bool insertProvider(Provider *p, int priority)
00369 {
00370 if(!global_check_load())
00371 return false;
00372
00373 global->ensure_first_scan();
00374
00375 return global->manager->add(p, priority);
00376 }
00377
00378 void setProviderPriority(const QString &name, int priority)
00379 {
00380 if(!global_check_load())
00381 return;
00382
00383 global->ensure_first_scan();
00384
00385 global->manager->changePriority(name, priority);
00386 }
00387
00388 int providerPriority(const QString &name)
00389 {
00390 if(!global_check_load())
00391 return -1;
00392
00393 global->ensure_first_scan();
00394
00395 return global->manager->getPriority(name);
00396 }
00397
00398 Provider *findProvider(const QString &name)
00399 {
00400 if(!global_check_load())
00401 return 0;
00402
00403 global->ensure_first_scan();
00404
00405 return global->manager->find(name);
00406 }
00407
00408 Provider *defaultProvider()
00409 {
00410 if(!global_check_load())
00411 return 0;
00412
00413 return global->manager->find("default");
00414 }
00415
00416 void scanForPlugins()
00417 {
00418 if(!global_check_load())
00419 return;
00420
00421 global->scan();
00422 global->ksm_scan();
00423 }
00424
00425 void unloadAllPlugins()
00426 {
00427 if(!global_check_load())
00428 return;
00429
00430 global->unloadAllPlugins();
00431 }
00432
00433 QString pluginDiagnosticText()
00434 {
00435 if(!global_check_load())
00436 return QString();
00437
00438 return global->manager->diagnosticText();
00439 }
00440
00441 void clearPluginDiagnosticText()
00442 {
00443 if(!global_check_load())
00444 return;
00445
00446 global->manager->clearDiagnosticText();
00447 }
00448
00449 void appendPluginDiagnosticText(const QString &text)
00450 {
00451 if(!global_check_load())
00452 return;
00453
00454 global->manager->appendDiagnosticText(text);
00455 }
00456
00457 void setProperty(const QString &name, const QVariant &value)
00458 {
00459 if(!global_check_load())
00460 return;
00461
00462 QMutexLocker locker(&global->prop_mutex);
00463
00464 global->properties[name] = value;
00465 }
00466
00467 QVariant getProperty(const QString &name)
00468 {
00469 if(!global_check_load())
00470 return QVariant();
00471
00472 QMutexLocker locker(&global->prop_mutex);
00473
00474 return global->properties.value(name);
00475 }
00476
00477 static bool configIsValid(const QVariantMap &config)
00478 {
00479 if(!config.contains("formtype"))
00480 return false;
00481 QMapIterator<QString,QVariant> it(config);
00482 while(it.hasNext())
00483 {
00484 it.next();
00485 const QVariant &v = it.value();
00486 if(v.type() != QVariant::String && v.type() != QVariant::Int && v.type() != QVariant::Bool)
00487 return false;
00488 }
00489 return true;
00490 }
00491
00492 static QVariantMap readConfig(const QString &name)
00493 {
00494 QSettings settings("Affinix", "QCA2");
00495 settings.beginGroup("ProviderConfig");
00496 QStringList providerNames = settings.value("providerNames").toStringList();
00497 if(!providerNames.contains(name))
00498 return QVariantMap();
00499
00500 settings.beginGroup(name);
00501 QStringList keys = settings.childKeys();
00502 QVariantMap map;
00503 foreach(const QString &key, keys)
00504 map[key] = settings.value(key);
00505 settings.endGroup();
00506
00507 if(!configIsValid(map))
00508 return QVariantMap();
00509 return map;
00510 }
00511
00512 static bool writeConfig(const QString &name, const QVariantMap &config, bool systemWide = false)
00513 {
00514 QSettings settings(QSettings::NativeFormat, systemWide ? QSettings::SystemScope : QSettings::UserScope, "Affinix", "QCA2");
00515 settings.beginGroup("ProviderConfig");
00516
00517
00518 settings.setValue("version", 2);
00519
00520
00521 QStringList providerNames = settings.value("providerNames").toStringList();
00522 if(!providerNames.contains(name))
00523 providerNames += name;
00524 settings.setValue("providerNames", providerNames);
00525
00526 settings.beginGroup(name);
00527 QMapIterator<QString,QVariant> it(config);
00528 while(it.hasNext())
00529 {
00530 it.next();
00531 settings.setValue(it.key(), it.value());
00532 }
00533 settings.endGroup();
00534
00535 if(settings.status() == QSettings::NoError)
00536 return true;
00537 return false;
00538 }
00539
00540 void setProviderConfig(const QString &name, const QVariantMap &config)
00541 {
00542 if(!global_check_load())
00543 return;
00544
00545 if(!configIsValid(config))
00546 return;
00547
00548 global->config_mutex.lock();
00549 global->config[name] = config;
00550 global->config_mutex.unlock();
00551
00552 Provider *p = findProvider(name);
00553 if(p)
00554 p->configChanged(config);
00555 }
00556
00557 QVariantMap getProviderConfig(const QString &name)
00558 {
00559 if(!global_check_load())
00560 return QVariantMap();
00561
00562 QVariantMap conf;
00563
00564 global->config_mutex.lock();
00565
00566
00567 conf = readConfig(name);
00568
00569
00570 if(conf.isEmpty())
00571 conf = global->config.value(name);
00572
00573 global->config_mutex.unlock();
00574
00575
00576
00577 Provider *p = findProvider(name);
00578 if(!p)
00579 return conf;
00580 QVariantMap pconf = p->defaultConfig();
00581 if(!configIsValid(pconf))
00582 return conf;
00583
00584
00585 if(conf.isEmpty())
00586 return pconf;
00587
00588
00589
00590 if(pconf["formtype"] != conf["formtype"])
00591 return pconf;
00592
00593
00594 return conf;
00595 }
00596
00597 void saveProviderConfig(const QString &name)
00598 {
00599 if(!global_check_load())
00600 return;
00601
00602 QMutexLocker locker(&global->config_mutex);
00603
00604 QVariantMap conf = global->config.value(name);
00605 if(conf.isEmpty())
00606 return;
00607
00608 writeConfig(name, conf);
00609 }
00610
00611 QVariantMap getProviderConfig_internal(Provider *p)
00612 {
00613 QVariantMap conf;
00614 QString name = p->name();
00615
00616 global->config_mutex.lock();
00617
00618
00619 conf = readConfig(name);
00620
00621
00622 if(conf.isEmpty())
00623 conf = global->config.value(name);
00624
00625 global->config_mutex.unlock();
00626
00627
00628
00629 QVariantMap pconf = p->defaultConfig();
00630 if(!configIsValid(pconf))
00631 return conf;
00632
00633
00634 if(conf.isEmpty())
00635 return pconf;
00636
00637
00638
00639 if(pconf["formtype"] != conf["formtype"])
00640 return pconf;
00641
00642
00643 return conf;
00644 }
00645
00646 QString globalRandomProvider()
00647 {
00648 QMutexLocker locker(global_random_mutex());
00649 return global_random()->provider()->name();
00650 }
00651
00652 void setGlobalRandomProvider(const QString &provider)
00653 {
00654 QMutexLocker locker(global_random_mutex());
00655 delete global->rng;
00656 global->rng = new Random(provider);
00657 }
00658
00659 Logger *logger()
00660 {
00661 return global->get_logger();
00662 }
00663
00664 bool haveSystemStore()
00665 {
00666
00667 KeyStoreManager::start("default");
00668 KeyStoreManager ksm;
00669 ksm.waitForBusyFinished();
00670
00671 QStringList list = ksm.keyStores();
00672 for(int n = 0; n < list.count(); ++n)
00673 {
00674 KeyStore ks(list[n], &ksm);
00675 if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates())
00676 return true;
00677 }
00678 return false;
00679 }
00680
00681 CertificateCollection systemStore()
00682 {
00683
00684 KeyStoreManager::start("default");
00685 KeyStoreManager ksm;
00686 ksm.waitForBusyFinished();
00687
00688 CertificateCollection col;
00689 QStringList list = ksm.keyStores();
00690 for(int n = 0; n < list.count(); ++n)
00691 {
00692 KeyStore ks(list[n], &ksm);
00693
00694
00695 if(ks.type() == KeyStore::System && ks.holdsTrustedCertificates())
00696 {
00697
00698 QList<KeyStoreEntry> entries = ks.entryList();
00699 for(int i = 0; i < entries.count(); ++i)
00700 {
00701 if(entries[i].type() == KeyStoreEntry::TypeCertificate)
00702 col.addCertificate(entries[i].certificate());
00703 else if(entries[i].type() == KeyStoreEntry::TypeCRL)
00704 col.addCRL(entries[i].crl());
00705 }
00706 break;
00707 }
00708 }
00709 return col;
00710 }
00711
00712 QString appName()
00713 {
00714 if(!global_check())
00715 return QString();
00716
00717 QMutexLocker locker(&global->name_mutex);
00718
00719 return global->app_name;
00720 }
00721
00722 void setAppName(const QString &s)
00723 {
00724 if(!global_check())
00725 return;
00726
00727 QMutexLocker locker(&global->name_mutex);
00728
00729 global->app_name = s;
00730 }
00731
00732 QString arrayToHex(const QByteArray &a)
00733 {
00734 return Hex().arrayToString(a);
00735 }
00736
00737 QByteArray hexToArray(const QString &str)
00738 {
00739 return Hex().stringToArray(str).toByteArray();
00740 }
00741
00742 static Provider *getProviderForType(const QString &type, const QString &provider)
00743 {
00744 Provider *p = 0;
00745 bool scanned = global->ensure_first_scan();
00746 if(!provider.isEmpty())
00747 {
00748
00749 p = global->manager->findFor(provider, type);
00750 if(!p && !scanned)
00751 {
00752
00753 global->scan();
00754 scanned = true;
00755 p = global->manager->findFor(provider, type);
00756 }
00757 }
00758 if(!p)
00759 {
00760
00761 p = global->manager->findFor(QString(), type);
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 if(!p && !scanned)
00773 {
00774
00775
00776 global->scan();
00777 scanned = true;
00778 p = global->manager->findFor(QString(), type);
00779 }
00780 }
00781
00782 return p;
00783 }
00784
00785 static inline Provider::Context *doCreateContext(Provider *p, const QString &type)
00786 {
00787 return p->createContext(type);
00788 }
00789
00790 Provider::Context *getContext(const QString &type, const QString &provider)
00791 {
00792 if(!global_check_load())
00793 return 0;
00794
00795 Provider *p;
00796 {
00797 p = getProviderForType(type, provider);
00798 if(!p)
00799 return 0;
00800 }
00801
00802 return doCreateContext(p, type);
00803 }
00804
00805 Provider::Context *getContext(const QString &type, Provider *_p)
00806 {
00807 if(!global_check_load())
00808 return 0;
00809
00810 Provider *p;
00811 {
00812 p = global->manager->find(_p);
00813 if(!p)
00814 return 0;
00815 }
00816
00817 return doCreateContext(p, type);
00818 }
00819
00820
00821
00822
00823 Initializer::Initializer(MemoryMode m, int prealloc)
00824 {
00825 init(m, prealloc);
00826 }
00827
00828 Initializer::~Initializer()
00829 {
00830 deinit();
00831 }
00832
00833
00834
00835
00836 Provider::~Provider()
00837 {
00838 }
00839
00840 void Provider::init()
00841 {
00842 }
00843
00844 void Provider::deinit()
00845 {
00846 }
00847
00848 int Provider::version() const
00849 {
00850 return 0;
00851 }
00852
00853 QString Provider::credit() const
00854 {
00855 return QString();
00856 }
00857
00858 QVariantMap Provider::defaultConfig() const
00859 {
00860 return QVariantMap();
00861 }
00862
00863 void Provider::configChanged(const QVariantMap &)
00864 {
00865 }
00866
00867 Provider::Context::Context(Provider *parent, const QString &type)
00868 :QObject()
00869 {
00870 _provider = parent;
00871 _type = type;
00872 }
00873
00874 Provider::Context::Context(const Context &from)
00875 :QObject()
00876 {
00877 _provider = from._provider;
00878 _type = from._type;
00879 }
00880
00881 Provider::Context::~Context()
00882 {
00883 }
00884
00885 Provider *Provider::Context::provider() const
00886 {
00887 return _provider;
00888 }
00889
00890 QString Provider::Context::type() const
00891 {
00892 return _type;
00893 }
00894
00895 bool Provider::Context::sameProvider(const Context *c) const
00896 {
00897 return (c->provider() == _provider);
00898 }
00899
00900
00901
00902
00903 BasicContext::BasicContext(Provider *parent, const QString &type)
00904 :Context(parent, type)
00905 {
00906 moveToThread(0);
00907 }
00908
00909 BasicContext::BasicContext(const BasicContext &from)
00910 :Context(from)
00911 {
00912 moveToThread(0);
00913 }
00914
00915 BasicContext::~BasicContext()
00916 {
00917 }
00918
00919
00920
00921
00922 QStringList InfoContext::supportedHashTypes() const
00923 {
00924 return QStringList();
00925 }
00926
00927 QStringList InfoContext::supportedCipherTypes() const
00928 {
00929 return QStringList();
00930 }
00931
00932 QStringList InfoContext::supportedMACTypes() const
00933 {
00934 return QStringList();
00935 }
00936
00937
00938
00939
00940 PKeyBase::PKeyBase(Provider *p, const QString &type)
00941 :BasicContext(p, type)
00942 {
00943 }
00944
00945 int PKeyBase::maximumEncryptSize(EncryptionAlgorithm) const
00946 {
00947 return 0;
00948 }
00949
00950 SecureArray PKeyBase::encrypt(const SecureArray &, EncryptionAlgorithm)
00951 {
00952 return SecureArray();
00953 }
00954
00955 bool PKeyBase::decrypt(const SecureArray &, SecureArray *, EncryptionAlgorithm)
00956 {
00957 return false;
00958 }
00959
00960 void PKeyBase::startSign(SignatureAlgorithm, SignatureFormat)
00961 {
00962 }
00963
00964 void PKeyBase::startVerify(SignatureAlgorithm, SignatureFormat)
00965 {
00966 }
00967
00968 void PKeyBase::update(const MemoryRegion &)
00969 {
00970 }
00971
00972 QByteArray PKeyBase::endSign()
00973 {
00974 return QByteArray();
00975 }
00976
00977 bool PKeyBase::endVerify(const QByteArray &)
00978 {
00979 return false;
00980 }
00981
00982 SymmetricKey PKeyBase::deriveKey(const PKeyBase &)
00983 {
00984 return SymmetricKey();
00985 }
00986
00987
00988
00989
00990 QByteArray PKeyContext::publicToDER() const
00991 {
00992 return QByteArray();
00993 }
00994
00995 QString PKeyContext::publicToPEM() const
00996 {
00997 return QString();
00998 }
00999
01000 ConvertResult PKeyContext::publicFromDER(const QByteArray &)
01001 {
01002 return ErrorDecode;
01003 }
01004
01005 ConvertResult PKeyContext::publicFromPEM(const QString &)
01006 {
01007 return ErrorDecode;
01008 }
01009
01010 SecureArray PKeyContext::privateToDER(const SecureArray &, PBEAlgorithm) const
01011 {
01012 return SecureArray();
01013 }
01014
01015 QString PKeyContext::privateToPEM(const SecureArray &, PBEAlgorithm) const
01016 {
01017 return QString();
01018 }
01019
01020 ConvertResult PKeyContext::privateFromDER(const SecureArray &, const SecureArray &)
01021 {
01022 return ErrorDecode;
01023 }
01024
01025 ConvertResult PKeyContext::privateFromPEM(const QString &, const SecureArray &)
01026 {
01027 return ErrorDecode;
01028 }
01029
01030
01031
01032
01033 bool KeyStoreEntryContext::isAvailable() const
01034 {
01035 return true;
01036 }
01037
01038 KeyBundle KeyStoreEntryContext::keyBundle() const
01039 {
01040 return KeyBundle();
01041 }
01042
01043 Certificate KeyStoreEntryContext::certificate() const
01044 {
01045 return Certificate();
01046 }
01047
01048 CRL KeyStoreEntryContext::crl() const
01049 {
01050 return CRL();
01051 }
01052
01053 PGPKey KeyStoreEntryContext::pgpSecretKey() const
01054 {
01055 return PGPKey();
01056 }
01057
01058 PGPKey KeyStoreEntryContext::pgpPublicKey() const
01059 {
01060 return PGPKey();
01061 }
01062
01063 bool KeyStoreEntryContext::ensureAccess()
01064 {
01065 return true;
01066 }
01067
01068
01069
01070
01071 void KeyStoreListContext::start()
01072 {
01073 QMetaObject::invokeMethod(this, "busyEnd", Qt::QueuedConnection);
01074 }
01075
01076 void KeyStoreListContext::setUpdatesEnabled(bool)
01077 {
01078 }
01079
01080 bool KeyStoreListContext::isReadOnly(int) const
01081 {
01082 return true;
01083 }
01084
01085 KeyStoreEntryContext *KeyStoreListContext::entry(int id, const QString &entryId)
01086 {
01087 KeyStoreEntryContext *out = 0;
01088 QList<KeyStoreEntryContext*> list = entryList(id);
01089 for(int n = 0; n < list.count(); ++n)
01090 {
01091 if(list[n]->id() == entryId)
01092 {
01093 out = list.takeAt(n);
01094 break;
01095 }
01096 }
01097 qDeleteAll(list);
01098 return out;
01099 }
01100
01101 KeyStoreEntryContext *KeyStoreListContext::entryPassive(const QString &serialized)
01102 {
01103 Q_UNUSED(serialized);
01104 return 0;
01105 }
01106
01107 QString KeyStoreListContext::writeEntry(int, const KeyBundle &)
01108 {
01109 return QString();
01110 }
01111
01112 QString KeyStoreListContext::writeEntry(int, const Certificate &)
01113 {
01114 return QString();
01115 }
01116
01117 QString KeyStoreListContext::writeEntry(int, const CRL &)
01118 {
01119 return QString();
01120 }
01121
01122 QString KeyStoreListContext::writeEntry(int, const PGPKey &)
01123 {
01124 return QString();
01125 }
01126
01127 bool KeyStoreListContext::removeEntry(int, const QString &)
01128 {
01129 return false;
01130 }
01131
01132
01133
01134
01135 void TLSContext::setMTU(int)
01136 {
01137 }
01138
01139
01140
01141
01142 QString MessageContext::diagnosticText() const
01143 {
01144 return QString();
01145 }
01146
01147
01148
01149
01150 void SMSContext::setTrustedCertificates(const CertificateCollection &)
01151 {
01152 }
01153
01154 void SMSContext::setUntrustedCertificates(const CertificateCollection &)
01155 {
01156 }
01157
01158 void SMSContext::setPrivateKeys(const QList<SecureMessageKey> &)
01159 {
01160 }
01161
01162
01163
01164
01165 BufferedComputation::~BufferedComputation()
01166 {
01167 }
01168
01169 MemoryRegion BufferedComputation::process(const MemoryRegion &a)
01170 {
01171 clear();
01172 update(a);
01173 return final();
01174 }
01175
01176
01177
01178
01179 Filter::~Filter()
01180 {
01181 }
01182
01183 MemoryRegion Filter::process(const MemoryRegion &a)
01184 {
01185 clear();
01186 MemoryRegion buf = update(a);
01187 if(!ok())
01188 return MemoryRegion();
01189 MemoryRegion fin = final();
01190 if(!ok())
01191 return MemoryRegion();
01192 if(buf.isSecure() || fin.isSecure())
01193 return (SecureArray(buf) + SecureArray(fin));
01194 else
01195 return (buf.toByteArray() + fin.toByteArray());
01196 }
01197
01198
01199
01200
01201 class Algorithm::Private : public QSharedData
01202 {
01203 public:
01204 Provider::Context *c;
01205
01206 Private(Provider::Context *context)
01207 {
01208 c = context;
01209
01210 }
01211
01212 Private(const Private &from) : QSharedData(from)
01213 {
01214 c = from.c->clone();
01215
01216 }
01217
01218 ~Private()
01219 {
01220
01221 delete c;
01222 }
01223 };
01224
01225 Algorithm::Algorithm()
01226 {
01227 }
01228
01229 Algorithm::Algorithm(const QString &type, const QString &provider)
01230 {
01231 change(type, provider);
01232 }
01233
01234 Algorithm::Algorithm(const Algorithm &from)
01235 {
01236 *this = from;
01237 }
01238
01239 Algorithm::~Algorithm()
01240 {
01241 }
01242
01243 Algorithm & Algorithm::operator=(const Algorithm &from)
01244 {
01245 d = from.d;
01246 return *this;
01247 }
01248
01249 QString Algorithm::type() const
01250 {
01251 if(d)
01252 return d->c->type();
01253 else
01254 return QString();
01255 }
01256
01257 Provider *Algorithm::provider() const
01258 {
01259 if(d)
01260 return d->c->provider();
01261 else
01262 return 0;
01263 }
01264
01265 Provider::Context *Algorithm::context()
01266 {
01267 if(d)
01268 return d->c;
01269 else
01270 return 0;
01271 }
01272
01273 const Provider::Context *Algorithm::context() const
01274 {
01275 if(d)
01276 return d->c;
01277 else
01278 return 0;
01279 }
01280
01281 void Algorithm::change(Provider::Context *c)
01282 {
01283 if(c)
01284 d = new Private(c);
01285 else
01286 d = 0;
01287 }
01288
01289 void Algorithm::change(const QString &type, const QString &provider)
01290 {
01291 if(!type.isEmpty())
01292 change(getContext(type, provider));
01293 else
01294 change(0);
01295 }
01296
01297 Provider::Context *Algorithm::takeContext()
01298 {
01299 if(d)
01300 {
01301 Provider::Context *c = d->c;
01302 d->c = 0;
01303 d = 0;
01304 return c;
01305 }
01306 else
01307 return 0;
01308 }
01309
01310
01311
01312
01313 SymmetricKey::SymmetricKey()
01314 {
01315 }
01316
01317 SymmetricKey::SymmetricKey(int size)
01318 {
01319 set(Random::randomArray(size));
01320 }
01321
01322 SymmetricKey::SymmetricKey(const SecureArray &a)
01323 {
01324 set(a);
01325 }
01326
01327 SymmetricKey::SymmetricKey(const QByteArray &a)
01328 {
01329 set(SecureArray(a));
01330 }
01331
01332
01333 static unsigned char desWeakKeyTable[64][8] =
01334 {
01335 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
01336 { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
01337 { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
01338 { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
01339 { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },
01340 { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
01341 { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
01342 { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
01343 { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 },
01344 { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
01345 { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
01346 { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
01347 { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },
01348 { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
01349 { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
01350 { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
01351 { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
01352 { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },
01353 { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
01354 { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
01355 { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
01356 { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },
01357 { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
01358 { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
01359 { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
01360 { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },
01361 { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
01362 { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
01363 { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
01364 { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },
01365 { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
01366 { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
01367 { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
01368 { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
01369 { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
01370 { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
01371 { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
01372 { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
01373 { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
01374 { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
01375 { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
01376 { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
01377 { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 },
01378 { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
01379 { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
01380 { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
01381 { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },
01382 { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
01383 { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
01384 { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
01385 { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
01386 { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 },
01387 { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
01388 { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
01389 { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
01390 { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
01391 { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
01392 { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
01393 { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
01394 { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
01395 { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
01396 { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
01397 { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
01398 { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }
01399 };
01400
01401 bool SymmetricKey::isWeakDESKey()
01402 {
01403 if(size() != 8)
01404 return false;
01405 SecureArray workingCopy(8);
01406
01407 for(uint i = 0; i < 8; i++)
01408 workingCopy[i] = (data()[i]) & 0xfe;
01409
01410 for(int n = 0; n < 64; n++)
01411 {
01412 if(memcmp(workingCopy.data(), desWeakKeyTable[n], 8) == 0)
01413 return true;
01414 }
01415 return false;
01416 }
01417
01418
01419
01420
01421 InitializationVector::InitializationVector()
01422 {
01423 }
01424
01425 InitializationVector::InitializationVector(int size)
01426 {
01427 set(Random::randomArray(size));
01428 }
01429
01430 InitializationVector::InitializationVector(const SecureArray &a)
01431 {
01432 set(a);
01433 }
01434
01435 InitializationVector::InitializationVector(const QByteArray &a)
01436 {
01437 set(SecureArray(a));
01438 }
01439
01440
01441
01442
01443 class Event::Private : public QSharedData
01444 {
01445 public:
01446 Type type;
01447 Source source;
01448 PasswordStyle style;
01449 KeyStoreInfo ksi;
01450 KeyStoreEntry kse;
01451 QString fname;
01452 void *ptr;
01453 };
01454
01455 Event::Event()
01456 {
01457 }
01458
01459 Event::Event(const Event &from)
01460 :d(from.d)
01461 {
01462 }
01463
01464 Event::~Event()
01465 {
01466 }
01467
01468 Event & Event::operator=(const Event &from)
01469 {
01470 d = from.d;
01471 return *this;
01472 }
01473
01474 bool Event::isNull() const
01475 {
01476 return (d ? false : true);
01477 }
01478
01479 Event::Type Event::type() const
01480 {
01481 return d->type;
01482 }
01483
01484 Event::Source Event::source() const
01485 {
01486 return d->source;
01487 }
01488
01489 Event::PasswordStyle Event::passwordStyle() const
01490 {
01491 return d->style;
01492 }
01493
01494 KeyStoreInfo Event::keyStoreInfo() const
01495 {
01496 return d->ksi;
01497 }
01498
01499 KeyStoreEntry Event::keyStoreEntry() const
01500 {
01501 return d->kse;
01502 }
01503
01504 QString Event::fileName() const
01505 {
01506 return d->fname;
01507 }
01508
01509 void *Event::ptr() const
01510 {
01511 return d->ptr;
01512 }
01513
01514 void Event::setPasswordKeyStore(PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
01515 {
01516 if(!d)
01517 d = new Private;
01518 d->type = Password;
01519 d->source = KeyStore;
01520 d->style = pstyle;
01521 d->ksi = keyStoreInfo;
01522 d->kse = keyStoreEntry;
01523 d->fname = QString();
01524 d->ptr = ptr;
01525 }
01526
01527 void Event::setPasswordData(PasswordStyle pstyle, const QString &fileName, void *ptr)
01528 {
01529 if(!d)
01530 d = new Private;
01531 d->type = Password;
01532 d->source = Data;
01533 d->style = pstyle;
01534 d->ksi = KeyStoreInfo();
01535 d->kse = KeyStoreEntry();
01536 d->fname = fileName;
01537 d->ptr = ptr;
01538 }
01539
01540 void Event::setToken(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
01541 {
01542 if(!d)
01543 d = new Private;
01544 d->type = Token;
01545 d->source = KeyStore;
01546 d->style = StylePassword;
01547 d->ksi = keyStoreInfo;
01548 d->kse = keyStoreEntry;
01549 d->fname = QString();
01550 d->ptr = ptr;
01551 }
01552
01553
01554
01555
01556 class HandlerBase : public QObject
01557 {
01558 Q_OBJECT
01559 public:
01560 HandlerBase(QObject *parent = 0) : QObject(parent)
01561 {
01562 }
01563
01564 protected slots:
01565 virtual void ask(int id, const QCA::Event &e) = 0;
01566 };
01567
01568 class AskerBase : public QObject
01569 {
01570 Q_OBJECT
01571 public:
01572 AskerBase(QObject *parent = 0) : QObject(parent)
01573 {
01574 }
01575
01576 virtual void set_accepted(const SecureArray &password) = 0;
01577 virtual void set_rejected() = 0;
01578 };
01579
01580 static void handler_add(HandlerBase *h, int pos = -1);
01581 static void handler_remove(HandlerBase *h);
01582 static void handler_accept(HandlerBase *h, int id, const SecureArray &password);
01583 static void handler_reject(HandlerBase *h, int id);
01584 static bool asker_ask(AskerBase *a, const Event &e);
01585 static void asker_cancel(AskerBase *a);
01586
01587 Q_GLOBAL_STATIC(QMutex, g_event_mutex)
01588
01589 class EventGlobal;
01590 static EventGlobal *g_event = 0;
01591
01592 class EventGlobal
01593 {
01594 public:
01595 class HandlerItem
01596 {
01597 public:
01598 HandlerBase *h;
01599 QList<int> ids;
01600 };
01601
01602 class AskerItem
01603 {
01604 public:
01605 AskerBase *a;
01606 int id;
01607 Event event;
01608 int handler_pos;
01609 };
01610
01611 QList<HandlerItem> handlers;
01612 QList<AskerItem> askers;
01613
01614 int next_id;
01615
01616 EventGlobal()
01617 {
01618 qRegisterMetaType<Event>("QCA::Event");
01619 qRegisterMetaType<SecureArray>("QCA::SecureArray");
01620 next_id = 0;
01621 }
01622
01623 int findHandlerItem(HandlerBase *h)
01624 {
01625 for(int n = 0; n < handlers.count(); ++n)
01626 {
01627 if(handlers[n].h == h)
01628 return n;
01629 }
01630 return -1;
01631 }
01632
01633 int findAskerItem(AskerBase *a)
01634 {
01635 for(int n = 0; n < askers.count(); ++n)
01636 {
01637 if(askers[n].a == a)
01638 return n;
01639 }
01640 return -1;
01641 }
01642
01643 int findAskerItemById(int id)
01644 {
01645 for(int n = 0; n < askers.count(); ++n)
01646 {
01647 if(askers[n].id == id)
01648 return n;
01649 }
01650 return -1;
01651 }
01652
01653 void ask(int asker_at)
01654 {
01655 AskerItem &i = askers[asker_at];
01656
01657 g_event->handlers[i.handler_pos].ids += i.id;
01658 QMetaObject::invokeMethod(handlers[i.handler_pos].h, "ask",
01659 Qt::QueuedConnection, Q_ARG(int, i.id),
01660 Q_ARG(QCA::Event, i.event));
01661 }
01662
01663 void reject(int asker_at)
01664 {
01665 AskerItem &i = askers[asker_at];
01666
01667
01668 int pos = -1;
01669 for(int n = i.handler_pos + 1; n < g_event->handlers.count(); ++n)
01670 {
01671
01672
01673
01674
01675 pos = n;
01676 break;
01677
01678 }
01679
01680
01681 if(pos != -1)
01682 {
01683 i.handler_pos = pos;
01684 ask(asker_at);
01685 }
01686
01687 else
01688 {
01689 AskerBase *asker = i.a;
01690 askers.removeAt(asker_at);
01691
01692 asker->set_rejected();
01693 }
01694 }
01695 };
01696
01697 void handler_add(HandlerBase *h, int pos)
01698 {
01699 QMutexLocker locker(g_event_mutex());
01700 if(!g_event)
01701 g_event = new EventGlobal;
01702
01703 EventGlobal::HandlerItem i;
01704 i.h = h;
01705
01706 if(pos != -1)
01707 {
01708 g_event->handlers.insert(pos, i);
01709
01710
01711 for(int n = 0; n < g_event->askers.count(); ++n)
01712 {
01713 if(g_event->askers[n].handler_pos >= pos)
01714 g_event->askers[n].handler_pos++;
01715 }
01716 }
01717 else
01718 g_event->handlers += i;
01719 }
01720
01721 void handler_remove(HandlerBase *h)
01722 {
01723 QMutexLocker locker(g_event_mutex());
01724 Q_ASSERT(g_event);
01725 if(!g_event)
01726 return;
01727 int at = g_event->findHandlerItem(h);
01728 Q_ASSERT(at != -1);
01729 if(at == -1)
01730 return;
01731
01732 QList<int> ids = g_event->handlers[at].ids;
01733 g_event->handlers.removeAt(at);
01734
01735
01736 for(int n = 0; n < g_event->askers.count(); ++n)
01737 {
01738 if(g_event->askers[n].handler_pos >= at)
01739 g_event->askers[n].handler_pos--;
01740 }
01741
01742
01743 foreach(int id, ids)
01744 {
01745 int asker_at = g_event->findAskerItemById(id);
01746 Q_ASSERT(asker_at != -1);
01747
01748 g_event->reject(asker_at);
01749 }
01750
01751 if(g_event->handlers.isEmpty())
01752 {
01753 delete g_event;
01754 g_event = 0;
01755 }
01756 }
01757
01758 void handler_accept(HandlerBase *h, int id, const SecureArray &password)
01759 {
01760 QMutexLocker locker(g_event_mutex());
01761 Q_ASSERT(g_event);
01762 if(!g_event)
01763 return;
01764 int at = g_event->findHandlerItem(h);
01765 Q_ASSERT(at != -1);
01766 if(at == -1)
01767 return;
01768 int asker_at = g_event->findAskerItemById(id);
01769 Q_ASSERT(asker_at != -1);
01770 if(asker_at == -1)
01771 return;
01772
01773 g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id);
01774
01775 AskerBase *asker = g_event->askers[asker_at].a;
01776 asker->set_accepted(password);
01777 }
01778
01779 void handler_reject(HandlerBase *h, int id)
01780 {
01781 QMutexLocker locker(g_event_mutex());
01782 Q_ASSERT(g_event);
01783 if(!g_event)
01784 return;
01785 int at = g_event->findHandlerItem(h);
01786 Q_ASSERT(at != -1);
01787 if(at == -1)
01788 return;
01789 int asker_at = g_event->findAskerItemById(id);
01790 Q_ASSERT(asker_at != -1);
01791 if(asker_at == -1)
01792 return;
01793
01794 g_event->handlers[at].ids.removeAll(g_event->askers[asker_at].id);
01795
01796 g_event->reject(asker_at);
01797 }
01798
01799 bool asker_ask(AskerBase *a, const Event &e)
01800 {
01801 QMutexLocker locker(g_event_mutex());
01802 if(!g_event)
01803 return false;
01804
01805 int pos = -1;
01806 for(int n = 0; n < g_event->handlers.count(); ++n)
01807 {
01808
01809
01810
01811
01812 pos = n;
01813 break;
01814
01815 }
01816 if(pos == -1)
01817 return false;
01818
01819 EventGlobal::AskerItem i;
01820 i.a = a;
01821 i.id = g_event->next_id++;
01822 i.event = e;
01823 i.handler_pos = pos;
01824 g_event->askers += i;
01825 int asker_at = g_event->askers.count() - 1;
01826
01827 g_event->ask(asker_at);
01828 return true;
01829 }
01830
01831 void asker_cancel(AskerBase *a)
01832 {
01833 QMutexLocker locker(g_event_mutex());
01834 if(!g_event)
01835 return;
01836 int at = g_event->findAskerItem(a);
01837 if(at == -1)
01838 return;
01839
01840 for(int n = 0; n < g_event->handlers.count(); ++n)
01841 g_event->handlers[n].ids.removeAll(g_event->askers[at].id);
01842
01843 g_event->askers.removeAt(at);
01844 }
01845
01846
01847
01848
01849 class EventHandler::Private : public HandlerBase
01850 {
01851 Q_OBJECT
01852 public:
01853 EventHandler *q;
01854 bool started;
01855 QList<int> activeIds;
01856
01857 Private(EventHandler *_q) : HandlerBase(_q), q(_q)
01858 {
01859 started = false;
01860 }
01861
01862 public slots:
01863 virtual void ask(int id, const QCA::Event &e)
01864 {
01865 activeIds += id;
01866 emit q->eventReady(id, e);
01867 }
01868 };
01869
01870 EventHandler::EventHandler(QObject *parent)
01871 :QObject(parent)
01872 {
01873 d = new Private(this);
01874 }
01875
01876 EventHandler::~EventHandler()
01877 {
01878 if(d->started)
01879 {
01880 foreach(int id, d->activeIds)
01881 handler_reject(d, id);
01882
01883 handler_remove(d);
01884 }
01885
01886 delete d;
01887 }
01888
01889 void EventHandler::start()
01890 {
01891 d->started = true;
01892 handler_add(d);
01893 }
01894
01895 void EventHandler::submitPassword(int id, const SecureArray &password)
01896 {
01897 if(!d->activeIds.contains(id))
01898 return;
01899
01900 d->activeIds.removeAll(id);
01901 handler_accept(d, id, password);
01902 }
01903
01904 void EventHandler::tokenOkay(int id)
01905 {
01906 if(!d->activeIds.contains(id))
01907 return;
01908
01909 d->activeIds.removeAll(id);
01910 handler_accept(d, id, SecureArray());
01911 }
01912
01913 void EventHandler::reject(int id)
01914 {
01915 if(!d->activeIds.contains(id))
01916 return;
01917
01918 d->activeIds.removeAll(id);
01919 handler_reject(d, id);
01920 }
01921
01922
01923
01924
01925 class AskerPrivate : public AskerBase
01926 {
01927 Q_OBJECT
01928 public:
01929 enum Type { Password, Token };
01930
01931 Type type;
01932 PasswordAsker *passwordAsker;
01933 TokenAsker *tokenAsker;
01934
01935 QMutex m;
01936 QWaitCondition w;
01937
01938 bool accepted;
01939 SecureArray password;
01940 bool waiting;
01941 bool done;
01942
01943 AskerPrivate(PasswordAsker *parent) : AskerBase(parent)
01944 {
01945 passwordAsker = parent;
01946 tokenAsker = 0;
01947 type = Password;
01948 accepted = false;
01949 waiting = false;
01950 done = true;
01951 }
01952
01953 AskerPrivate(TokenAsker *parent) : AskerBase(parent)
01954 {
01955 passwordAsker = 0;
01956 tokenAsker = parent;
01957 type = Token;
01958 accepted = false;
01959 waiting = false;
01960 done = true;
01961 }
01962
01963 void ask(const Event &e)
01964 {
01965 accepted = false;
01966 waiting = false;
01967 done = false;
01968 password.clear();
01969
01970 if(!asker_ask(this, e))
01971 {
01972 done = true;
01973 QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
01974 }
01975 }
01976
01977 void cancel()
01978 {
01979 if(!done)
01980 asker_cancel(this);
01981 }
01982
01983 virtual void set_accepted(const SecureArray &_password)
01984 {
01985 QMutexLocker locker(&m);
01986 accepted = true;
01987 password = _password;
01988 done = true;
01989 if(waiting)
01990 w.wakeOne();
01991 else
01992 QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
01993 }
01994
01995 virtual void set_rejected()
01996 {
01997 QMutexLocker locker(&m);
01998 done = true;
01999 if(waiting)
02000 w.wakeOne();
02001 else
02002 QMetaObject::invokeMethod(this, "emitResponseReady", Qt::QueuedConnection);
02003 }
02004
02005 void waitForResponse()
02006 {
02007 QMutexLocker locker(&m);
02008 if(done)
02009 return;
02010 waiting = true;
02011 w.wait(&m);
02012 waiting = false;
02013 }
02014
02015 public slots:
02016 virtual void emitResponseReady() = 0;
02017 };
02018
02019 class PasswordAsker::Private : public AskerPrivate
02020 {
02021 public:
02022 Private(PasswordAsker *_q) : AskerPrivate(_q)
02023 {
02024 }
02025
02026 virtual void emitResponseReady()
02027 {
02028 emit passwordAsker->responseReady();
02029 }
02030 };
02031
02032 PasswordAsker::PasswordAsker(QObject *parent)
02033 :QObject(parent)
02034 {
02035 d = new Private(this);
02036 }
02037
02038 PasswordAsker::~PasswordAsker()
02039 {
02040 delete d;
02041 }
02042
02043 void PasswordAsker::ask(Event::PasswordStyle pstyle, const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
02044 {
02045 Event e;
02046 e.setPasswordKeyStore(pstyle, keyStoreInfo, keyStoreEntry, ptr);
02047 d->ask(e);
02048 }
02049
02050 void PasswordAsker::ask(Event::PasswordStyle pstyle, const QString &fileName, void *ptr)
02051 {
02052 Event e;
02053 e.setPasswordData(pstyle, fileName, ptr);
02054 d->ask(e);
02055 }
02056
02057 void PasswordAsker::cancel()
02058 {
02059 d->cancel();
02060 }
02061
02062 void PasswordAsker::waitForResponse()
02063 {
02064 d->waitForResponse();
02065 }
02066
02067 bool PasswordAsker::accepted() const
02068 {
02069 return d->accepted;
02070 }
02071
02072 SecureArray PasswordAsker::password() const
02073 {
02074 return d->password;
02075 }
02076
02077
02078
02079
02080 class TokenAsker::Private : public AskerPrivate
02081 {
02082 public:
02083 Private(TokenAsker *_q) : AskerPrivate(_q)
02084 {
02085 }
02086
02087 virtual void emitResponseReady()
02088 {
02089 emit tokenAsker->responseReady();
02090 }
02091 };
02092
02093 TokenAsker::TokenAsker(QObject *parent)
02094 :QObject(parent)
02095 {
02096 d = new Private(this);
02097 }
02098
02099 TokenAsker::~TokenAsker()
02100 {
02101 delete d;
02102 }
02103
02104 void TokenAsker::ask(const KeyStoreInfo &keyStoreInfo, const KeyStoreEntry &keyStoreEntry, void *ptr)
02105 {
02106 Event e;
02107 e.setToken(keyStoreInfo, keyStoreEntry, ptr);
02108 d->ask(e);
02109 }
02110
02111 void TokenAsker::cancel()
02112 {
02113 d->cancel();
02114 }
02115
02116 void TokenAsker::waitForResponse()
02117 {
02118 d->waitForResponse();
02119 }
02120
02121 bool TokenAsker::accepted() const
02122 {
02123 return d->accepted;
02124 }
02125
02126 }
02127
02128 #include "qca_core.moc"