summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/libiris/qca/src
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/jabber/libiris/qca/src')
-rw-r--r--kopete/protocols/jabber/libiris/qca/src/Makefile.am7
-rw-r--r--kopete/protocols/jabber/libiris/qca/src/qca.cpp1481
-rw-r--r--kopete/protocols/jabber/libiris/qca/src/qca.h466
-rw-r--r--kopete/protocols/jabber/libiris/qca/src/qcaprovider.h191
4 files changed, 2145 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/libiris/qca/src/Makefile.am b/kopete/protocols/jabber/libiris/qca/src/Makefile.am
new file mode 100644
index 00000000..b43d303e
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/qca/src/Makefile.am
@@ -0,0 +1,7 @@
+METASOURCES = AUTO
+
+noinst_LTLIBRARIES = libqca.la
+INCLUDES = $(all_includes)
+
+libqca_la_SOURCES = \
+ qca.cpp
diff --git a/kopete/protocols/jabber/libiris/qca/src/qca.cpp b/kopete/protocols/jabber/libiris/qca/src/qca.cpp
new file mode 100644
index 00000000..5b67e6e3
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/qca/src/qca.cpp
@@ -0,0 +1,1481 @@
+/*
+ * qca.cpp - Qt Cryptographic Architecture
+ * Copyright (C) 2003 Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include"qca.h"
+
+#include<qptrlist.h>
+#include<qdir.h>
+#include<qfileinfo.h>
+#include<qstringlist.h>
+#include<qlibrary.h>
+#include<qtimer.h>
+#include<qhostaddress.h>
+#include<qapplication.h>
+#include<qguardedptr.h>
+#include<stdlib.h>
+#include"qcaprovider.h"
+
+#if defined(Q_OS_WIN32)
+#define PLUGIN_EXT "dll"
+#elif defined(Q_OS_MAC)
+#define PLUGIN_EXT "dylib"
+#else
+#define PLUGIN_EXT "so"
+#endif
+
+using namespace QCA;
+
+class ProviderItem
+{
+public:
+ QCAProvider *p;
+ QString fname;
+
+ static ProviderItem *load(const QString &fname)
+ {
+ QLibrary *lib = new QLibrary(fname);
+ if(!lib->load()) {
+ delete lib;
+ return 0;
+ }
+ void *s = lib->resolve("createProvider");
+ if(!s) {
+ delete lib;
+ return 0;
+ }
+ QCAProvider *(*createProvider)() = (QCAProvider *(*)())s;
+ QCAProvider *p = createProvider();
+ if(!p) {
+ delete lib;
+ return 0;
+ }
+ ProviderItem *i = new ProviderItem(lib, p);
+ i->fname = fname;
+ return i;
+ }
+
+ static ProviderItem *fromClass(QCAProvider *p)
+ {
+ ProviderItem *i = new ProviderItem(0, p);
+ return i;
+ }
+
+ ~ProviderItem()
+ {
+ delete p;
+ delete lib;
+ }
+
+ void ensureInit()
+ {
+ if(init_done)
+ return;
+ init_done = true;
+ p->init();
+ }
+
+private:
+ QLibrary *lib;
+ bool init_done;
+
+ ProviderItem(QLibrary *_lib, QCAProvider *_p)
+ {
+ lib = _lib;
+ p = _p;
+ init_done = false;
+ }
+};
+
+static QPtrList<ProviderItem> providerList;
+static bool qca_init = false;
+
+static bool plugin_have(const QString &fname)
+{
+ QPtrListIterator<ProviderItem> it(providerList);
+ for(ProviderItem *i; (i = it.current()); ++it) {
+ if(i->fname == fname)
+ return true;
+ }
+ return false;
+}
+
+static void plugin_scan()
+{
+ QStringList dirs = QApplication::libraryPaths();
+ for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
+ QDir libpath(*it);
+ QDir dir(libpath.filePath("crypto"));
+ if(!dir.exists())
+ continue;
+
+ QStringList list = dir.entryList();
+ for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ QFileInfo fi(dir.filePath(*it));
+ if(fi.isDir())
+ continue;
+ if(fi.extension() != PLUGIN_EXT)
+ continue;
+ QString fname = fi.filePath();
+
+ // don't load the same plugin again!
+ if(plugin_have(fname))
+ continue;
+ //printf("f=[%s]\n", fname.latin1());
+
+ ProviderItem *i = ProviderItem::load(fname);
+ if(!i)
+ continue;
+ if(i->p->qcaVersion() != QCA_PLUGIN_VERSION) {
+ delete i;
+ continue;
+ }
+
+ providerList.append(i);
+ }
+ }
+}
+
+static void plugin_addClass(QCAProvider *p)
+{
+ ProviderItem *i = ProviderItem::fromClass(p);
+ providerList.prepend(i);
+}
+
+static void plugin_unloadall()
+{
+ providerList.clear();
+}
+
+static int plugin_caps()
+{
+ int caps = 0;
+ QPtrListIterator<ProviderItem> it(providerList);
+ for(ProviderItem *i; (i = it.current()); ++it)
+ caps |= i->p->capabilities();
+ return caps;
+}
+
+QString QCA::arrayToHex(const QByteArray &a)
+{
+ QString out;
+ for(int n = 0; n < (int)a.size(); ++n) {
+ QString str;
+ str.sprintf("%02x", (uchar)a[n]);
+ out.append(str);
+ }
+ return out;
+}
+
+QByteArray QCA::hexToArray(const QString &str)
+{
+ QByteArray out(str.length() / 2);
+ int at = 0;
+ for(int n = 0; n + 1 < (int)str.length(); n += 2) {
+ uchar a = str[n];
+ uchar b = str[n+1];
+ uchar c = ((a & 0x0f) << 4) + (b & 0x0f);
+ out[at++] = c;
+ }
+ return out;
+}
+
+void QCA::init()
+{
+ if(qca_init)
+ return;
+ qca_init = true;
+ providerList.setAutoDelete(true);
+}
+
+bool QCA::isSupported(int capabilities)
+{
+ init();
+
+ int caps = plugin_caps();
+ if(caps & capabilities)
+ return true;
+
+ // ok, try scanning for new stuff
+ plugin_scan();
+ caps = plugin_caps();
+ if(caps & capabilities)
+ return true;
+
+ return false;
+}
+
+void QCA::insertProvider(QCAProvider *p)
+{
+ plugin_addClass(p);
+}
+
+void QCA::unloadAllPlugins()
+{
+ plugin_unloadall();
+}
+
+static void *getContext(int cap)
+{
+ init();
+
+ // this call will also trip a scan for new plugins if needed
+ if(!QCA::isSupported(cap))
+ return 0;
+
+ QPtrListIterator<ProviderItem> it(providerList);
+ for(ProviderItem *i; (i = it.current()); ++it) {
+ if(i->p->capabilities() & cap) {
+ i->ensureInit();
+ return i->p->context(cap);
+ }
+ }
+ return 0;
+}
+
+
+//----------------------------------------------------------------------------
+// Hash
+//----------------------------------------------------------------------------
+class Hash::Private
+{
+public:
+ Private()
+ {
+ c = 0;
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ void reset()
+ {
+ c->reset();
+ }
+
+ QCA_HashContext *c;
+};
+
+Hash::Hash(QCA_HashContext *c)
+{
+ d = new Private;
+ d->c = c;
+}
+
+Hash::Hash(const Hash &from)
+{
+ d = new Private;
+ *this = from;
+}
+
+Hash & Hash::operator=(const Hash &from)
+{
+ delete d->c;
+ d->c = from.d->c->clone();
+ return *this;
+}
+
+Hash::~Hash()
+{
+ delete d;
+}
+
+void Hash::clear()
+{
+ d->reset();
+}
+
+void Hash::update(const QByteArray &a)
+{
+ d->c->update(a.data(), a.size());
+}
+
+QByteArray Hash::final()
+{
+ QByteArray buf;
+ d->c->final(&buf);
+ return buf;
+}
+
+
+//----------------------------------------------------------------------------
+// Cipher
+//----------------------------------------------------------------------------
+class Cipher::Private
+{
+public:
+ Private()
+ {
+ c = 0;
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ void reset()
+ {
+ dir = Encrypt;
+ key.resize(0);
+ iv.resize(0);
+ err = false;
+ }
+
+ QCA_CipherContext *c;
+ int dir;
+ int mode;
+ QByteArray key, iv;
+ bool err;
+};
+
+Cipher::Cipher(QCA_CipherContext *c, int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad)
+{
+ d = new Private;
+ d->c = c;
+ reset(dir, mode, key, iv, pad);
+}
+
+Cipher::Cipher(const Cipher &from)
+{
+ d = new Private;
+ *this = from;
+}
+
+Cipher & Cipher::operator=(const Cipher &from)
+{
+ delete d->c;
+ d->c = from.d->c->clone();
+ d->dir = from.d->dir;
+ d->mode = from.d->mode;
+ d->key = from.d->key.copy();
+ d->iv = from.d->iv.copy();
+ d->err = from.d->err;
+ return *this;
+}
+
+Cipher::~Cipher()
+{
+ delete d;
+}
+
+QByteArray Cipher::dyn_generateKey(int size) const
+{
+ QByteArray buf;
+ if(size != -1)
+ buf.resize(size);
+ else
+ buf.resize(d->c->keySize());
+ if(!d->c->generateKey(buf.data(), size))
+ return QByteArray();
+ return buf;
+}
+
+QByteArray Cipher::dyn_generateIV() const
+{
+ QByteArray buf(d->c->blockSize());
+ if(!d->c->generateIV(buf.data()))
+ return QByteArray();
+ return buf;
+}
+
+void Cipher::reset(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad)
+{
+ d->reset();
+
+ d->dir = dir;
+ d->mode = mode;
+ d->key = key.copy();
+ d->iv = iv.copy();
+ if(!d->c->setup(d->dir, d->mode, d->key.isEmpty() ? 0: d->key.data(), d->key.size(), d->iv.isEmpty() ? 0 : d->iv.data(), pad)) {
+ d->err = true;
+ return;
+ }
+}
+
+bool Cipher::update(const QByteArray &a)
+{
+ if(d->err)
+ return false;
+
+ if(!a.isEmpty()) {
+ if(!d->c->update(a.data(), a.size())) {
+ d->err = true;
+ return false;
+ }
+ }
+ return true;
+}
+
+QByteArray Cipher::final(bool *ok)
+{
+ if(ok)
+ *ok = false;
+ if(d->err)
+ return QByteArray();
+
+ QByteArray out;
+ if(!d->c->final(&out)) {
+ d->err = true;
+ return QByteArray();
+ }
+ if(ok)
+ *ok = true;
+ return out;
+}
+
+
+//----------------------------------------------------------------------------
+// SHA1
+//----------------------------------------------------------------------------
+SHA1::SHA1()
+:Hash((QCA_HashContext *)getContext(CAP_SHA1))
+{
+}
+
+
+//----------------------------------------------------------------------------
+// SHA256
+//----------------------------------------------------------------------------
+SHA256::SHA256()
+:Hash((QCA_HashContext *)getContext(CAP_SHA256))
+{
+}
+
+
+//----------------------------------------------------------------------------
+// MD5
+//----------------------------------------------------------------------------
+MD5::MD5()
+:Hash((QCA_HashContext *)getContext(CAP_MD5))
+{
+}
+
+
+//----------------------------------------------------------------------------
+// BlowFish
+//----------------------------------------------------------------------------
+BlowFish::BlowFish(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad)
+:Cipher((QCA_CipherContext *)getContext(CAP_BlowFish), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// TripleDES
+//----------------------------------------------------------------------------
+TripleDES::TripleDES(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad)
+:Cipher((QCA_CipherContext *)getContext(CAP_TripleDES), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// AES128
+//----------------------------------------------------------------------------
+AES128::AES128(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad)
+:Cipher((QCA_CipherContext *)getContext(CAP_AES128), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// AES256
+//----------------------------------------------------------------------------
+AES256::AES256(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad)
+:Cipher((QCA_CipherContext *)getContext(CAP_AES256), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// RSAKey
+//----------------------------------------------------------------------------
+class RSAKey::Private
+{
+public:
+ Private()
+ {
+ c = 0;
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ QCA_RSAKeyContext *c;
+};
+
+RSAKey::RSAKey()
+{
+ d = new Private;
+ d->c = (QCA_RSAKeyContext *)getContext(CAP_RSA);
+}
+
+RSAKey::RSAKey(const RSAKey &from)
+{
+ d = new Private;
+ *this = from;
+}
+
+RSAKey & RSAKey::operator=(const RSAKey &from)
+{
+ delete d->c;
+ d->c = from.d->c->clone();
+ return *this;
+}
+
+RSAKey::~RSAKey()
+{
+ delete d;
+}
+
+bool RSAKey::isNull() const
+{
+ return d->c->isNull();
+}
+
+bool RSAKey::havePublic() const
+{
+ return d->c->havePublic();
+}
+
+bool RSAKey::havePrivate() const
+{
+ return d->c->havePrivate();
+}
+
+QByteArray RSAKey::toDER(bool publicOnly) const
+{
+ QByteArray out;
+ if(!d->c->toDER(&out, publicOnly))
+ return QByteArray();
+ return out;
+}
+
+bool RSAKey::fromDER(const QByteArray &a)
+{
+ return d->c->createFromDER(a.data(), a.size());
+}
+
+QString RSAKey::toPEM(bool publicOnly) const
+{
+ QByteArray out;
+ if(!d->c->toPEM(&out, publicOnly))
+ return QByteArray();
+
+ QCString cs;
+ cs.resize(out.size()+1);
+ memcpy(cs.data(), out.data(), out.size());
+ return QString::fromLatin1(cs);
+}
+
+bool RSAKey::fromPEM(const QString &str)
+{
+ QCString cs = str.latin1();
+ QByteArray a(cs.length());
+ memcpy(a.data(), cs.data(), a.size());
+ return d->c->createFromPEM(a.data(), a.size());
+}
+
+bool RSAKey::fromNative(void *p)
+{
+ return d->c->createFromNative(p);
+}
+
+bool RSAKey::encrypt(const QByteArray &a, QByteArray *b, bool oaep) const
+{
+ QByteArray out;
+ if(!d->c->encrypt(a, &out, oaep))
+ return false;
+ *b = out;
+ return true;
+}
+
+bool RSAKey::decrypt(const QByteArray &a, QByteArray *b, bool oaep) const
+{
+ QByteArray out;
+ if(!d->c->decrypt(a, &out, oaep))
+ return false;
+ *b = out;
+ return true;
+}
+
+bool RSAKey::generate(unsigned int bits)
+{
+ return d->c->generate(bits);
+}
+
+
+//----------------------------------------------------------------------------
+// RSA
+//----------------------------------------------------------------------------
+RSA::RSA()
+{
+}
+
+RSA::~RSA()
+{
+}
+
+RSAKey RSA::key() const
+{
+ return v_key;
+}
+
+void RSA::setKey(const RSAKey &k)
+{
+ v_key = k;
+}
+
+bool RSA::encrypt(const QByteArray &a, QByteArray *b, bool oaep) const
+{
+ if(v_key.isNull())
+ return false;
+ return v_key.encrypt(a, b, oaep);
+}
+
+bool RSA::decrypt(const QByteArray &a, QByteArray *b, bool oaep) const
+{
+ if(v_key.isNull())
+ return false;
+ return v_key.decrypt(a, b, oaep);
+}
+
+RSAKey RSA::generateKey(unsigned int bits)
+{
+ RSAKey k;
+ k.generate(bits);
+ return k;
+}
+
+
+//----------------------------------------------------------------------------
+// Cert
+//----------------------------------------------------------------------------
+class Cert::Private
+{
+public:
+ Private()
+ {
+ c = 0;
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ QCA_CertContext *c;
+};
+
+Cert::Cert()
+{
+ d = new Private;
+ d->c = (QCA_CertContext *)getContext(CAP_X509);
+}
+
+Cert::Cert(const Cert &from)
+{
+ d = new Private;
+ *this = from;
+}
+
+Cert & Cert::operator=(const Cert &from)
+{
+ delete d->c;
+ d->c = from.d->c->clone();
+ return *this;
+}
+
+Cert::~Cert()
+{
+ delete d;
+}
+
+void Cert::fromContext(QCA_CertContext *ctx)
+{
+ delete d->c;
+ d->c = ctx;
+}
+
+bool Cert::isNull() const
+{
+ return d->c->isNull();
+}
+
+QString Cert::commonName() const
+{
+ CertProperties props = subject();
+ return props["CN"];
+}
+
+QString Cert::serialNumber() const
+{
+ return d->c->serialNumber();
+}
+
+QString Cert::subjectString() const
+{
+ return d->c->subjectString();
+}
+
+QString Cert::issuerString() const
+{
+ return d->c->issuerString();
+}
+
+CertProperties Cert::subject() const
+{
+ QValueList<QCA_CertProperty> list = d->c->subject();
+ CertProperties props;
+ for(QValueList<QCA_CertProperty>::ConstIterator it = list.begin(); it != list.end(); ++it)
+ props[(*it).var] = (*it).val;
+ return props;
+}
+
+CertProperties Cert::issuer() const
+{
+ QValueList<QCA_CertProperty> list = d->c->issuer();
+ CertProperties props;
+ for(QValueList<QCA_CertProperty>::ConstIterator it = list.begin(); it != list.end(); ++it)
+ props[(*it).var] = (*it).val;
+ return props;
+}
+
+QDateTime Cert::notBefore() const
+{
+ return d->c->notBefore();
+}
+
+QDateTime Cert::notAfter() const
+{
+ return d->c->notAfter();
+}
+
+QByteArray Cert::toDER() const
+{
+ QByteArray out;
+ if(!d->c->toDER(&out))
+ return QByteArray();
+ return out;
+}
+
+bool Cert::fromDER(const QByteArray &a)
+{
+ return d->c->createFromDER(a.data(), a.size());
+}
+
+QString Cert::toPEM() const
+{
+ QByteArray out;
+ if(!d->c->toPEM(&out))
+ return QByteArray();
+
+ QCString cs;
+ cs.resize(out.size()+1);
+ memcpy(cs.data(), out.data(), out.size());
+ return QString::fromLatin1(cs);
+}
+
+bool Cert::fromPEM(const QString &str)
+{
+ QCString cs = str.latin1();
+ QByteArray a(cs.length());
+ memcpy(a.data(), cs.data(), a.size());
+ return d->c->createFromPEM(a.data(), a.size());
+}
+
+
+//----------------------------------------------------------------------------
+// TLS
+//----------------------------------------------------------------------------
+class TLS::Private
+{
+public:
+ Private()
+ {
+ c = (QCA_TLSContext *)getContext(CAP_TLS);
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ void reset()
+ {
+ handshaken = false;
+ closing = false;
+ in.resize(0);
+ out.resize(0);
+ from_net.resize(0);
+ to_net.resize(0);
+ host = "";
+ hostMismatch = false;
+ cert = Cert();
+ bytesEncoded = 0;
+ tryMore = false;
+ }
+
+ void appendArray(QByteArray *a, const QByteArray &b)
+ {
+ int oldsize = a->size();
+ a->resize(oldsize + b.size());
+ memcpy(a->data() + oldsize, b.data(), b.size());
+ }
+
+ Cert cert;
+ QCA_TLSContext *c;
+ QByteArray in, out, to_net, from_net;
+ int bytesEncoded;
+ bool tryMore;
+ bool handshaken;
+ QString host;
+ bool hostMismatch;
+ bool closing;
+
+ Cert ourCert;
+ RSAKey ourKey;
+ QPtrList<QCA_CertContext> store;
+};
+
+TLS::TLS(QObject *parent)
+:QObject(parent)
+{
+ d = new Private;
+}
+
+TLS::~TLS()
+{
+ delete d;
+}
+
+void TLS::setCertificate(const Cert &cert, const RSAKey &key)
+{
+ d->ourCert = cert;
+ d->ourKey = key;
+}
+
+void TLS::setCertificateStore(const QPtrList<Cert> &store)
+{
+ // convert the cert list into a context list
+ d->store.clear();
+ QPtrListIterator<Cert> it(store);
+ for(Cert *cert; (cert = it.current()); ++it)
+ d->store.append(cert->d->c);
+}
+
+void TLS::reset()
+{
+ d->reset();
+}
+
+bool TLS::startClient(const QString &host)
+{
+ d->reset();
+ d->host = host;
+
+ if(!d->c->startClient(d->store, *d->ourCert.d->c, *d->ourKey.d->c))
+ return false;
+ QTimer::singleShot(0, this, SLOT(update()));
+ return true;
+}
+
+bool TLS::startServer()
+{
+ d->reset();
+
+ if(!d->c->startServer(d->store, *d->ourCert.d->c, *d->ourKey.d->c))
+ return false;
+ QTimer::singleShot(0, this, SLOT(update()));
+ return true;
+}
+
+void TLS::close()
+{
+ if(!d->handshaken || d->closing)
+ return;
+
+ d->closing = true;
+ QTimer::singleShot(0, this, SLOT(update()));
+}
+
+bool TLS::isHandshaken() const
+{
+ return d->handshaken;
+}
+
+void TLS::write(const QByteArray &a)
+{
+ d->appendArray(&d->out, a);
+ update();
+}
+
+QByteArray TLS::read()
+{
+ QByteArray a = d->in.copy();
+ d->in.resize(0);
+ return a;
+}
+
+void TLS::writeIncoming(const QByteArray &a)
+{
+ d->appendArray(&d->from_net, a);
+ update();
+}
+
+QByteArray TLS::readOutgoing()
+{
+ QByteArray a = d->to_net.copy();
+ d->to_net.resize(0);
+ return a;
+}
+
+QByteArray TLS::readUnprocessed()
+{
+ QByteArray a = d->from_net.copy();
+ d->from_net.resize(0);
+ return a;
+}
+
+const Cert & TLS::peerCertificate() const
+{
+ return d->cert;
+}
+
+int TLS::certificateValidityResult() const
+{
+ if(d->hostMismatch)
+ return QCA::TLS::HostMismatch;
+ else
+ return d->c->validityResult();
+}
+
+void TLS::update()
+{
+ bool force_read = false;
+ bool eof = false;
+ bool done = false;
+ QGuardedPtr<TLS> self = this;
+
+ if(d->closing) {
+ QByteArray a;
+ int r = d->c->shutdown(d->from_net, &a);
+ d->from_net.resize(0);
+ if(r == QCA_TLSContext::Error) {
+ reset();
+ error(ErrHandshake);
+ return;
+ }
+ if(r == QCA_TLSContext::Success) {
+ d->from_net = d->c->unprocessed().copy();
+ done = true;
+ }
+ d->appendArray(&d->to_net, a);
+ }
+ else {
+ if(!d->handshaken) {
+ QByteArray a;
+ int r = d->c->handshake(d->from_net, &a);
+ d->from_net.resize(0);
+ if(r == QCA_TLSContext::Error) {
+ reset();
+ error(ErrHandshake);
+ return;
+ }
+ d->appendArray(&d->to_net, a);
+ if(r == QCA_TLSContext::Success) {
+ QCA_CertContext *cc = d->c->peerCertificate();
+ if(cc && !d->host.isEmpty() && d->c->validityResult() == QCA::TLS::Valid) {
+ if(!cc->matchesAddress(d->host))
+ d->hostMismatch = true;
+ }
+ d->cert.fromContext(cc);
+ d->handshaken = true;
+ handshaken();
+ if(!self)
+ return;
+
+ // there is a teeny tiny possibility that incoming data awaits. let us get it.
+ force_read = true;
+ }
+ }
+
+ if(d->handshaken) {
+ if(!d->out.isEmpty() || d->tryMore) {
+ d->tryMore = false;
+ QByteArray a;
+ int enc;
+ bool more = false;
+ bool ok = d->c->encode(d->out, &a, &enc);
+ eof = d->c->eof();
+ if(ok && enc < (int)d->out.size())
+ more = true;
+ d->out.resize(0);
+ if(!eof) {
+ if(!ok) {
+ reset();
+ error(ErrCrypt);
+ return;
+ }
+ d->bytesEncoded += enc;
+ if(more)
+ d->tryMore = true;
+ d->appendArray(&d->to_net, a);
+ }
+ }
+ if(!d->from_net.isEmpty() || force_read) {
+ QByteArray a, b;
+ bool ok = d->c->decode(d->from_net, &a, &b);
+ eof = d->c->eof();
+ d->from_net.resize(0);
+ if(!ok) {
+ reset();
+ error(ErrCrypt);
+ return;
+ }
+ d->appendArray(&d->in, a);
+ d->appendArray(&d->to_net, b);
+ }
+
+ if(!d->in.isEmpty()) {
+ readyRead();
+ if(!self)
+ return;
+ }
+ }
+ }
+
+ if(!d->to_net.isEmpty()) {
+ int bytes = d->bytesEncoded;
+ d->bytesEncoded = 0;
+ readyReadOutgoing(bytes);
+ if(!self)
+ return;
+ }
+
+ if(eof) {
+ close();
+ if(!self)
+ return;
+ return;
+ }
+
+ if(d->closing && done) {
+ reset();
+ closed();
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// SASL
+//----------------------------------------------------------------------------
+QString saslappname = "qca";
+class SASL::Private
+{
+public:
+ Private()
+ {
+ c = (QCA_SASLContext *)getContext(CAP_SASL);
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ void setSecurityProps()
+ {
+ c->setSecurityProps(noPlain, noActive, noDict, noAnon, reqForward, reqCreds, reqMutual, ssfmin, ssfmax, ext_authid, ext_ssf);
+ }
+
+ // security opts
+ bool noPlain, noActive, noDict, noAnon, reqForward, reqCreds, reqMutual;
+ int ssfmin, ssfmax;
+ QString ext_authid;
+ int ext_ssf;
+
+ bool tried;
+ QCA_SASLContext *c;
+ QHostAddress localAddr, remoteAddr;
+ int localPort, remotePort;
+ QByteArray stepData;
+ bool allowCSF;
+ bool first, server;
+
+ QByteArray inbuf, outbuf;
+};
+
+SASL::SASL(QObject *parent)
+:QObject(parent)
+{
+ d = new Private;
+ reset();
+}
+
+SASL::~SASL()
+{
+ delete d;
+}
+
+void SASL::setAppName(const QString &name)
+{
+ saslappname = name;
+}
+
+void SASL::reset()
+{
+ d->localPort = -1;
+ d->remotePort = -1;
+
+ d->noPlain = false;
+ d->noActive = false;
+ d->noDict = false;
+ d->noAnon = false;
+ d->reqForward = false;
+ d->reqCreds = false;
+ d->reqMutual = false;
+ d->ssfmin = 0;
+ d->ssfmax = 0;
+ d->ext_authid = "";
+ d->ext_ssf = 0;
+
+ d->inbuf.resize(0);
+ d->outbuf.resize(0);
+
+ d->c->reset();
+}
+
+int SASL::errorCondition() const
+{
+ return d->c->errorCond();
+}
+
+void SASL::setAllowPlain(bool b)
+{
+ d->noPlain = !b;
+}
+
+void SASL::setAllowAnonymous(bool b)
+{
+ d->noAnon = !b;
+}
+
+void SASL::setAllowActiveVulnerable(bool b)
+{
+ d->noActive = !b;
+}
+
+void SASL::setAllowDictionaryVulnerable(bool b)
+{
+ d->noDict = !b;
+}
+
+void SASL::setRequireForwardSecrecy(bool b)
+{
+ d->reqForward = b;
+}
+
+void SASL::setRequirePassCredentials(bool b)
+{
+ d->reqCreds = b;
+}
+
+void SASL::setRequireMutualAuth(bool b)
+{
+ d->reqMutual = b;
+}
+
+void SASL::setMinimumSSF(int x)
+{
+ d->ssfmin = x;
+}
+
+void SASL::setMaximumSSF(int x)
+{
+ d->ssfmax = x;
+}
+
+void SASL::setExternalAuthID(const QString &authid)
+{
+ d->ext_authid = authid;
+}
+
+void SASL::setExternalSSF(int x)
+{
+ d->ext_ssf = x;
+}
+
+void SASL::setLocalAddr(const QHostAddress &addr, Q_UINT16 port)
+{
+ d->localAddr = addr;
+ d->localPort = port;
+}
+
+void SASL::setRemoteAddr(const QHostAddress &addr, Q_UINT16 port)
+{
+ d->remoteAddr = addr;
+ d->remotePort = port;
+}
+
+bool SASL::startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst)
+{
+ QCA_SASLHostPort la, ra;
+ if(d->localPort != -1) {
+ la.addr = d->localAddr;
+ la.port = d->localPort;
+ }
+ if(d->remotePort != -1) {
+ ra.addr = d->remoteAddr;
+ ra.port = d->remotePort;
+ }
+
+ d->allowCSF = allowClientSendFirst;
+ d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
+ d->setSecurityProps();
+
+ if(!d->c->clientStart(mechlist))
+ return false;
+ d->first = true;
+ d->server = false;
+ d->tried = false;
+ QTimer::singleShot(0, this, SLOT(tryAgain()));
+ return true;
+}
+
+bool SASL::startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist)
+{
+ QCA_SASLHostPort la, ra;
+ if(d->localPort != -1) {
+ la.addr = d->localAddr;
+ la.port = d->localPort;
+ }
+ if(d->remotePort != -1) {
+ ra.addr = d->remoteAddr;
+ ra.port = d->remotePort;
+ }
+
+ d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0);
+ d->setSecurityProps();
+
+ if(!d->c->serverStart(realm, mechlist, saslappname))
+ return false;
+ d->first = true;
+ d->server = true;
+ d->tried = false;
+ return true;
+}
+
+void SASL::putServerFirstStep(const QString &mech)
+{
+ int r = d->c->serverFirstStep(mech, 0);
+ handleServerFirstStep(r);
+}
+
+void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit)
+{
+ int r = d->c->serverFirstStep(mech, &clientInit);
+ handleServerFirstStep(r);
+}
+
+void SASL::handleServerFirstStep(int r)
+{
+ if(r == QCA_SASLContext::Success)
+ authenticated();
+ else if(r == QCA_SASLContext::Continue)
+ nextStep(d->c->result());
+ else if(r == QCA_SASLContext::AuthCheck)
+ tryAgain();
+ else
+ error(ErrAuth);
+}
+
+void SASL::putStep(const QByteArray &stepData)
+{
+ d->stepData = stepData.copy();
+ tryAgain();
+}
+
+void SASL::setUsername(const QString &user)
+{
+ d->c->setClientParams(&user, 0, 0, 0);
+}
+
+void SASL::setAuthzid(const QString &authzid)
+{
+ d->c->setClientParams(0, &authzid, 0, 0);
+}
+
+void SASL::setPassword(const QString &pass)
+{
+ d->c->setClientParams(0, 0, &pass, 0);
+}
+
+void SASL::setRealm(const QString &realm)
+{
+ d->c->setClientParams(0, 0, 0, &realm);
+}
+
+void SASL::continueAfterParams()
+{
+ tryAgain();
+}
+
+void SASL::continueAfterAuthCheck()
+{
+ tryAgain();
+}
+
+void SASL::tryAgain()
+{
+ int r;
+
+ if(d->server) {
+ if(!d->tried) {
+ r = d->c->nextStep(d->stepData);
+ d->tried = true;
+ }
+ else {
+ r = d->c->tryAgain();
+ }
+
+ if(r == QCA_SASLContext::Error) {
+ error(ErrAuth);
+ return;
+ }
+ else if(r == QCA_SASLContext::Continue) {
+ d->tried = false;
+ nextStep(d->c->result());
+ return;
+ }
+ else if(r == QCA_SASLContext::AuthCheck) {
+ authCheck(d->c->username(), d->c->authzid());
+ return;
+ }
+ }
+ else {
+ if(d->first) {
+ if(!d->tried) {
+ r = d->c->clientFirstStep(d->allowCSF);
+ d->tried = true;
+ }
+ else
+ r = d->c->tryAgain();
+
+ if(r == QCA_SASLContext::Error) {
+ error(ErrAuth);
+ return;
+ }
+ else if(r == QCA_SASLContext::NeedParams) {
+ //d->tried = false;
+ QCA_SASLNeedParams np = d->c->clientParamsNeeded();
+ needParams(np.user, np.authzid, np.pass, np.realm);
+ return;
+ }
+
+ QString mech = d->c->mech();
+ const QByteArray *clientInit = d->c->clientInit();
+
+ d->first = false;
+ d->tried = false;
+ clientFirstStep(mech, clientInit);
+ }
+ else {
+ if(!d->tried) {
+ r = d->c->nextStep(d->stepData);
+ d->tried = true;
+ }
+ else
+ r = d->c->tryAgain();
+
+ if(r == QCA_SASLContext::Error) {
+ error(ErrAuth);
+ return;
+ }
+ else if(r == QCA_SASLContext::NeedParams) {
+ //d->tried = false;
+ QCA_SASLNeedParams np = d->c->clientParamsNeeded();
+ needParams(np.user, np.authzid, np.pass, np.realm);
+ return;
+ }
+ d->tried = false;
+ //else if(r == QCA_SASLContext::Continue) {
+ nextStep(d->c->result());
+ // return;
+ //}
+ }
+ }
+
+ if(r == QCA_SASLContext::Success)
+ authenticated();
+ else if(r == QCA_SASLContext::Error)
+ error(ErrAuth);
+}
+
+int SASL::ssf() const
+{
+ return d->c->security();
+}
+
+void SASL::write(const QByteArray &a)
+{
+ QByteArray b;
+ if(!d->c->encode(a, &b)) {
+ error(ErrCrypt);
+ return;
+ }
+ int oldsize = d->outbuf.size();
+ d->outbuf.resize(oldsize + b.size());
+ memcpy(d->outbuf.data() + oldsize, b.data(), b.size());
+ readyReadOutgoing(a.size());
+}
+
+QByteArray SASL::read()
+{
+ QByteArray a = d->inbuf.copy();
+ d->inbuf.resize(0);
+ return a;
+}
+
+void SASL::writeIncoming(const QByteArray &a)
+{
+ QByteArray b;
+ if(!d->c->decode(a, &b)) {
+ error(ErrCrypt);
+ return;
+ }
+ int oldsize = d->inbuf.size();
+ d->inbuf.resize(oldsize + b.size());
+ memcpy(d->inbuf.data() + oldsize, b.data(), b.size());
+ readyRead();
+}
+
+QByteArray SASL::readOutgoing()
+{
+ QByteArray a = d->outbuf.copy();
+ d->outbuf.resize(0);
+ return a;
+}
+
+#include "qca.moc"
diff --git a/kopete/protocols/jabber/libiris/qca/src/qca.h b/kopete/protocols/jabber/libiris/qca/src/qca.h
new file mode 100644
index 00000000..e7cd1609
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/qca/src/qca.h
@@ -0,0 +1,466 @@
+/*
+ * qca.h - Qt Cryptographic Architecture
+ * Copyright (C) 2003 Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef QCA_H
+#define QCA_H
+
+#include<qstring.h>
+#include<qcstring.h>
+#include<qdatetime.h>
+#include<qmap.h>
+#include<qptrlist.h>
+#include<qobject.h>
+
+#ifdef Q_OS_WIN32
+# ifndef QCA_STATIC
+# ifdef QCA_MAKEDLL
+# define QCA_EXPORT __declspec(dllexport)
+# else
+# define QCA_EXPORT __declspec(dllimport)
+# endif
+# endif
+#endif
+#ifndef QCA_EXPORT
+#define QCA_EXPORT
+#endif
+
+#ifdef Q_OS_WIN32
+# ifdef QCA_PLUGIN_DLL
+# define QCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+# else
+# define QCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
+# endif
+#endif
+#ifndef QCA_PLUGIN_EXPORT
+#define QCA_PLUGIN_EXPORT extern "C"
+#endif
+
+class QHostAddress;
+class QStringList;
+
+class QCAProvider;
+class QCA_HashContext;
+class QCA_CipherContext;
+class QCA_CertContext;
+
+namespace QCA
+{
+ enum {
+ CAP_SHA1 = 0x0001,
+ CAP_SHA256 = 0x0002,
+ CAP_MD5 = 0x0004,
+ CAP_BlowFish = 0x0008,
+ CAP_TripleDES = 0x0010,
+ CAP_AES128 = 0x0020,
+ CAP_AES256 = 0x0040,
+ CAP_RSA = 0x0080,
+ CAP_X509 = 0x0100,
+ CAP_TLS = 0x0200,
+ CAP_SASL = 0x0400
+ };
+
+ enum {
+ CBC = 0x0001,
+ CFB = 0x0002
+ };
+
+ enum {
+ Encrypt = 0x0001,
+ Decrypt = 0x0002
+ };
+
+ QCA_EXPORT void init();
+ QCA_EXPORT bool isSupported(int capabilities);
+ QCA_EXPORT void insertProvider(QCAProvider *);
+ QCA_EXPORT void unloadAllPlugins();
+
+ QCA_EXPORT QString arrayToHex(const QByteArray &);
+ QCA_EXPORT QByteArray hexToArray(const QString &);
+
+ class QCA_EXPORT Hash
+ {
+ public:
+ Hash(const Hash &);
+ Hash & operator=(const Hash &);
+ ~Hash();
+
+ void clear();
+ void update(const QByteArray &a);
+ QByteArray final();
+
+ protected:
+ Hash(QCA_HashContext *);
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+ template <class T>
+ class QCA_EXPORT HashStatic
+ {
+ public:
+ HashStatic<T>() {}
+
+ static QByteArray hash(const QByteArray &a)
+ {
+ T obj;
+ obj.update(a);
+ return obj.final();
+ }
+
+ static QByteArray hash(const QCString &cs)
+ {
+ QByteArray a(cs.length());
+ memcpy(a.data(), cs.data(), a.size());
+ return hash(a);
+ }
+
+ static QString hashToString(const QByteArray &a)
+ {
+ return arrayToHex(hash(a));
+ }
+
+ static QString hashToString(const QCString &cs)
+ {
+ return arrayToHex(hash(cs));
+ }
+ };
+
+ class QCA_EXPORT Cipher
+ {
+ public:
+ Cipher(const Cipher &);
+ Cipher & operator=(const Cipher &);
+ ~Cipher();
+
+ QByteArray dyn_generateKey(int size=-1) const;
+ QByteArray dyn_generateIV() const;
+ void reset(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad=true);
+ bool update(const QByteArray &a);
+ QByteArray final(bool *ok=0);
+
+ protected:
+ Cipher(QCA_CipherContext *, int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad);
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+ template <class T>
+ class QCA_EXPORT CipherStatic
+ {
+ public:
+ CipherStatic<T>() {}
+
+ static QByteArray generateKey(int size=-1)
+ {
+ T obj;
+ return obj.dyn_generateKey(size);
+ }
+
+ static QByteArray generateIV()
+ {
+ T obj;
+ return obj.dyn_generateIV();
+ }
+ };
+
+ class QCA_EXPORT SHA1 : public Hash, public HashStatic<SHA1>
+ {
+ public:
+ SHA1();
+ };
+
+ class QCA_EXPORT SHA256 : public Hash, public HashStatic<SHA256>
+ {
+ public:
+ SHA256();
+ };
+
+ class QCA_EXPORT MD5 : public Hash, public HashStatic<MD5>
+ {
+ public:
+ MD5();
+ };
+
+ class QCA_EXPORT BlowFish : public Cipher, public CipherStatic<BlowFish>
+ {
+ public:
+ BlowFish(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+ };
+
+ class QCA_EXPORT TripleDES : public Cipher, public CipherStatic<TripleDES>
+ {
+ public:
+ TripleDES(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+ };
+
+ class QCA_EXPORT AES128 : public Cipher, public CipherStatic<AES128>
+ {
+ public:
+ AES128(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+ };
+
+ class QCA_EXPORT AES256 : public Cipher, public CipherStatic<AES256>
+ {
+ public:
+ AES256(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true);
+ };
+
+ class RSA;
+ class QCA_EXPORT RSAKey
+ {
+ public:
+ RSAKey();
+ RSAKey(const RSAKey &from);
+ RSAKey & operator=(const RSAKey &from);
+ ~RSAKey();
+
+ bool isNull() const;
+ bool havePublic() const;
+ bool havePrivate() const;
+
+ QByteArray toDER(bool publicOnly=false) const;
+ bool fromDER(const QByteArray &a);
+
+ QString toPEM(bool publicOnly=false) const;
+ bool fromPEM(const QString &);
+
+ // only call if you know what you are doing
+ bool fromNative(void *);
+
+ private:
+ class Private;
+ Private *d;
+
+ friend class RSA;
+ friend class TLS;
+ bool encrypt(const QByteArray &a, QByteArray *out, bool oaep) const;
+ bool decrypt(const QByteArray &a, QByteArray *out, bool oaep) const;
+ bool generate(unsigned int bits);
+ };
+
+ class QCA_EXPORT RSA
+ {
+ public:
+ RSA();
+ ~RSA();
+
+ RSAKey key() const;
+ void setKey(const RSAKey &);
+
+ bool encrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const;
+ bool decrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const;
+
+ static RSAKey generateKey(unsigned int bits);
+
+ private:
+ RSAKey v_key;
+ };
+
+ typedef QMap<QString, QString> CertProperties;
+ class QCA_EXPORT Cert
+ {
+ public:
+ Cert();
+ Cert(const Cert &);
+ Cert & operator=(const Cert &);
+ ~Cert();
+
+ bool isNull() const;
+
+ QString commonName() const;
+ QString serialNumber() const;
+ QString subjectString() const;
+ QString issuerString() const;
+ CertProperties subject() const;
+ CertProperties issuer() const;
+ QDateTime notBefore() const;
+ QDateTime notAfter() const;
+
+ QByteArray toDER() const;
+ bool fromDER(const QByteArray &a);
+
+ QString toPEM() const;
+ bool fromPEM(const QString &);
+
+ private:
+ class Private;
+ Private *d;
+
+ friend class TLS;
+ void fromContext(QCA_CertContext *);
+ };
+
+ class QCA_EXPORT TLS : public QObject
+ {
+ Q_OBJECT
+ public:
+ enum Validity {
+ NoCert,
+ Valid,
+ HostMismatch,
+ Rejected,
+ Untrusted,
+ SignatureFailed,
+ InvalidCA,
+ InvalidPurpose,
+ SelfSigned,
+ Revoked,
+ PathLengthExceeded,
+ Expired,
+ Unknown
+ };
+ enum Error { ErrHandshake, ErrCrypt };
+
+ TLS(QObject *parent=0);
+ ~TLS();
+
+ void setCertificate(const Cert &cert, const RSAKey &key);
+ void setCertificateStore(const QPtrList<Cert> &store); // note: store must persist
+
+ void reset();
+ bool startClient(const QString &host="");
+ bool startServer();
+ void close();
+ bool isHandshaken() const;
+
+ // plain (application side)
+ void write(const QByteArray &a);
+ QByteArray read();
+
+ // encoded (socket side)
+ void writeIncoming(const QByteArray &a);
+ QByteArray readOutgoing();
+ QByteArray readUnprocessed();
+
+ // cert related
+ const Cert & peerCertificate() const;
+ int certificateValidityResult() const;
+
+ signals:
+ void handshaken();
+ void readyRead();
+ void readyReadOutgoing(int plainBytes);
+ void closed();
+ void error(int);
+
+ private slots:
+ void update();
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+ class QCA_EXPORT SASL : public QObject
+ {
+ Q_OBJECT
+ public:
+ enum Error { ErrAuth, ErrCrypt };
+ enum ErrorCond {
+ NoMech,
+ BadProto,
+ BadServ,
+ BadAuth,
+ NoAuthzid,
+ TooWeak,
+ NeedEncrypt,
+ Expired,
+ Disabled,
+ NoUser,
+ RemoteUnavail
+ };
+ SASL(QObject *parent=0);
+ ~SASL();
+
+ static void setAppName(const QString &name);
+
+ void reset();
+ int errorCondition() const;
+
+ // options
+ void setAllowPlain(bool);
+ void setAllowAnonymous(bool);
+ void setAllowActiveVulnerable(bool);
+ void setAllowDictionaryVulnerable(bool);
+ void setRequireForwardSecrecy(bool);
+ void setRequirePassCredentials(bool);
+ void setRequireMutualAuth(bool);
+
+ void setMinimumSSF(int);
+ void setMaximumSSF(int);
+ void setExternalAuthID(const QString &authid);
+ void setExternalSSF(int);
+
+ void setLocalAddr(const QHostAddress &addr, Q_UINT16 port);
+ void setRemoteAddr(const QHostAddress &addr, Q_UINT16 port);
+
+ // initialize
+ bool startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst=true);
+ bool startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist);
+
+ // authentication
+ void putStep(const QByteArray &stepData);
+ void putServerFirstStep(const QString &mech);
+ void putServerFirstStep(const QString &mech, const QByteArray &clientInit);
+ void setUsername(const QString &user);
+ void setAuthzid(const QString &auth);
+ void setPassword(const QString &pass);
+ void setRealm(const QString &realm);
+ void continueAfterParams();
+ void continueAfterAuthCheck();
+
+ // security layer
+ int ssf() const;
+ void write(const QByteArray &a);
+ QByteArray read();
+ void writeIncoming(const QByteArray &a);
+ QByteArray readOutgoing();
+
+ signals:
+ // for authentication
+ void clientFirstStep(const QString &mech, const QByteArray *clientInit);
+ void nextStep(const QByteArray &stepData);
+ void needParams(bool user, bool authzid, bool pass, bool realm);
+ void authCheck(const QString &user, const QString &authzid);
+ void authenticated();
+
+ // for security layer
+ void readyRead();
+ void readyReadOutgoing(int plainBytes);
+
+ // error
+ void error(int);
+
+ private slots:
+ void tryAgain();
+
+ private:
+ class Private;
+ Private *d;
+
+ void handleServerFirstStep(int r);
+ };
+}
+
+#endif
diff --git a/kopete/protocols/jabber/libiris/qca/src/qcaprovider.h b/kopete/protocols/jabber/libiris/qca/src/qcaprovider.h
new file mode 100644
index 00000000..a7f1805b
--- /dev/null
+++ b/kopete/protocols/jabber/libiris/qca/src/qcaprovider.h
@@ -0,0 +1,191 @@
+/*
+ * qcaprovider.h - QCA Plugin API
+ * Copyright (C) 2003 Justin Karneges
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef QCAPROVIDER_H
+#define QCAPROVIDER_H
+
+#include<qglobal.h>
+#include<qstring.h>
+#include<qdatetime.h>
+#include<qobject.h>
+#include<qhostaddress.h>
+#include"qca.h"
+
+#define QCA_PLUGIN_VERSION 1
+
+class QCAProvider
+{
+public:
+ QCAProvider() {}
+ virtual ~QCAProvider() {}
+
+ virtual void init()=0;
+ virtual int qcaVersion() const=0;
+ virtual int capabilities() const=0;
+ virtual void *context(int cap)=0;
+};
+
+class QCA_HashContext
+{
+public:
+ virtual ~QCA_HashContext() {}
+
+ virtual QCA_HashContext *clone()=0;
+ virtual void reset()=0;
+ virtual void update(const char *in, unsigned int len)=0;
+ virtual void final(QByteArray *out)=0;
+};
+
+class QCA_CipherContext
+{
+public:
+ virtual ~QCA_CipherContext() {}
+
+ virtual QCA_CipherContext *clone()=0;
+ virtual int keySize()=0;
+ virtual int blockSize()=0;
+ virtual bool generateKey(char *out, int keysize=-1)=0;
+ virtual bool generateIV(char *out)=0;
+
+ virtual bool setup(int dir, int mode, const char *key, int keysize, const char *iv, bool pad)=0;
+ virtual bool update(const char *in, unsigned int len)=0;
+ virtual bool final(QByteArray *out)=0;
+};
+
+class QCA_RSAKeyContext
+{
+public:
+ virtual ~QCA_RSAKeyContext() {}
+
+ virtual QCA_RSAKeyContext *clone() const=0;
+ virtual bool isNull() const=0;
+ virtual bool havePublic() const=0;
+ virtual bool havePrivate() const=0;
+ virtual bool createFromDER(const char *in, unsigned int len)=0;
+ virtual bool createFromPEM(const char *in, unsigned int len)=0;
+ virtual bool createFromNative(void *in)=0;
+ virtual bool generate(unsigned int bits)=0;
+ virtual bool toDER(QByteArray *out, bool publicOnly)=0;
+ virtual bool toPEM(QByteArray *out, bool publicOnly)=0;
+
+ virtual bool encrypt(const QByteArray &in, QByteArray *out, bool oaep)=0;
+ virtual bool decrypt(const QByteArray &in, QByteArray *out, bool oaep)=0;
+};
+
+struct QCA_CertProperty
+{
+ QString var;
+ QString val;
+};
+
+class QCA_CertContext
+{
+public:
+ virtual ~QCA_CertContext() {}
+
+ virtual QCA_CertContext *clone() const=0;
+ virtual bool isNull() const=0;
+ virtual bool createFromDER(const char *in, unsigned int len)=0;
+ virtual bool createFromPEM(const char *in, unsigned int len)=0;
+ virtual bool toDER(QByteArray *out)=0;
+ virtual bool toPEM(QByteArray *out)=0;
+
+ virtual QString serialNumber() const=0;
+ virtual QString subjectString() const=0;
+ virtual QString issuerString() const=0;
+ virtual QValueList<QCA_CertProperty> subject() const=0;
+ virtual QValueList<QCA_CertProperty> issuer() const=0;
+ virtual QDateTime notBefore() const=0;
+ virtual QDateTime notAfter() const=0;
+ virtual bool matchesAddress(const QString &realHost) const=0;
+};
+
+class QCA_TLSContext
+{
+public:
+ enum Result { Success, Error, Continue };
+ virtual ~QCA_TLSContext() {}
+
+ virtual void reset()=0;
+ virtual bool startClient(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0;
+ virtual bool startServer(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0;
+
+ virtual int handshake(const QByteArray &in, QByteArray *out)=0;
+ virtual int shutdown(const QByteArray &in, QByteArray *out)=0;
+ virtual bool encode(const QByteArray &plain, QByteArray *to_net, int *encoded)=0;
+ virtual bool decode(const QByteArray &from_net, QByteArray *plain, QByteArray *to_net)=0;
+ virtual bool eof() const=0;
+ virtual QByteArray unprocessed()=0;
+
+ virtual QCA_CertContext *peerCertificate() const=0;
+ virtual int validityResult() const=0;
+};
+
+struct QCA_SASLHostPort
+{
+ QHostAddress addr;
+ Q_UINT16 port;
+};
+
+struct QCA_SASLNeedParams
+{
+ bool user, authzid, pass, realm;
+};
+
+class QCA_SASLContext
+{
+public:
+ enum Result { Success, Error, NeedParams, AuthCheck, Continue };
+ virtual ~QCA_SASLContext() {}
+
+ // common
+ virtual void reset()=0;
+ virtual void setCoreProps(const QString &service, const QString &host, QCA_SASLHostPort *local, QCA_SASLHostPort *remote)=0;
+ virtual void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax, const QString &_ext_authid, int _ext_ssf)=0;
+ virtual int security() const=0;
+ virtual int errorCond() const=0;
+
+ // init / first step
+ virtual bool clientStart(const QStringList &mechlist)=0;
+ virtual int clientFirstStep(bool allowClientSendFirst)=0;
+ virtual bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)=0;
+ virtual int serverFirstStep(const QString &mech, const QByteArray *in)=0;
+
+ // get / set params
+ virtual QCA_SASLNeedParams clientParamsNeeded() const=0;
+ virtual void setClientParams(const QString *user, const QString *authzid, const QString *pass, const QString *realm)=0;
+ virtual QString username() const=0;
+ virtual QString authzid() const=0;
+
+ // continue steps
+ virtual int nextStep(const QByteArray &in)=0;
+ virtual int tryAgain()=0;
+
+ // results
+ virtual QString mech() const=0;
+ virtual const QByteArray *clientInit() const=0;
+ virtual QByteArray result() const=0;
+
+ // security layer
+ virtual bool encode(const QByteArray &in, QByteArray *out)=0;
+ virtual bool decode(const QByteArray &in, QByteArray *out)=0;
+};
+
+#endif