From b8760d26ff07cb80584d677ba0d4aa4940728888 Mon Sep 17 00:00:00 2001 From: gregory guy Date: Thu, 2 Jan 2020 11:47:18 +0100 Subject: Conversion to the cmake building system. Signed-off-by: gregory guy (cherry picked from commit 671faf252fe4100120aa86f1e144ae5c93b26900) --- CMakeLists.txt | 69 +++ ConfigureChecks.cmake | 37 ++ config.h.cmake | 8 + src/CMakeLists.txt | 50 ++ src/qca.cpp | 1479 ------------------------------------------------ src/qca.h | 466 ---------------- src/qcaprovider.h | 191 ------- src/tqca.cpp | 1481 +++++++++++++++++++++++++++++++++++++++++++++++++ src/tqca.h | 466 ++++++++++++++++ src/tqca.pc.cmake | 12 + src/tqcaprovider.h | 191 +++++++ 11 files changed, 2314 insertions(+), 2136 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 ConfigureChecks.cmake create mode 100644 config.h.cmake create mode 100644 src/CMakeLists.txt delete mode 100644 src/qca.cpp delete mode 100644 src/qca.h delete mode 100644 src/qcaprovider.h create mode 100644 src/tqca.cpp create mode 100644 src/tqca.h create mode 100644 src/tqca.pc.cmake create mode 100644 src/tqcaprovider.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ba877a9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,69 @@ +############################################ +# # +# Improvements and feedbacks are welcome # +# # +# This file is released under GPL >= 3 # +# # +############################################ + + +cmake_minimum_required( VERSION 2.8 ) + + +#### general package setup + +project( tqca ) +set( VERSION R14.1.0 ) + + +#### include essential cmake modules + +include( FindPkgConfig ) +include( CheckFunctionExists ) +include( CheckSymbolExists ) +include( CheckIncludeFile ) +include( CheckLibraryExists ) +include( CheckCSourceCompiles ) +include( CheckCXXSourceCompiles ) + + +#### include our cmake modules + +set( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ) +include( TDEMacros ) + + +##### setup install paths + +include( TDESetupPaths ) +tde_setup_paths( ) + + +##### optional stuff + +option( WITH_ALL_OPTIONS "Enable all optional support" OFF ) +option( WITH_GCC_VISIBILITY "Enable fvisibility and fvisibility-inlines-hidden" ${WITH_ALL_OPTIONS} ) + + +##### configure checks + +include( ConfigureChecks.cmake ) + + +###### global compiler settings + +add_definitions( -DHAVE_CONFIG_H ) + +set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TQT_CXX_FLAGS}" ) +set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" ) +set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined" ) + + +##### source directories + +add_subdirectory( src ) + + +##### write configure files + +configure_file( config.h.cmake config.h @ONLY ) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake new file mode 100644 index 0000000..fb41aa9 --- /dev/null +++ b/ConfigureChecks.cmake @@ -0,0 +1,37 @@ +########################################### +# # +# Improvements and feedback are welcome # +# # +# This file is released under GPL >= 3 # +# # +########################################### + +# required stuff +tde_setup_architecture_flags( ) + +include(TestBigEndian) +test_big_endian(WORDS_BIGENDIAN) + +tde_setup_largefiles( ) +find_package( TQt ) +find_package( TDE ) + + +##### check for gcc visibility support + +if( WITH_GCC_VISIBILITY ) + tde_setup_gcc_visibility( ) +endif( WITH_GCC_VISIBILITY ) + + +##### look for tqt3 headers path + +execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} + --variable=includedir tqt-mt + OUTPUT_VARIABLE TQT_HEADERS_DIRS + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if( TQT_HEADER_DIRS ) + set( TQT_HEADERS_DIRS "${TQT_HEADERS_DIRS}" ) +endif() diff --git a/config.h.cmake b/config.h.cmake new file mode 100644 index 0000000..61ede3a --- /dev/null +++ b/config.h.cmake @@ -0,0 +1,8 @@ +#define VERSION "@VERSION@" + +// Defined if you have fvisibility and fvisibility-inlines-hidden support. +#cmakedefine __KDE_HAVE_GCC_VISIBILITY 1 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#cmakedefine WORDS_BIGENDIAN @WORDS_BIGENDIAN@ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..1cf2db8 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,50 @@ +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_SOURCE_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} + ${TDE_LIB_DIR} +) + + +##### tqca (shared) + +tde_add_library( ${PROJECT_NAME} SHARED AUTOMOC + + SOURCES + tqca.cpp + LINK + tdecore-shared + + VERSION 1.0.0 + + DESTINATION ${LIB_INSTALL_DIR} +) + + +##### headers + +install( + FILES ${PROJECT_NAME}.h + DESTINATION ${TQT_HEADERS_DIRS} +) + + +##### other data + +string( REGEX REPLACE "^${CMAKE_INSTALL_PREFIX}" "\${prefix}" PC_EXEC_PREFIX ${EXEC_INSTALL_PREFIX} ) +string( REGEX REPLACE "^${CMAKE_INSTALL_PREFIX}" "\${prefix}" TQT_HEADERS_DIRS ${TQT_HEADERS_DIRS} ) +string( REGEX REPLACE "^${CMAKE_INSTALL_PREFIX}" "\${prefix}" PC_LIB_DIR ${LIB_INSTALL_DIR} ) + +configure_file( ${PROJECT_NAME}.pc.cmake ${PROJECT_NAME}.pc @ONLY ) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc + DESTINATION ${PKGCONFIG_INSTALL_DIR} +) diff --git a/src/qca.cpp b/src/qca.cpp deleted file mode 100644 index b54671e..0000000 --- a/src/qca.cpp +++ /dev/null @@ -1,1479 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 providerList; -static bool qca_init = false; - -static bool plugin_have(const TQString &fname) -{ - TQPtrListIterator 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 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 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 list = d->c->subject(); - CertProperties props; - for(TQValueList::ConstIterator it = list.begin(); it != list.end(); ++it) - props[(*it).var] = (*it).val; - return props; -} - -CertProperties Cert::issuer() const -{ - TQValueList list = d->c->issuer(); - CertProperties props; - for(TQValueList::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 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 &store) -{ - // convert the cert list into a context list - d->store.clear(); - TQPtrListIterator 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 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, TQ_UINT16 port) -{ - d->localAddr = addr; - d->localPort = port; -} - -void SASL::setRemoteAddr(const TQHostAddress &addr, TQ_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 deleted file mode 100644 index 11a8b92..0000000 --- a/src/qca.h +++ /dev/null @@ -1,466 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -#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 TQCA_EXPORT HashStatic - { - public: - HashStatic() {} - - 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 TQCA_EXPORT CipherStatic - { - public: - CipherStatic() {} - - 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 - { - public: - SHA1(); - }; - - class TQCA_EXPORT SHA256 : public Hash, public HashStatic - { - public: - SHA256(); - }; - - class TQCA_EXPORT MD5 : public Hash, public HashStatic - { - public: - MD5(); - }; - - class TQCA_EXPORT BlowFish : public Cipher, public CipherStatic - { - 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 - { - 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 - { - 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 - { - 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 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 &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 deleted file mode 100644 index 198b606..0000000 --- a/src/qcaprovider.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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 subject() const=0; - virtual TQValueList 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 &store, const TQCA_CertContext &cert, const TQCA_RSAKeyContext &key)=0; - virtual bool startServer(const TQPtrList &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; - TQ_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 diff --git a/src/tqca.cpp b/src/tqca.cpp new file mode 100644 index 0000000..bd17094 --- /dev/null +++ b/src/tqca.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 "tqca.h" +#include "tqcaprovider.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 providerList; +static bool qca_init = false; + +static bool plugin_have(const TQString &fname) +{ + TQPtrListIterator 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 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 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 list = d->c->subject(); + CertProperties props; + for(TQValueList::ConstIterator it = list.begin(); it != list.end(); ++it) + props[(*it).var] = (*it).val; + return props; +} + +CertProperties Cert::issuer() const +{ + TQValueList list = d->c->issuer(); + CertProperties props; + for(TQValueList::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 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 &store) +{ + // convert the cert list into a context list + d->store.clear(); + TQPtrListIterator 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 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, TQ_UINT16 port) +{ + d->localAddr = addr; + d->localPort = port; +} + +void SASL::setRemoteAddr(const TQHostAddress &addr, TQ_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; +} + +#include "tqca.moc" diff --git a/src/tqca.h b/src/tqca.h new file mode 100644 index 0000000..dc87da1 --- /dev/null +++ b/src/tqca.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 +#include +#include +#include +#include +#include + +#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 TQCA_EXPORT HashStatic + { + public: + HashStatic() {} + + 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 TQCA_EXPORT CipherStatic + { + public: + CipherStatic() {} + + 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 + { + public: + SHA1(); + }; + + class TQCA_EXPORT SHA256 : public Hash, public HashStatic + { + public: + SHA256(); + }; + + class TQCA_EXPORT MD5 : public Hash, public HashStatic + { + public: + MD5(); + }; + + class TQCA_EXPORT BlowFish : public Cipher, public CipherStatic + { + 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 + { + 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 + { + 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 + { + 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 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 &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/tqca.pc.cmake b/src/tqca.pc.cmake new file mode 100644 index 0000000..1ba2793 --- /dev/null +++ b/src/tqca.pc.cmake @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@PC_EXEC_PREFIX@ +libdir=@PC_LIB_DIR@ +includedir=@TQT_HEADERS_DIRS@ + +Name: @PROJECT_NAME@ +Description: TQt Cryptographic Architecture. +URL: https://mirror.git.trinitydesktop.org/gitea/TDE/tqca.git +Requires: +Version: 1.0.0 +Libs: -L${libdir} -l@PROJECT_NAME@ +Cflags: -I${includedir} diff --git a/src/tqcaprovider.h b/src/tqcaprovider.h new file mode 100644 index 0000000..27ed422 --- /dev/null +++ b/src/tqcaprovider.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 +#include +#include +#include +#include +#include "tqca.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 subject() const=0; + virtual TQValueList 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 &store, const TQCA_CertContext &cert, const TQCA_RSAKeyContext &key)=0; + virtual bool startServer(const TQPtrList &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; + TQ_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 -- cgit v1.2.1