• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

qca

qca_basic.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2007  Justin Karneges <justin@affinix.com>
00003  * Copyright (C) 2004,2005,2007  Brad Hards <bradh@frogmouth.net>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00018  * 02110-1301  USA
00019  *
00020  */
00021 
00022 #include "qca_basic.h"
00023 
00024 #include "qcaprovider.h"
00025 
00026 #include <QMutexLocker>
00027 #include <QtGlobal>
00028 
00029 namespace QCA {
00030 
00031 // from qca_core.cpp
00032 QMutex *global_random_mutex();
00033 Random *global_random();
00034 Provider::Context *getContext(const QString &type, Provider *p);
00035 
00036 // from qca_publickey.cpp
00037 ProviderList allProviders();
00038 Provider *providerForName(const QString &name);
00039 
00040 static void mergeList(QStringList *a, const QStringList &b)
00041 {
00042     foreach(const QString &s, b)
00043     {
00044         if(!a->contains(s))
00045             a->append(s);
00046     }
00047 }
00048 
00049 static QStringList get_hash_types(Provider *p)
00050 {
00051     QStringList out;
00052     InfoContext *c = static_cast<InfoContext *>(getContext("info", p));
00053     if(!c)
00054         return out;
00055     out = c->supportedHashTypes();
00056     delete c;
00057     return out;
00058 }
00059 
00060 static QStringList get_cipher_types(Provider *p)
00061 {
00062     QStringList out;
00063     InfoContext *c = static_cast<InfoContext *>(getContext("info", p));
00064     if(!c)
00065         return out;
00066     out = c->supportedCipherTypes();
00067     delete c;
00068     return out;
00069 }
00070 
00071 static QStringList get_mac_types(Provider *p)
00072 {
00073     QStringList out;
00074     InfoContext *c = static_cast<InfoContext *>(getContext("info", p));
00075     if(!c)
00076         return out;
00077     out = c->supportedMACTypes();
00078     delete c;
00079     return out;
00080 }
00081 
00082 static QStringList get_types(QStringList (*get_func)(Provider *p), const QString &provider)
00083 {
00084     QStringList out;
00085     if(!provider.isEmpty())
00086     {
00087         Provider *p = providerForName(provider);
00088         if(p)
00089             out = get_func(p);
00090     }
00091     else
00092     {
00093         ProviderList pl = allProviders();
00094         foreach(Provider *p, pl)
00095             mergeList(&out, get_func(p));
00096     }
00097     return out;
00098 }
00099 
00100 static QStringList supportedHashTypes(const QString &provider)
00101 {
00102     return get_types(get_hash_types, provider);
00103 }
00104 
00105 static QStringList supportedCipherTypes(const QString &provider)
00106 {
00107     return get_types(get_cipher_types, provider);
00108 }
00109 
00110 static QStringList supportedMACTypes(const QString &provider)
00111 {
00112     return get_types(get_mac_types, provider);
00113 }
00114 
00115 //----------------------------------------------------------------------------
00116 // Random
00117 //----------------------------------------------------------------------------
00118 Random::Random(const QString &provider)
00119 :Algorithm("random", provider)
00120 {
00121 }
00122 
00123 Random::Random(const Random &from)
00124 :Algorithm(from)
00125 {
00126 }
00127 
00128 Random::~Random()
00129 {
00130 }
00131 
00132 Random & Random::operator=(const Random &from)
00133 {
00134     Algorithm::operator=(from);
00135     return *this;
00136 }
00137 
00138 uchar Random::nextByte()
00139 {
00140     return (uchar)(nextBytes(1)[0]);
00141 }
00142 
00143 SecureArray Random::nextBytes(int size)
00144 {
00145     return static_cast<RandomContext *>(context())->nextBytes(size);
00146 }
00147 
00148 uchar Random::randomChar()
00149 {
00150     QMutexLocker locker(global_random_mutex());
00151     return global_random()->nextByte();
00152 }
00153 
00154 int Random::randomInt()
00155 {
00156     QMutexLocker locker(global_random_mutex());
00157     SecureArray a = global_random()->nextBytes(sizeof(int));
00158     int x;
00159     memcpy(&x, a.data(), a.size());
00160     return x;
00161 }
00162 
00163 SecureArray Random::randomArray(int size)
00164 {
00165     QMutexLocker locker(global_random_mutex());
00166     return global_random()->nextBytes(size);
00167 }
00168 
00169 //----------------------------------------------------------------------------
00170 // Hash
00171 //----------------------------------------------------------------------------
00172 Hash::Hash(const QString &type, const QString &provider)
00173 :Algorithm(type, provider)
00174 {
00175 }
00176 
00177 Hash::Hash(const Hash &from)
00178 :Algorithm(from), BufferedComputation(from)
00179 {
00180 }
00181 
00182 Hash::~Hash()
00183 {
00184 }
00185 
00186 Hash & Hash::operator=(const Hash &from)
00187 {
00188     Algorithm::operator=(from);
00189     return *this;
00190 }
00191 
00192 QStringList Hash::supportedTypes(const QString &provider)
00193 {
00194     return supportedHashTypes(provider);
00195 }
00196 
00197 QString Hash::type() const
00198 {
00199     // algorithm type is the same as the hash type
00200     return Algorithm::type();
00201 }
00202 
00203 void Hash::clear()
00204 {
00205     static_cast<HashContext *>(context())->clear();
00206 }
00207 
00208 void Hash::update(const MemoryRegion &a)
00209 {
00210     static_cast<HashContext *>(context())->update(a);
00211 }
00212 
00213 void Hash::update(const QByteArray &a)
00214 {
00215     update(MemoryRegion(a));
00216 }
00217 
00218 void Hash::update(const char *data, int len)
00219 {
00220     if(len < 0)
00221         len = qstrlen(data);
00222     if(len == 0)
00223         return;
00224 
00225     update(MemoryRegion(QByteArray::fromRawData(data, len)));
00226 }
00227 
00228 // Reworked from KMD5, from KDE's kdelibs
00229 void Hash::update(QIODevice *file)
00230 {
00231     char buffer[1024];
00232     int len;
00233 
00234     while ((len=file->read(reinterpret_cast<char*>(buffer), sizeof(buffer))) > 0)
00235         update(buffer, len);
00236 }
00237 
00238 MemoryRegion Hash::final()
00239 {
00240     return static_cast<HashContext *>(context())->final();
00241 }
00242 
00243 MemoryRegion Hash::hash(const MemoryRegion &a)
00244 {
00245     return process(a);
00246 }
00247 
00248 QString Hash::hashToString(const MemoryRegion &a)
00249 {
00250     return arrayToHex(hash(a).toByteArray());
00251 }
00252 
00253 //----------------------------------------------------------------------------
00254 // Cipher
00255 //----------------------------------------------------------------------------
00256 class Cipher::Private
00257 {
00258 public:
00259     QString type;
00260     Cipher::Mode mode;
00261     Cipher::Padding pad;
00262     Direction dir;
00263     SymmetricKey key;
00264     InitializationVector iv;
00265 
00266     bool ok, done;
00267 };
00268 
00269 Cipher::Cipher(const QString &type, Mode mode, Padding pad,
00270     Direction dir, const SymmetricKey &key,
00271     const InitializationVector &iv,
00272     const QString &provider)
00273 :Algorithm(withAlgorithms(type, mode, pad), provider)
00274 {
00275     d = new Private;
00276     d->type = type;
00277     d->mode = mode;
00278     d->pad = pad;
00279     if(!key.isEmpty())
00280         setup(dir, key, iv);
00281 }
00282 
00283 Cipher::Cipher(const Cipher &from)
00284 :Algorithm(from), Filter(from)
00285 {
00286     d = new Private(*from.d);
00287 }
00288 
00289 Cipher::~Cipher()
00290 {
00291     delete d;
00292 }
00293 
00294 Cipher & Cipher::operator=(const Cipher &from)
00295 {
00296     Algorithm::operator=(from);
00297     *d = *from.d;
00298     return *this;
00299 }
00300 
00301 QStringList Cipher::supportedTypes(const QString &provider)
00302 {
00303     return supportedCipherTypes(provider);
00304 }
00305 
00306 QString Cipher::type() const
00307 {
00308     return d->type;
00309 }
00310 
00311 Cipher::Mode Cipher::mode() const
00312 {
00313     return d->mode;
00314 }
00315 
00316 Cipher::Padding Cipher::padding() const
00317 {
00318     return d->pad;
00319 }
00320 
00321 Direction Cipher::direction() const
00322 {
00323     return d->dir;
00324 }
00325 
00326 KeyLength Cipher::keyLength() const
00327 {
00328     return static_cast<const CipherContext *>(context())->keyLength();
00329 }
00330 
00331 bool Cipher::validKeyLength(int n) const
00332 {
00333     KeyLength len = keyLength();
00334     return ((n >= len.minimum()) && (n <= len.maximum()) && (n % len.multiple() == 0));
00335 }
00336 
00337 int Cipher::blockSize() const
00338 {
00339     return static_cast<const CipherContext *>(context())->blockSize();
00340 }
00341 
00342 void Cipher::clear()
00343 {
00344     d->done = false;
00345     static_cast<CipherContext *>(context())->setup(d->dir, d->key, d->iv);
00346 }
00347 
00348 MemoryRegion Cipher::update(const MemoryRegion &a)
00349 {
00350     SecureArray out;
00351     if(d->done)
00352         return out;
00353     d->ok = static_cast<CipherContext *>(context())->update(a, &out);
00354     return out;
00355 }
00356 
00357 MemoryRegion Cipher::final()
00358 {
00359     SecureArray out;
00360     if(d->done)
00361         return out;
00362     d->done = true;
00363     d->ok = static_cast<CipherContext *>(context())->final(&out);
00364     return out;
00365 }
00366 
00367 bool Cipher::ok() const
00368 {
00369     return d->ok;
00370 }
00371 
00372 void Cipher::setup(Direction dir, const SymmetricKey &key, const InitializationVector &iv)
00373 {
00374     d->dir = dir;
00375     d->key = key;
00376     d->iv = iv;
00377     clear();
00378 }
00379 
00380 QString Cipher::withAlgorithms(const QString &cipherType, Mode modeType, Padding paddingType)
00381 {
00382     QString mode;
00383     switch(modeType) {
00384     case CBC:
00385         mode = "cbc";
00386         break;
00387     case CFB:
00388         mode = "cfb";
00389         break;
00390     case OFB:
00391         mode = "ofb";
00392         break;
00393     case ECB:
00394         mode = "ecb";
00395         break;
00396     default:
00397         Q_ASSERT(0);
00398     }
00399 
00400     // do the default
00401     if(paddingType == DefaultPadding)
00402     {
00403         // logic from Botan
00404         if(modeType == CBC)
00405             paddingType = PKCS7;
00406         else
00407             paddingType = NoPadding;
00408     }
00409 
00410     QString pad;
00411     if(paddingType == NoPadding)
00412         pad = "";
00413     else
00414         pad = "pkcs7";
00415 
00416     QString result = cipherType + '-' + mode;
00417     if(!pad.isEmpty())
00418         result += QString("-") + pad;
00419 
00420     return result;
00421 }
00422 
00423 //----------------------------------------------------------------------------
00424 // MessageAuthenticationCode
00425 //----------------------------------------------------------------------------
00426 class MessageAuthenticationCode::Private
00427 {
00428 public:
00429     SymmetricKey key;
00430 
00431     bool done;
00432     MemoryRegion buf;
00433 };
00434 
00435 
00436 MessageAuthenticationCode::MessageAuthenticationCode(const QString &type,
00437     const SymmetricKey &key,
00438     const QString &provider)
00439 :Algorithm(type, provider)
00440 {
00441     d = new Private;
00442     setup(key);
00443 }
00444 
00445 MessageAuthenticationCode::MessageAuthenticationCode(const MessageAuthenticationCode &from)
00446 :Algorithm(from), BufferedComputation(from)
00447 {
00448     d = new Private(*from.d);
00449 }
00450 
00451 MessageAuthenticationCode::~MessageAuthenticationCode()
00452 {
00453     delete d;
00454 }
00455 
00456 MessageAuthenticationCode & MessageAuthenticationCode::operator=(const MessageAuthenticationCode &from)
00457 {
00458     Algorithm::operator=(from);
00459     *d = *from.d;
00460     return *this;
00461 }
00462 
00463 QStringList MessageAuthenticationCode::supportedTypes(const QString &provider)
00464 {
00465     return supportedMACTypes(provider);
00466 }
00467 
00468 QString MessageAuthenticationCode::type() const
00469 {
00470     // algorithm type is the same as the mac type
00471     return Algorithm::type();
00472 }
00473 
00474 KeyLength MessageAuthenticationCode::keyLength() const
00475 {
00476     return static_cast<const MACContext *>(context())->keyLength();
00477 }
00478 
00479 bool MessageAuthenticationCode::validKeyLength(int n) const
00480 {
00481     KeyLength len = keyLength();
00482     return ((n >= len.minimum()) && (n <= len.maximum()) && (n % len.multiple() == 0));
00483 }
00484 
00485 void MessageAuthenticationCode::clear()
00486 {
00487     d->done = false;
00488     static_cast<MACContext *>(context())->setup(d->key);
00489 }
00490 
00491 void MessageAuthenticationCode::update(const MemoryRegion &a)
00492 {
00493     if(d->done)
00494         return;
00495     static_cast<MACContext *>(context())->update(a);
00496 }
00497 
00498 MemoryRegion MessageAuthenticationCode::final()
00499 {
00500     if(!d->done)
00501     {
00502         d->done = true;
00503         static_cast<MACContext *>(context())->final(&d->buf);
00504     }
00505     return d->buf;
00506 }
00507 
00508 void MessageAuthenticationCode::setup(const SymmetricKey &key)
00509 {
00510     d->key = key;
00511     clear();
00512 }
00513 
00514 //----------------------------------------------------------------------------
00515 // Key Derivation Function
00516 //----------------------------------------------------------------------------
00517 KeyDerivationFunction::KeyDerivationFunction(const QString &type, const QString &provider)
00518 :Algorithm(type, provider)
00519 {
00520 }
00521 
00522 KeyDerivationFunction::KeyDerivationFunction(const KeyDerivationFunction &from)
00523 :Algorithm(from)
00524 {
00525 }
00526 
00527 KeyDerivationFunction::~KeyDerivationFunction()
00528 {
00529 }
00530 
00531 KeyDerivationFunction & KeyDerivationFunction::operator=(const KeyDerivationFunction &from)
00532 {
00533     Algorithm::operator=(from);
00534     return *this;
00535 }
00536 
00537 SymmetricKey KeyDerivationFunction::makeKey(const SecureArray &secret, const InitializationVector &salt, unsigned int keyLength, unsigned int iterationCount)
00538 {
00539     return static_cast<KDFContext *>(context())->makeKey(secret, salt, keyLength, iterationCount);
00540 }
00541 
00542 QString KeyDerivationFunction::withAlgorithm(const QString &kdfType, const QString &algType)
00543 {
00544     return (kdfType + '(' + algType + ')');
00545 }
00546 
00547 }

qca

Skip menu "qca"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal