summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDarrell Anderson <humanreadable@yahoo.com>2012-04-17 19:51:44 -0500
committerDarrell Anderson <humanreadable@yahoo.com>2012-04-17 19:51:44 -0500
commitc663e43e7172bb80a8fb779e4dc74f579a60ec45 (patch)
treefd72db9c80e6c1aacf67e8bd24f75a4da57c4a2e /src
downloadtqca-c663e43e7172bb80a8fb779e4dc74f579a60ec45.tar.gz
tqca-c663e43e7172bb80a8fb779e4dc74f579a60ec45.zip
Added tqca package to the sources tree. This module is from
the original qca-1.0 sources with the TQt layer added. This resolves bug report 817.
Diffstat (limited to 'src')
-rw-r--r--src/qca.cpp1479
-rw-r--r--src/qca.h466
-rw-r--r--src/qcaprovider.h191
3 files changed, 2136 insertions, 0 deletions
diff --git a/src/qca.cpp b/src/qca.cpp
new file mode 100644
index 0000000..7db8379
--- /dev/null
+++ b/src/qca.cpp
@@ -0,0 +1,1479 @@
+/*
+ * 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<tqptrlist.h>
+#include<tqdir.h>
+#include<tqfileinfo.h>
+#include<tqstringlist.h>
+#include<tqlibrary.h>
+#include<tqtimer.h>
+#include<tqhostaddress.h>
+#include<tqapplication.h>
+#include<tqguardedptr.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 TQCA;
+
+class ProviderItem
+{
+public:
+ TQCAProvider *p;
+ TQString fname;
+
+ static ProviderItem *load(const TQString &fname)
+ {
+ TQLibrary *lib = new TQLibrary(fname);
+ if(!lib->load()) {
+ delete lib;
+ return 0;
+ }
+ void *s = lib->resolve("createProvider");
+ if(!s) {
+ delete lib;
+ return 0;
+ }
+ TQCAProvider *(*createProvider)() = (TQCAProvider *(*)())s;
+ TQCAProvider *p = createProvider();
+ if(!p) {
+ delete lib;
+ return 0;
+ }
+ ProviderItem *i = new ProviderItem(lib, p);
+ i->fname = fname;
+ return i;
+ }
+
+ static ProviderItem *fromClass(TQCAProvider *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:
+ TQLibrary *lib;
+ bool init_done;
+
+ ProviderItem(TQLibrary *_lib, TQCAProvider *_p)
+ {
+ lib = _lib;
+ p = _p;
+ init_done = false;
+ }
+};
+
+static TQPtrList<ProviderItem> providerList;
+static bool qca_init = false;
+
+static bool plugin_have(const TQString &fname)
+{
+ TQPtrListIterator<ProviderItem> it(providerList);
+ for(ProviderItem *i; (i = it.current()); ++it) {
+ if(i->fname == fname)
+ return true;
+ }
+ return false;
+}
+
+static void plugin_scan()
+{
+ TQStringList dirs = TQApplication::libraryPaths();
+ for(TQStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
+ TQDir libpath(*it);
+ TQDir dir(libpath.filePath("crypto"));
+ if(!dir.exists())
+ continue;
+
+ TQStringList list = dir.entryList();
+ for(TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ TQFileInfo fi(dir.filePath(*it));
+ if(fi.isDir())
+ continue;
+ if(fi.extension() != PLUGIN_EXT)
+ continue;
+ TQString 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() != TQCA_PLUGIN_VERSION) {
+ delete i;
+ continue;
+ }
+
+ providerList.append(i);
+ }
+ }
+}
+
+static void plugin_addClass(TQCAProvider *p)
+{
+ ProviderItem *i = ProviderItem::fromClass(p);
+ providerList.prepend(i);
+}
+
+static void plugin_unloadall()
+{
+ providerList.clear();
+}
+
+static int plugin_caps()
+{
+ int caps = 0;
+ TQPtrListIterator<ProviderItem> it(providerList);
+ for(ProviderItem *i; (i = it.current()); ++it)
+ caps |= i->p->capabilities();
+ return caps;
+}
+
+TQString TQCA::arrayToHex(const TQByteArray &a)
+{
+ TQString out;
+ for(int n = 0; n < (int)a.size(); ++n) {
+ TQString str;
+ str.sprintf("%02x", (uchar)a[n]);
+ out.append(str);
+ }
+ return out;
+}
+
+TQByteArray TQCA::hexToArray(const TQString &str)
+{
+ TQByteArray 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 TQCA::init()
+{
+ if(qca_init)
+ return;
+ qca_init = true;
+ providerList.setAutoDelete(true);
+}
+
+bool TQCA::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 TQCA::insertProvider(TQCAProvider *p)
+{
+ plugin_addClass(p);
+}
+
+void TQCA::unloadAllPlugins()
+{
+ plugin_unloadall();
+}
+
+static void *getContext(int cap)
+{
+ init();
+
+ // this call will also trip a scan for new plugins if needed
+ if(!TQCA::isSupported(cap))
+ return 0;
+
+ TQPtrListIterator<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();
+ }
+
+ TQCA_HashContext *c;
+};
+
+Hash::Hash(TQCA_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 TQByteArray &a)
+{
+ d->c->update(a.data(), a.size());
+}
+
+TQByteArray Hash::final()
+{
+ TQByteArray 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;
+ }
+
+ TQCA_CipherContext *c;
+ int dir;
+ int mode;
+ TQByteArray key, iv;
+ bool err;
+};
+
+Cipher::Cipher(TQCA_CipherContext *c, int dir, int mode, const TQByteArray &key, const TQByteArray &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;
+}
+
+TQByteArray Cipher::dyn_generateKey(int size) const
+{
+ TQByteArray buf;
+ if(size != -1)
+ buf.resize(size);
+ else
+ buf.resize(d->c->keySize());
+ if(!d->c->generateKey(buf.data(), size))
+ return TQByteArray();
+ return buf;
+}
+
+TQByteArray Cipher::dyn_generateIV() const
+{
+ TQByteArray buf(d->c->blockSize());
+ if(!d->c->generateIV(buf.data()))
+ return TQByteArray();
+ return buf;
+}
+
+void Cipher::reset(int dir, int mode, const TQByteArray &key, const TQByteArray &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 TQByteArray &a)
+{
+ if(d->err)
+ return false;
+
+ if(!a.isEmpty()) {
+ if(!d->c->update(a.data(), a.size())) {
+ d->err = true;
+ return false;
+ }
+ }
+ return true;
+}
+
+TQByteArray Cipher::final(bool *ok)
+{
+ if(ok)
+ *ok = false;
+ if(d->err)
+ return TQByteArray();
+
+ TQByteArray out;
+ if(!d->c->final(&out)) {
+ d->err = true;
+ return TQByteArray();
+ }
+ if(ok)
+ *ok = true;
+ return out;
+}
+
+
+//----------------------------------------------------------------------------
+// SHA1
+//----------------------------------------------------------------------------
+SHA1::SHA1()
+:Hash((TQCA_HashContext *)getContext(CAP_SHA1))
+{
+}
+
+
+//----------------------------------------------------------------------------
+// SHA256
+//----------------------------------------------------------------------------
+SHA256::SHA256()
+:Hash((TQCA_HashContext *)getContext(CAP_SHA256))
+{
+}
+
+
+//----------------------------------------------------------------------------
+// MD5
+//----------------------------------------------------------------------------
+MD5::MD5()
+:Hash((TQCA_HashContext *)getContext(CAP_MD5))
+{
+}
+
+
+//----------------------------------------------------------------------------
+// BlowFish
+//----------------------------------------------------------------------------
+BlowFish::BlowFish(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad)
+:Cipher((TQCA_CipherContext *)getContext(CAP_BlowFish), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// TripleDES
+//----------------------------------------------------------------------------
+TripleDES::TripleDES(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad)
+:Cipher((TQCA_CipherContext *)getContext(CAP_TripleDES), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// AES128
+//----------------------------------------------------------------------------
+AES128::AES128(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad)
+:Cipher((TQCA_CipherContext *)getContext(CAP_AES128), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// AES256
+//----------------------------------------------------------------------------
+AES256::AES256(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad)
+:Cipher((TQCA_CipherContext *)getContext(CAP_AES256), dir, mode, key, iv, pad)
+{
+}
+
+
+//----------------------------------------------------------------------------
+// RSAKey
+//----------------------------------------------------------------------------
+class RSAKey::Private
+{
+public:
+ Private()
+ {
+ c = 0;
+ }
+
+ ~Private()
+ {
+ delete c;
+ }
+
+ TQCA_RSAKeyContext *c;
+};
+
+RSAKey::RSAKey()
+{
+ d = new Private;
+ d->c = (TQCA_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();
+}
+
+TQByteArray RSAKey::toDER(bool publicOnly) const
+{
+ TQByteArray out;
+ if(!d->c->toDER(&out, publicOnly))
+ return TQByteArray();
+ return out;
+}
+
+bool RSAKey::fromDER(const TQByteArray &a)
+{
+ return d->c->createFromDER(a.data(), a.size());
+}
+
+TQString RSAKey::toPEM(bool publicOnly) const
+{
+ TQByteArray out;
+ if(!d->c->toPEM(&out, publicOnly))
+ return TQByteArray();
+
+ TQCString cs;
+ cs.resize(out.size()+1);
+ memcpy(cs.data(), out.data(), out.size());
+ return TQString::fromLatin1(cs);
+}
+
+bool RSAKey::fromPEM(const TQString &str)
+{
+ TQCString cs = str.latin1();
+ TQByteArray 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 TQByteArray &a, TQByteArray *b, bool oaep) const
+{
+ TQByteArray out;
+ if(!d->c->encrypt(a, &out, oaep))
+ return false;
+ *b = out;
+ return true;
+}
+
+bool RSAKey::decrypt(const TQByteArray &a, TQByteArray *b, bool oaep) const
+{
+ TQByteArray 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 TQByteArray &a, TQByteArray *b, bool oaep) const
+{
+ if(v_key.isNull())
+ return false;
+ return v_key.encrypt(a, b, oaep);
+}
+
+bool RSA::decrypt(const TQByteArray &a, TQByteArray *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;
+ }
+
+ TQCA_CertContext *c;
+};
+
+Cert::Cert()
+{
+ d = new Private;
+ d->c = (TQCA_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(TQCA_CertContext *ctx)
+{
+ delete d->c;
+ d->c = ctx;
+}
+
+bool Cert::isNull() const
+{
+ return d->c->isNull();
+}
+
+TQString Cert::commonName() const
+{
+ CertProperties props = subject();
+ return props["CN"];
+}
+
+TQString Cert::serialNumber() const
+{
+ return d->c->serialNumber();
+}
+
+TQString Cert::subjectString() const
+{
+ return d->c->subjectString();
+}
+
+TQString Cert::issuerString() const
+{
+ return d->c->issuerString();
+}
+
+CertProperties Cert::subject() const
+{
+ TQValueList<TQCA_CertProperty> list = d->c->subject();
+ CertProperties props;
+ for(TQValueList<TQCA_CertProperty>::ConstIterator it = list.begin(); it != list.end(); ++it)
+ props[(*it).var] = (*it).val;
+ return props;
+}
+
+CertProperties Cert::issuer() const
+{
+ TQValueList<TQCA_CertProperty> list = d->c->issuer();
+ CertProperties props;
+ for(TQValueList<TQCA_CertProperty>::ConstIterator it = list.begin(); it != list.end(); ++it)
+ props[(*it).var] = (*it).val;
+ return props;
+}
+
+TQDateTime Cert::notBefore() const
+{
+ return d->c->notBefore();
+}
+
+TQDateTime Cert::notAfter() const
+{
+ return d->c->notAfter();
+}
+
+TQByteArray Cert::toDER() const
+{
+ TQByteArray out;
+ if(!d->c->toDER(&out))
+ return TQByteArray();
+ return out;
+}
+
+bool Cert::fromDER(const TQByteArray &a)
+{
+ return d->c->createFromDER(a.data(), a.size());
+}
+
+TQString Cert::toPEM() const
+{
+ TQByteArray out;
+ if(!d->c->toPEM(&out))
+ return TQByteArray();
+
+ TQCString cs;
+ cs.resize(out.size()+1);
+ memcpy(cs.data(), out.data(), out.size());
+ return TQString::fromLatin1(cs);
+}
+
+bool Cert::fromPEM(const TQString &str)
+{
+ TQCString cs = str.latin1();
+ TQByteArray 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 = (TQCA_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(TQByteArray *a, const TQByteArray &b)
+ {
+ int oldsize = a->size();
+ a->resize(oldsize + b.size());
+ memcpy(a->data() + oldsize, b.data(), b.size());
+ }
+
+ Cert cert;
+ TQCA_TLSContext *c;
+ TQByteArray in, out, to_net, from_net;
+ int bytesEncoded;
+ bool tryMore;
+ bool handshaken;
+ TQString host;
+ bool hostMismatch;
+ bool closing;
+
+ Cert ourCert;
+ RSAKey ourKey;
+ TQPtrList<TQCA_CertContext> store;
+};
+
+TLS::TLS(TQObject *parent)
+:TQObject(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 TQPtrList<Cert> &store)
+{
+ // convert the cert list into a context list
+ d->store.clear();
+ TQPtrListIterator<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 TQString &host)
+{
+ d->reset();
+ d->host = host;
+
+ if(!d->c->startClient(d->store, *d->ourCert.d->c, *d->ourKey.d->c))
+ return false;
+ TQTimer::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;
+ TQTimer::singleShot(0, this, SLOT(update()));
+ return true;
+}
+
+void TLS::close()
+{
+ if(!d->handshaken || d->closing)
+ return;
+
+ d->closing = true;
+ TQTimer::singleShot(0, this, SLOT(update()));
+}
+
+bool TLS::isHandshaken() const
+{
+ return d->handshaken;
+}
+
+void TLS::write(const TQByteArray &a)
+{
+ d->appendArray(&d->out, a);
+ update();
+}
+
+TQByteArray TLS::read()
+{
+ TQByteArray a = d->in.copy();
+ d->in.resize(0);
+ return a;
+}
+
+void TLS::writeIncoming(const TQByteArray &a)
+{
+ d->appendArray(&d->from_net, a);
+ update();
+}
+
+TQByteArray TLS::readOutgoing()
+{
+ TQByteArray a = d->to_net.copy();
+ d->to_net.resize(0);
+ return a;
+}
+
+TQByteArray TLS::readUnprocessed()
+{
+ TQByteArray 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 TQCA::TLS::HostMismatch;
+ else
+ return d->c->validityResult();
+}
+
+void TLS::update()
+{
+ bool force_read = false;
+ bool eof = false;
+ bool done = false;
+ TQGuardedPtr<TLS> self = this;
+
+ if(d->closing) {
+ TQByteArray a;
+ int r = d->c->shutdown(d->from_net, &a);
+ d->from_net.resize(0);
+ if(r == TQCA_TLSContext::Error) {
+ reset();
+ error(ErrHandshake);
+ return;
+ }
+ if(r == TQCA_TLSContext::Success) {
+ d->from_net = d->c->unprocessed().copy();
+ done = true;
+ }
+ d->appendArray(&d->to_net, a);
+ }
+ else {
+ if(!d->handshaken) {
+ TQByteArray a;
+ int r = d->c->handshake(d->from_net, &a);
+ d->from_net.resize(0);
+ if(r == TQCA_TLSContext::Error) {
+ reset();
+ error(ErrHandshake);
+ return;
+ }
+ d->appendArray(&d->to_net, a);
+ if(r == TQCA_TLSContext::Success) {
+ TQCA_CertContext *cc = d->c->peerCertificate();
+ if(cc && !d->host.isEmpty() && d->c->validityResult() == TQCA::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;
+ TQByteArray 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) {
+ TQByteArray 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
+//----------------------------------------------------------------------------
+TQString saslappname = "qca";
+class SASL::Private
+{
+public:
+ Private()
+ {
+ c = (TQCA_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;
+ TQString ext_authid;
+ int ext_ssf;
+
+ bool tried;
+ TQCA_SASLContext *c;
+ TQHostAddress localAddr, remoteAddr;
+ int localPort, remotePort;
+ TQByteArray stepData;
+ bool allowCSF;
+ bool first, server;
+
+ TQByteArray inbuf, outbuf;
+};
+
+SASL::SASL(TQObject *parent)
+:TQObject(parent)
+{
+ d = new Private;
+ reset();
+}
+
+SASL::~SASL()
+{
+ delete d;
+}
+
+void SASL::setAppName(const TQString &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 TQString &authid)
+{
+ d->ext_authid = authid;
+}
+
+void SASL::setExternalSSF(int x)
+{
+ d->ext_ssf = x;
+}
+
+void SASL::setLocalAddr(const TQHostAddress &addr, Q_UINT16 port)
+{
+ d->localAddr = addr;
+ d->localPort = port;
+}
+
+void SASL::setRemoteAddr(const TQHostAddress &addr, Q_UINT16 port)
+{
+ d->remoteAddr = addr;
+ d->remotePort = port;
+}
+
+bool SASL::startClient(const TQString &service, const TQString &host, const TQStringList &mechlist, bool allowClientSendFirst)
+{
+ TQCA_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;
+ TQTimer::singleShot(0, this, SLOT(tryAgain()));
+ return true;
+}
+
+bool SASL::startServer(const TQString &service, const TQString &host, const TQString &realm, TQStringList *mechlist)
+{
+ TQCA_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 TQString &mech)
+{
+ int r = d->c->serverFirstStep(mech, 0);
+ handleServerFirstStep(r);
+}
+
+void SASL::putServerFirstStep(const TQString &mech, const TQByteArray &clientInit)
+{
+ int r = d->c->serverFirstStep(mech, &clientInit);
+ handleServerFirstStep(r);
+}
+
+void SASL::handleServerFirstStep(int r)
+{
+ if(r == TQCA_SASLContext::Success)
+ authenticated();
+ else if(r == TQCA_SASLContext::Continue)
+ nextStep(d->c->result());
+ else if(r == TQCA_SASLContext::AuthCheck)
+ tryAgain();
+ else
+ error(ErrAuth);
+}
+
+void SASL::putStep(const TQByteArray &stepData)
+{
+ d->stepData = stepData.copy();
+ tryAgain();
+}
+
+void SASL::setUsername(const TQString &user)
+{
+ d->c->setClientParams(&user, 0, 0, 0);
+}
+
+void SASL::setAuthzid(const TQString &authzid)
+{
+ d->c->setClientParams(0, &authzid, 0, 0);
+}
+
+void SASL::setPassword(const TQString &pass)
+{
+ d->c->setClientParams(0, 0, &pass, 0);
+}
+
+void SASL::setRealm(const TQString &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 == TQCA_SASLContext::Error) {
+ error(ErrAuth);
+ return;
+ }
+ else if(r == TQCA_SASLContext::Continue) {
+ d->tried = false;
+ nextStep(d->c->result());
+ return;
+ }
+ else if(r == TQCA_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 == TQCA_SASLContext::Error) {
+ error(ErrAuth);
+ return;
+ }
+ else if(r == TQCA_SASLContext::NeedParams) {
+ //d->tried = false;
+ TQCA_SASLNeedParams np = d->c->clientParamsNeeded();
+ needParams(np.user, np.authzid, np.pass, np.realm);
+ return;
+ }
+
+ TQString mech = d->c->mech();
+ const TQByteArray *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 == TQCA_SASLContext::Error) {
+ error(ErrAuth);
+ return;
+ }
+ else if(r == TQCA_SASLContext::NeedParams) {
+ //d->tried = false;
+ TQCA_SASLNeedParams np = d->c->clientParamsNeeded();
+ needParams(np.user, np.authzid, np.pass, np.realm);
+ return;
+ }
+ d->tried = false;
+ //else if(r == TQCA_SASLContext::Continue) {
+ nextStep(d->c->result());
+ // return;
+ //}
+ }
+ }
+
+ if(r == TQCA_SASLContext::Success)
+ authenticated();
+ else if(r == TQCA_SASLContext::Error)
+ error(ErrAuth);
+}
+
+int SASL::ssf() const
+{
+ return d->c->security();
+}
+
+void SASL::write(const TQByteArray &a)
+{
+ TQByteArray 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());
+}
+
+TQByteArray SASL::read()
+{
+ TQByteArray a = d->inbuf.copy();
+ d->inbuf.resize(0);
+ return a;
+}
+
+void SASL::writeIncoming(const TQByteArray &a)
+{
+ TQByteArray 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();
+}
+
+TQByteArray SASL::readOutgoing()
+{
+ TQByteArray a = d->outbuf.copy();
+ d->outbuf.resize(0);
+ return a;
+}
diff --git a/src/qca.h b/src/qca.h
new file mode 100644
index 0000000..11a8b92
--- /dev/null
+++ b/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 TQCA_H
+#define TQCA_H
+
+#include<tqstring.h>
+#include<tqcstring.h>
+#include<tqdatetime.h>
+#include<tqmap.h>
+#include<tqptrlist.h>
+#include<tqobject.h>
+
+#ifdef Q_OS_WIN32
+# ifndef TQCA_STATIC
+# ifdef TQCA_MAKEDLL
+# define TQCA_EXPORT __declspec(dllexport)
+# else
+# define TQCA_EXPORT __declspec(dllimport)
+# endif
+# endif
+#endif
+#ifndef TQCA_EXPORT
+#define TQCA_EXPORT
+#endif
+
+#ifdef Q_OS_WIN32
+# ifdef TQCA_PLUGIN_DLL
+# define TQCA_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+# else
+# define TQCA_PLUGIN_EXPORT extern "C" __declspec(dllimport)
+# endif
+#endif
+#ifndef TQCA_PLUGIN_EXPORT
+#define TQCA_PLUGIN_EXPORT extern "C"
+#endif
+
+class TQHostAddress;
+class TQStringList;
+
+class TQCAProvider;
+class TQCA_HashContext;
+class TQCA_CipherContext;
+class TQCA_CertContext;
+
+namespace TQCA
+{
+ 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
+ };
+
+ TQCA_EXPORT void init();
+ TQCA_EXPORT bool isSupported(int capabilities);
+ TQCA_EXPORT void insertProvider(TQCAProvider *);
+ TQCA_EXPORT void unloadAllPlugins();
+
+ TQCA_EXPORT TQString arrayToHex(const TQByteArray &);
+ TQCA_EXPORT TQByteArray hexToArray(const TQString &);
+
+ class TQCA_EXPORT Hash
+ {
+ public:
+ Hash(const Hash &);
+ Hash & operator=(const Hash &);
+ ~Hash();
+
+ void clear();
+ void update(const TQByteArray &a);
+ TQByteArray final();
+
+ protected:
+ Hash(TQCA_HashContext *);
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+ template <class T>
+ class TQCA_EXPORT HashStatic
+ {
+ public:
+ HashStatic<T>() {}
+
+ static TQByteArray hash(const TQByteArray &a)
+ {
+ T obj;
+ obj.update(a);
+ return obj.final();
+ }
+
+ static TQByteArray hash(const TQCString &cs)
+ {
+ TQByteArray a(cs.length());
+ memcpy(a.data(), cs.data(), a.size());
+ return hash(a);
+ }
+
+ static TQString hashToString(const TQByteArray &a)
+ {
+ return arrayToHex(hash(a));
+ }
+
+ static TQString hashToString(const TQCString &cs)
+ {
+ return arrayToHex(hash(cs));
+ }
+ };
+
+ class TQCA_EXPORT Cipher
+ {
+ public:
+ Cipher(const Cipher &);
+ Cipher & operator=(const Cipher &);
+ ~Cipher();
+
+ TQByteArray dyn_generateKey(int size=-1) const;
+ TQByteArray dyn_generateIV() const;
+ void reset(int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad=true);
+ bool update(const TQByteArray &a);
+ TQByteArray final(bool *ok=0);
+
+ protected:
+ Cipher(TQCA_CipherContext *, int dir, int mode, const TQByteArray &key, const TQByteArray &iv, bool pad);
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+ template <class T>
+ class TQCA_EXPORT CipherStatic
+ {
+ public:
+ CipherStatic<T>() {}
+
+ static TQByteArray generateKey(int size=-1)
+ {
+ T obj;
+ return obj.dyn_generateKey(size);
+ }
+
+ static TQByteArray generateIV()
+ {
+ T obj;
+ return obj.dyn_generateIV();
+ }
+ };
+
+ class TQCA_EXPORT SHA1 : public Hash, public HashStatic<SHA1>
+ {
+ public:
+ SHA1();
+ };
+
+ class TQCA_EXPORT SHA256 : public Hash, public HashStatic<SHA256>
+ {
+ public:
+ SHA256();
+ };
+
+ class TQCA_EXPORT MD5 : public Hash, public HashStatic<MD5>
+ {
+ public:
+ MD5();
+ };
+
+ class TQCA_EXPORT BlowFish : public Cipher, public CipherStatic<BlowFish>
+ {
+ public:
+ BlowFish(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
+ };
+
+ class TQCA_EXPORT TripleDES : public Cipher, public CipherStatic<TripleDES>
+ {
+ public:
+ TripleDES(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
+ };
+
+ class TQCA_EXPORT AES128 : public Cipher, public CipherStatic<AES128>
+ {
+ public:
+ AES128(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
+ };
+
+ class TQCA_EXPORT AES256 : public Cipher, public CipherStatic<AES256>
+ {
+ public:
+ AES256(int dir=Encrypt, int mode=CBC, const TQByteArray &key=TQByteArray(), const TQByteArray &iv=TQByteArray(), bool pad=true);
+ };
+
+ class RSA;
+ class TQCA_EXPORT RSAKey
+ {
+ public:
+ RSAKey();
+ RSAKey(const RSAKey &from);
+ RSAKey & operator=(const RSAKey &from);
+ ~RSAKey();
+
+ bool isNull() const;
+ bool havePublic() const;
+ bool havePrivate() const;
+
+ TQByteArray toDER(bool publicOnly=false) const;
+ bool fromDER(const TQByteArray &a);
+
+ TQString toPEM(bool publicOnly=false) const;
+ bool fromPEM(const TQString &);
+
+ // 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 TQByteArray &a, TQByteArray *out, bool oaep) const;
+ bool decrypt(const TQByteArray &a, TQByteArray *out, bool oaep) const;
+ bool generate(unsigned int bits);
+ };
+
+ class TQCA_EXPORT RSA
+ {
+ public:
+ RSA();
+ ~RSA();
+
+ RSAKey key() const;
+ void setKey(const RSAKey &);
+
+ bool encrypt(const TQByteArray &a, TQByteArray *out, bool oaep=false) const;
+ bool decrypt(const TQByteArray &a, TQByteArray *out, bool oaep=false) const;
+
+ static RSAKey generateKey(unsigned int bits);
+
+ private:
+ RSAKey v_key;
+ };
+
+ typedef TQMap<TQString, TQString> CertProperties;
+ class TQCA_EXPORT Cert
+ {
+ public:
+ Cert();
+ Cert(const Cert &);
+ Cert & operator=(const Cert &);
+ ~Cert();
+
+ bool isNull() const;
+
+ TQString commonName() const;
+ TQString serialNumber() const;
+ TQString subjectString() const;
+ TQString issuerString() const;
+ CertProperties subject() const;
+ CertProperties issuer() const;
+ TQDateTime notBefore() const;
+ TQDateTime notAfter() const;
+
+ TQByteArray toDER() const;
+ bool fromDER(const TQByteArray &a);
+
+ TQString toPEM() const;
+ bool fromPEM(const TQString &);
+
+ private:
+ class Private;
+ Private *d;
+
+ friend class TLS;
+ void fromContext(TQCA_CertContext *);
+ };
+
+ class TQCA_EXPORT TLS : public TQObject
+ {
+ Q_OBJECT
+ public:
+ enum Validity {
+ NoCert,
+ Valid,
+ HostMismatch,
+ Rejected,
+ Untrusted,
+ SignatureFailed,
+ InvalidCA,
+ InvalidPurpose,
+ SelfSigned,
+ Revoked,
+ PathLengthExceeded,
+ Expired,
+ Unknown
+ };
+ enum Error { ErrHandshake, ErrCrypt };
+
+ TLS(TQObject *parent=0);
+ ~TLS();
+
+ void setCertificate(const Cert &cert, const RSAKey &key);
+ void setCertificateStore(const TQPtrList<Cert> &store); // note: store must persist
+
+ void reset();
+ bool startClient(const TQString &host="");
+ bool startServer();
+ void close();
+ bool isHandshaken() const;
+
+ // plain (application side)
+ void write(const TQByteArray &a);
+ TQByteArray read();
+
+ // encoded (socket side)
+ void writeIncoming(const TQByteArray &a);
+ TQByteArray readOutgoing();
+ TQByteArray 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 TQCA_EXPORT SASL : public TQObject
+ {
+ Q_OBJECT
+ public:
+ enum Error { ErrAuth, ErrCrypt };
+ enum ErrorCond {
+ NoMech,
+ BadProto,
+ BadServ,
+ BadAuth,
+ NoAuthzid,
+ TooWeak,
+ NeedEncrypt,
+ Expired,
+ Disabled,
+ NoUser,
+ RemoteUnavail
+ };
+ SASL(TQObject *parent=0);
+ ~SASL();
+
+ static void setAppName(const TQString &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 TQString &authid);
+ void setExternalSSF(int);
+
+ void setLocalAddr(const TQHostAddress &addr, TQ_UINT16 port);
+ void setRemoteAddr(const TQHostAddress &addr, TQ_UINT16 port);
+
+ // initialize
+ bool startClient(const TQString &service, const TQString &host, const TQStringList &mechlist, bool allowClientSendFirst=true);
+ bool startServer(const TQString &service, const TQString &host, const TQString &realm, TQStringList *mechlist);
+
+ // authentication
+ void putStep(const TQByteArray &stepData);
+ void putServerFirstStep(const TQString &mech);
+ void putServerFirstStep(const TQString &mech, const TQByteArray &clientInit);
+ void setUsername(const TQString &user);
+ void setAuthzid(const TQString &auth);
+ void setPassword(const TQString &pass);
+ void setRealm(const TQString &realm);
+ void continueAfterParams();
+ void continueAfterAuthCheck();
+
+ // security layer
+ int ssf() const;
+ void write(const TQByteArray &a);
+ TQByteArray read();
+ void writeIncoming(const TQByteArray &a);
+ TQByteArray readOutgoing();
+
+ signals:
+ // for authentication
+ void clientFirstStep(const TQString &mech, const TQByteArray *clientInit);
+ void nextStep(const TQByteArray &stepData);
+ void needParams(bool user, bool authzid, bool pass, bool realm);
+ void authCheck(const TQString &user, const TQString &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/src/qcaprovider.h b/src/qcaprovider.h
new file mode 100644
index 0000000..1b8277b
--- /dev/null
+++ b/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 TQCAPROVIDER_H
+#define TQCAPROVIDER_H
+
+#include<tqglobal.h>
+#include<tqstring.h>
+#include<tqdatetime.h>
+#include<tqobject.h>
+#include<tqhostaddress.h>
+#include"qca.h"
+
+#define TQCA_PLUGIN_VERSION 1
+
+class TQCAProvider
+{
+public:
+ TQCAProvider() {}
+ virtual ~TQCAProvider() {}
+
+ virtual void init()=0;
+ virtual int qcaVersion() const=0;
+ virtual int capabilities() const=0;
+ virtual void *context(int cap)=0;
+};
+
+class TQCA_HashContext
+{
+public:
+ virtual ~TQCA_HashContext() {}
+
+ virtual TQCA_HashContext *clone()=0;
+ virtual void reset()=0;
+ virtual void update(const char *in, unsigned int len)=0;
+ virtual void final(TQByteArray *out)=0;
+};
+
+class TQCA_CipherContext
+{
+public:
+ virtual ~TQCA_CipherContext() {}
+
+ virtual TQCA_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(TQByteArray *out)=0;
+};
+
+class TQCA_RSAKeyContext
+{
+public:
+ virtual ~TQCA_RSAKeyContext() {}
+
+ virtual TQCA_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(TQByteArray *out, bool publicOnly)=0;
+ virtual bool toPEM(TQByteArray *out, bool publicOnly)=0;
+
+ virtual bool encrypt(const TQByteArray &in, TQByteArray *out, bool oaep)=0;
+ virtual bool decrypt(const TQByteArray &in, TQByteArray *out, bool oaep)=0;
+};
+
+struct TQCA_CertProperty
+{
+ TQString var;
+ TQString val;
+};
+
+class TQCA_CertContext
+{
+public:
+ virtual ~TQCA_CertContext() {}
+
+ virtual TQCA_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(TQByteArray *out)=0;
+ virtual bool toPEM(TQByteArray *out)=0;
+
+ virtual TQString serialNumber() const=0;
+ virtual TQString subjectString() const=0;
+ virtual TQString issuerString() const=0;
+ virtual TQValueList<TQCA_CertProperty> subject() const=0;
+ virtual TQValueList<TQCA_CertProperty> issuer() const=0;
+ virtual TQDateTime notBefore() const=0;
+ virtual TQDateTime notAfter() const=0;
+ virtual bool matchesAddress(const TQString &realHost) const=0;
+};
+
+class TQCA_TLSContext
+{
+public:
+ enum Result { Success, Error, Continue };
+ virtual ~TQCA_TLSContext() {}
+
+ virtual void reset()=0;
+ virtual bool startClient(const TQPtrList<TQCA_CertContext> &store, const TQCA_CertContext &cert, const TQCA_RSAKeyContext &key)=0;
+ virtual bool startServer(const TQPtrList<TQCA_CertContext> &store, const TQCA_CertContext &cert, const TQCA_RSAKeyContext &key)=0;
+
+ virtual int handshake(const TQByteArray &in, TQByteArray *out)=0;
+ virtual int shutdown(const TQByteArray &in, TQByteArray *out)=0;
+ virtual bool encode(const TQByteArray &plain, TQByteArray *to_net, int *encoded)=0;
+ virtual bool decode(const TQByteArray &from_net, TQByteArray *plain, TQByteArray *to_net)=0;
+ virtual bool eof() const=0;
+ virtual TQByteArray unprocessed()=0;
+
+ virtual TQCA_CertContext *peerCertificate() const=0;
+ virtual int validityResult() const=0;
+};
+
+struct TQCA_SASLHostPort
+{
+ TQHostAddress addr;
+ Q_UINT16 port;
+};
+
+struct TQCA_SASLNeedParams
+{
+ bool user, authzid, pass, realm;
+};
+
+class TQCA_SASLContext
+{
+public:
+ enum Result { Success, Error, NeedParams, AuthCheck, Continue };
+ virtual ~TQCA_SASLContext() {}
+
+ // common
+ virtual void reset()=0;
+ virtual void setCoreProps(const TQString &service, const TQString &host, TQCA_SASLHostPort *local, TQCA_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 TQString &_ext_authid, int _ext_ssf)=0;
+ virtual int security() const=0;
+ virtual int errorCond() const=0;
+
+ // init / first step
+ virtual bool clientStart(const TQStringList &mechlist)=0;
+ virtual int clientFirstStep(bool allowClientSendFirst)=0;
+ virtual bool serverStart(const TQString &realm, TQStringList *mechlist, const TQString &name)=0;
+ virtual int serverFirstStep(const TQString &mech, const TQByteArray *in)=0;
+
+ // get / set params
+ virtual TQCA_SASLNeedParams clientParamsNeeded() const=0;
+ virtual void setClientParams(const TQString *user, const TQString *authzid, const TQString *pass, const TQString *realm)=0;
+ virtual TQString username() const=0;
+ virtual TQString authzid() const=0;
+
+ // continue steps
+ virtual int nextStep(const TQByteArray &in)=0;
+ virtual int tryAgain()=0;
+
+ // results
+ virtual TQString mech() const=0;
+ virtual const TQByteArray *clientInit() const=0;
+ virtual TQByteArray result() const=0;
+
+ // security layer
+ virtual bool encode(const TQByteArray &in, TQByteArray *out)=0;
+ virtual bool decode(const TQByteArray &in, TQByteArray *out)=0;
+};
+
+#endif